diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 309d60b1b1ac29304927e5896612d666041add46..854bed47c53d833120a7b1ca47f8d31bf33cc739 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -5135,28 +5135,57 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private handleAsExpressionImport(tsAsExpr: ts.AsExpression): void { + if (!this.useStatic || !this.options.arkts2) { + return; + } + const type = tsAsExpr.type; - const restrictedTypes = [ + const expression = tsAsExpr.expression; + const restrictedPrimitiveTypes = [ ts.SyntaxKind.NumberKeyword, ts.SyntaxKind.BooleanKeyword, ts.SyntaxKind.StringKeyword, - ts.SyntaxKind.BigIntKeyword + ts.SyntaxKind.BigIntKeyword, + ts.SyntaxKind.UndefinedKeyword ]; - if (this.useStatic && this.options.arkts2 && restrictedTypes.includes(type.kind)) { - const expr = ts.isPropertyAccessExpression(tsAsExpr.expression) ? - tsAsExpr.expression.expression : - tsAsExpr.expression; - - if (ts.isIdentifier(expr)) { - const sym = this.tsUtils.trueSymbolAtLocation(expr); - const decl = TsUtils.getDeclaration(sym); - if (decl?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { - this.incrementCounters(tsAsExpr, FaultID.InterOpConvertImport); - } + this.handleAsExpressionImportNull(tsAsExpr); + const isRestrictedPrimitive = restrictedPrimitiveTypes.includes(type.kind); + const isRestrictedArrayType = + type.kind === ts.SyntaxKind.ArrayType || + ts.isTypeReferenceNode(type) && ts.isIdentifier(type.typeName) && type.typeName.text === 'Array'; + + if (!isRestrictedPrimitive && !isRestrictedArrayType) { + return; + } + + let identifier: ts.Identifier | undefined; + if (ts.isIdentifier(expression)) { + identifier = expression; + } else if (ts.isPropertyAccessExpression(expression)) { + identifier = ts.isIdentifier(expression.expression) ? expression.expression : undefined; + } + + if (identifier) { + const sym = this.tsUtils.trueSymbolAtLocation(identifier); + const decl = TsUtils.getDeclaration(sym); + if (decl?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { + this.incrementCounters(tsAsExpr, FaultID.InterOpConvertImport); } } } + private handleAsExpressionImportNull(tsAsExpr: ts.AsExpression): void { + const type = tsAsExpr.type; + const isNullAssertion = + type.kind === ts.SyntaxKind.NullKeyword || + ts.isLiteralTypeNode(type) && type.literal.kind === ts.SyntaxKind.NullKeyword || + type.getText() === 'null'; + if (isNullAssertion) { + this.incrementCounters(tsAsExpr, FaultID.InterOpConvertImport); + + } + } + private handleSdkConstructorIface(typeRef: ts.TypeReferenceNode): void { if (!this.options.arkts2 && typeRef?.typeName === undefined && !ts.isQualifiedName(typeRef.typeName)) { return; diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets b/ets2panda/linter/test/interop/interop_convert_import.ets index 296d7bb3ed6204c3e6836a9274e9afd1ad8dffe1..5aa8263372d7254a9167e642f75879abce842bd7 100755 --- a/ets2panda/linter/test/interop/interop_convert_import.ets +++ b/ets2panda/linter/test/interop/interop_convert_import.ets @@ -14,9 +14,28 @@ */ 'use static' - import {foo, foo2, foo3, foo4} from "./interop_convert_import_js.js" + import {foo, foo2, foo3, foo4, array_val, null_val, undefined_val} from "./interop_convert_import_js.js" let a: number = foo.num as number let a: boolean = foo2.bool as boolean let a: string = foo3.str as string - let a: bigint = foo4.big as bigint" \ No newline at end of file + let a: bigint = foo4.big as bigint" + +test_helper.test(() => { +return (array_val as Array).toString() === new Array(1, 2, 3).toString();// 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "array_val as Array === [1, 2, 3]"); + +// convert type - Array +test_helper.test(() => { +return (array_val as number[]).toString() === [1,2,3].toString();// 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "array_val as Array === [1, 2, 3]"); + +// convert type - null +test_helper.test(() => { +return null_val as null === null;// 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "null_val as null === null"); + +// convert type - undefined +test_helper.test(() => { +return undefined_val as undefined === undefined; // 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "undefined_val as undefined === undefined"); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json b/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json index 8b318f2ad32df1717c0fc31f8b15ce7f2d8c1eb0..d824d726d2b4687205c405cffdc1d48df2c9ec5b 100755 --- a/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json @@ -18,7 +18,7 @@ "line": 17, "column": 2, "endLine": 17, - "endColumn": 70, + "endColumn": 106, "problem": "ImportAfterStatement", "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", @@ -28,7 +28,7 @@ "line": 17, "column": 2, "endLine": 17, - "endColumn": 70, + "endColumn": 106, "problem": "InterOpImportJs", "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", @@ -143,6 +143,116 @@ "suggest": "", "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", "severity": "ERROR" + }, + { + "line": 25, + "column": 9, + "endLine": 25, + "endColumn": 27, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 44, + "endLine": 25, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 54, + "endLine": 25, + "endColumn": 55, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 57, + "endLine": 25, + "endColumn": 58, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 60, + "endLine": 25, + "endColumn": 61, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 30, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 48, + "endLine": 30, + "endColumn": 49, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 50, + "endLine": 30, + "endColumn": 51, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 52, + "endLine": 30, + "endColumn": 53, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 8, + "endLine": 35, + "endColumn": 24, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 34, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.json b/ets2panda/linter/test/interop/interop_convert_import.ets.json index 1d059f0d382adbf11dac846f30473a60ba3985a2..ac2dfbe6f88152a66598a802845b33446231f158 100755 --- a/ets2panda/linter/test/interop/interop_convert_import.ets.json +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.json @@ -18,7 +18,7 @@ "line": 17, "column": 2, "endLine": 17, - "endColumn": 70, + "endColumn": 106, "problem": "ImportAfterStatement", "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", diff --git a/ets2panda/linter/test/interop/interop_convert_import_js.js b/ets2panda/linter/test/interop/interop_convert_import_js.js index f3895baaa7f2e4cf2d75b9c4ecfc5a1c50879481..cce72a8fb7f192f91addc00968c283556c0d205f 100755 --- a/ets2panda/linter/test/interop/interop_convert_import_js.js +++ b/ets2panda/linter/test/interop/interop_convert_import_js.js @@ -16,4 +16,7 @@ export let foo = {name: 123} export let foo2 = {bool: true} export let foo3 = {str: '123'} -export let foo4 = {big: 123n} \ No newline at end of file +export let foo4 = {big: 123n} +export let array_val = [1, 2, 3]; +export let null_val = null; +export let undefined_val = undefined; \ No newline at end of file