From bbc9e3540576891552dc2dc54b2acbc54104be9d Mon Sep 17 00:00:00 2001 From: Alex T Date: Sun, 18 Oct 2020 22:49:58 +0300 Subject: [PATCH] feat(eslint-plugin): [dot-notation] add `allowProtectedClassPropertyAccess` option (#2622) --- .../eslint-plugin/docs/rules/dot-notation.md | 15 +++++++++ .../eslint-plugin/src/rules/dot-notation.ts | 21 ++++++++++-- .../tests/rules/dot-notation.test.ts | 32 +++++++++++++++++++ .../eslint-plugin/typings/eslint-rules.d.ts | 1 + 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/dot-notation.md b/packages/eslint-plugin/docs/rules/dot-notation.md index bd1ea7487df..56097090e2e 100644 --- a/packages/eslint-plugin/docs/rules/dot-notation.md +++ b/packages/eslint-plugin/docs/rules/dot-notation.md @@ -23,10 +23,12 @@ This rule adds the following options: ```ts interface Options extends BaseDotNotationOptions { allowPrivateClassPropertyAccess?: boolean; + allowProtectedClassPropertyAccess?: boolean; } const defaultOptions: Options = { ...baseDotNotationDefaultOptions, allowPrivateClassPropertyAccess: false, + allowProtectedClassPropertyAccess: false, }; ``` @@ -43,4 +45,17 @@ const x = new X(); x['priv_prop'] = 123; ``` +### `allowProtectedClassPropertyAccess` + +Example of a correct code when `allowProtectedClassPropertyAccess` is set to `true` + +```ts +class X { + protected protected_prop = 123; +} + +const x = new X(); +x['protected_prop'] = 123; +``` + Taken with ❤️ [from ESLint core](https://github.com/eslint/eslint/blob/master/docs/rules/dot-notation.md) diff --git a/packages/eslint-plugin/src/rules/dot-notation.ts b/packages/eslint-plugin/src/rules/dot-notation.ts index 3cc2be22deb..2c9dd9f2351 100644 --- a/packages/eslint-plugin/src/rules/dot-notation.ts +++ b/packages/eslint-plugin/src/rules/dot-notation.ts @@ -38,6 +38,10 @@ export default createRule({ type: 'boolean', default: false, }, + allowProtectedClassPropertyAccess: { + type: 'boolean', + default: false, + }, }, additionalProperties: false, }, @@ -48,6 +52,7 @@ export default createRule({ defaultOptions: [ { allowPrivateClassPropertyAccess: false, + allowProtectedClassPropertyAccess: false, allowKeywords: true, allowPattern: '', }, @@ -56,20 +61,30 @@ export default createRule({ const rules = baseRule.create(context); const allowPrivateClassPropertyAccess = options.allowPrivateClassPropertyAccess; + const allowProtectedClassPropertyAccess = + options.allowProtectedClassPropertyAccess; const parserServices = getParserServices(context); const typeChecker = parserServices.program.getTypeChecker(); return { MemberExpression(node: TSESTree.MemberExpression): void { - if (allowPrivateClassPropertyAccess && node.computed) { + if ( + (allowPrivateClassPropertyAccess || + allowProtectedClassPropertyAccess) && + node.computed + ) { // for perf reasons - only fetch the symbol if we have to const objectSymbol = typeChecker.getSymbolAtLocation( parserServices.esTreeNodeToTSNodeMap.get(node.property), ); + const modifierKind = objectSymbol?.getDeclarations()?.[0] + ?.modifiers?.[0].kind; if ( - objectSymbol?.getDeclarations()?.[0]?.modifiers?.[0].kind === - ts.SyntaxKind.PrivateKeyword + (allowPrivateClassPropertyAccess && + modifierKind == ts.SyntaxKind.PrivateKeyword) || + (allowProtectedClassPropertyAccess && + modifierKind == ts.SyntaxKind.ProtectedKeyword) ) { return; } diff --git a/packages/eslint-plugin/tests/rules/dot-notation.test.ts b/packages/eslint-plugin/tests/rules/dot-notation.test.ts index 797b111cb17..0d1f755b482 100644 --- a/packages/eslint-plugin/tests/rules/dot-notation.test.ts +++ b/packages/eslint-plugin/tests/rules/dot-notation.test.ts @@ -75,6 +75,18 @@ x['priv_prop'] = 123; `, options: [{ allowPrivateClassPropertyAccess: true }], }, + + { + code: ` +class X { + protected protected_prop = 123; +} + +const x = new X(); +x['protected_prop'] = 123; + `, + options: [{ allowProtectedClassPropertyAccess: true }], + }, ], invalid: [ { @@ -255,5 +267,25 @@ x.pub_prop = 123; options: [{ allowKeywords: false }], errors: [{ messageId: 'useBrackets', data: { key: 'if' } }], }, + { + code: ` +class X { + protected protected_prop = 123; +} + +const x = new X(); +x['protected_prop'] = 123; + `, + options: [{ allowProtectedClassPropertyAccess: false }], + output: ` +class X { + protected protected_prop = 123; +} + +const x = new X(); +x.protected_prop = 123; + `, + errors: [{ messageId: 'useDot' }], + }, ], }); diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index d11c5589b38..8a6c89d529b 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -708,6 +708,7 @@ declare module 'eslint/lib/rules/dot-notation' { allowKeywords?: boolean; allowPattern?: string; allowPrivateClassPropertyAccess?: boolean; + allowProtectedClassPropertyAccess?: boolean; }, ], {