diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 7a6dd23d96c159848928bf3d1454328e93c1db4e..8e3356d4f1b231357d365dee970f61f733f5f98a 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -175,6 +175,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { static literalAsPropertyNameTypeSet: Set; private localApiListItem: ApiListItem | undefined = undefined; static constructorFuncsSet: Set; + static ConstructorIfaceSet: Set; static initGlobals(): void { TypeScriptLinter.sharedModulesCache = new Map(); @@ -268,11 +269,18 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private static addSdkConstructorIfaceSetData(item: ApiListItem): void { + if (item.api_info.problem === SdkProblem.ConstructorIface) { + TypeScriptLinter.ConstructorIfaceSet.add(item); + } + } + private static initSdkWhitelist(): void { TypeScriptLinter.indexedTypeSet = new Set(); TypeScriptLinter.literalAsPropertyNameTypeSet = new Set(); TypeScriptLinter.constructorFuncsSet = new Set(); const list: ApiList = new ApiList(apiWhiteList); + TypeScriptLinter.ConstructorIfaceSet = new Set(); if (list?.api_list?.length > 0) { for (const item of list.api_list) { if (item.file_path !== '') { @@ -285,6 +293,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { TypeScriptLinter.addSdkliteralAsPropertyNameTypeSetData(item); TypeScriptLinter.addSdkConstructorFuncsSetData(item); TypeScriptLinter.addGlobalApiInfosCollocetionData(item); + TypeScriptLinter.addSdkConstructorIfaceSetData(item); } } } @@ -4337,7 +4346,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const tsCallExpr = node as ts.CallExpression; this.handleStateStyles(tsCallExpr); this.handleBuiltinCtorCallSignature(tsCallExpr); - + this.handleSdkConstructorIfaceForCallExpression(tsCallExpr); if (this.options.arkts2 && tsCallExpr.typeArguments !== undefined) { this.handleSdkPropertyAccessByIndex(tsCallExpr); } @@ -5013,30 +5022,32 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!this.options.arkts2 || !this.useStatic) { return; } - - if (!ts.isReturnStatement(newExpression.parent)) { - return; - } - const calleeExpr = newExpression.expression; if (!ts.isIdentifier(calleeExpr)) { return; } const type = this.tsTypeChecker.getTypeAtLocation(calleeExpr); - if (!type.symbol) { - return; - } - const typeDeclarations = type.symbol.declarations; - if (!typeDeclarations || typeDeclarations.length === 0) { - return; - } - - if (!ts.isInterfaceDeclaration(typeDeclarations[0])) { - return; + const typeDeclaration = TsUtils.getDeclaration(type.symbol); + if (typeDeclaration && ts.isInterfaceDeclaration(typeDeclaration) && type.symbol) { + const filePath = typeDeclaration.getSourceFile().fileName; + this.checkIsConstructorIface(calleeExpr, type.symbol.name, path.basename(filePath)); } + } - this.incrementCounters(calleeExpr, FaultID.ConstructorIfaceFromSdk); + private checkIsConstructorIface(node: ts.Node, symbol: string, filePath: string): void { + const constructorIfaceSetInfos = Array.from(TypeScriptLinter.ConstructorIfaceSet); + constructorIfaceSetInfos.some((constructorFuncsInfo) => { + const api_name = constructorFuncsInfo.api_info.parent_api[0].api_name; + if ( + symbol === api_name && + (constructorFuncsInfo.file_path.includes(filePath) || constructorFuncsInfo.import_path.includes(filePath)) + ) { + this.incrementCounters(node, FaultID.ConstructorIfaceFromSdk); + return true; + } + return false; + }); } private handleNewExpression(node: ts.Node): void { @@ -5266,6 +5277,52 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private handleSdkConstructorIfaceForCallExpression(callExpr: ts.CallExpression): void { + if (!this.options.arkts2) { + return; + } + let type: ts.Type | undefined; + if (!callExpr.arguments || callExpr.arguments.length === 0) { + if (ts.isPropertyAccessExpression(callExpr.expression)) { + type = this.tsTypeChecker.getTypeAtLocation(callExpr.expression.expression); + } + } + callExpr.arguments.some((args) => { + if (ts.isIdentifier(args)) { + type = this.tsTypeChecker.getTypeAtLocation(args); + } + }); + if (!type) { + return; + } + const decl = TsUtils.getDeclaration(type?.symbol); + if (!decl) { + return; + } + const filePath = TypeScriptLinter.getFileName(decl); + this.checkIsConstructorIface(callExpr, type.symbol.name, filePath); + } + + private static getFileName(decl: ts.Declaration): string { + let filePath = ''; + if ( + ts.isImportSpecifier(decl) && + ts.isImportDeclaration(decl.parent.parent.parent) && + ts.isStringLiteral(decl.parent.parent.parent.moduleSpecifier) + ) { + filePath = decl.parent.parent.parent.moduleSpecifier.text; + } else if ( + ts.isImportClause(decl) && + ts.isImportDeclaration(decl.parent) && + ts.isStringLiteral(decl.parent.moduleSpecifier) + ) { + filePath = decl.parent.moduleSpecifier.text; + } else { + filePath = decl.getSourceFile().fileName; + } + return path.basename(filePath); + } + private handleSharedArrayBuffer( node: ts.TypeReferenceNode | ts.NewExpression | ts.ExpressionWithTypeArguments ): void { diff --git a/ets2panda/linter/test/main/dynamic_ctor_call.ets.arkts2.json b/ets2panda/linter/test/main/dynamic_ctor_call.ets.arkts2.json index b4ee74500e610e14150f1907769481521dccf99e..0ef26c352d653b6c6e8fd73f0070ea28f6847bbe 100644 --- a/ets2panda/linter/test/main/dynamic_ctor_call.ets.arkts2.json +++ b/ets2panda/linter/test/main/dynamic_ctor_call.ets.arkts2.json @@ -124,16 +124,6 @@ "rule": "Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)", "severity": "ERROR" }, - { - "line": 39, - "column": 14, - "endLine": 39, - "endColumn": 18, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 39, "column": 14, diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json index bc1cd482a41b7487c1b342d0bf71524cb06befd0..7b4b3be153ea9b62d47dd4b4f5537a54a8565c69 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json @@ -254,16 +254,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 44, - "column": 14, - "endLine": 44, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 44, "column": 10, @@ -274,16 +264,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 48, - "column": 14, - "endLine": 48, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 48, "column": 10, @@ -304,16 +284,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 52, - "column": 14, - "endLine": 52, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 52, "column": 10, @@ -334,16 +304,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 56, - "column": 14, - "endLine": 56, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 56, "column": 10, @@ -354,16 +314,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 61, - "column": 16, - "endLine": 61, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 61, "column": 12, @@ -374,16 +324,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 65, - "column": 16, - "endLine": 65, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 65, "column": 12, @@ -404,16 +344,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 69, - "column": 16, - "endLine": 69, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 69, "column": 12, @@ -434,16 +364,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 73, - "column": 16, - "endLine": 73, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 73, "column": 12, diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json index e59af03e373bd0e79d080f72f6d92e1369e02e6a..ae3ace8f9c996004329808217c87c52762171119 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json @@ -375,16 +375,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 44, - "column": 14, - "endLine": 44, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 44, "column": 10, @@ -406,16 +396,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 48, - "column": 14, - "endLine": 48, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 48, "column": 10, @@ -447,16 +427,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 52, - "column": 14, - "endLine": 52, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 52, "column": 10, @@ -477,16 +447,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 56, - "column": 14, - "endLine": 56, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 56, "column": 10, @@ -497,16 +457,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 61, - "column": 16, - "endLine": 61, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 61, "column": 12, @@ -528,16 +478,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 65, - "column": 16, - "endLine": 65, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 65, "column": 12, @@ -569,16 +509,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 69, - "column": 16, - "endLine": 69, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 69, "column": 12, @@ -599,16 +529,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 73, - "column": 16, - "endLine": 73, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 73, "column": 12, diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json index 7926f03ac94dcdc467fc0e4a01f20384c2d1735c..53303d2c6088a72053f154cf705dbd025372edcf 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json @@ -144,26 +144,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 47, - "column": 14, - "endLine": 47, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 14, - "endLine": 51, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 55, "column": 10, @@ -174,16 +154,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 55, - "column": 14, - "endLine": 55, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 55, "column": 10, @@ -204,16 +174,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 59, - "column": 14, - "endLine": 59, - "endColumn": 17, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 59, "column": 10, @@ -224,26 +184,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 64, - "column": 16, - "endLine": 64, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 16, - "endLine": 68, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 72, "column": 12, @@ -254,16 +194,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 72, - "column": 16, - "endLine": 72, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 72, "column": 12, @@ -284,16 +214,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 76, - "column": 16, - "endLine": 76, - "endColumn": 19, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 76, "column": 12, diff --git a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json index 89cd070221de4abd16abf56e37ba1cec76a7c1be..d621318a9c870f74a3c2588d51b5d9c60233f8e3 100644 --- a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json +++ b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json @@ -1613,16 +1613,6 @@ "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" - }, - { - "line": 699, - "column": 14, - "endLine": 699, - "endColumn": 21, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts_overload.ets.arkts2.json b/ets2panda/linter/test/main/ts_overload.ets.arkts2.json index 625ed5b8331918d9b2851ec2693750f323c1c975..cf5dc0b7d075724669746d259f56779074c10c3d 100644 --- a/ets2panda/linter/test/main/ts_overload.ets.arkts2.json +++ b/ets2panda/linter/test/main/ts_overload.ets.arkts2.json @@ -44,26 +44,6 @@ "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", "severity": "ERROR" }, - { - "line": 20, - "column": 16, - "endLine": 20, - "endColumn": 20, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 16, - "endLine": 22, - "endColumn": 20, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 25, "column": 21, diff --git a/ets2panda/linter/test/rules/rule37.ets.migrate.json b/ets2panda/linter/test/rules/rule37.ets.migrate.json index 0a1c7ec09788dc01f74297d811e3c342a1e47d88..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/rules/rule37.ets.migrate.json +++ b/ets2panda/linter/test/rules/rule37.ets.migrate.json @@ -13,16 +13,5 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - { - "line": 59, - "column": 21, - "endLine": 59, - "endColumn": 27, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - } - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json index 7b974d3450d22c88c7a7dedab6df6e5722470b8d..9245dba0a11bbaf806692701835f36a58b3f051b 100644 --- a/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json @@ -44,16 +44,6 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, - { - "line": 26, - "column": 14, - "endLine": 26, - "endColumn": 15, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 26, "column": 14, @@ -74,16 +64,6 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, - { - "line": 30, - "column": 14, - "endLine": 30, - "endColumn": 15, - "problem": "ConstructorIfaceFromSdk", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 30, "column": 14,