Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(eslint-plugin): [explicit-member-accessibility] autofix no-public (
  • Loading branch information
pablobirukov committed Feb 29, 2020
1 parent baf7c98 commit dd233b5
Show file tree
Hide file tree
Showing 3 changed files with 389 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/eslint-plugin/README.md
Expand Up @@ -102,7 +102,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int
| [`@typescript-eslint/consistent-type-assertions`](./docs/rules/consistent-type-assertions.md) | Enforces consistent usage of type assertions | :heavy_check_mark: | | |
| [`@typescript-eslint/consistent-type-definitions`](./docs/rules/consistent-type-definitions.md) | Consistent with type definition either `interface` or `type` | | :wrench: | |
| [`@typescript-eslint/explicit-function-return-type`](./docs/rules/explicit-function-return-type.md) | Require explicit return types on functions and class methods | :heavy_check_mark: | | |
| [`@typescript-eslint/explicit-member-accessibility`](./docs/rules/explicit-member-accessibility.md) | Require explicit accessibility modifiers on class properties and methods | | | |
| [`@typescript-eslint/explicit-member-accessibility`](./docs/rules/explicit-member-accessibility.md) | Require explicit accessibility modifiers on class properties and methods | | :wrench: | |
| [`@typescript-eslint/explicit-module-boundary-types`](./docs/rules/explicit-module-boundary-types.md) | Require explicit return and argument types on exported functions' and classes' public class methods | | | |
| [`@typescript-eslint/member-delimiter-style`](./docs/rules/member-delimiter-style.md) | Require a specific member delimiter style for interfaces and type literals | :heavy_check_mark: | :wrench: | |
| [`@typescript-eslint/member-ordering`](./docs/rules/member-ordering.md) | Require a consistent member declaration order | | | |
Expand Down
49 changes: 49 additions & 0 deletions packages/eslint-plugin/src/rules/explicit-member-accessibility.ts
@@ -1,6 +1,8 @@
import {
AST_NODE_TYPES,
TSESTree,
AST_TOKEN_TYPES,
TSESLint,
} from '@typescript-eslint/experimental-utils';
import * as util from '../util';

Expand Down Expand Up @@ -38,6 +40,7 @@ export default util.createRule<Options, MessageIds>({
// too opinionated to be recommended
recommended: false,
},
fixable: 'code',
messages: {
missingAccessibility:
'Missing accessibility modifier on {{type}} {{name}}.',
Expand Down Expand Up @@ -91,6 +94,7 @@ export default util.createRule<Options, MessageIds>({
nodeType: string,
node: TSESTree.Node,
nodeName: string,
fix: TSESLint.ReportFixFunction | null = null,
): void {
context.report({
node: node,
Expand All @@ -99,6 +103,7 @@ export default util.createRule<Options, MessageIds>({
type: nodeType,
name: nodeName,
},
fix: fix,
});
}

Expand Down Expand Up @@ -140,6 +145,7 @@ export default util.createRule<Options, MessageIds>({
nodeType,
methodDefinition,
methodName,
getUnwantedPublicAccessibilityFixer(methodDefinition),
);
} else if (check === 'explicit' && !methodDefinition.accessibility) {
reportIssue(
Expand All @@ -151,6 +157,47 @@ export default util.createRule<Options, MessageIds>({
}
}

/**
* Creates a fixer that removes a "public" keyword with following spaces
*/
function getUnwantedPublicAccessibilityFixer(
node:
| TSESTree.MethodDefinition
| TSESTree.ClassProperty
| TSESTree.TSParameterProperty,
): TSESLint.ReportFixFunction {
return function(fixer: TSESLint.RuleFixer): TSESLint.RuleFix {
const tokens = sourceCode.getTokens(node);
let rangeToRemove: TSESLint.AST.Range;
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
if (
token.type === AST_TOKEN_TYPES.Keyword &&
token.value === 'public'
) {
const commensAfterPublicKeyword = sourceCode.getCommentsAfter(
token,
);
if (commensAfterPublicKeyword.length) {
// public /* Hi there! */ static foo()
// ^^^^^^^
rangeToRemove = [
token.range[0],
commensAfterPublicKeyword[0].range[0],
];
break;
} else {
// public static foo()
// ^^^^^^^
rangeToRemove = [token.range[0], tokens[i + 1].range[0]];
break;
}
}
}
return fixer.removeRange(rangeToRemove!);
};
}

/**
* Checks if property has an accessibility modifier.
* @param classProperty The node representing a ClassProperty.
Expand All @@ -170,6 +217,7 @@ export default util.createRule<Options, MessageIds>({
nodeType,
classProperty,
propertyName,
getUnwantedPublicAccessibilityFixer(classProperty),
);
} else if (propCheck === 'explicit' && !classProperty.accessibility) {
reportIssue(
Expand Down Expand Up @@ -217,6 +265,7 @@ export default util.createRule<Options, MessageIds>({
nodeType,
node,
nodeName,
getUnwantedPublicAccessibilityFixer(node),
);
}
break;
Expand Down

0 comments on commit dd233b5

Please sign in to comment.