diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index e535b3251aab6811b301845c13b0f97d313a2bc4..b72b41dba49948b1624d28b6d42d22218d53d191 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -3845,24 +3845,31 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private checkMethodType(allBaseTypes: ts.Type[], methodName: string, node: ts.MethodDeclaration, isStatic: boolean = false): void { + private checkMethodType( + allBaseTypes: ts.Type[], + methodName: string, + node: ts.MethodDeclaration, + isStatic: boolean = false + ): void { for (const baseType of allBaseTypes) { let baseMethod: ts.Symbol | undefined; - const symbol = baseType.getSymbol(); + const symbol = baseType.getSymbol(); if (isStatic && symbol) { const constructorType = this.tsTypeChecker.getTypeOfSymbolAtLocation(symbol, node); - baseMethod = constructorType.getProperty(methodName) || - symbol.members?.get(ts.escapeLeadingUnderscores(methodName)); + baseMethod = + constructorType.getProperty(methodName) || symbol.members?.get(ts.escapeLeadingUnderscores(methodName)); } else { baseMethod = baseType.getProperty(methodName); } if (!baseMethod) { continue; } - const baseMethodDecl = baseMethod.declarations?.find(d => - (ts.isMethodDeclaration(d) || ts.isMethodSignature(d)) && - this.isSameDeclarationType(d.parent, baseType, isStatic) - ) as ts.MethodDeclaration | ts.MethodSignature; + const baseMethodDecl = baseMethod.declarations?.find((d) => { + return ( + (ts.isMethodDeclaration(d) || ts.isMethodSignature(d)) && + this.isSameDeclarationType(d.parent, baseType, isStatic) + ); + }) as ts.MethodDeclaration | ts.MethodSignature; if (!baseMethodDecl) { continue; @@ -4022,7 +4029,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }); } } - return [...resolvedBaseClasses, ...interfaces]; + return [...resolvedBaseClasses, ...interfaces]; } private getStaticAllBaseTypes(classDecl: ts.ClassDeclaration): ts.Type[] | undefined { @@ -4093,7 +4100,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { derivedMethod: ts.MethodDeclaration, baseMethod: ts.MethodDeclaration | ts.MethodSignature ): void { - if(this.shouldSkipTypeParameterCheck(derivedMethod, baseMethod)) { + if (this.shouldSkipTypeParameterCheck(derivedMethod, baseMethod)) { return; } const baseMethodType = this.getActualReturnType(baseMethod); @@ -4144,8 +4151,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ): boolean { const baseMethodType = this.getActualReturnType(baseMethod); const derivedMethodType = this.getActualReturnType(derivedMethod); - - if (baseMethodType && (baseMethodType.flags & ts.TypeFlags.TypeParameter)) { + + if (baseMethodType && baseMethodType.flags & ts.TypeFlags.TypeParameter) { if (derivedMethodType && !(derivedMethodType.flags & ts.TypeFlags.TypeParameter)) { return true; } @@ -4895,7 +4902,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); } } else if (this.tsTypeChecker.typeToString(argType) === 'number') { - if (this.isArrayIndexValidNumber(argExpr) || this.hasNonIntegerInitializer(argExpr)) { + if (this.isArrayIndexValidNumber(argExpr)) { return; } const autofix = this.autofixer?.fixArrayIndexExprType(argExpr); @@ -4925,7 +4932,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ) { const raw = declNode.initializer.getText(); const num = Number(raw); - return !Number.isInteger(num); + return Number.isInteger(num); } return false; } @@ -4966,7 +4973,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return null; } - if (declaration.type !== undefined) { + if (declaration.type !== undefined && declaration.type.getText() !== NUMBER_LITERAL) { return 'skip'; } @@ -5007,12 +5014,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return false; } - const valueString = String(evaluatedValue); - if (!Number.isInteger(evaluatedValue)) { return false; } - if (valueString.includes('.')) { + + const valueString = String(evaluatedValue); + if (valueString.includes('.') && !valueString.endsWith('.0')) { return false; } @@ -8207,7 +8214,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - /** + /** * Ensures classes fully implement all properties from their interfaces. */ private handleInterfaceFieldImplementation(clause: ts.HeritageClause): void { @@ -13483,14 +13490,14 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return true; } - private handleESObjectUsage(typeRef: ts.TypeReferenceNode): void { + private handleESObjectUsage(typeRef: ts.TypeReferenceNode): void { if (!this.options.arkts2) { return; } if ( - (ts.isIdentifier(typeRef.typeName) && typeRef.typeName.text === ES_OBJECT) || - (ts.isQualifiedName(typeRef.typeName) && typeRef.typeName.right.text === ES_OBJECT) + ts.isIdentifier(typeRef.typeName) && typeRef.typeName.text === ES_OBJECT || + ts.isQualifiedName(typeRef.typeName) && typeRef.typeName.right.text === ES_OBJECT ) { this.incrementCounters(typeRef, FaultID.NoESObjectSupport); } diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json b/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json index 31545145079a4bf762ccfc2671c83ee689d2a404..b51fb2c3b00f2135212a898d114f88c8f1c963cc 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json @@ -505,19 +505,19 @@ "severity": "ERROR" }, { - "line": 40, - "column": 1, - "endLine": 40, - "endColumn": 15, - "problem": "RuntimeArrayCheck", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 14, + "problem": "ArrayIndexExprType", "suggest": "", - "rule": "Array bound not checked. (arkts-runtime-array-check)", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, { - "line": 41, + "line": 40, "column": 1, - "endLine": 41, + "endLine": 40, "endColumn": 15, "problem": "RuntimeArrayCheck", "suggest": "", @@ -525,15 +525,25 @@ "severity": "ERROR" }, { - "line": 41, + "line": 40, "column": 7, - "endLine": 41, + "endLine": 40, "endColumn": 14, "problem": "ArrayIndexExprType", "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 15, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 42, "column": 20, @@ -554,16 +564,6 @@ "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, - { - "line": 45, - "column": 7, - "endLine": 45, - "endColumn": 14, - "problem": "ArrayIndexExprType", - "suggest": "", - "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", - "severity": "ERROR" - }, { "line": 48, "column": 26, @@ -684,16 +684,6 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 55, - "column": 22, - "endLine": 55, - "endColumn": 23, - "problem": "ArrayIndexExprType", - "suggest": "", - "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", - "severity": "ERROR" - }, { "line": 58, "column": 19, diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json b/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json index 2ca2aebf6a3c14eefaa734154b5dbf4a933beefe..52b566a13ad8afff77d52bb0aea8a57259f2153b 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json @@ -824,19 +824,30 @@ "severity": "ERROR" }, { - "line": 40, - "column": 1, - "endLine": 40, - "endColumn": 15, - "problem": "RuntimeArrayCheck", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1201, + "end": 1208, + "replacementText": "index_1 as int", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 14 + } + ], "suggest": "", - "rule": "Array bound not checked. (arkts-runtime-array-check)", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, { - "line": 41, + "line": 40, "column": 1, - "endLine": 41, + "endLine": 40, "endColumn": 15, "problem": "RuntimeArrayCheck", "suggest": "", @@ -844,19 +855,19 @@ "severity": "ERROR" }, { - "line": 41, + "line": 40, "column": 7, - "endLine": 41, + "endLine": 40, "endColumn": 14, "problem": "ArrayIndexExprType", "autofix": [ { - "start": 1233, - "end": 1240, - "replacementText": "index_3 as int", - "line": 41, + "start": 1217, + "end": 1224, + "replacementText": "index_2 as int", + "line": 40, "column": 7, - "endLine": 41, + "endLine": 40, "endColumn": 14 } ], @@ -864,6 +875,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 15, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 42, "column": 20, @@ -895,27 +916,6 @@ "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, - { - "line": 45, - "column": 7, - "endLine": 45, - "endColumn": 14, - "problem": "ArrayIndexExprType", - "autofix": [ - { - "start": 1315, - "end": 1322, - "replacementText": "index_5 as int", - "line": 45, - "column": 7, - "endLine": 45, - "endColumn": 14 - } - ], - "suggest": "", - "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", - "severity": "ERROR" - }, { "line": 48, "column": 26, @@ -1157,27 +1157,6 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, - { - "line": 55, - "column": 22, - "endLine": 55, - "endColumn": 23, - "problem": "ArrayIndexExprType", - "autofix": [ - { - "start": 1527, - "end": 1528, - "replacementText": "i as int", - "line": 55, - "column": 22, - "endLine": 55, - "endColumn": 23 - } - ], - "suggest": "", - "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", - "severity": "ERROR" - }, { "line": 58, "column": 19, @@ -1948,4 +1927,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets index 7266dd25101a50a8c50e62a93a01b2654ac08926..34bc33f9799e378afd6799a96343d4a530a1b2b7 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets @@ -41,13 +41,13 @@ let array: number[] = [1.0,2.0,3.0] const index_1: number = 1.3; let index_2: number = 1.3; let index_3: number = 1.0; -array[index_1]; -array[index_2]; -array[index_3 as int]; +array[index_1 as int]; +array[index_2 as int]; +array[index_3]; let index_4: int = 2.0 array[index_4]; const index_5: number = 1.0; -array[index_5 as int]; +array[index_5]; function getIndex(): number { return Math.random() * 10.0; @@ -57,7 +57,7 @@ array1[getIndex() as int]; let array2: number[] = [1.0, 2.0, 3.0]; for (let i: number = 0.0; i < array2.length; i++) { - console.log(array2[i as int]); + console.log(array2[i]); } for (let i: int = 0.0; i < array2.length; i++) { diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json index 7d6f66ccb49e10e0f838c0cf6264aefd11ac8807..70e54eb98936fc16985fc2feabaa2048e2e95a2d 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json @@ -115,9 +115,9 @@ "severity": "ERROR" }, { - "line": 44, + "line": 46, "column": 1, - "endLine": 44, + "endLine": 46, "endColumn": 15, "problem": "RuntimeArrayCheck", "suggest": "", @@ -125,9 +125,9 @@ "severity": "ERROR" }, { - "line": 45, + "line": 50, "column": 1, - "endLine": 45, + "endLine": 50, "endColumn": 15, "problem": "RuntimeArrayCheck", "suggest": "", @@ -245,4 +245,4 @@ "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets index 5531ae7190fbacfb0cd23ea1d5aefaab27680da0..f3179e9701d51272595069e888e3e0435a442471 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets @@ -17,7 +17,7 @@ const arr: int[] = [1.0, 2.0, 3.0, 4.0]; for (let i: number = 0.0; i < arr.length; i++) { - arr[i as int]; //legal + arr[i]; //legal } for (let i: number = 0.0; i < 100.0; i++) { @@ -42,7 +42,7 @@ for (let i: number = 0.0; i < arr4.length; i++) { const arr5: int[] = [1.0, 2.0, 3.0, 4.0]; for (let i: number = 0.0; i < 10.0; i++) { - arr5[i as int]; //should report + arr5[i]; //should report } @@ -84,42 +84,42 @@ if (arr10.length > newIndex) { newIndex = 22.0; -arr10[newIndex as int]; +arr10[newIndex]; let arr: number[] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] for(let i: number = 0.0; i < arr.length; i++) { -arr[i as int] = arr[i as int] + 1.0; +arr[i] = arr[i] + 1.0; } for(let i: number = 0.0; i < arr.length; i++) { i = 10.0; -arr[i as int] = arr[i as int] + 1.0; +arr[i] = arr[i] + 1.0; } let arr: number[] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] let idx: number = 2.0; if(idx > 0.0 && idx < arr.length) { -arr[idx as int] = arr[idx as int] + 1.0; +arr[idx] = arr[idx] + 1.0; } if(idx > 0.0 && idx < arr.length) { idx = 10.0; -arr[idx as int] = arr[idx as int] + 1.0; +arr[idx] = arr[idx] + 1.0; } let arr: number[] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] let idx: number = 0.0; while(idx > 0.0 && idx < arr.length) { -arr[idx as int] = arr[idx as int] + 1.0; +arr[idx] = arr[idx] + 1.0; idx++; idx = 10.0; } while(idx > 0.0 && idx < arr.length) { idx = 10.0; -arr[idx as int] = arr[idx as int] + 1.0; +arr[idx] = arr[idx] + 1.0; } let arr: number[] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] let idx: number = 0.0; -arr[idx as int]; +arr[idx]; arr[10]; if (arr.length > 10.0) { arr[10] = 10.0; @@ -168,7 +168,7 @@ arr1[TE.AA] = 12.0; let a: string[] = []; let b: Array = new Array(a.length); for (let i: number = 0.0; i < a.length; i++) { - b[i as int]; + b[i]; } function test1(arr: object[]) { @@ -199,8 +199,8 @@ function test4(arr?: object[]) { function test5(arrA: object[], arrB: object[]) { const length: number = Math.max(arrA.length, arrB.length); for (let i: number = 0.0; i < length; i++) { - let numA = arrA[i as int] || 0.0; - let numB = arrB[i as int] || 0.0; + let numA = arrA[i] || 0.0; + let numB = arrB[i] || 0.0; } } @@ -224,10 +224,10 @@ let index2: number = 1.0 let index3: number = 2.0 -arr1[index1 as int] +arr1[index1] if (index1 >= 0.0 && index1 < arr1.length) { - arr1[index1 as int] + arr1[index1] } arr1[3] @@ -237,39 +237,39 @@ if (arr1.length > 3.0) { } for(let i: number = 0.0; i < arr1.length; i++) { - arr1[i as int]; + arr1[i]; } let i: number = 0.0; while(i < arr1.length) { - arr1[i as int]; + arr1[i]; } if (index1 >= 0.0 && index1 < arr1.length) { index1 = 100.0 - arr1[index1 as int] + arr1[index1] } let a: string[] = []; let b: Array = new Array(a.length); for (let i: number = 0.0; i < a.length; i++) { - b[i as int]; + b[i]; } for (let i: number = 0.0; i < a.length; i++) { b.push("abc"); - b[i as int]; + b[i]; } for (let i: number = 0.0; i < a.length; i++) { b.pop(); - b[i as int]; + b[i]; } let arr_len: number = 8.0; let b: Array = new Array(arr_len); for (let i: number = 0.0; i < arr_len; i++) { - b[i as int]; + b[i]; } function test7(config: Record, name: string) { @@ -286,14 +286,14 @@ const arr: Record = {}; let keys: string[] = Object.keys(arr); let values: string[] = Object.values(arr); for (let i: number = 0.0; i < keys.length; i++) { - values[i as int]; + values[i]; } const arr: Map = new Map(); let keys: string[] = Object.keys(arr); let values: string[] = Object.values(arr); for (let i: number = 0.0; i < keys.length; i++) { - values[i as int]; + values[i]; } let concatArray: ConcatArray = new Array(1.0, 2.0, 3.0); @@ -302,7 +302,7 @@ let tempNum: number = concatArray[5]; for (let i: number = 0.0; i < concatArray.length; i++) { - concatArray[i as int] + concatArray[i] }; if (concatArray.length > 10.0) { 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 84420569c7afc81e1a53ff83f2da02c069d5981a..7f3ade653994e970c73e913d2f1441c821119536 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json @@ -34,6 +34,16 @@ "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 59, "column": 1, @@ -44,6 +54,86 @@ "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 1, + "endLine": 95, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 10, + "endLine": 95, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 1, + "endLine": 105, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 12, + "endLine": 105, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 1, + "endLine": 117, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 12, + "endLine": 117, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 1, + "endLine": 122, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 123, "column": 1, @@ -194,6 +284,16 @@ "rule": "Smart type differences (arkts-no-ts-like-smart-type)", "severity": "ERROR" }, + { + "line": 227, + "column": 1, + "endLine": 227, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 233, "column": 1, @@ -204,6 +304,26 @@ "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, + { + "line": 250, + "column": 5, + "endLine": 250, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 266, + "column": 3, + "endLine": 266, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 276, "column": 7,