From 9380d6fc68fd3b91a79499a57e62885a2f169161 Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Fri, 27 Oct 2023 11:24:59 +0300 Subject: [PATCH] [ArkTS Linter] #14184: Do not report 'Class used as object' for 'property access' on enum in namespace. Change-Id: I098a6d0ece73add8c0f259aa62b9389e71b38adc Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 9 ++- linter-4.2/test/class_as_object.ts | 19 ++++++ linter-4.2/test/class_as_object.ts.relax.json | 63 ++++++++++++++----- .../test/class_as_object.ts.strict.json | 63 ++++++++++++++----- .../functions/identiferUseInValueContext.ts | 7 +-- linter/test/class_as_object.ts | 19 ++++++ linter/test/class_as_object.ts.relax.json | 63 ++++++++++++++----- linter/test/class_as_object.ts.strict.json | 63 ++++++++++++++----- 8 files changed, 244 insertions(+), 62 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 27442da9f..44bfd20aa 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1559,8 +1559,7 @@ export class TypeScriptLinter { // treat TypeQuery as valid because it's already forbidden (FaultID.TypeQuery) (ts.isTypeNode(parent) && !ts.isTypeOfExpression(parent)) || // ElementAccess is allowed for enum types - (ts.isElementAccessExpression(parent) - && (parent as ts.ElementAccessExpression).expression == ident && (tsSym.flags & ts.SymbolFlags.Enum)) || + this.isEnumPropAccess(ident, tsSym, parent) || ts.isExpressionWithTypeArguments(parent) || ts.isExportAssignment(parent) || ts.isExportSpecifier(parent) || @@ -1584,6 +1583,12 @@ export class TypeScriptLinter { ); } + private isEnumPropAccess(ident: ts.Identifier, tsSym: ts.Symbol, context: ts.Node): boolean { + return ts.isElementAccessExpression(context) && !!(tsSym.flags & ts.SymbolFlags.Enum) && + (context.expression == ident || + (ts.isPropertyAccessExpression(context.expression) && context.expression.name == ident)); + } + private handleElementAccessExpression(node: ts.Node) { const tsElementAccessExpr = node as ts.ElementAccessExpression; const tsElemAccessBaseExprType = this.tsTypeChecker.getTypeAtLocation( diff --git a/linter-4.2/test/class_as_object.ts b/linter-4.2/test/class_as_object.ts index 302432975..919423057 100644 --- a/linter-4.2/test/class_as_object.ts +++ b/linter-4.2/test/class_as_object.ts @@ -91,3 +91,22 @@ for (let item = 0; item < Object.keys(Color).length; item++) { foo2(() => C); export { C as H }; + +let col = 'WHITE'; +console.log(Color[col]) + +// #14184 +namespace NS { + export enum E { + A = 'A', + B = 'B', + C = 'C' + } +} + +let s: string = 'B'; +let s2: string = NS.E[s]; + +for (let item = 0; item < Object.keys(NS.E).length; item++) { + console.log(item); +} \ No newline at end of file diff --git a/linter-4.2/test/class_as_object.ts.relax.json b/linter-4.2/test/class_as_object.ts.relax.json index fbae23bf5..10a550408 100644 --- a/linter-4.2/test/class_as_object.ts.relax.json +++ b/linter-4.2/test/class_as_object.ts.relax.json @@ -15,72 +15,107 @@ { "line": 27, "column": 9, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 28, "column": 5, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 29, "column": 11, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 30, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 38, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 39, "column": 6, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 42, "column": 10, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 45, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 46, "column": 8, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 49, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 58, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 60, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 87, "column": 39, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 91, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" + }, + { + "line": 110, + "column": 42, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" } ] } \ No newline at end of file diff --git a/linter-4.2/test/class_as_object.ts.strict.json b/linter-4.2/test/class_as_object.ts.strict.json index fbae23bf5..10a550408 100644 --- a/linter-4.2/test/class_as_object.ts.strict.json +++ b/linter-4.2/test/class_as_object.ts.strict.json @@ -15,72 +15,107 @@ { "line": 27, "column": 9, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 28, "column": 5, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 29, "column": 11, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 30, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 38, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 39, "column": 6, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 42, "column": 10, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 45, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 46, "column": 8, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 49, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 58, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 60, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 87, "column": 39, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 91, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" + }, + { + "line": 110, + "column": 42, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" } ] } \ No newline at end of file diff --git a/linter/src/utils/functions/identiferUseInValueContext.ts b/linter/src/utils/functions/identiferUseInValueContext.ts index 43c1389a9..96a762c2d 100644 --- a/linter/src/utils/functions/identiferUseInValueContext.ts +++ b/linter/src/utils/functions/identiferUseInValueContext.ts @@ -43,11 +43,10 @@ function getQualifiedStart(ident: ts.Node): ts.Node { } function isEnumPropAccess(ident: ts.Identifier, tsSym: ts.Symbol, context: ts.Node): boolean { - return ts.isElementAccessExpression(context) && - (context as ts.ElementAccessExpression).expression == ident && - !!(tsSym.flags & ts.SymbolFlags.Enum); + return ts.isElementAccessExpression(context) && !!(tsSym.flags & ts.SymbolFlags.Enum) && + (context.expression == ident || + (ts.isPropertyAccessExpression(context.expression) && context.expression.name == ident)); } - function isValidTypeNode(node: ts.TypeNode): boolean { return !ts.isTypeOfExpression(node); } diff --git a/linter/test/class_as_object.ts b/linter/test/class_as_object.ts index e91d6c024..0aedf67e0 100644 --- a/linter/test/class_as_object.ts +++ b/linter/test/class_as_object.ts @@ -91,3 +91,22 @@ for (let item = 0; item < Object.keys(Color).length; item++) { foo2(() => C); export { C as H }; + +let col = 'WHITE'; +console.log(Color[col]) + +// #14184 +namespace NS { + export enum E { + A = 'A', + B = 'B', + C = 'C' + } +} + +let s: string = 'B'; +let s2: string = NS.E[s]; + +for (let item = 0; item < Object.keys(NS.E).length; item++) { + console.log(item); +} \ No newline at end of file diff --git a/linter/test/class_as_object.ts.relax.json b/linter/test/class_as_object.ts.relax.json index 0fdca9072..bab7b32ed 100644 --- a/linter/test/class_as_object.ts.relax.json +++ b/linter/test/class_as_object.ts.relax.json @@ -15,72 +15,107 @@ { "line": 27, "column": 9, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 28, "column": 5, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 29, "column": 11, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 30, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 38, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 39, "column": 6, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 42, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 45, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 46, "column": 8, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 49, "column": 14, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 58, "column": 22, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 60, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 87, "column": 39, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 91, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" + }, + { + "line": 110, + "column": 42, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" } ] } \ No newline at end of file diff --git a/linter/test/class_as_object.ts.strict.json b/linter/test/class_as_object.ts.strict.json index 0fdca9072..bab7b32ed 100644 --- a/linter/test/class_as_object.ts.strict.json +++ b/linter/test/class_as_object.ts.strict.json @@ -15,72 +15,107 @@ { "line": 27, "column": 9, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 28, "column": 5, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 29, "column": 11, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 30, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 38, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 39, "column": 6, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 42, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 45, "column": 20, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 46, "column": 8, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 49, "column": 14, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 58, "column": 22, - "problem": "TypeQuery" + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)" }, { "line": 60, "column": 7, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 87, "column": 39, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" }, { "line": 91, "column": 12, - "problem": "ClassAsObject" + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" + }, + { + "line": 110, + "column": 42, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)" } ] } \ No newline at end of file -- Gitee