From fc5773f37d5286fe45599a8bb66a11a9f8efa7ce Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Fri, 20 Oct 2023 13:23:49 +0300 Subject: [PATCH] [ArkTS Linter] #13972: Iterate over all child nodes to not miss comment directives between punctuation tokens. Change-Id: I9b820591bc9cb82cdd2045e12315390eba0b05a3 Signed-off-by: Evgeniy Okolnov --- linter-4.2/src/TypeScriptLinter.ts | 26 +++++++++-- linter-4.2/src/TypeScriptLinterConfig.ts | 2 +- linter-4.2/test/ts_ignore.ts.relax.json | 57 ++++++++++++++++++------ linter-4.2/test/ts_ignore.ts.strict.json | 57 ++++++++++++++++++------ linter/src/TypeScriptLinter.ts | 11 ++++- linter/src/TypeScriptLinterConfig.ts | 2 +- linter/test/ts_ignore.ts.relax.json | 57 ++++++++++++++++++------ linter/test/ts_ignore.ts.strict.json | 57 ++++++++++++++++++------ 8 files changed, 211 insertions(+), 58 deletions(-) diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 9b9719ea2..3e2ff041a 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -61,6 +61,7 @@ export class TypeScriptLinter { currentErrorLine: number; currentWarningLine: number; staticBlocks: Set; + walkedComments: Set; libraryTypeCallDiagnosticChecker: LibraryTypeCallDiagnosticChecker; private sourceFile?: ts.SourceFile; @@ -83,6 +84,7 @@ export class TypeScriptLinter { this.currentErrorLine = 0; this.currentWarningLine = 0; this.staticBlocks = new Set(); + this.walkedComments = new Set(); this.libraryTypeCallDiagnosticChecker = new LibraryTypeCallDiagnosticChecker(TypeScriptLinter.filteredDiagnosticMessages); for (let i = 0; i < FaultID.LAST_ID; i++) { @@ -254,7 +256,12 @@ export class TypeScriptLinter { } } - ts.forEachChild(node, visitTSNodeImpl); + // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. + // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. + // to traverse child nodes. + for (const child of node.getChildren()) { + visitTSNodeImpl(child); + } } } @@ -1188,6 +1195,8 @@ export class TypeScriptLinter { ) { this.incrementCounters(node, FaultID.InstanceofUnsupported); } + } else if (tsBinaryExpr.operatorToken.kind === ts.SyntaxKind.InKeyword) { + this.incrementCounters(tsBinaryExpr.operatorToken, FaultID.InOperator); } else if (tsBinaryExpr.operatorToken.kind === ts.SyntaxKind.EqualsToken) { if (this.tsUtils.needToDeduceStructuralIdentity(rightOperandType, leftOperandType)) { this.incrementCounters(tsBinaryExpr, FaultID.StructuralIdentity); @@ -2052,7 +2061,12 @@ export class TypeScriptLinter { ); if (leadingComments) { for (const comment of leadingComments) { - this.checkErrorSuppressingAnnotation(comment, srcText); + // In the real-time linter comment from the first line is double proccessed. + // It may be caused by tsc, but it should be investigated. This is a workaround + if (!this.walkedComments.has(comment.pos) && comment.pos !== comment.end) { + this.walkedComments.add(comment.pos); + this.checkErrorSuppressingAnnotation(comment, srcText); + } } } } @@ -2064,7 +2078,12 @@ export class TypeScriptLinter { ); if (trailingComments) { for (const comment of trailingComments) { - this.checkErrorSuppressingAnnotation(comment, srcText); + // In the real-time linter comment from the first line is double proccessed. + // It may be caused by tsc, but it should be investigated. This is a workaround + if (!this.walkedComments.has(comment.pos) && comment.pos !== comment.end) { + this.walkedComments.add(comment.pos); + this.checkErrorSuppressingAnnotation(comment, srcText); + } } } } @@ -2221,6 +2240,7 @@ export class TypeScriptLinter { } public lint(sourceFile: ts.SourceFile) { + this.walkedComments.clear(); this.sourceFile = sourceFile; this.visitTSNode(this.sourceFile); } diff --git a/linter-4.2/src/TypeScriptLinterConfig.ts b/linter-4.2/src/TypeScriptLinterConfig.ts index fcb5d1988..423c18076 100644 --- a/linter-4.2/src/TypeScriptLinterConfig.ts +++ b/linter-4.2/src/TypeScriptLinterConfig.ts @@ -175,7 +175,7 @@ export class LinterConfig { [ts.SyntaxKind.TypePredicate, FaultID.IsOperator], [ts.SyntaxKind.YieldExpression, FaultID.YieldExpression], [ts.SyntaxKind.IndexSignature, FaultID.IndexMember], [ts.SyntaxKind.WithStatement, FaultID.WithStatement], [ts.SyntaxKind.IndexedAccessType, FaultID.IndexedAccessType],[ts.SyntaxKind.UnknownKeyword, FaultID.UnknownType], - [ts.SyntaxKind.InKeyword, FaultID.InOperator], [ts.SyntaxKind.CallSignature, FaultID.CallSignature], + [ts.SyntaxKind.CallSignature, FaultID.CallSignature], [ts.SyntaxKind.IntersectionType, FaultID.IntersectionType], [ts.SyntaxKind.TypeLiteral, FaultID.ObjectTypeLiteral], [ts.SyntaxKind.ConstructorType, FaultID.ConstructorFuncs], [ts.SyntaxKind.PrivateIdentifier, FaultID.PrivateIdentifier], diff --git a/linter-4.2/test/ts_ignore.ts.relax.json b/linter-4.2/test/ts_ignore.ts.relax.json index d1f517671..8342e1744 100644 --- a/linter-4.2/test/ts_ignore.ts.relax.json +++ b/linter-4.2/test/ts_ignore.ts.relax.json @@ -17,62 +17,93 @@ { "line": 16, "column": 1, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 21, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 25, "column": 19, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 30, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 33, "column": 2, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 43, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 52, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 53, "column": 3, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 55, "column": 22, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 58, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 75, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 18, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Type 'null' is not assignable to type 'number'.", + "rule": "Type 'null' is not assignable to type 'number'." } ] -} +} \ No newline at end of file diff --git a/linter-4.2/test/ts_ignore.ts.strict.json b/linter-4.2/test/ts_ignore.ts.strict.json index d1f517671..8342e1744 100644 --- a/linter-4.2/test/ts_ignore.ts.strict.json +++ b/linter-4.2/test/ts_ignore.ts.strict.json @@ -17,62 +17,93 @@ { "line": 16, "column": 1, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 21, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 25, "column": 19, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 30, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 33, "column": 2, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 43, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 52, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 53, "column": 3, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 55, "column": 22, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 58, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 75, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 18, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Type 'null' is not assignable to type 'number'.", + "rule": "Type 'null' is not assignable to type 'number'." } ] -} +} \ No newline at end of file diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 2b9e6c52e..24b52a96d 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -268,7 +268,13 @@ export class TypeScriptLinter { handler.call(self, node); } } - ts.forEachChild(node, visitTSNodeImpl); + + // #13972: The 'ts.forEachChild' doesn't iterate over in-between punctuation tokens. + // As result, we can miss comment directives attached to those. Instead, use 'node.getChildren()'. + // to traverse child nodes. + for (const child of node.getChildren()) { + visitTSNodeImpl(child); + } } } @@ -917,6 +923,9 @@ export class TypeScriptLinter { case ts.SyntaxKind.InstanceOfKeyword: this.processBinaryInstanceOf(node, tsLhsExpr, leftOperandType); break; + case ts.SyntaxKind.InKeyword: + this.incrementCounters(tsBinaryExpr.operatorToken, FaultID.InOperator); + break; case ts.SyntaxKind.EqualsToken: if (this.tsUtils.needToDeduceStructuralIdentity(rightOperandType, leftOperandType)) { this.incrementCounters(tsBinaryExpr, FaultID.StructuralIdentity); diff --git a/linter/src/TypeScriptLinterConfig.ts b/linter/src/TypeScriptLinterConfig.ts index 83427d5e6..03ebd743e 100644 --- a/linter/src/TypeScriptLinterConfig.ts +++ b/linter/src/TypeScriptLinterConfig.ts @@ -81,7 +81,7 @@ export class LinterConfig { [ts.SyntaxKind.TypePredicate, FaultID.IsOperator], [ts.SyntaxKind.YieldExpression, FaultID.YieldExpression], [ts.SyntaxKind.IndexSignature, FaultID.IndexMember], [ts.SyntaxKind.WithStatement, FaultID.WithStatement], [ts.SyntaxKind.IndexedAccessType, FaultID.IndexedAccessType], [ts.SyntaxKind.UnknownKeyword, FaultID.UnknownType], - [ts.SyntaxKind.InKeyword, FaultID.InOperator], [ts.SyntaxKind.CallSignature, FaultID.CallSignature], + [ts.SyntaxKind.CallSignature, FaultID.CallSignature], [ts.SyntaxKind.IntersectionType, FaultID.IntersectionType], [ts.SyntaxKind.TypeLiteral, FaultID.ObjectTypeLiteral], [ts.SyntaxKind.ConstructorType, FaultID.ConstructorFuncs], [ts.SyntaxKind.PrivateIdentifier, FaultID.PrivateIdentifier], diff --git a/linter/test/ts_ignore.ts.relax.json b/linter/test/ts_ignore.ts.relax.json index d1f517671..8342e1744 100644 --- a/linter/test/ts_ignore.ts.relax.json +++ b/linter/test/ts_ignore.ts.relax.json @@ -17,62 +17,93 @@ { "line": 16, "column": 1, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 21, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 25, "column": 19, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 30, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 33, "column": 2, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 43, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 52, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 53, "column": 3, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 55, "column": 22, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 58, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 75, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 18, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Type 'null' is not assignable to type 'number'.", + "rule": "Type 'null' is not assignable to type 'number'." } ] -} +} \ No newline at end of file diff --git a/linter/test/ts_ignore.ts.strict.json b/linter/test/ts_ignore.ts.strict.json index d1f517671..8342e1744 100644 --- a/linter/test/ts_ignore.ts.strict.json +++ b/linter/test/ts_ignore.ts.strict.json @@ -17,62 +17,93 @@ { "line": 16, "column": 1, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 21, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 25, "column": 19, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 30, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 33, "column": 2, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 43, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 52, "column": 3, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 53, "column": 3, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 55, "column": 22, - "problem": "AnyType" + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)" }, { "line": 56, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 58, "column": 9, - "problem": "ErrorSuppression" + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" + }, + { + "line": 75, + "column": 1, + "problem": "ErrorSuppression", + "suggest": "", + "rule": "Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)" }, { "line": 18, "column": 5, - "problem": "StrictDiagnostic" + "problem": "StrictDiagnostic", + "suggest": "Type 'null' is not assignable to type 'number'.", + "rule": "Type 'null' is not assignable to type 'number'." } ] -} +} \ No newline at end of file -- Gitee