From 41c56526f323dd07bfe8080eef574c864f27fc23 Mon Sep 17 00:00:00 2001 From: liwentao_uiw Date: Tue, 12 Aug 2025 20:31:36 +0800 Subject: [PATCH 1/2] Add CheckTupleOptional and code-style fix Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICSN18 Test scenarios: npm test for linter Signed-off-by: liwentao --- ets2panda/linter/rule-config.json | 7 +- ets2panda/linter/src/lib/CookBookMsg.ts | 1 + ets2panda/linter/src/lib/FaultAttrs.ts | 1 + ets2panda/linter/src/lib/FaultDesc.ts | 1 + ets2panda/linter/src/lib/Problems.ts | 1 + ets2panda/linter/src/lib/TypeScriptLinter.ts | 10 +++ .../linter/src/lib/autofixes/Autofixer.ts | 6 +- .../src/lib/statistics/scan/WorkLoadInfo.ts | 2 +- .../linter/test/main/class_static_init.ets | 2 +- .../main/class_static_init.ets.arkts2.json | 26 +++---- .../linter/test/main/optional_tuple_type.ets | 55 +++++++++++++++ .../main/optional_tuple_type.ets.args.json | 19 ++++++ .../main/optional_tuple_type.ets.arkts2.json | 68 +++++++++++++++++++ .../test/main/optional_tuple_type.ets.json | 17 +++++ 14 files changed, 196 insertions(+), 20 deletions(-) create mode 100644 ets2panda/linter/test/main/optional_tuple_type.ets create mode 100644 ets2panda/linter/test/main/optional_tuple_type.ets.args.json create mode 100644 ets2panda/linter/test/main/optional_tuple_type.ets.arkts2.json create mode 100644 ets2panda/linter/test/main/optional_tuple_type.ets.json diff --git a/ets2panda/linter/rule-config.json b/ets2panda/linter/rule-config.json index 2b4b13d656..85f47e04ae 100644 --- a/ets2panda/linter/rule-config.json +++ b/ets2panda/linter/rule-config.json @@ -72,11 +72,12 @@ "arkts-numeric-bigint-compare", "arkts-only-support-decimal-bigint-literal", "arkts-unsupport-operator", - "arkts-no-duplicate-function-name", + "arkts-no-duplicate-function-name", "arkts-require-func-arg-type", - "arkts-subclass-must-call-super-constructor-with-args", + "arkts-subclass-must-call-super-constructor-with-args", "arkts-no-esobject-support", - "arkts-not-support-tuple-generic-validation" + "arkts-not-support-tuple-generic-validation", + "arkts-no-optional-tuple-type" ], "interop": [ "arkts-interop-js2s-inherit-js-class", diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index eb595308ca..04eda0dded 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -432,6 +432,7 @@ cookBookTag[405] = 'API is not support use class in this API (arkts-builtin-fina cookBookTag[406] = 'Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)'; cookBookTag[407] = 'API has been disabled (arkts-builtin-disable-api)'; cookBookTag[408] = 'The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)'; +cookBookTag[409] = 'No optional tuple type (arkts-no-optional-tuple-type)'; for (let i = 0; i <= cookBookTag.length; i++) { cookBookMsg[i] = ''; diff --git a/ets2panda/linter/src/lib/FaultAttrs.ts b/ets2panda/linter/src/lib/FaultAttrs.ts index d7d64f4e67..d54e4df5c2 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -305,3 +305,4 @@ faultsAttrs[FaultID.BuiltinFinalClass] = new FaultAttributes(405); faultsAttrs[FaultID.BuiltinNarrowTypes] = new FaultAttributes(406); faultsAttrs[FaultID.BuiltinDisableApi] = new FaultAttributes(407); faultsAttrs[FaultID.BuiltinIteratorResultValue] = new FaultAttributes(408); +faultsAttrs[FaultID.OptionalTupleType] = new FaultAttributes(409); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index eebe9aef41..954cb23665 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -295,3 +295,4 @@ faultDesc[FaultID.BuiltinFinalClass] = 'Not support use class in this APIe'; faultDesc[FaultID.BuiltinNarrowTypes] = 'Using narrowing of types is not allowed'; faultDesc[FaultID.BuiltinDisableApi] = 'Disable Api'; faultDesc[FaultID.BuiltinIteratorResultValue] = 'IteratorResult.value is not supported'; +faultDesc[FaultID.OptionalTupleType] = 'No optional tuple type'; diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index 99bdbd2687..9f05adbe77 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -294,6 +294,7 @@ export enum FaultID { BuiltinNarrowTypes, BuiltinDisableApi, BuiltinIteratorResultValue, + OptionalTupleType, // this should always be last enum LAST_ID } diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index c2f34353a2..e3e4a14da7 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -3840,6 +3840,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } + this.checkOptionalTupleType(node); + node.elements.forEach((elementType) => { if (elementType.kind === ts.SyntaxKind.VoidKeyword) { this.incrementCounters(elementType, FaultID.LimitedVoidType); @@ -3847,6 +3849,14 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }); } + private checkOptionalTupleType(node: ts.TupleTypeNode): void { + node.elements.forEach((elementType) => { + if (elementType.kind === ts.SyntaxKind.OptionalType) { + this.incrementCounters(elementType, FaultID.OptionalTupleType); + } + }); + } + private handleImportClause(node: ts.Node): void { const tsImportClause = node as ts.ImportClause; if (this.options.arkts2 && tsImportClause.isLazy) { diff --git a/ets2panda/linter/src/lib/autofixes/Autofixer.ts b/ets2panda/linter/src/lib/autofixes/Autofixer.ts index 91ff39cad5..179b43b46c 100644 --- a/ets2panda/linter/src/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/src/lib/autofixes/Autofixer.ts @@ -3733,7 +3733,7 @@ export class Autofixer { const codeStartLine = isUseStaticAtStart ? annotationEndLine + 1 : - file.getLineAndCharacterOfPosition(file.getStart()).line; + file.getLineAndCharacterOfPosition(file.getStart()).line; for (let i = 2; i > codeStartLine - annotationEndLine; i--) { text = text + this.getNewLine(); } @@ -3760,7 +3760,9 @@ export class Autofixer { } private static checkUseStaticAtStart(stmt: ts.Statement): boolean { - return stmt.getText().trim().replace(/^'|'$/g, '').endsWith(USE_STATIC_STATEMENT); + return stmt.getText().trim(). + replace(/^'|'$/g, ''). + endsWith(USE_STATIC_STATEMENT); } fixStylesDecoratorGlobal( diff --git a/ets2panda/linter/src/lib/statistics/scan/WorkLoadInfo.ts b/ets2panda/linter/src/lib/statistics/scan/WorkLoadInfo.ts index 0fbb9d817c..9376d47509 100644 --- a/ets2panda/linter/src/lib/statistics/scan/WorkLoadInfo.ts +++ b/ets2panda/linter/src/lib/statistics/scan/WorkLoadInfo.ts @@ -54,7 +54,7 @@ export class WorkLoadInfo { (problemCount * AVERAGE_LINE_FOR_REPAIRE_RULE_COEFFICIENT * TEST_DEBUG_WORKLOAD_COEFFICIENT + this.totalNapiCodeLines * NPAI_REPAIRE_WORKLOADA_COEFFICIEN) / totalLines; - + this.manualFixRate = `${(ratio * 100).toFixed(2)}%`; } } diff --git a/ets2panda/linter/test/main/class_static_init.ets b/ets2panda/linter/test/main/class_static_init.ets index c74ec693d9..05149dab13 100755 --- a/ets2panda/linter/test/main/class_static_init.ets +++ b/ets2panda/linter/test/main/class_static_init.ets @@ -139,7 +139,7 @@ class FunctionTypes { class ComplexTypes { static uninitializedComplexArray: Array<{ id: number; data: Map> }>; static uninitializedRecord: Record; - static uninitializedTuple: [string, number, boolean?]; + static uninitializedTuple: [string, number, boolean]; } // Custom Class Types diff --git a/ets2panda/linter/test/main/class_static_init.ets.arkts2.json b/ets2panda/linter/test/main/class_static_init.ets.arkts2.json index da2a0d8e4b..6f8984af61 100644 --- a/ets2panda/linter/test/main/class_static_init.ets.arkts2.json +++ b/ets2panda/linter/test/main/class_static_init.ets.arkts2.json @@ -1,17 +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." + "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": [ { @@ -398,7 +398,7 @@ "line": 142, "column": 3, "endLine": 142, - "endColumn": 57, + "endColumn": 56, "problem": "ClassstaticInitialization", "suggest": "", "rule": "The static property has no initializer (arkts-class-static-initialization)", diff --git a/ets2panda/linter/test/main/optional_tuple_type.ets b/ets2panda/linter/test/main/optional_tuple_type.ets new file mode 100644 index 0000000000..510267dad2 --- /dev/null +++ b/ets2panda/linter/test/main/optional_tuple_type.ets @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023-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. + */ + +// Test optional tuple type rule + +// Basic optional tuple type +type BasicOptionalTuple = [string, number?]; // Error: number? is optional + +// Optional element in nested tuple +type NestedOptionalTuple = [string, [number, string?]]; // Error: string? is optional + +// Optional tuple type in function parameters +function processOptionalTuple( + data: [string, number?] // Error: number? is optional +): void { + console.log(data); +} + +// Optional tuple property in interface +interface DataProcessor { + process(data: [string, number?]): void; // Error: number? is optional +} + +// Optional tuple in type +let t: [number, boolean?] = [1]; // Error: boolean? is optional + +// Correct usage +type CorrectTuple1 = [string, number]; // Correct: all elements are required + +// Correct function parameter usage +function processCorrectTuple( + data: [string, number] // Correct: all elements are required +): void { + console.log(data); +} + +// Correct interface usage +interface CorrectDataProcessor { + process(data: [string, number]): void; // Correct: all elements are required +} + +// Correct type alias usage +type CorrectDataTuple = [string, number]; // Correct: all elements are required \ No newline at end of file diff --git a/ets2panda/linter/test/main/optional_tuple_type.ets.args.json b/ets2panda/linter/test/main/optional_tuple_type.ets.args.json new file mode 100644 index 0000000000..4c5ee75ae1 --- /dev/null +++ b/ets2panda/linter/test/main/optional_tuple_type.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2024-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." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/optional_tuple_type.ets.arkts2.json b/ets2panda/linter/test/main/optional_tuple_type.ets.arkts2.json new file mode 100644 index 0000000000..9be7efa7bf --- /dev/null +++ b/ets2panda/linter/test/main/optional_tuple_type.ets.arkts2.json @@ -0,0 +1,68 @@ +{ + "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": [ + { + "line": 19, + "column": 36, + "endLine": 19, + "endColumn": 43, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 46, + "endLine": 22, + "endColumn": 53, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 18, + "endLine": 26, + "endColumn": 25, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 33, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 17, + "endLine": 37, + "endColumn": 25, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/optional_tuple_type.ets.json b/ets2panda/linter/test/main/optional_tuple_type.ets.json new file mode 100644 index 0000000000..2844fc25ba --- /dev/null +++ b/ets2panda/linter/test/main/optional_tuple_type.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2023-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 From 85590901b8e5cfdc6cd428370850924545027c59 Mon Sep 17 00:00:00 2001 From: liwentao_uiw Date: Wed, 13 Aug 2025 14:11:36 +0800 Subject: [PATCH 2/2] add large numeric literal check Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICSN18 Test scenarios: npm test for linter Signed-off-by: liwentao --- ets2panda/linter/rule-config.json | 3 +- ets2panda/linter/src/lib/CookBookMsg.ts | 1 + ets2panda/linter/src/lib/FaultAttrs.ts | 1 + ets2panda/linter/src/lib/FaultDesc.ts | 1 + ets2panda/linter/src/lib/Problems.ts | 1 + ets2panda/linter/src/lib/TypeScriptLinter.ts | 6 + ets2panda/linter/src/lib/utils/TsUtils.ts | 9 +- .../lib/utils/consts/NumericalConstants.ts | 4 + .../test/main/large_numeric_literal.ets | 65 +++++++ .../main/large_numeric_literal.ets.args.json | 19 ++ .../large_numeric_literal.ets.arkts2.json | 168 ++++++++++++++++++ .../test/main/large_numeric_literal.ets.json | 28 +++ 12 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 ets2panda/linter/test/main/large_numeric_literal.ets create mode 100644 ets2panda/linter/test/main/large_numeric_literal.ets.args.json create mode 100755 ets2panda/linter/test/main/large_numeric_literal.ets.arkts2.json create mode 100644 ets2panda/linter/test/main/large_numeric_literal.ets.json diff --git a/ets2panda/linter/rule-config.json b/ets2panda/linter/rule-config.json index 85f47e04ae..4e7aab8304 100644 --- a/ets2panda/linter/rule-config.json +++ b/ets2panda/linter/rule-config.json @@ -77,7 +77,8 @@ "arkts-subclass-must-call-super-constructor-with-args", "arkts-no-esobject-support", "arkts-not-support-tuple-generic-validation", - "arkts-no-optional-tuple-type" + "arkts-no-optional-tuple-type", + "arkts-no-large-numeric-literal" ], "interop": [ "arkts-interop-js2s-inherit-js-class", diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index 04eda0dded..34809d01bd 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -433,6 +433,7 @@ cookBookTag[406] = 'Using narrowing of types is not allowed in this API (arkts-b cookBookTag[407] = 'API has been disabled (arkts-builtin-disable-api)'; cookBookTag[408] = 'The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)'; cookBookTag[409] = 'No optional tuple type (arkts-no-optional-tuple-type)'; +cookBookTag[410] = 'Numeric literal exceeds allowed range (arkts-no-large-numeric-literal)'; for (let i = 0; i <= cookBookTag.length; i++) { cookBookMsg[i] = ''; diff --git a/ets2panda/linter/src/lib/FaultAttrs.ts b/ets2panda/linter/src/lib/FaultAttrs.ts index d54e4df5c2..da10cb73ad 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -306,3 +306,4 @@ faultsAttrs[FaultID.BuiltinNarrowTypes] = new FaultAttributes(406); faultsAttrs[FaultID.BuiltinDisableApi] = new FaultAttributes(407); faultsAttrs[FaultID.BuiltinIteratorResultValue] = new FaultAttributes(408); faultsAttrs[FaultID.OptionalTupleType] = new FaultAttributes(409); +faultsAttrs[FaultID.LargeNumericLiteral] = new FaultAttributes(410); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index 954cb23665..4ed647541b 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -296,3 +296,4 @@ faultDesc[FaultID.BuiltinNarrowTypes] = 'Using narrowing of types is not allowed faultDesc[FaultID.BuiltinDisableApi] = 'Disable Api'; faultDesc[FaultID.BuiltinIteratorResultValue] = 'IteratorResult.value is not supported'; faultDesc[FaultID.OptionalTupleType] = 'No optional tuple type'; +faultDesc[FaultID.LargeNumericLiteral] = 'Numeric literal exceeds allowed range'; diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index 9f05adbe77..2230dc3edb 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -295,6 +295,7 @@ export enum FaultID { BuiltinDisableApi, BuiltinIteratorResultValue, OptionalTupleType, + LargeNumericLiteral, // this should always be last enum LAST_ID } diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index e3e4a14da7..781938bd9d 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -12450,6 +12450,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const parent = node.parent; const isPrefix = ts.isPrefixUnaryExpression(parent) && parent.operator === ts.SyntaxKind.MinusToken; + if (TsUtils.isLargeNumericLiteral(node, isPrefix)) { + this.incrementCounters(node, FaultID.LargeNumericLiteral); + return; + } + + // Check for int overflow (existing logic) const type = isPrefix ? this.tsTypeChecker.getContextualType(parent) : this.tsTypeChecker.getContextualType(node); const isLarge = TsUtils.ifLargerThanInt(node, isPrefix); if (!isLarge) { diff --git a/ets2panda/linter/src/lib/utils/TsUtils.ts b/ets2panda/linter/src/lib/utils/TsUtils.ts index 1eea1826ef..e9cfd673d3 100644 --- a/ets2panda/linter/src/lib/utils/TsUtils.ts +++ b/ets2panda/linter/src/lib/utils/TsUtils.ts @@ -47,7 +47,7 @@ import { STRINGLITERAL_NUMBER, STRINGLITERAL_NUMBER_ARRAY } from './consts/Strin import { ETS_MODULE, PATH_SEPARATOR, VALID_OHM_COMPONENTS_MODULE_PATH } from './consts/OhmUrl'; import { EXTNAME_ETS, EXTNAME_JS, EXTNAME_D_ETS } from './consts/ExtensionName'; import { CONCAT_ARRAY, STRING_ERROR_LITERAL } from './consts/Literals'; -import { INT_MIN, INT_MAX } from './consts/NumericalConstants'; +import { INT_MIN, INT_MAX, LARGE_NUMBER_MIN, LARGE_NUMBER_MAX } from './consts/NumericalConstants'; import { IGNORE_TYPE_LIST } from './consts/TypesToBeIgnored'; export const PROMISE_METHODS = new Set(['all', 'race', 'any', 'resolve', 'allSettled']); @@ -1701,6 +1701,13 @@ export class TsUtils { return value < INT_MIN || value > INT_MAX; } + static isLargeNumericLiteral(node: ts.NumericLiteral, isPrefix: boolean): boolean { + const raw = node.getText(); + const value = isPrefix ? Number(raw) * -1 : Number(raw); + + return value < LARGE_NUMBER_MIN || value > LARGE_NUMBER_MAX; + } + isStdErrorType(type: ts.Type): boolean { const symbol = type.symbol; if (!symbol) { diff --git a/ets2panda/linter/src/lib/utils/consts/NumericalConstants.ts b/ets2panda/linter/src/lib/utils/consts/NumericalConstants.ts index f15e7fc233..2bf076304c 100644 --- a/ets2panda/linter/src/lib/utils/consts/NumericalConstants.ts +++ b/ets2panda/linter/src/lib/utils/consts/NumericalConstants.ts @@ -15,3 +15,7 @@ export const INT_MIN = -2147483648; export const INT_MAX = 2147483647; + +// Large number literal constants (2^63 - 1 to -2^63) +export const LARGE_NUMBER_MAX = Number('9223372036854775807'); +export const LARGE_NUMBER_MIN = Number('-9223372036854775808'); diff --git a/ets2panda/linter/test/main/large_numeric_literal.ets b/ets2panda/linter/test/main/large_numeric_literal.ets new file mode 100644 index 0000000000..d18e4f7ba6 --- /dev/null +++ b/ets2panda/linter/test/main/large_numeric_literal.ets @@ -0,0 +1,65 @@ +/* + * 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. + */ + + Test large number literal rule +// These should be detected as errors + +// Large number literals beyond 2^63 - 1 to -2^63 range +const tooLargePositive = 9223372036854775808; // Error: exceeds 2^63 - 1 +const tooLargeNegative = -9223372036854775809; // Error: below -2^63 + +// Edge cases - these should not report errors +const maxAllowedPositive = 9223372036854775807; // Correct: exactly 2^63 - 1 +const maxAllowedNegative = -9223372036854775808; // Correct: exactly -2^63 + +// Normal numbers - these should not report errors +const normalPositive = 1000000; +const normalNegative = -1000000; +const zero = 0; + +// Large but acceptable numbers +const largeButOk = 9223372036854775800; // Correct: within range +const largeButOkNegative = -9223372036854775800; // Correct: within range + +// Function parameters +function processLargeNumber( + value: number = 9223372036854775808 // Error: exceeds 2^63 - 1 +): void { + console.log(value); +} + +// Interface property +interface DataConfig { + maxValue: number; // This will be checked when assigned +} + +// Variable assignment +let config: DataConfig = { + maxValue: 9223372036854775808 // Error: exceeds 2^63 - 1 +}; + +// Array literal +const largeNumbers = [ + 9223372036854775808, // Error: exceeds 2^63 - 1 + -9223372036854775809, // Error: below -2^63 + 1000, // Correct: normal number + 9223372036854775807 // Correct: exactly at limit +]; + +// Object literal +const settings = { + threshold: 9223372036854775808, // Error: exceeds 2^63 - 1 + limit: 9223372036854775807 // Correct: exactly at limit +}; \ No newline at end of file diff --git a/ets2panda/linter/test/main/large_numeric_literal.ets.args.json b/ets2panda/linter/test/main/large_numeric_literal.ets.args.json new file mode 100644 index 0000000000..75871d1ccc --- /dev/null +++ b/ets2panda/linter/test/main/large_numeric_literal.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2023-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." + ], + "mode": { + "arkts2": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/large_numeric_literal.ets.arkts2.json b/ets2panda/linter/test/main/large_numeric_literal.ets.arkts2.json new file mode 100755 index 0000000000..c3520de662 --- /dev/null +++ b/ets2panda/linter/test/main/large_numeric_literal.ets.arkts2.json @@ -0,0 +1,168 @@ +{ + "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": [ + { + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 45, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 27, + "endLine": 21, + "endColumn": 46, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 28, + "endLine": 24, + "endColumn": 47, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 29, + "endLine": 25, + "endColumn": 48, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 20, + "endLine": 33, + "endColumn": 39, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 29, + "endLine": 34, + "endColumn": 48, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 19, + "endLine": 38, + "endColumn": 38, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 13, + "endLine": 50, + "endColumn": 32, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 3, + "endLine": 55, + "endColumn": 22, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 4, + "endLine": 56, + "endColumn": 23, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 22, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 18, + "endLine": 62, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 14, + "endLine": 63, + "endColumn": 33, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 10, + "endLine": 64, + "endColumn": 29, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 6, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Test\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/large_numeric_literal.ets.json b/ets2panda/linter/test/main/large_numeric_literal.ets.json new file mode 100644 index 0000000000..24907755d1 --- /dev/null +++ b/ets2panda/linter/test/main/large_numeric_literal.ets.json @@ -0,0 +1,28 @@ +{ + "copyright": [ + "Copyright (c) 2023-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": [ + { + "line": 62, + "column": 18, + "endLine": 62, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file -- Gitee