Skip to content

Commit

Permalink
refactor(eslint-plugin): avoid looking for nodes that do not match th…
Browse files Browse the repository at this point in the history
…e provided options (#3922)

* refactor(eslint-plugin): avoid looking for nodes that do not match the provided options

* refactor: normalize options indexes access

Co-authored-by: Josh Goldberg <joshuakgoldberg@outlook.com>
  • Loading branch information
rafaelss95 and Josh Goldberg committed Oct 18, 2021
1 parent a75d9c8 commit 713fd77
Show file tree
Hide file tree
Showing 18 changed files with 310 additions and 314 deletions.
8 changes: 3 additions & 5 deletions packages/eslint-plugin-tslint/src/rules/config.ts
Expand Up @@ -104,11 +104,9 @@ export default createRule<Options, MessageIds>({
/**
* The TSLint rules configuration passed in by the user
*/
const {
rules: tslintRules,
rulesDirectory: tslintRulesDirectory,
lintFile,
} = context.options[0];
const [
{ rules: tslintRules, rulesDirectory: tslintRulesDirectory, lintFile },
] = context.options;

const program = parserServices.program;

Expand Down
67 changes: 33 additions & 34 deletions packages/eslint-plugin/src/rules/class-literal-property-style.ts
Expand Up @@ -55,9 +55,9 @@ export default util.createRule<Options, MessageIds>({
},
defaultOptions: ['fields'],
create(context, [style]) {
if (style === 'fields') {
return {
MethodDefinition(node: TSESTree.MethodDefinition): void {
return {
...(style === 'fields' && {
MethodDefinition(node): void {
if (
node.kind !== 'get' ||
!node.value.body ||
Expand Down Expand Up @@ -95,38 +95,37 @@ export default util.createRule<Options, MessageIds>({
},
});
},
};
}
}),
...(style === 'getters' && {
PropertyDefinition(node): void {
if (!node.readonly || node.declare) {
return;
}

return {
PropertyDefinition(node: TSESTree.PropertyDefinition): void {
if (!node.readonly || node.declare) {
return;
}

const { value } = node;

if (!value || !isSupportedLiteral(value)) {
return;
}

context.report({
node: node.key,
messageId: 'preferGetterStyle',
fix(fixer) {
const sourceCode = context.getSourceCode();
const name = sourceCode.getText(node.key);

let text = '';

text += printNodeModifiers(node, 'get');
text += node.computed ? `[${name}]` : name;
text += `() { return ${sourceCode.getText(value)}; }`;

return fixer.replaceText(node, text);
},
});
},
const { value } = node;

if (!value || !isSupportedLiteral(value)) {
return;
}

context.report({
node: node.key,
messageId: 'preferGetterStyle',
fix(fixer) {
const sourceCode = context.getSourceCode();
const name = sourceCode.getText(node.key);

let text = '';

text += printNodeModifiers(node, 'get');
text += node.computed ? `[${name}]` : name;
text += `() { return ${sourceCode.getText(value)}; }`;

return fixer.replaceText(node, text);
},
});
},
}),
};
},
});
98 changes: 48 additions & 50 deletions packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts
@@ -1,9 +1,9 @@
import { createRule } from '../util';
import {
AST_NODE_TYPES,
TSESTree,
TSESLint,
TSESTree,
} from '@typescript-eslint/experimental-utils';
import { createRule } from '../util';

type MessageIds = 'preferRecord' | 'preferIndexSignature';
type Options = ['record' | 'index-signature'];
Expand All @@ -29,38 +29,9 @@ export default createRule<Options, MessageIds>({
],
},
defaultOptions: ['record'],
create(context) {
create(context, [mode]) {
const sourceCode = context.getSourceCode();

if (context.options[0] === 'index-signature') {
return {
TSTypeReference(node): void {
const typeName = node.typeName;
if (typeName.type !== AST_NODE_TYPES.Identifier) {
return;
}
if (typeName.name !== 'Record') {
return;
}

const params = node.typeParameters?.params;
if (params?.length !== 2) {
return;
}

context.report({
node,
messageId: 'preferIndexSignature',
fix(fixer) {
const key = sourceCode.getText(params[0]);
const type = sourceCode.getText(params[1]);
return fixer.replaceText(node, `{ [key: ${key}]: ${type} }`);
},
});
},
};
}

function checkMembers(
members: TSESTree.TypeElement[],
node: TSESTree.Node,
Expand Down Expand Up @@ -113,27 +84,54 @@ export default createRule<Options, MessageIds>({
}

return {
TSTypeLiteral(node): void {
checkMembers(node.members, node, '', '');
},
...(mode === 'index-signature' && {
TSTypeReference(node): void {
const typeName = node.typeName;
if (typeName.type !== AST_NODE_TYPES.Identifier) {
return;
}
if (typeName.name !== 'Record') {
return;
}

TSInterfaceDeclaration(node): void {
let genericTypes = '';
const params = node.typeParameters?.params;
if (params?.length !== 2) {
return;
}

if ((node.typeParameters?.params ?? []).length > 0) {
genericTypes = `<${node.typeParameters?.params
.map(p => p.name.name)
.join(', ')}>`;
}
context.report({
node,
messageId: 'preferIndexSignature',
fix(fixer) {
const key = sourceCode.getText(params[0]);
const type = sourceCode.getText(params[1]);
return fixer.replaceText(node, `{ [key: ${key}]: ${type} }`);
},
});
},
}),
...(mode === 'record' && {
TSTypeLiteral(node): void {
checkMembers(node.members, node, '', '');
},
TSInterfaceDeclaration(node): void {
let genericTypes = '';

checkMembers(
node.body.body,
node,
`type ${node.id.name}${genericTypes} = `,
';',
!node.extends?.length,
);
},
if ((node.typeParameters?.params ?? []).length > 0) {
genericTypes = `<${node.typeParameters?.params
.map(p => p.name.name)
.join(', ')}>`;
}

checkMembers(
node.body.body,
node,
`type ${node.id.name}${genericTypes} = `,
';',
!node.extends?.length,
);
},
}),
};
},
});
20 changes: 10 additions & 10 deletions packages/eslint-plugin/src/rules/consistent-type-definitions.ts
Expand Up @@ -47,10 +47,10 @@ export default util.createRule({
}

return {
"TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(
node: TSESTree.TSTypeAliasDeclaration,
): void {
if (option === 'interface') {
...(option === 'interface' && {
"TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(
node: TSESTree.TSTypeAliasDeclaration,
): void {
context.report({
node: node.id,
messageId: 'interfaceOverType',
Expand Down Expand Up @@ -81,10 +81,10 @@ export default util.createRule({
return fixes;
},
});
}
},
TSInterfaceDeclaration(node): void {
if (option === 'type') {
},
}),
...(option === 'type' && {
TSInterfaceDeclaration(node): void {
context.report({
node: node.id,
messageId: 'typeOverInterface',
Expand Down Expand Up @@ -137,8 +137,8 @@ export default util.createRule({
return fixes;
},
});
}
},
},
}),
};
},
});
Expand Up @@ -129,7 +129,6 @@ export default util.createRule<Options, MessageIds>({
TSExportAssignment(node): void {
checkNode(node.expression);
},

'ArrowFunctionExpression, FunctionDeclaration, FunctionExpression'(
node: FunctionNode,
): void {
Expand Down
9 changes: 4 additions & 5 deletions packages/eslint-plugin/src/rules/init-declarations.ts
@@ -1,12 +1,12 @@
import {
TSESTree,
AST_NODE_TYPES,
TSESTree,
} from '@typescript-eslint/experimental-utils';
import { getESLintCoreRule } from '../util/getESLintCoreRule';
import {
InferOptionsTypeFromRule,
InferMessageIdsTypeFromRule,
createRule,
InferMessageIdsTypeFromRule,
InferOptionsTypeFromRule,
} from '../util';

const baseRule = getESLintCoreRule('init-declarations');
Expand All @@ -29,9 +29,8 @@ export default createRule<Options, MessageIds>({
messages: baseRule.meta.messages,
},
defaultOptions: ['always'],
create(context) {
create(context, [mode]) {
const rules = baseRule.create(context);
const mode = context.options[0] || 'always';

return {
'VariableDeclaration:exit'(node: TSESTree.VariableDeclaration): void {
Expand Down
Expand Up @@ -43,10 +43,10 @@ export default util.createRule<Options, MessageIds>({
exceptAfterSingleLine: false,
},
],
create(context, options) {
create(context, [firstOption, secondOption]) {
const rules = baseRule.create(context);
const exceptAfterOverload =
options[1]?.exceptAfterOverload && options[0] === 'always';
secondOption?.exceptAfterOverload && firstOption === 'always';

function isOverload(node: TSESTree.Node): boolean {
return (
Expand Down

0 comments on commit 713fd77

Please sign in to comment.