From 522c1408e5bcc6b8f593e87577fcd54979a7a81c Mon Sep 17 00:00:00 2001 From: c30058867 Date: Sun, 8 Jun 2025 22:30:18 +0800 Subject: [PATCH] Fix sdk-limited-void-type Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICDHGO Signed-off-by: caiy --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 106 +++++++++++------- .../src/lib/utils/consts/AssociatedInfo.ts | 22 ++++ .../styles_decorator_struct_1.ets.arkts2.json | 10 ++ ...styles_decorator_struct_1.ets.autofix.json | 10 ++ ...styles_decorator_struct_1.ets.migrate.json | 10 ++ .../styles_decorator_struct_2.ets.arkts2.json | 10 ++ ...styles_decorator_struct_2.ets.autofix.json | 10 ++ ...styles_decorator_struct_2.ets.migrate.json | 10 ++ 8 files changed, 148 insertions(+), 40 deletions(-) create mode 100644 ets2panda/linter/src/lib/utils/consts/AssociatedInfo.ts diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index e2ebe7badf..c2ad9a4d31 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -140,6 +140,7 @@ import { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; import type { ArrayAccess, UncheckedIdentifier, CheckedIdentifier } from './utils/consts/RuntimeCheckAPI'; import { CheckResult } from './utils/consts/RuntimeCheckAPI'; import { NUMBER_LITERAL } from './utils/consts/RuntimeCheckAPI'; +import { globalApiAssociatedInfo } from './utils/consts/AssociatedInfo'; interface InterfaceSymbolTypeResult { propNames: string[]; @@ -694,7 +695,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleDeclarationDestructuring(tsParam); this.handleDeclarationInferredType(tsParam); this.handleInvalidIdentifier(tsParam); - this.handleSdkDuplicateDeclName(tsParam); + this.handleSdkGlobalApi(tsParam); const typeNode = tsParam.type; if (this.options.arkts2 && typeNode && typeNode.kind === ts.SyntaxKind.VoidKeyword) { this.incrementCounters(typeNode, FaultID.LimitedVoidType); @@ -1424,7 +1425,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private isJsRelated(node: ts.Expression): boolean { + private isJsRelated(node: ts.Expression): boolean { if (this.tsUtils.isJsImport(node)) { return true; } @@ -1466,8 +1467,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } return current; - } - + }; + const firstObjNode = getFirstObjectNode(propertyAccessNode); const isJsObject = this.isJsRelated(firstObjNode); if (!isJsObject) { @@ -1660,7 +1661,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleInvalidIdentifier(node); this.handleStructPropertyDecl(node); this.handlePropertyDeclarationForProp(node); - this.handleSdkDuplicateDeclName(node); + this.handleSdkGlobalApi(node); this.handleObjectLiteralAssignmentToClass(node); } @@ -2183,7 +2184,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkAssignmentMatching(tsBinaryExpr, leftOperandType, tsRhsExpr); this.checkFunctionTypeCompatible(typeNode, tsRhsExpr); this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); - this.handleSdkDuplicateDeclName(tsBinaryExpr); + this.handleSdkGlobalApi(tsBinaryExpr); this.checkArrayTypeImmutable(tsBinaryExpr); break; case ts.SyntaxKind.AmpersandAmpersandEqualsToken: @@ -2629,7 +2630,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleObjectLiteralAssignmentToClass(tsVarDecl); this.handleObjectLiteralAssignment(tsVarDecl); this.handlePropertyDescriptorInScenarios(tsVarDecl); - this.handleSdkDuplicateDeclName(tsVarDecl); + this.handleSdkGlobalApi(tsVarDecl); this.checkArrayTypeImmutable(tsVarDecl); } @@ -3549,6 +3550,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } this.checkDefaultParamBeforeRequired(tsMethodDecl); this.handleMethodInherit(tsMethodDecl); + this.handleSdkGlobalApi(tsMethodDecl); } private checkDefaultParamBeforeRequired(node: ts.FunctionLikeDeclarationBase): void { @@ -4533,7 +4535,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleNoTsLikeFunctionCall(tsCallExpr); this.handleObjectLiteralInFunctionArgs(tsCallExpr); this.handleTaskPoolDeprecatedUsages(tsCallExpr); - this.handleSdkDuplicateDeclName(tsCallExpr); + this.handleSdkGlobalApi(tsCallExpr); this.handleObjectLiteralAssignmentToClass(tsCallExpr); } @@ -5107,7 +5109,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkForInterfaceInitialization(tsNewExpr); this.handleSharedArrayBuffer(tsNewExpr); - this.handleSdkDuplicateDeclName(tsNewExpr); + this.handleSdkGlobalApi(tsNewExpr); this.checkConstrutorAccess(tsNewExpr); this.checkCreatingPrimitiveTypes(tsNewExpr); @@ -5218,7 +5220,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleNoTuplesArrays(node, targetType, exprType); this.handleObjectLiteralAssignmentToClass(tsAsExpr); } - + private isExemptedAsExpression(node: ts.AsExpression): boolean { if (!ts.isElementAccessExpression(node.expression)) { return false; @@ -5366,7 +5368,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleBuiltinCtorCallSignature(typeRef); this.handleSharedArrayBuffer(typeRef); - this.handleSdkDuplicateDeclName(typeRef); + this.handleSdkGlobalApi(typeRef); this.handleSdkConstructorIface(typeRef); @@ -5502,7 +5504,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; this.incrementCounters(tsTypeExpr, faultId); } - this.handleSdkDuplicateDeclName(tsTypeExpr); + this.handleSdkGlobalApi(tsTypeExpr); } private handleComputedPropertyName(node: ts.Node): void { @@ -6045,7 +6047,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (ts.isNewExpression(rhsExpr) && ts.isIdentifier(rhsExpr.expression) && rhsExpr.expression.text === 'Promise') { const isReturnStatement = ts.isReturnStatement(rhsExpr.parent); const enclosingFunction = ts.findAncestor(rhsExpr, ts.isFunctionLike); - const isAsyncFunction = enclosingFunction && (enclosingFunction.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) || false); + const isAsyncFunction = + enclosingFunction && + (enclosingFunction.modifiers?.some((m) => { + return m.kind === ts.SyntaxKind.AsyncKeyword; + }) || + false); if (isReturnStatement && isAsyncFunction) { return; } @@ -6200,10 +6207,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { // Helper function to check if a call is recursive private static isRecursiveCall(callExpr: ts.CallExpression, fn: ts.FunctionLikeDeclaration): boolean { - return ts.isIdentifier(callExpr.expression) && - ts.isFunctionDeclaration(fn) && - !!fn.name && - fn.name.text === callExpr.expression.text; + return ( + ts.isIdentifier(callExpr.expression) && + ts.isFunctionDeclaration(fn) && + !!fn.name && + fn.name.text === callExpr.expression.text + ); } private handleArrayType(arrayType: ts.Node): void { @@ -7771,8 +7780,14 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return undefined; } - private processApiNodeSdkDuplicateDeclName(apiName: string, errorNode: ts.Node): void { - const setApiListItem = TypeScriptLinter.globalApiInfo.get(SdkProblem.DeclWithDuplicateName); + private processApiNodeSdkGlobalApi(apiName: string, errorNode: ts.Node): void { + for (const [key, value] of globalApiAssociatedInfo) { + this.doProcessApiNodeSdkGlobalApi(apiName, errorNode, key, value); + } + } + + private doProcessApiNodeSdkGlobalApi(apiName: string, errorNode: ts.Node, key: string, faultId: number): void { + const setApiListItem = TypeScriptLinter.globalApiInfo.get(key); if (!setApiListItem) { return; } @@ -7795,11 +7810,11 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }); if (matchedApi) { - this.incrementCounters(errorNode, FaultID.DuplicateDeclNameFromSdk); + this.incrementCounters(errorNode, faultId); } } - private handleSdkDuplicateDeclName( + private handleSdkGlobalApi( node: | ts.TypeReferenceNode | ts.NewExpression @@ -7810,75 +7825,86 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { | ts.BinaryExpression | ts.ExpressionWithTypeArguments | ts.Identifier + | ts.MethodDeclaration ): void { if (!this.options.arkts2) { return; } switch (node.kind) { case ts.SyntaxKind.TypeReference: - this.checkTypeReferenceForSdkDuplicateDeclName(node); + this.checkTypeReferenceForSdkGlobalApi(node); break; case ts.SyntaxKind.NewExpression: - this.checkNewExpressionForSdkDuplicateDeclName(node); + this.checkNewExpressionForSdkGlobalApi(node); break; case ts.SyntaxKind.Identifier: - this.checkHeritageClauseForSdkDuplicateDeclName(node); + this.checkHeritageClauseForSdkGlobalApi(node); break; case ts.SyntaxKind.VariableDeclaration: case ts.SyntaxKind.PropertyDeclaration: case ts.SyntaxKind.Parameter: - this.checkDeclarationForSdkDuplicateDeclName(node); + this.checkDeclarationForSdkGlobalApi(node); break; case ts.SyntaxKind.CallExpression: - this.checkCallExpressionForSdkDuplicateDeclName(node); + this.checkCallExpressionForSdkGlobalApi(node); break; case ts.SyntaxKind.BinaryExpression: - this.checkBinaryExpressionForSdkDuplicateDeclName(node); + this.checkBinaryExpressionForSdkGlobalApi(node); + break; + case ts.SyntaxKind.MethodDeclaration: + this.checkMethodDeclarationForSdkGlobalApi(node); break; default: } } - private checkTypeReferenceForSdkDuplicateDeclName(node: ts.TypeReferenceNode): void { + private checkTypeReferenceForSdkGlobalApi(node: ts.TypeReferenceNode): void { const typeName = node.typeName; if (ts.isIdentifier(typeName)) { - this.processApiNodeSdkDuplicateDeclName(typeName.text, node); + this.processApiNodeSdkGlobalApi(typeName.text, node); } } - private checkNewExpressionForSdkDuplicateDeclName(node: ts.NewExpression): void { + private checkNewExpressionForSdkGlobalApi(node: ts.NewExpression): void { const expression = node.expression; if (ts.isIdentifier(expression)) { - this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + this.processApiNodeSdkGlobalApi(expression.text, expression); } } - private checkHeritageClauseForSdkDuplicateDeclName(node: ts.Identifier): void { + private checkHeritageClauseForSdkGlobalApi(node: ts.Identifier): void { if (ts.isIdentifier(node)) { - this.processApiNodeSdkDuplicateDeclName(node.text, node); + this.processApiNodeSdkGlobalApi(node.text, node); } } - private checkDeclarationForSdkDuplicateDeclName( + private checkDeclarationForSdkGlobalApi( node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration ): void { const expression = node.initializer; if (expression && ts.isIdentifier(expression)) { - this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + this.processApiNodeSdkGlobalApi(expression.text, expression); } } - private checkCallExpressionForSdkDuplicateDeclName(node: ts.CallExpression): void { + private checkCallExpressionForSdkGlobalApi(node: ts.CallExpression): void { if (ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { const expression = node.expression.expression; - this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + this.processApiNodeSdkGlobalApi(expression.text, expression); } } - private checkBinaryExpressionForSdkDuplicateDeclName(node: ts.BinaryExpression): void { + private checkBinaryExpressionForSdkGlobalApi(node: ts.BinaryExpression): void { const expression = node.right; if (ts.isIdentifier(expression)) { - this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + this.processApiNodeSdkGlobalApi(expression.text, expression); + } + } + + private checkMethodDeclarationForSdkGlobalApi(node: ts.MethodDeclaration): void { + const expression = node.name; + if (ts.isIdentifier(expression)) { + this.processApiNodeSdkGlobalApi(expression.text, expression); } } @@ -7891,7 +7917,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleSharedArrayBuffer(type); const expr = type.expression; if (ts.isIdentifier(expr)) { - this.processApiNodeSdkDuplicateDeclName(expr.text, expr); + this.processApiNodeSdkGlobalApi(expr.text, expr); } }); } diff --git a/ets2panda/linter/src/lib/utils/consts/AssociatedInfo.ts b/ets2panda/linter/src/lib/utils/consts/AssociatedInfo.ts new file mode 100644 index 0000000000..2c3409d7ce --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/AssociatedInfo.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FaultID } from '../../Problems'; +import { SdkProblem } from './SdkWhitelist'; + +export const globalApiAssociatedInfo: Map = new Map([ + [SdkProblem.DeclWithDuplicateName, FaultID.DuplicateDeclNameFromSdk], + [SdkProblem.LimitedVoidType, FaultID.LimitedVoidTypeFromSdk] +]); diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json index c4491ce76c..fe74c1ad28 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json @@ -74,6 +74,16 @@ "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, + { + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, { "line": 105, "column": 3, diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json index 3575cf7b84..129ca0c809 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json @@ -176,6 +176,16 @@ "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, + { + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, { "line": 105, "column": 3, diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json index 0e17a7dad5..b0daffd23c 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 101, + "column": 24, + "endLine": 101, + "endColumn": 37, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, { "line": 105, "column": 26, diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json index 7ead10ecf2..1e21ab6ed3 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json @@ -34,6 +34,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 101, + "column": 24, + "endLine": 101, + "endColumn": 37, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, { "line": 105, "column": 26, diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json index 524d890233..bfbd6bbec9 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json @@ -56,6 +56,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 101, + "column": 24, + "endLine": 101, + "endColumn": 37, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, { "line": 105, "column": 26, diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json index 0e17a7dad5..b0daffd23c 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 101, + "column": 24, + "endLine": 101, + "endColumn": 37, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, { "line": 105, "column": 26, -- Gitee