From 320f19cc16ccffda9d4db4d1e8ca2d5b1444a182 Mon Sep 17 00:00:00 2001 From: cihatfurkaneken Date: Fri, 22 Aug 2025 15:21:34 +0300 Subject: [PATCH] arkts-no-ts-like-smart-type false error Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICTXL7 Signed-off-by: cihatfurkaneken --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 46 +++++++- .../test/deprecatedapi/common.ets.arkts2.json | 40 ------- .../test/main/no_ts_like_smart_type.ets | 71 +++++++++++-- .../no_ts_like_smart_type.ets.arkts2.json | 100 ++++++++++++++---- .../test/main/no_ts_like_smart_type.ets.json | 40 +++++-- .../main/runtime_array_bound.ets.arkts2.json | 10 -- .../main/runtime_array_bound.ets.migrate.json | 10 -- 7 files changed, 216 insertions(+), 101 deletions(-) diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 6481f26d69..1025e7f3db 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -11563,7 +11563,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { handleInstanceOfFunction(node: ts.BinaryExpression): void { const right = node.right; - let symbol = this.tsUtils.trueSymbolAtLocation(right); + const symbol = this.tsUtils.trueSymbolAtLocation(right); if (!symbol) { return; } @@ -12472,20 +12472,58 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!this.options.arkts2) { return; } + const symbol = this.tsTypeChecker.getSymbolAtLocation(expr.expression); + if (!symbol) { + return; + } + const declaredType = this.tsTypeChecker.getTypeOfSymbolAtLocation(symbol, expr.expression); + const usageType = this.tsTypeChecker.getTypeAtLocation(expr.expression); + const declaration = this.tsUtils.getDeclarationNode(expr.expression); if (!declaration) { return; } if ( - (ts.isParameter(declaration) || ts.isPropertyDeclaration(declaration)) && - !!declaration.questionToken && - !ts.isPropertyAccessChain(expr) + (ts.isParameter(declaration) || ts.isPropertyDeclaration(declaration) || ts.isVariableDeclaration(declaration)) && + TsUtils.isNullableUnionType(declaredType) && + TsUtils.isNullableUnionType(usageType) && + !ts.isPropertyAccessChain(expr) && + !this.isWriteAccess(expr.expression) ) { this.incrementCounters(expr, FaultID.NoTsLikeSmartType); } } + private isWriteAccess(node: ts.Node): boolean { + const parent = node.parent; + if (!parent) { + return false; + } + + if (ts.isBinaryExpression(parent) && parent.left === node) { + return isAssignmentOperator(parent.operatorToken); + } + + if (ts.isVariableDeclaration(parent) && parent.name === node) { + return true; + } + + if (ts.isPropertyAccessExpression(parent) && parent.name === node) { + return this.isWriteAccess(parent); + } + + if (ts.isBindingElement(parent) && parent.name === node) { + return true; + } + + if (ts.isParameter(parent) && parent.name === node) { + return true; + } + + return false; + } + private handleNotsLikeSmartType(classDecl: ts.ClassDeclaration): void { if (!this.options.arkts2) { return; diff --git a/ets2panda/linter/test/deprecatedapi/common.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/common.ets.arkts2.json index 5f0c2d4f2b..ad8333f4ad 100644 --- a/ets2panda/linter/test/deprecatedapi/common.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/common.ets.arkts2.json @@ -34,16 +34,6 @@ "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, - { - "line": 41, - "column": 13, - "endLine": 41, - "endColumn": 26, - "problem": "NoTsLikeSmartType", - "suggest": "", - "rule": "Smart type differences (arkts-no-ts-like-smart-type)", - "severity": "ERROR" - }, { "line": 42, "column": 13, @@ -54,36 +44,6 @@ "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, - { - "line": 42, - "column": 13, - "endLine": 42, - "endColumn": 26, - "problem": "NoTsLikeSmartType", - "suggest": "", - "rule": "Smart type differences (arkts-no-ts-like-smart-type)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 13, - "endLine": 47, - "endColumn": 26, - "problem": "NoTsLikeSmartType", - "suggest": "", - "rule": "Smart type differences (arkts-no-ts-like-smart-type)", - "severity": "ERROR" - }, - { - "line": 48, - "column": 13, - "endLine": 48, - "endColumn": 26, - "problem": "NoTsLikeSmartType", - "suggest": "", - "rule": "Smart type differences (arkts-no-ts-like-smart-type)", - "severity": "ERROR" - }, { "line": 16, "column": 2, diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets b/ets2panda/linter/test/main/no_ts_like_smart_type.ets index 78878b39c2..8a353aff28 100755 --- a/ets2panda/linter/test/main/no_ts_like_smart_type.ets +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets @@ -13,10 +13,10 @@ * limitations under the License. */ -class A { - private static instance:A = new A(); - static get():A { - return A.instance; // +class AW { + private static instance:AW = new AW(); + static get():AW { + return AW.instance; // } } @@ -155,7 +155,7 @@ function foo4(uri: string | number | boolean) : string { return uri as string } -class AA { +class AA5 { public static starUrl(url: string) { if (url?startsWith('http')) { url = `https:/test?appid=2000?url=${foo4(url)}`; @@ -185,7 +185,7 @@ class ClassA { } } -class A { +class AT { b?: boolean isRelease(): boolean { @@ -249,4 +249,61 @@ export class AB { return this.count_; //legal }) } -} \ No newline at end of file +} + +class AG { +h?: number; +f(): number | null { + return 1; +} +} + +function check(obj?: AG) { +if (obj) { + console.log(obj.f()); // valid(guarded) +} +if (obj !== undefined) { + obj.f(); // valid(guarded) +} +} + +function check4(obj?: AG) { + +if (!obj) { + return; +} +obj.f(); // valid(guarded) +} +function check2(obj?: AG) { +obj.f(); // ERROR + +if (obj == null) return; +obj.f(); // valid(guarded) + +} +function check3(obj?: AG) { + +return obj ? obj.f() : null; // guarded in ternary + +} + +function check35(obj?: AG) { + +if (obj.h == 3) { //error + console.log('3'); +} + +} + +function check36(obj?: AG) { + +if (obj && obj.h == 3) { // valid(guarded) + console.log('3'); +} + +} + +function check43(obj?: AG) { +const val = obj.h; // NOT guarded +return val; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets.arkts2.json b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.arkts2.json index d3a7239f5d..d5577d300c 100755 --- a/ets2panda/linter/test/main/no_ts_like_smart_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.arkts2.json @@ -174,16 +174,6 @@ "rule": "Smart type differences (arkts-no-ts-like-smart-type)", "severity": "ERROR" }, - { - "line": 133, - "column": 11, - "endLine": 133, - "endColumn": 16, - "problem": "NoTsLikeSmartType", - "suggest": "", - "rule": "Smart type differences (arkts-no-ts-like-smart-type)", - "severity": "ERROR" - }, { "line": 137, "column": 5, @@ -194,6 +184,16 @@ "rule": "Smart type differences (arkts-no-ts-like-smart-type)", "severity": "ERROR" }, + { + "line": 143, + "column": 1, + "endLine": 147, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, { "line": 144, "column": 7, @@ -204,16 +204,6 @@ "rule": "Smart type differences (arkts-no-ts-like-smart-type)", "severity": "ERROR" }, - { - "line": 151, - "column": 7, - "endLine": 151, - "endColumn": 20, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, { "line": 151, "column": 13, @@ -264,6 +254,46 @@ "rule": "Smart type differences (arkts-no-ts-like-smart-type)", "severity": "ERROR" }, + { + "line": 261, + "column": 1, + "endLine": 268, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 278, + "column": 1, + "endLine": 278, + "endColumn": 6, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 292, + "column": 5, + "endLine": 292, + "endColumn": 10, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 307, + "column": 13, + "endLine": 307, + "endColumn": 18, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, { "line": 137, "column": 5, @@ -303,6 +333,36 @@ "suggest": "Function lacks ending return statement and return type does not include 'undefined'.", "rule": "Function lacks ending return statement and return type does not include 'undefined'.", "severity": "ERROR" + }, + { + "line": 278, + "column": 1, + "endLine": 278, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 292, + "column": 5, + "endLine": 292, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 307, + "column": 13, + "endLine": 307, + "endColumn": 16, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json index 0eff9f6a24..f892c8a98b 100755 --- a/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json @@ -14,16 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 151, - "column": 7, - "endLine": 151, - "endColumn": 20, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, { "line": 137, "column": 5, @@ -63,6 +53,36 @@ "suggest": "Function lacks ending return statement and return type does not include 'undefined'.", "rule": "Function lacks ending return statement and return type does not include 'undefined'.", "severity": "ERROR" + }, + { + "line": 278, + "column": 1, + "endLine": 278, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 292, + "column": 5, + "endLine": 292, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 307, + "column": 13, + "endLine": 307, + "endColumn": 16, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json b/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json index 0f96cd9029..ee1c3bc9cd 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json @@ -444,16 +444,6 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, - { - "line": 194, - "column": 14, - "endLine": 194, - "endColumn": 24, - "problem": "NoTsLikeSmartType", - "suggest": "", - "rule": "Smart type differences (arkts-no-ts-like-smart-type)", - "severity": "ERROR" - }, { "line": 219, "column": 16, diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json index 1d451093ec..9998799a22 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json @@ -284,16 +284,6 @@ "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", "severity": "WARNING" }, - { - "line": 194, - "column": 14, - "endLine": 194, - "endColumn": 24, - "problem": "NoTsLikeSmartType", - "suggest": "", - "rule": "Smart type differences (arkts-no-ts-like-smart-type)", - "severity": "ERROR" - }, { "line": 219, "column": 16, -- Gitee