From 89befb245395dbdbfcc9dbb88fd213a300a3b3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=92=9F=E6=9F=A0?= Date: Wed, 9 Jul 2025 18:01:37 +0800 Subject: [PATCH] Fix bug arkts-no-ts-like-catch-type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIW6Y Test scenarios:Fix bug arkts-no-ts-like-catch-type Signed-off-by: 钟柠 --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 296 ++++++- .../linter/test/main/ts-like-catch-type.ets | 181 +++++ .../main/ts-like-catch-type.ets.arkts2.json | 756 +++++++++++++++++- .../test/main/ts-like-catch-type.ets.json | 104 ++- .../linter/test/main/ts-like-catch-type111.ts | 48 ++ .../main/ts-like-catch-type111.ts.args.json | 17 + .../test/main/ts-like-catch-type111.ts.json | 17 + 7 files changed, 1404 insertions(+), 15 deletions(-) create mode 100644 ets2panda/linter/test/main/ts-like-catch-type111.ts create mode 100644 ets2panda/linter/test/main/ts-like-catch-type111.ts.args.json create mode 100644 ets2panda/linter/test/main/ts-like-catch-type111.ts.json diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index ca04dbcfcd..64c84b751e 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -2655,23 +2655,309 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (this.options.arkts2 && tsCatch.variableDeclaration?.name) { const varDeclName = tsCatch.variableDeclaration?.name.getText(); tsCatch.block.statements.forEach((statement) => { - this.checkTsLikeCatchType(statement, varDeclName); + this.checkTsLikeCatchType(statement, varDeclName, undefined); }); } } - private checkTsLikeCatchType(node: ts.Node, variableDeclarationName: string): void { + private checkTsLikeCatchType( + node: ts.Node, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): void { if (!node) { return; } + const hasChecked = this.hasCheckedTsLikeCatchTypeInIfStatement(node, variableDeclarationName, typeNode); + if (hasChecked) { + return; + } + const hasCheckedInConditionalExpr = this.hasCheckedTsLikeCatchTypeInConditionalExpression( + node, + variableDeclarationName, + typeNode + ); + if (hasCheckedInConditionalExpr) { + return; + } + this.checkTsLikeCatchTypeForAsExpr(node, variableDeclarationName); + for (const child of node.getChildren()) { if (ts.isPropertyAccessExpression(child)) { - if (child.expression.getText() === variableDeclarationName && !ERROR_PROP_LIST.has(child.name.getText())) { - this.incrementCounters(child, FaultID.TsLikeCatchType); + this.checkTsLikeCatchTypeForPropAccessExpr(child, variableDeclarationName, typeNode); + + if ( + ts.isParenthesizedExpression(child.expression) && + ts.isAsExpression(child.expression.expression) && + child.expression.expression.expression.getText() === variableDeclarationName + ) { + this.checkTsLikeCatchTypePropForAsExpression(child, child.expression.expression); + } + } + this.checkTsLikeCatchType(child, variableDeclarationName, typeNode); + } + } + + private hasCheckedTsLikeCatchTypeInIfStatement( + node: ts.Node, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): boolean { + const checkSubStatement = (node: ts.IfStatement, declaration: ts.ClassDeclaration): void => { + if (!this.isErrorOrInheritError(declaration)) { + this.incrementCounters(node.expression, FaultID.TsLikeCatchType); + } else { + this.checkTsLikeCatchType(node.thenStatement, variableDeclarationName, declaration); + } + const elseStatement = node.elseStatement; + if (elseStatement) { + this.checkTsLikeCatchType(elseStatement, variableDeclarationName, typeNode); + } + }; + + if ( + ts.isIfStatement(node) && + ts.isBinaryExpression(node.expression) && + node.expression.operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword && + node.expression.left.getText() === variableDeclarationName + ) { + const rightSym = this.tsTypeChecker.getSymbolAtLocation(node.expression.right); + const decl = rightSym?.declarations?.[0]; + if (decl && ts.isClassDeclaration(decl)) { + checkSubStatement(node, decl); + return true; + } + if (decl && ts.isImportSpecifier(decl)) { + const symbol = this.getSymbolByImportSpecifier(decl); + const declaration = symbol?.declarations?.[0]; + if (declaration && ts.isClassDeclaration(declaration)) { + checkSubStatement(node, declaration); + return true; + } + } + } + return false; + } + + private hasCheckedTsLikeCatchTypeInConditionalExpression( + node: ts.Node, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): boolean { + if ( + ts.isConditionalExpression(node) && + ts.isBinaryExpression(node.condition) && + node.condition.operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword && + node.condition.left.getText() === variableDeclarationName + ) { + const rightSym = this.tsTypeChecker.getSymbolAtLocation(node.condition.right); + const decl = rightSym?.declarations?.[0]; + if (decl && ts.isClassDeclaration(decl)) { + this.checkTsLikeCatchTypeInConditionalExprSubStatement(node, decl, variableDeclarationName, typeNode); + return true; + } else if (decl && ts.isImportSpecifier(decl)) { + const symbol = this.getSymbolByImportSpecifier(decl); + const declaration = symbol?.declarations?.[0]; + if (declaration && ts.isClassDeclaration(declaration)) { + this.checkTsLikeCatchTypeInConditionalExprSubStatement(node, declaration, variableDeclarationName, typeNode); + return true; + } + } + } + return false; + } + + private checkTsLikeCatchTypeInConditionalExprSubStatement( + node: ts.ConditionalExpression, + declarationType: ts.ClassDeclaration, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): void { + const checkWhenFalseExpr = ( + whenFalse: ts.Node, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): void => { + if (ts.isPropertyAccessExpression(whenFalse) && whenFalse.expression.getText() === variableDeclarationName) { + if (!typeNode) { + if (!ERROR_PROP_LIST.has(whenFalse.name.getText())) { + this.incrementCounters(whenFalse, FaultID.TsLikeCatchType); + } + } else { + const isValidErrorPropAccess = this.isValidErrorPropAccess(whenFalse, typeNode); + if (!isValidErrorPropAccess) { + this.incrementCounters(whenFalse, FaultID.TsLikeCatchType); + } + } + } else { + this.checkTsLikeCatchType(whenFalse, variableDeclarationName, typeNode); + } + }; + + if (!this.isErrorOrInheritError(declarationType)) { + this.incrementCounters(node.condition, FaultID.TsLikeCatchType); + checkWhenFalseExpr(node.whenFalse, typeNode); + } else { + if ( + ts.isPropertyAccessExpression(node.whenTrue) && + node.whenTrue.expression.getText() === variableDeclarationName + ) { + const whenTrue: ts.PropertyAccessExpression = node.whenTrue; + const isValidErrorPropAccess = this.isValidErrorPropAccess(whenTrue, declarationType); + if (!isValidErrorPropAccess) { + this.incrementCounters(whenTrue, FaultID.TsLikeCatchType); } + } else { + this.checkTsLikeCatchType(node.whenTrue, variableDeclarationName, declarationType); + } + checkWhenFalseExpr(node.whenFalse, typeNode); + } + } + + private checkTsLikeCatchTypeForAsExpr(node: ts.Node, variableDeclarationName: string): void { + if (!ts.isAsExpression(node) || node.expression.getText() !== variableDeclarationName) { + return; + } + const asExprTypeNode = node.type; + if (!asExprTypeNode || !ts.isTypeReferenceNode(asExprTypeNode)) { + return; + } + const checkReport = (node: ts.AsExpression, declaration: ts.ClassDeclaration | ts.InterfaceDeclaration): void => { + if (!this.isErrorOrInheritError(declaration)) { + this.incrementCounters(node, FaultID.TsLikeCatchType); + } + }; + + const checkImportSpecifier = (decl: ts.ImportSpecifier): void => { + const symbol = this.getSymbolByImportSpecifier(decl); + const declaration = symbol?.declarations?.[0]; + if (declaration && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration))) { + checkReport(node, declaration); + } + }; + const typeName = asExprTypeNode.typeName; + const sym = this.tsTypeChecker.getSymbolAtLocation(typeName); + const decl = sym?.declarations?.[0]; + if (decl && (ts.isClassDeclaration(decl) || ts.isInterfaceDeclaration(decl))) { + checkReport(node, decl); + } else if (decl && ts.isImportSpecifier(decl)) { + checkImportSpecifier(decl); + } + } + + private checkTsLikeCatchTypeHasPropInType( + propAccessExpr: ts.PropertyAccessExpression, + decl: ts.ClassDeclaration | ts.InterfaceDeclaration + ): void { + if (!decl) { + return; + } + if (this.isErrorOrInheritError(decl)) { + const isValidErrorPropAccess = this.isValidErrorPropAccess(propAccessExpr, decl); + if (!isValidErrorPropAccess) { + this.incrementCounters(propAccessExpr, FaultID.TsLikeCatchType); + } + } + } + + private checkTsLikeCatchTypeForPropAccessExpr( + propAccessExpr: ts.PropertyAccessExpression, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): void { + const checkProp = (): void => { + if (!typeNode) { + if (!ERROR_PROP_LIST.has(propAccessExpr.name.getText())) { + this.incrementCounters(propAccessExpr, FaultID.TsLikeCatchType); + } + } else { + const isValidErrorPropAccess = this.isValidErrorPropAccess(propAccessExpr, typeNode); + if (!isValidErrorPropAccess) { + this.incrementCounters(propAccessExpr, FaultID.TsLikeCatchType); + } + } + }; + + if (propAccessExpr.expression.getText() === variableDeclarationName) { + checkProp(); + return; + } + + const sym = this.tsTypeChecker.getSymbolAtLocation(propAccessExpr.expression); + const decl = sym?.declarations?.[0]; + if (decl && ts.isVariableDeclaration(decl) && decl.initializer) { + if (decl.initializer.getText() === variableDeclarationName) { + checkProp(); + return; + } + if (ts.isAsExpression(decl.initializer) && decl.initializer.expression.getText() === variableDeclarationName) { + this.checkTsLikeCatchTypePropForAsExpression(propAccessExpr, decl.initializer); + } + } + } + + private checkTsLikeCatchTypePropForAsExpression( + propAccessExpr: ts.PropertyAccessExpression, + asExpr: ts.AsExpression + ): void { + const asExprTypeNode = asExpr.type; + if (asExprTypeNode && ts.isTypeReferenceNode(asExprTypeNode)) { + const typeName = asExprTypeNode.typeName; + const sym = this.tsTypeChecker.getSymbolAtLocation(typeName); + const decl = sym?.declarations?.[0]; + if (decl && (ts.isClassDeclaration(decl) || ts.isInterfaceDeclaration(decl))) { + this.checkTsLikeCatchTypeHasPropInType(propAccessExpr, decl); + } else if (decl && ts.isImportSpecifier(decl)) { + const symbol = this.getSymbolByImportSpecifier(decl); + const declaration = symbol?.declarations?.[0]; + if (declaration && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration))) { + this.checkTsLikeCatchTypeHasPropInType(propAccessExpr, declaration); + } + } + } + } + + private isErrorOrInheritError(declaration: ts.ClassDeclaration | ts.InterfaceDeclaration): boolean { + const type = this.tsTypeChecker.getTypeAtLocation(declaration); + return this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdErrorType); + } + + private isValidErrorPropAccess( + propertyAccessExpr: ts.PropertyAccessExpression, + decl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): boolean { + void this; + let containsMember = false; + decl?.members.forEach((member) => { + if (member.name?.getText() === propertyAccessExpr.name.getText()) { + containsMember = true; + } + }); + return containsMember || ERROR_PROP_LIST.has(propertyAccessExpr.name.getText()); + } + + private getSymbolByImportSpecifier(declaration: ts.ImportSpecifier): ts.Symbol | undefined { + if (!declaration?.parent?.parent) { + return undefined; + } + if (!ts.isImportClause(declaration.parent.parent)) { + return undefined; + } + const importClause = declaration.parent.parent; + const namedBindings = importClause.namedBindings; + let symbol: ts.Symbol | undefined; + if (namedBindings) { + if (ts.isNamedImports(namedBindings) && namedBindings.elements?.length > 0) { + for (let i = 0; i < namedBindings.elements.length; i++) { + if (namedBindings.elements[i].name.getText() === declaration.name.getText()) { + symbol = this.tsUtils.trueSymbolAtLocation(namedBindings.elements[i].name); + break; + } + } + } else if (ts.isNamespaceImport(namedBindings)) { + symbol = this.tsUtils.trueSymbolAtLocation(namedBindings.name); } - this.checkTsLikeCatchType(child, variableDeclarationName); } + return symbol; } private handleClassExtends(tsClassDecl: ts.ClassDeclaration): void { diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets b/ets2panda/linter/test/main/ts-like-catch-type.ets index 84b0d23a10..1f16edc96f 100644 --- a/ets2panda/linter/test/main/ts-like-catch-type.ets +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets @@ -14,6 +14,7 @@ */ import { BusinessError } from '@ohos.base'; +import { AError, AError1, BError, BError1 } from "./ts-like-catch-type111"; try { throw new Error(); @@ -31,4 +32,184 @@ try { let that = 123; } catch (err: BusinessError) { console.log(err.toString()); +} + +class RpcException { + msg: string; + code: number; +} + +class RpcException1 { + msg: string; + code: number; +} + +// not extends Error +function a1() { + try { + throw new RpcException('msg', 1); + } catch (e) { + let errorCode = 1; + let errorMsg = ''; + if (e instanceof RpcException) { // error + errorMsg = e.msg; // not check + errorCode = e.code; // not check + } else if (e instanceof RpcException1) { // error + errorMsg = e.msg; // not check + errorCode = e.code; // not check + } else { + console.log('else prop: ' + e.prop); // error + console.log('else message: ' + e.message); // ok + } + // e instanceof RpcException / e.prop error + e instanceof RpcException ? e.msg : e.prop; + // e instanceof RpcException / e.prop error + e instanceof RpcException ? console.log('when true: ' + e.msg) : console.log('when false: ' + e.prop); + // e instanceof RpcException / e instanceof RpcException1 / e.prop error + e instanceof RpcException ? console.log('when true: ' + (e instanceof RpcException1 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof RpcException1 ? e.msg : e.prop)); + // e instanceof RpcException / e instanceof RpcException1 + e instanceof RpcException ? console.log('when true: ' + (e instanceof RpcException1 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof RpcException1 ? e.msg : e.message)); // error * 2 + console.log(errorMsg); + (e as RpcException).msg; // error + console.log('errorMsg: ' + (e as RpcException).msg); // error + const temp = e; + temp.prop; // error + console.log('errorMsg: ' + temp.prop); // error + const temp1 = e as RpcException; // error + temp1.msg; // not check + temp1.message; // not check + console.log('errorMsg: ' + temp1.message); // not check + } +} + +// import / not extends Error +function a2() { + try { + throw new BError('msg', 1); + } catch (e) { + let errorCode = 1; + let errorMsg = ''; + if (e instanceof BError) { // error + errorMsg = e.a; // not check + errorCode = e.code; // not check + } else if (e instanceof BError1) { // error + errorMsg = e.b; // not check + errorCode = e.message; // not check + } else { + console.log('else prop: ' + e.prop); // error + console.log('else message: ' + e.message); // ok + } + // e instanceof BError / e.prop error + e instanceof BError ? e.msg : e.prop; + // e instanceof BError / e.prop error + e instanceof BError ? console.log('when true: ' + e.msg) : console.log('when false: ' + e.prop); + // e instanceof BError / e instanceof BError1 / e.prop error + e instanceof BError ? console.log('when true: ' + (e instanceof BError1 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof BError1 ? e.msg : e.prop)); + // e instanceof BError / e instanceof BError1 + e instanceof BError ? console.log('when true: ' + (e instanceof BError1 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof BError1 ? e.msg : e.message)); + console.log(errorMsg); + (e as BError).msg; // error + console.log('errorMsg: ' + (e as BError).msg); // error + const temp = e; + temp.prop; // error + console.log('errorMsg: ' + temp.prop); // error + const temp1 = e as BError; // error + temp1.msg; // not check + temp1.message; // not check + console.log('errorMsg: ' + temp1.message); // not check + } +} + +class RpcException2 extends Error { + msg: string; + code: number; + constructor(msg: string, code: number) { + super(msg); + this.msg = msg; + this.code = code; + } +} + +class RpcException3 extends Error { + msg: string; + code: number; + constructor(msg: string, code: number) { + super(msg); + this.msg = msg; + this.code = code; + } +} + +// extends Error +function a3() { + try { + throw new RpcException2(); + } catch (e) { + let errorCode = 1; + let errorMsg = ''; + if (e instanceof RpcException2) { + errorMsg = e.msg; + errorCode = e.code; + console.log('a3: ' + e.prop); // error + } else if (e instanceof RpcException3) { + errorMsg = e.msg; + errorCode = e.code; + } else { + console.log('else prop: ' + e.prop); // error + console.log('else message: ' + e.message); // ok + } + e instanceof RpcException2 ? e.msg : e.prop; // e.prop error + e instanceof RpcException2 ? console.log('when true: ' + e.msg) : console.log('when false: ' + e.prop); // e.prop error + // e.msg1 / e.prop error + e instanceof RpcException2 ? console.log('when true: ' + (e instanceof RpcException3 ? e.msg1 : e.code)) : console.log('when false: ' + (e instanceof RpcException3 ? e.msg : e.prop)); + e instanceof RpcException2 ? console.log('when true: ' + (e instanceof RpcException3 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof RpcException3 ? e.msg : e.message)); + console.log(errorMsg); + (e as RpcException2).msg; // ok + console.log('errorMsg: ' + (e as RpcException2).msg); // ok + const temp = e; + temp.prop; // error + console.log('errorMsg: ' + temp.prop); // error + const temp1 = e as RpcException2; + temp1.msg; // ok + temp1.message; // ok + console.log('errorMsg: ' + temp1.message); // ok + console.log('errorMsg: ' + temp1.prop); // error + } +} + +// import / extends Error +function a4() { + try { + throw new AError('msg'); + } catch (e) { + let errorCode = 1; + let errorMsg = ''; + if (e instanceof AError) { + errorMsg = e.customProp; + errorCode = e.code; + console.log('a4: ' + e.prop); // error + } else if (e instanceof AError1) { + errorMsg = e.customProp; + errorCode = e.code; + } else { + console.log('else prop: ' + e.prop); // error + console.log('else message: ' + e.message); // ok + } + e instanceof AError ? e.customProp : e.prop; // e.prop error + e instanceof AError ? console.log('when true: ' + e.customProp) : console.log('when false: ' + e.prop); // e.prop error + // e.customProp1 / e.prop error + e instanceof AError ? console.log('when true: ' + (e instanceof AError1 ? e.customProp1 : e.code)) : console.log('when false: ' + (e instanceof AError1 ? e.customProp : e.prop)); + e instanceof AError ? console.log('when true: ' + (e instanceof AError1 ? e.customProp : e.code)) : console.log('when false: ' + (e instanceof AError1 ? e.customProp : e.message)); + console.log(errorMsg); + (e as AError).customProp; // ok + console.log('errorMsg: ' + (e as AError).customProp); // ok + const temp = e; + temp.prop; // error + console.log('errorMsg: ' + temp.prop); // error + const temp1 = e as AError; + temp1.customProp; // ok + temp1.message; // ok + console.log('errorMsg: ' + temp1.message); // ok + console.log('errorMsg: ' + temp1.prop); // error + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json b/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json index e77370a4f3..1b7c442314 100644 --- a/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 22, + "line": 23, "column": 3, - "endLine": 22, + "endLine": 23, "endColumn": 9, "problem": "TsLikeCatchType", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 32, "column": 7, - "endLine": 31, + "endLine": 32, "endColumn": 17, "problem": "NumericSemantics", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 32, "column": 14, - "endLine": 31, + "endLine": 32, "endColumn": 17, "problem": "NumericSemantics", "suggest": "", @@ -45,14 +45,754 @@ "severity": "ERROR" }, { - "line": 32, + "line": 33, "column": 10, - "endLine": 32, + "endLine": 33, "endColumn": 28, "problem": "CatchWithUnsupportedType", "suggest": "", "rule": "Type annotation in catch clause is not supported (arkts-no-types-in-catch)", "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 38, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 35, + "endLine": 50, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 9, + "endLine": 54, + "endColumn": 34, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 16, + "endLine": 57, + "endColumn": 42, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 35, + "endLine": 61, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 30, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 41, + "endLine": 65, + "endColumn": 47, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 30, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 99, + "endLine": 67, + "endColumn": 105, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 30, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 141, + "endLine": 69, + "endColumn": 167, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 178, + "endLine": 69, + "endColumn": 184, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 30, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 141, + "endLine": 71, + "endColumn": 167, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 6, + "endLine": 73, + "endColumn": 23, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 33, + "endLine": 74, + "endColumn": 50, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 5, + "endLine": 76, + "endColumn": 14, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 32, + "endLine": 77, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 19, + "endLine": 78, + "endColumn": 36, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 9, + "endLine": 52, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 21, + "endLine": 52, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 11, + "endLine": 75, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 5, + "endLine": 88, + "endColumn": 32, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 29, + "endLine": 88, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 9, + "endLine": 92, + "endColumn": 28, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 16, + "endLine": 95, + "endColumn": 36, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 35, + "endLine": 99, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 5, + "endLine": 103, + "endColumn": 24, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 35, + "endLine": 103, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 24, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 93, + "endLine": 105, + "endColumn": 99, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 5, + "endLine": 107, + "endColumn": 24, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 129, + "endLine": 107, + "endColumn": 149, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 160, + "endLine": 107, + "endColumn": 166, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 5, + "endLine": 109, + "endColumn": 24, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 129, + "endLine": 109, + "endColumn": 149, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 6, + "endLine": 111, + "endColumn": 17, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 33, + "endLine": 112, + "endColumn": 44, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 5, + "endLine": 114, + "endColumn": 14, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 32, + "endLine": 115, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 19, + "endLine": 116, + "endColumn": 30, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 9, + "endLine": 90, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 21, + "endLine": 90, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 11, + "endLine": 113, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 5, + "endLine": 127, + "endColumn": 10, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 5, + "endLine": 137, + "endColumn": 10, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 28, + "endLine": 153, + "endColumn": 34, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 35, + "endLine": 158, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 42, + "endLine": 161, + "endColumn": 48, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 100, + "endLine": 162, + "endColumn": 106, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 92, + "endLine": 164, + "endColumn": 98, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 180, + "endLine": 164, + "endColumn": 186, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 5, + "endLine": 170, + "endColumn": 14, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 32, + "endLine": 171, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 32, + "endLine": 176, + "endColumn": 42, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 9, + "endLine": 148, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 21, + "endLine": 148, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 11, + "endLine": 169, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 190, + "column": 28, + "endLine": 190, + "endColumn": 34, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 195, + "column": 35, + "endLine": 195, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 42, + "endLine": 198, + "endColumn": 48, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 100, + "endLine": 199, + "endColumn": 106, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 79, + "endLine": 201, + "endColumn": 92, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 175, + "endLine": 201, + "endColumn": 181, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 207, + "column": 5, + "endLine": 207, + "endColumn": 14, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 208, + "column": 32, + "endLine": 208, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 213, + "column": 32, + "endLine": 213, + "endColumn": 42, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 9, + "endLine": 185, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 21, + "endLine": 185, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 11, + "endLine": 206, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 43, + "column": 3, + "endLine": 43, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets.json b/ets2panda/linter/test/main/ts-like-catch-type.ets.json index 50c51fe194..e5a6b2de81 100644 --- a/ets2panda/linter/test/main/ts-like-catch-type.ets.json +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets.json @@ -15,14 +15,114 @@ ], "result": [ { - "line": 32, + "line": 33, "column": 10, - "endLine": 32, + "endLine": 33, "endColumn": 28, "problem": "CatchWithUnsupportedType", "suggest": "", "rule": "Type annotation in catch clause is not supported (arkts-no-types-in-catch)", "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 38, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 11, + "endLine": 75, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 5, + "endLine": 88, + "endColumn": 32, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 11, + "endLine": 113, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 11, + "endLine": 169, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 11, + "endLine": 206, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 43, + "column": 3, + "endLine": 43, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type111.ts b/ets2panda/linter/test/main/ts-like-catch-type111.ts new file mode 100644 index 0000000000..4c483947ad --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type111.ts @@ -0,0 +1,48 @@ +/* + * 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. +*/ + +export class AError extends Error { + customProp: string; + constructor(message: string) { + super(message); + this.customProp = "custom"; + } +} + +export class AError1 extends Error { + customProp: string; + constructor(message: string) { + super(message); + this.customProp = "custom"; + } +} + +export class BError { + msg: string; + code: number; + constructor(msg: string, code: number) { + this.msg = msg; + this.code = code; + } +} + +export class BError1 { + msg: string; + code: number; + constructor(msg: string, code: number) { + this.msg = msg; + this.code = code; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type111.ts.args.json b/ets2panda/linter/test/main/ts-like-catch-type111.ts.args.json new file mode 100644 index 0000000000..b87ffd2bb3 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type111.ts.args.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "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." + ], + "commonArgs": "--no-check-ts-as-source" +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type111.ts.json b/ets2panda/linter/test/main/ts-like-catch-type111.ts.json new file mode 100644 index 0000000000..ca88f857e9 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type111.ts.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "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." + ], + "result": [] +} \ No newline at end of file -- Gitee