From 51fbc686f1c504230390909d986fb8fba05c4fbc Mon Sep 17 00:00:00 2001 From: wangjiahui Date: Tue, 19 Aug 2025 11:17:27 +0800 Subject: [PATCH] 0702 sync 0728 Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICTLS2 Signed-off-by: wangjiahui --- .../arkanalyzer/src/core/common/Const.ts | 2 + .../src/core/common/TypeInference.ts | 7 + .../linter/arkanalyzer/src/core/graph/Cfg.ts | 4 + .../arkanalyzer/src/core/model/ArkMethod.ts | 19 +- .../core/model/builder/ArkMethodBuilder.ts | 15 +- ets2panda/linter/homecheck/ruleSet.json | 196 ----- .../homecheck/scripts/install_arkanalyzer.sh | 33 - .../linter/homecheck/scripts/run_ci_ut.sh | 71 -- .../checker/migration/NumericSemanticCheck.ts | 749 +++++++++++++---- .../homecheck/src/utils/common/CheckEntry.ts | 1 + .../homecheck/src/utils/common/SDKUtils.ts | 40 +- ets2panda/linter/rule-config.json | 9 +- ets2panda/linter/src/lib/CookBookMsg.ts | 4 + ets2panda/linter/src/lib/FaultAttrs.ts | 3 + ets2panda/linter/src/lib/FaultDesc.ts | 3 + ets2panda/linter/src/lib/LinterRunner.ts | 2 + ets2panda/linter/src/lib/Problems.ts | 3 + ets2panda/linter/src/lib/TypeScriptLinter.ts | 351 +++++--- .../linter/src/lib/autofixes/Autofixer.ts | 213 ++--- .../src/lib/statistics/scan/WorkLoadInfo.ts | 2 +- .../linter/src/lib/ts-compiler/ResolveSdks.ts | 4 + ets2panda/linter/src/lib/utils/TsUtils.ts | 29 +- .../src/lib/utils/consts/ArkuiImportList.ts | 1 + .../linter/src/lib/utils/consts/Literals.ts | 3 + .../lib/utils/consts/NumericalConstants.ts | 4 + .../src/lib/utils/functions/CommonApiInfo.ts | 47 ++ ets2panda/linter/src/testRunner/LintTest.ts | 2 +- .../builtin_array_negative.ets.arkts2.json | 784 +++++++++--------- .../deprecatedapi/COMPONENT.ets.arkts2.json | 2 +- ...tBeforeBackPageOptions_api.ets.arkts2.json | 2 +- .../test/deprecatedapi/SM.ets.arkts2.json | 8 +- .../action_sheet.ets.arkts2.json | 2 +- .../alert_dialog.ets.arkts2.json | 2 +- .../deprecatedapi/animator.ets.arkts2.json | 2 +- .../appStorageIsMutable_api.ets.arkts2.json | 10 +- .../appscreenOnVisible_api.ets.arkts2.json | 2 +- .../deprecatedapi/buttons.ets.arkts2.json | 10 +- .../deprecatedapi/common_api.ets.arkts2.json | 52 +- .../common_ts_ets_api.ets.arkts2.json | 2 +- .../curvesInit_api.ets.arkts2.json | 2 +- .../deprecatedapi/custom_api.ets.arkts2.json | 10 +- .../deprecated_api_font.ets.arkts2.json | 10 +- .../deprecated_api_router.ets.arkts2.json | 4 +- .../environmentEnvProp_api.ets.arkts2.json | 6 +- .../foldable_api.ets.arkts2.json | 10 +- .../listitem_api.ets.arkts2.json | 4 +- .../matrix4Rotate_api.ets.arkts2.json | 6 +- .../deprecatedapi/minibar_api.ets.arkts2.json | 10 +- .../navigator_api.ets.arkts2.json | 16 +- .../navrouter_api.ets.arkts2.json | 56 +- .../deprecatedapi/node_api.ets.arkts2.json | 8 +- .../panelModePanelMode_api.ets.arkts2.json | 12 +- ...entStoragePersistProps_api.ets.arkts2.json | 4 +- .../deprecatedapi/prompts_api.ets.arkts2.json | 34 +- ...bleAlertBeforeBackPage_api.ets.arkts2.json | 14 +- .../routerPush_api.ets.arkts2.json | 2 +- .../deprecatedapi/scroll_api.ets.arkts2.json | 2 +- .../setImageCacheCount_api.ets.arkts2.json | 2 +- .../setImageFileCacheSize_api.ets.arkts2.json | 2 +- ...tImageRawDataCacheSize_api.ets.arkts2.json | 2 +- .../showActionMenu.ets.arkts2.json | 16 +- .../deprecatedapi/sizeType.ets.arkts2.json | 20 +- .../sizeTypeXS_api.ets.arkts2.json | 8 +- .../deprecatedapi/swiper_api.ets.arkts2.json | 44 +- .../temporary_api.ets.arkts2.json | 10 +- .../wrap_content_api.ets.arkts2.json | 10 +- .../object_literal_union_type.ets.arkts2.json | 40 + ets2panda/linter/test/main/arkui-select.ets | 61 ++ .../test/main/arkui-select.ets.args.json | 19 + .../test/main/arkui-select.ets.arkts2.json | 288 +++++++ .../linter/test/main/arkui-select.ets.json | 17 + .../test/main/avoid_using_union_types.ets | 8 +- .../test/main/builder_node.ets.arkts2.json | 20 + .../linter/test/main/class_static_init.ets | 2 +- .../main/class_static_init.ets.arkts2.json | 26 +- ...=> destructuring_object_property_name.ets} | 71 +- ...cturing_object_property_name.ets.args.json | 20 + ...ring_object_property_name.ets.autofix.json | 150 ++++ ...estructuring_object_property_name.ets.json | 128 +++ ...uring_object_property_name.ets.migrate.ets | 33 + ...ring_object_property_name.ets.migrate.json | 108 +++ .../test/main/incompatible_function.ets | 66 ++ .../incompatible_function.ets.arkts2.json | 100 +++ .../test/main/incompatible_function.ets.json | 93 ++- .../main/interface_import_5.ets.arkts2.json | 2 +- .../main/interface_import_5.ets.autofix.json | 2 +- .../test/main/large_numeric_literal.ets | 65 ++ .../main/large_numeric_literal.ets.args.json | 19 + .../large_numeric_literal.ets.arkts2.json | 168 ++++ ...ts.json => large_numeric_literal.ets.json} | 24 +- .../test/main/no_ts_like_smart_type.ets | 20 +- .../linter/test/main/optional_tuple_type.ets | 55 ++ .../main/optional_tuple_type.ets.args.json | 19 + ...on => optional_tuple_type.ets.arkts2.json} | 58 +- .../test/main/optional_tuple_type.ets.json | 17 + ..._assignment_with_obj_literal_ambiguity.ets | 123 +++ ..._with_obj_literal_ambiguity.ets.args.json} | 0 ...with_obj_literal_ambiguity.ets.arkts2.json | 138 +++ ...gnment_with_obj_literal_ambiguity.ets.json | 38 + .../wrapped_builder_generic_1.ets.arkts2.json | 20 + .../wrapped_builder_generic_2.ets.arkts2.json | 40 + 101 files changed, 3678 insertions(+), 1399 deletions(-) delete mode 100644 ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh delete mode 100644 ets2panda/linter/homecheck/scripts/run_ci_ut.sh create mode 100644 ets2panda/linter/src/lib/utils/functions/CommonApiInfo.ts create mode 100644 ets2panda/linter/test/main/arkui-select.ets create mode 100644 ets2panda/linter/test/main/arkui-select.ets.args.json create mode 100644 ets2panda/linter/test/main/arkui-select.ets.arkts2.json create mode 100644 ets2panda/linter/test/main/arkui-select.ets.json rename ets2panda/linter/test/main/{call_expression_matching_argument.ets => destructuring_object_property_name.ets} (37%) create mode 100644 ets2panda/linter/test/main/destructuring_object_property_name.ets.args.json create mode 100644 ets2panda/linter/test/main/destructuring_object_property_name.ets.autofix.json create mode 100644 ets2panda/linter/test/main/destructuring_object_property_name.ets.json create mode 100644 ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.ets create mode 100644 ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.json 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 100644 ets2panda/linter/test/main/large_numeric_literal.ets.arkts2.json rename ets2panda/linter/test/main/{call_expression_matching_argument.ets.json => large_numeric_literal.ets.json} (55%) create mode 100644 ets2panda/linter/test/main/optional_tuple_type.ets create mode 100644 ets2panda/linter/test/main/optional_tuple_type.ets.args.json rename ets2panda/linter/test/main/{call_expression_matching_argument.ets.arkts2.json => optional_tuple_type.ets.arkts2.json} (46%) create mode 100644 ets2panda/linter/test/main/optional_tuple_type.ets.json create mode 100644 ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets rename ets2panda/linter/test/main/{call_expression_matching_argument.ets.args.json => union_assignment_with_obj_literal_ambiguity.ets.args.json} (100%) create mode 100644 ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.arkts2.json create mode 100644 ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.json diff --git a/ets2panda/linter/arkanalyzer/src/core/common/Const.ts b/ets2panda/linter/arkanalyzer/src/core/common/Const.ts index 1fb1a81e79..34a8c9afc0 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/Const.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/Const.ts @@ -31,6 +31,8 @@ export const STATIC_INIT_METHOD_NAME = NAME_PREFIX + 'statInit'; export const STATIC_BLOCK_METHOD_NAME_PREFIX = NAME_PREFIX + 'statBlock'; export const ANONYMOUS_METHOD_PREFIX = NAME_PREFIX + 'AM'; export const CALL_SIGNATURE_NAME = 'create'; +export const GETTER_METHOD_PREFIX = 'Get-'; +export const SETTER_METHOD_PREFIX = 'Set-'; // ArkSignature const export const UNKNOWN_PROJECT_NAME = NAME_PREFIX + UNKNOWN_NAME; diff --git a/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts b/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts index b2caf8ad56..691a0d854b 100644 --- a/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts +++ b/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts @@ -208,6 +208,13 @@ export class TypeInference { } } signatures.forEach(s => this.inferSignatureReturnType(s, arkMethod)); + if (arkMethod.isGetter()) { + // should also update the corresponding field type with the getter method return type + const field = arkMethod.getGeneratedFieldOfGetter(); + if (field) { + field.getSignature().setType(arkMethod.getReturnType()); + } + } } private static resolveStmt(stmt: Stmt, arkMethod: ArkMethod): void { diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts b/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts index 7b1c4a6e5a..840ceee435 100644 --- a/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts +++ b/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts @@ -133,6 +133,10 @@ export class Cfg { } } + /** + * Get all basic blocks with topological order. + * @returns The set of all basic blocks. + */ public getBlocks(): Set { return this.blocks; } diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts index dd275f7324..9365a9762e 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts @@ -33,7 +33,7 @@ import { ArkClass, ClassCategory } from './ArkClass'; import { MethodSignature, MethodSubSignature } from './ArkSignature'; import { BodyBuilder } from './builder/BodyBuilder'; import { ArkExport, ExportType } from './ArkExport'; -import { ANONYMOUS_METHOD_PREFIX, DEFAULT_ARK_METHOD_NAME, LEXICAL_ENV_NAME_PREFIX } from '../common/Const'; +import { ANONYMOUS_METHOD_PREFIX, DEFAULT_ARK_METHOD_NAME, GETTER_METHOD_PREFIX, LEXICAL_ENV_NAME_PREFIX, SETTER_METHOD_PREFIX } from '../common/Const'; import { getColNo, getLineNo, LineCol, setCol, setLine } from '../base/Position'; import { ArkBaseModel, ModifierType } from './ArkBaseModel'; import { ArkError, ArkErrorCode } from '../common/ArkError'; @@ -44,6 +44,7 @@ import { ArkFile, Language } from './ArkFile'; import { CONSTRUCTOR_NAME } from '../common/TSConst'; import { MethodParameter } from './builder/ArkMethodBuilder'; import { TypeInference } from '../common/TypeInference'; +import { ArkField } from './ArkField'; export const arkMethodNodeKind = [ 'MethodDeclaration', @@ -575,6 +576,22 @@ export class ArkMethod extends ArkBaseModel implements ArkExport { return this.isGeneratedFlag; } + public isGetter(): boolean { + return this.getName().startsWith(GETTER_METHOD_PREFIX); + } + + public getGeneratedFieldOfGetter(): ArkField | null { + if (!this.isGetter()) { + return null; + } + const fieldName = this.getName().slice(4); + return this.getDeclaringArkClass().getFieldWithName(fieldName); + } + + public isSetter(): boolean { + return this.getName().startsWith(SETTER_METHOD_PREFIX); + } + public setIsGeneratedFlag(isGeneratedFlag: boolean): void { this.isGeneratedFlag = isGeneratedFlag; } diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts index 4dcc8b5216..72eadc8773 100644 --- a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts @@ -39,7 +39,16 @@ import { BasicBlock } from '../../graph/BasicBlock'; import { Local } from '../../base/Local'; import { Value } from '../../base/Value'; import { CONSTRUCTOR_NAME, SUPER_NAME, THIS_NAME } from '../../common/TSConst'; -import { ANONYMOUS_METHOD_PREFIX, CALL_SIGNATURE_NAME, DEFAULT_ARK_CLASS_NAME, DEFAULT_ARK_METHOD_NAME, NAME_DELIMITER, NAME_PREFIX } from '../../common/Const'; +import { + ANONYMOUS_METHOD_PREFIX, + CALL_SIGNATURE_NAME, + DEFAULT_ARK_CLASS_NAME, + DEFAULT_ARK_METHOD_NAME, + GETTER_METHOD_PREFIX, + NAME_DELIMITER, + NAME_PREFIX, + SETTER_METHOD_PREFIX, +} from '../../common/Const'; import { ArkSignatureBuilder } from './ArkSignatureBuilder'; import { IRUtils } from '../../common/IRUtils'; import { ArkErrorCode } from '../../common/ArkError'; @@ -163,9 +172,9 @@ function buildMethodName(node: MethodLikeNode, declaringClass: ArkClass, sourceF } else if (ts.isCallSignatureDeclaration(node)) { name = CALL_SIGNATURE_NAME; } else if (ts.isGetAccessor(node) && ts.isIdentifier(node.name)) { - name = 'Get-' + node.name.text; + name = GETTER_METHOD_PREFIX + node.name.text; } else if (ts.isSetAccessor(node) && ts.isIdentifier(node.name)) { - name = 'Set-' + node.name.text; + name = SETTER_METHOD_PREFIX + node.name.text; } else if (ts.isArrowFunction(node)) { name = buildAnonymousMethodName(node, declaringClass); } diff --git a/ets2panda/linter/homecheck/ruleSet.json b/ets2panda/linter/homecheck/ruleSet.json index ebfa295c23..0bd8f48742 100644 --- a/ets2panda/linter/homecheck/ruleSet.json +++ b/ets2panda/linter/homecheck/ruleSet.json @@ -1,200 +1,4 @@ { - "plugin:@ArkTS-eslint/all": { - "@ArkTS-eslint/require-await-check": 2, - "@ArkTS-eslint/triple-slash-reference-check": 2, - "@ArkTS-eslint/restrict-template-expressions-check": 2, - "@ArkTS-eslint/restrict-plus-operands-check": 2, - "@ArkTS-eslint/switch-exhaustiveness-check": 2, - "@ArkTS-eslint/unified-signatures-check": 2, - "@ArkTS-eslint/no-regex-spaces-check": 2, - "@ArkTS-eslint/valid-typeof-check": 2, - "@ArkTS-eslint/array-type-check": 2, - "@ArkTS-eslint/no-useless-backreference-check": 2, - "@ArkTS-eslint/ban-tslint-comment-check": 2, - "@ArkTS-eslint/prefer-arrow-callback-check":2, - "@ArkTS-eslint/no-unnecessary-boolean-literal-compare-check":2, - "@ArkTS-eslint/ban-types-check": 2, - "@ArkTS-eslint/brace-style-check": 2, - "@ArkTS-eslint/no-unsafe-optional-chaining-check": 2, - "@ArkTS-eslint/no-useless-escape-check": 2, - "@ArkTS-eslint/no-useless-catch-check": 2, - "@ArkTS-eslint/no-this-alias-check": 2, - "@ArkTS-eslint/no-non-null-assertion-check": 2, - "@ArkTS-eslint/no-misused-new-check": 2, - "@ArkTS-eslint/no-require-imports-check": 2, - "@ArkTS-eslint/no-parameter-properties-check": 2, - "@ArkTS-eslint/no-redeclare-check": 2, - "@ArkTS-eslint/no-shadow-check": 2, - "@ArkTS-eslint/no-non-null-asserted-optional-chain-check": 2, - "@ArkTS-eslint/consistent-type-assertions-check": 2, - "@ArkTS-eslint/consistent-type-definitions-check": 2, - "@ArkTS-eslint/consistent-type-imports-check": 2, - "@ArkTS-eslint/consistent-indexed-object-style-check": 2, - "@ArkTS-eslint/no-new-wrappers-check": 2, - "@ArkTS-eslint/max-classes-per-file-check": 2, - "@ArkTS-eslint/max-nested-callbacks-check": 2, - "@ArkTS-eslint/no-async-promise-executor-check": 2, - "@ArkTS-eslint/no-array-constructor-check": 2, - "@ArkTS-eslint/max-depth-check": 2, - "@ArkTS-eslint/eqeqeq-check": 2, - "@ArkTS-eslint/no-array-constructor-ts-check": 2, - "@ArkTS-eslint/no-extra-semi-check": 2, - "@ArkTS-eslint/no-extra-boolean-cast-check":2, - "@ArkTS-eslint/no-confusing-void-expression-check":2, - "@ArkTS-eslint/prefer-const-check": 2, - "@ArkTS-eslint/await-thenable-check": 2, - "@ArkTS-eslint/init-declarations-check": 2, - "@ArkTS-eslint/default-param-last-check": 2, - "@ArkTS-eslint/explicit-function-return-type-check": 2, - "@ArkTS-eslint/explicit-module-boundary-types-check": 2, - "@ArkTS-eslint/no-dupe-class-members-check": 2, - "@ArkTS-eslint/ban-ts-comment-check": 2, - "@ArkTS-eslint/member-ordering-check": 2, - "@ArkTS-eslint/no-unnecessary-condition-check": 2, - "@ArkTS-eslint/no-unnecessary-qualifier-check": 2, - "@ArkTS-eslint/no-unnecessary-type-arguments-check": 2, - "@ArkTS-eslint/no-unnecessary-type-assertion-check": 2, - "@ArkTS-eslint/prefer-string-starts-ends-with-check": 2, - "@ArkTS-eslint/prefer-regexp-exec-check": 2, - "@ArkTS-eslint/max-lines-per-function-check": 2, - "@ArkTS-eslint/no-cond-assign-check": 2, - "@ArkTS-eslint/no-for-in-array-check": 2, - "@ArkTS-eslint/no-loss-of-precision-check": 2, - "@ArkTS-eslint/no-loop-func-check": 2, - "@ArkTS-eslint/no-extraneous-class-check": 2, - "@ArkTS-eslint/no-duplicate-imports-check": 2, - "@ArkTS-eslint/no-case-declarations-check": 2, - "@ArkTS-eslint/default-case-check": 2, - "@ArkTS-eslint/default-case-last-check": 2, - "@ArkTS-eslint/use-isnan-check": 2, - "@ArkTS-eslint/no-invalid-void-type-check": 2, - "@ArkTS-eslint/no-namespace-check": 2, - "@ArkTS-eslint/typedef-check": 2, - "@ArkTS-eslint/return-await-check":2, - "@ArkTS-eslint/prefer-reduce-type-parameter-check":2, - "@ArkTS-eslint/prefer-nullish-coalescing-check": 2, - "@ArkTS-eslint/max-lines-check": 2, - "@ArkTS-eslint/no-unnecessary-type-constraint-check": 2, - "@ArkTS-eslint/no-unsafe-argument-check": 2, - "@ArkTS-eslint/no-unsafe-call-check": 2, - "@ArkTS-eslint/no-control-regex-check": 2, - "@ArkTS-eslint/no-empty-character-class-check": 2, - "@ArkTS-eslint/no-ex-assign-check": 2, - "@ArkTS-eslint/no-invalid-regexp-check": 2, - "@ArkTS-eslint/no-octal-check": 2, - "@ArkTS-eslint/no-unexpected-multiline-check": 2, - "@ArkTS-eslint/no-unreachable-check": 2, - "@ArkTS-eslint/no-inferrable-types-check": 2, - "@ArkTS-eslint/space-before-function-paren-check": 2, - "@ArkTS-eslint/space-infix-ops-check": 2, - "@ArkTS-eslint/no-restricted-syntax-check": 2, - "@ArkTS-eslint/adjacent-overload-signatures-check": 2, - "@ArkTS-eslint/class-literal-property-style-check": 2, - "@ArkTS-eslint/no-confusing-non-null-assertion-check": 2, - "@ArkTS-eslint/no-empty-function-check": 2, - "@ArkTS-eslint/no-magic-numbers-check": 2, - "@ArkTS-eslint/prefer-enum-initializers-check": 2, - "@ArkTS-eslint/prefer-literal-enum-member-check": 2, - "@ArkTS-eslint/prefer-readonly-parameter-types-check": 2, - "@ArkTS-eslint/require-array-sort-compare-check": 2, - "@ArkTS-eslint/no-invalid-this-check": 2, - "@ArkTS-eslint/no-fallthrough-check": 2, - "@ArkTS-eslint/no-explicit-any-check": 2, - "@ArkTS-eslint/no-unused-expressions-check": 2, - "@ArkTS-eslint/no-throw-literal-check": 2, - "@ArkTS-eslint/comma-dangle-check": 2, - "@ArkTS-eslint/prefer-ts-expect-error-check": 2, - "@ArkTS-eslint/no-extra-parens-check": 2, - "@ArkTS-eslint/no-dynamic-delete-check": 2, - "@ArkTS-eslint/no-implicit-any-catch-check": 2, - "@ArkTS-eslint/no-empty-interface-check": 2, - "@ArkTS-eslint/no-unsafe-finally-check": 3, - "@ArkTS-eslint/prefer-function-type-check":3, - "@ArkTS-eslint/prefer-namespace-keyword-check": 3, - "@ArkTS-eslint/prefer-readonly-check": 2, - "@ArkTS-eslint/comma-spacing-check": 2, - "@ArkTS-eslint/naming-convention-check": 2, - "@ArkTS-eslint/no-extra-non-null-assertion-check": 2, - "@ArkTS-eslint/no-type-alias-check": 2, - "@ArkTS-eslint/type-annotation-spacing-check": 2, - "@ArkTS-eslint/func-call-spacing-check": 1, - "@ArkTS-eslint/unbound-method-check": 2, - "@ArkTS-eslint/method-signature-style-check": 2, - "@ArkTS-eslint/lines-between-class-members-check": 2, - "@ArkTS-eslint/member-delimiter-style-check": 2, - "@ArkTS-eslint/no-unsafe-return-check": 2, - "@ArkTS-eslint/no-use-before-define-check": 1, - "@ArkTS-eslint/quotes-check": 2, - "@ArkTS-eslint/prefer-as-const-check": 2, - "@ArkTS-eslint/prefer-optional-chain-check": 2, - "@ArkTS-eslint/no-trailing-spaces-check": 2, - "@ArkTS-eslint/no-unsafe-assignment-check": 2, - "@ArkTS-eslint/prefer-for-of-check": 2, - "@ArkTS-eslint/strict-boolean-expressions-check": 2, - "@ArkTS-eslint/no-implied-eval-check": 2, - "@ArkTS-eslint/semi-check": 2, - "@ArkTS-eslint/no-base-to-string-check": 2, - "@ArkTS-eslint/promise-function-async-check": 2, - "@ArkTS-eslint/prefer-includes-check": 2, - "@ArkTS-eslint/no-unsafe-member-access-check": 2, - "@ArkTS-eslint/no-unused-vars-check": 2, - "@ArkTS-eslint/no-useless-constructor-check": 2, - "@ArkTS-eslint/dot-notation-check": 2, - "@ArkTS-eslint/explicit-member-accessibility-check": 2, - "@ArkTS-eslint/keyword-spacing-check": 2, - "@ArkTS-eslint/no-floating-promises-check": 2, - "@ArkTS-eslint/no-misused-promises-check": 2 - }, - "plugin:@performance/all": { - "@performance/array-definition-check": 3, - "@performance/avoid-empty-callback-check": 3, - "@performance/avoid-update-auto-state-var-in-aboutToReuse-check": 3, - "@performance/constant-property-referencing-check-in-loops": 3, - "@performance/effectkit-blur-check": 3, - "@performance/foreach-args-check": 3, - "@performance/foreach-index-check": 1, - "@performance/image-sync-load-check": 3, - "@performance/list-in-scroll-check": 3, - "@performance/lottie-animation-destroy-check": 3, - "@performance/multiple-associations-state-var-check": 3, - "@performance/remove-redundant-state-var-check": 3, - "@performance/set-cached-count-for-lazyforeach-check": 3, - "@performance/start-window-icon-check": 3, - "@performance/timezone-interface-check": 3, - "@performance/typed-array-check": 3, - "@performance/use-object-link-to-replace-prop-check": 3, - "@performance/web-cache-mode-check": 3, - "@performance/number-init-check": 3, - "@performance/sparse-array-check": 3, - "@performance/high-frequency-log-check": 1, - "@performance/waterflow-data-preload-check": 3, - "@performance/union-type-array-check": 3, - "@performance/layout-properties-scale-check": 3, - "@performance/optional-parameters-check": 3, - "@performance/use-grid-layout-options-check": 3, - "@performance/remove-unchanged-state-var-check": 3, - "@performance/js-code-cache-by-precompile-check": 3, - "@performance/js-code-cache-by-interception-check": 3, - "@performance/web-on-active-check": 3, - "@performance/gif-hardware-decoding-check": 1 - }, - "plugin:@performance/recommended": { - "@performance/foreach-args-check": 1, - "@performance/start-window-icon-check": 3, - "@performance/waterflow-data-preload-check": 3, - "@performance/high-frequency-log-check": 1 - }, - "plugin:@security/all": { - "@security/specified-interface-call-chain-check": 3 - }, - "plugin:@correctness/all": { - "@correctness/audio-interrupt-check": 2, - "@correctness/audio-pause-or-mute-check": 1, - "@correctness/avsession-buttons-check": 1, - "@correctness/avsession-metadata-check": 1, - "@correctness/image-interpolation-check": 1, - "@correctness/image-pixel-format-check": 1 - }, "plugin:@migration/all": { "@migration/arkts-obj-literal-generate-class-instance": 1, "@migration/arkts-instance-method-bind-this": 1, diff --git a/ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh b/ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh deleted file mode 100644 index 282d190c67..0000000000 --- a/ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -# 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. -# - -set -x - -# install and pack dependency arkanalyzer -cd ../arkanalyzer -npm install - -cp package.json package.json.bak - -sed -i '/postinstall/d' package.json -npm pack - -TAR_FILE=$(find . -maxdepth 1 -name "arkanalyzer-*.tgz" -print0) -cd ../homecheck -npm install ../arkanalyzer/$TAR_FILE - -# revert the project files -mv ../arkanalyzer/package.json.bak ../arkanalyzer/package.json -rm ../arkanalyzer/$TAR_FILE diff --git a/ets2panda/linter/homecheck/scripts/run_ci_ut.sh b/ets2panda/linter/homecheck/scripts/run_ci_ut.sh deleted file mode 100644 index 56f455f87b..0000000000 --- a/ets2panda/linter/homecheck/scripts/run_ci_ut.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/bash -# Copyright (c) 2024 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. -# - -set -x - -if [ -z "${ROOT_DIR+x}" ]; then - export ROOT_DIR=$(pwd) - echo "ROOT_DIR was not set. Initialized to $ROOT_DIR" -else - echo "ROOT_DIR is already set to $ROOT_DIR" -fi - -NODE_VERSION=v22.3.0 -NODE_HOME=$ROOT_DIR/pre_scripts/node-$NODE_VERSION-linux-x64 -NODE_URL=https://gitee.com/muya318/pre_scripts/raw/master/node-v22.3.0-linux-x64.tar.gz -NODE_BIN=node-v22.3.0-linux-x64.tar.gz - -prepare_nodejs() { - echo "### preparing nodejs" - if [ ! -d "$NODE_HOME" ]; then - cd $ROOT_DIR/pre_scripts - tar -xf $NODE_BIN - chmod 777 $NODE_HOME/bin/* - cd - - export PATH=$NODE_HOME/bin:$PATH - fi - npm config set registry=https://repo.huaweicloud.com/repository/npm/ - npm config set strict-ssl false - echo "###nodejs env ready" -} - -git clone https://gitee.com/muya318/pre_scripts.git - -prepare_nodejs - -pwd -cd $ROOT_DIR - -node -v -npm -v - -npm install -npm run test - -if [ $? -ne 0 ]; then - echo "************* Unit test failed *************" - exit 1 -fi - -echo "************* Unit test success *************" - -npm pack -if [ $? -ne 0 ]; then - echo "************* Npm pack failed *************" - exit 1 -fi -echo "************* Npm pack success *************" - -exit 0 \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/checker/migration/NumericSemanticCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/NumericSemanticCheck.ts index f0b5433573..b6250b7da0 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/NumericSemanticCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/NumericSemanticCheck.ts @@ -140,6 +140,8 @@ export class NumericSemanticCheck implements BaseChecker { private visited: Set = new Set(); private callDepth = 0; private classFieldRes: Map = new Map(); + private issuesMap: Map = new Map(); + private sourceFiles: Map = new Map(); public registerMatchers(): MatcherCallback[] { const matchBuildCb: MatcherCallback = { @@ -169,6 +171,8 @@ export class NumericSemanticCheck implements BaseChecker { if (arkFile.getLanguage() !== Language.ARKTS1_2) { continue; } + // 用于记录与issue相关的文件的tsc信息,避免每次新增issue时重复创建,提升性能。每次遍历新文件时清空map,节省内存。 + this.sourceFiles = new Map(); const defaultMethod = arkFile.getDefaultClass().getDefaultArkMethod(); if (defaultMethod) { this.dvfgBuilder.buildForSingleMethod(defaultMethod); @@ -182,14 +186,16 @@ export class NumericSemanticCheck implements BaseChecker { } } } + + this.issues = Array.from(this.issuesMap.values()); }; public processClass(arkClass: ArkClass): void { - if (arkClass.getCategory() === ClassCategory.ENUM) { + if (arkClass.getCategory() === ClassCategory.ENUM || arkClass.getCategory() === ClassCategory.TYPE_LITERAL) { // Enum类型的class不需要处理,仅有statint函数,一定不涉及SDK调用,整型字面量不能进行浮点字面量的修改,也不涉及类型注解修改 + // TYPE_LITERAL类型的class不需要处理,仅作为type使用,该class内无方法,仅有field的定义,且field无初始化语句,仅设定类型 return; } - // TODO: type literal类型的class需要处理吗 this.classFieldRes = new Map(); // 查找全部method,包含constructor、%instInit,%statInit等 for (let mtd of arkClass.getMethods(true)) { @@ -203,16 +209,18 @@ export class NumericSemanticCheck implements BaseChecker { for (const stmt of stmts) { try { this.checkSdkArgsInStmt(stmt); + this.checkSdkReturnValueInStmt(stmt); + this.checkSdkFieldValueInStmt(stmt); } catch (e) { logger.error(`Error checking sdk called in stmt: ${stmt.toString()}, method: ${target.getSignature().toString()}, error: ${e}`); } } - // 场景2:需要检查整型字面量出现的stmt,该stmt为sink点。场景2在场景1之后执行,优先让SDK调用来决定变量的类型为int、long、number,剩余的场景2处理,避免issue之间的冲突 + // 场景2:需要检查整型字面量或除法出现的stmt,该stmt为sink点。场景2在场景1之后执行,优先让SDK调用来决定变量的类型为int、long、number,剩余的场景2处理,避免issue之间的冲突 if (target.isGenerated()) { // statInit、instInit等方法不进行检查,不主动对类属性的类型进行检查,因为类属性的使用范围很广,很难找全,仅对涉及的1/2这种进行告警,自动修复为1.0/2.0 try { - this.checkFieldInitializerWithDivision(target); + this.checkFieldInitializerWithIntLiteral(target); } catch (e) { logger.error(`Error checking init method with numeric literal, method: ${target.getSignature().toString()}, error: ${e}`); } @@ -239,18 +247,18 @@ export class NumericSemanticCheck implements BaseChecker { } private checkSdkArgsInStmt(stmt: Stmt): void { - // res用于存放检查过程中所有找到的Local变量,记录这些变量是否均仅当做int使用,若是则可以设置成int类型,跨函数场景下可能包含其他method中的Local变量 - const res = new Map(); - this.callDepth = 0; const intArgs = this.getSDKIntLongArgs(stmt); if (intArgs === null || intArgs.size === 0) { return; } + // res用于存放检查过程中所有找到的Local变量,记录这些变量是否均仅当做int使用,若是则可以设置成int类型,跨函数场景下可能包含其他method中的Local变量 + const res = new Map(); + this.callDepth = 0; for (const [arg, category] of intArgs) { const issueReason = this.checkValueOnlyUsedAsIntLong(stmt, arg, res, category); if (issueReason !== IssueReason.OnlyUsedAsIntLong) { - this.addIssueReport(RuleCategory.SDKIntType, category, issueReason, true, stmt, arg); + this.addIssueReportForSDKArg(RuleCategory.SDKIntType, category, issueReason, true, stmt, arg); } } res.forEach((issueInfo, local) => { @@ -259,19 +267,130 @@ export class NumericSemanticCheck implements BaseChecker { } const declaringStmt = local.getDeclaringStmt(); if (declaringStmt !== null && issueInfo.issueReason === IssueReason.OnlyUsedAsIntLong) { - this.addIssueReport(RuleCategory.SDKIntType, issueInfo.numberCategory, issueInfo.issueReason, true, declaringStmt, local, undefined, stmt); + this.addIssueReportForSDKArg( + RuleCategory.SDKIntType, + issueInfo.numberCategory, + issueInfo.issueReason, + true, + declaringStmt, + local, + undefined, + stmt + ); } }); this.classFieldRes.forEach((fieldInfo, field) => { if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { // 如果能明确判断出field是int或非int,则添加类型注解int或number,其他找不全的场景不变 - this.addIssueReport(RuleCategory.NumericLiteral, fieldInfo.numberCategory, fieldInfo.issueReason, true, undefined, undefined, field); + this.addIssueReportForSDKArg(RuleCategory.SDKIntType, fieldInfo.numberCategory, fieldInfo.issueReason, true, undefined, undefined, field, stmt); } }); } - private checkFieldInitializerWithDivision(method: ArkMethod): void { - // 仅对类属性的初始化语句进行检查,判断其中是否有涉及整型字面量参与的除法运算 + private checkSdkReturnValueInStmt(stmt: Stmt): void { + if (!(stmt instanceof ArkAssignStmt)) { + return; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof AbstractInvokeExpr)) { + return; + } + const numberCategory = this.checkSDKReturnType(rightOp); + if (!numberCategory) { + return; + } + + const res = new Map(); + this.callDepth = 0; + const leftOp = stmt.getLeftOp(); + this.checkValueOnlyUsedAsIntLong(stmt, leftOp, res, numberCategory); + res.forEach((issueInfo, local) => { + if (this.shouldIgnoreLocal(local)) { + return; + } + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt !== null) { + this.addIssueReportForSDKReturnOrField( + RuleCategory.SDKIntType, + issueInfo.numberCategory, + issueInfo.issueReason, + declaringStmt, + local, + undefined, + stmt + ); + } + }); + this.classFieldRes.forEach((fieldInfo, field) => { + if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { + // 如果能明确判断出field是int或非int,则添加类型注解int或number,其他找不全的场景不变 + this.addIssueReportForSDKReturnOrField( + RuleCategory.SDKIntType, + fieldInfo.numberCategory, + fieldInfo.issueReason, + undefined, + undefined, + field, + stmt + ); + } + }); + } + + private checkSdkFieldValueInStmt(stmt: Stmt): void { + if (!(stmt instanceof ArkAssignStmt)) { + return; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof AbstractFieldRef)) { + return; + } + const numberCategory = this.checkSDKFieldType(rightOp); + if (!numberCategory) { + return; + } + const res = new Map(); + this.callDepth = 0; + const leftOp = stmt.getLeftOp(); + if (!Utils.isNearlyNumberType(leftOp.getType())) { + return; + } + this.checkValueOnlyUsedAsIntLong(stmt, leftOp, res, numberCategory); + res.forEach((issueInfo, local) => { + if (this.shouldIgnoreLocal(local)) { + return; + } + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt !== null) { + this.addIssueReportForSDKReturnOrField( + RuleCategory.SDKIntType, + issueInfo.numberCategory, + issueInfo.issueReason, + declaringStmt, + local, + undefined, + stmt + ); + } + }); + this.classFieldRes.forEach((fieldInfo, field) => { + if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { + // 如果能明确判断出field是int或非int,则添加类型注解int或number,其他找不全的场景不变 + this.addIssueReportForSDKReturnOrField( + RuleCategory.SDKIntType, + fieldInfo.numberCategory, + fieldInfo.issueReason, + undefined, + undefined, + field, + stmt + ); + } + }); + } + + private checkFieldInitializerWithIntLiteral(method: ArkMethod): void { + // 仅对类属性的初始化语句进行检查,判断其中是否有涉及整型字面量的赋值或涉及除法运算 if (method.getName() !== STATIC_INIT_METHOD_NAME && method.getName() !== INSTANCE_INIT_METHOD_NAME) { return; } @@ -288,16 +407,73 @@ export class NumericSemanticCheck implements BaseChecker { continue; } const rightOp = stmt.getRightOp(); - if (rightOp instanceof Local && !rightOp.getName().startsWith(TEMP_LOCAL_PREFIX)) { - // 类属性的初始化语句使用Local赋值,且Local非临时变量,则一定不涉及除法运算,无需继续本轮检查 - continue; + if (rightOp instanceof Local && rightOp.getName().startsWith(TEMP_LOCAL_PREFIX)) { + // 类属性的初始化语句使用Local赋值,且Local为临时变量,则可能涉及除法运算 + // 整型字面量参与除法运算的告警和自动修复信息在检查过程中就已生成,无需在此处额外生成 + this.checkValueOnlyUsedAsIntLong(stmt, rightOp, new Map(), NumberCategory.int); + this.checkFieldRef( + leftOp, + stmt.getCfg().getDeclaringMethod().getDeclaringArkClass().getSignature(), + NumberCategory.int, + new Map() + ); + } + if (rightOp instanceof NumberConstant && !this.isNumberConstantActuallyFloat(rightOp)) { + this.checkFieldRef( + leftOp, + stmt.getCfg().getDeclaringMethod().getDeclaringArkClass().getSignature(), + NumberCategory.int, + new Map() + ); } - // 整型字面量参与除法运算的告警和自动修复信息在检查过程中就已生成,无需在此处额外生成 - this.checkValueOnlyUsedAsIntLong(stmt, stmt.getRightOp(), new Map(), NumberCategory.int); } + this.classFieldRes.forEach((fieldInfo, field) => { + this.addIssueReport(RuleCategory.NumericLiteral, fieldInfo.numberCategory, fieldInfo.issueReason, true, undefined, undefined, field); + }); } private checkStmtContainsNumericLiteral(stmt: Stmt): void { + const res = new Map(); + this.callDepth = 0; + + // 场景1:先判断是否涉及除法运算 + if (stmt instanceof ArkAssignStmt) { + const leftOp = stmt.getLeftOp(); + const rightOp = stmt.getRightOp(); + if (leftOp instanceof Local && rightOp instanceof ArkNormalBinopExpr && rightOp.getOperator() === NormalBinaryOperator.Division) { + if (this.isLocalAssigned2Array(leftOp)) { + // local为临时变量,用于给数组元素赋值的场景,不在本规则的实现范围内,归另一处的规则开发实现 + return; + } + if (!Utils.isNearlyNumberType(leftOp.getType())) { + // 对左值进行检查决定是否对其添加类型注解int或number,如果不是number相关类型则无需继续进行检查 + return; + } + this.checkValueOnlyUsedAsIntLong(stmt, stmt.getLeftOp(), res, NumberCategory.number); + // 因为如果let a10 = a1/2; a10 = a2/3;第1句能判断a10为number,则不会继续后面的检查,所以需要额外对除法表达式的op1和op2进行number类型注解的补充 + this.isAbstractExprOnlyUsedAsIntLong(stmt, rightOp, res, NumberCategory.number); + res.forEach((issueInfo, local) => { + if (this.shouldIgnoreLocal(local)) { + return; + } + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt === null) { + return; + } + // 无论local的判定结果是什么,均需要进行自动修复类型注解为int或者number + this.addIssueReport(RuleCategory.NumericLiteral, issueInfo.numberCategory, issueInfo.issueReason, true, declaringStmt, local); + }); + this.classFieldRes.forEach((fieldInfo, field) => { + if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { + // 如果能明确判断出field是int或非int,则添加类型注解int或number,其他找不全的场景不变 + this.addIssueReport(RuleCategory.NumericLiteral, fieldInfo.numberCategory, fieldInfo.issueReason, true, undefined, undefined, field); + } + }); + return; + } + } + + // 场景2:非除法运算场景,处理其余涉及整型字面量的场景 if (!this.isStmtContainsIntLiteral(stmt)) { return; } @@ -334,9 +510,7 @@ export class NumericSemanticCheck implements BaseChecker { return; } - const res = new Map(); - this.callDepth = 0; - if (rightOp instanceof NumberConstant && !this.isNumberConstantWithDecimalPoint(rightOp)) { + if (rightOp instanceof NumberConstant && !this.isNumberConstantActuallyFloat(rightOp)) { // 整型字面量直接赋值给左值,判断左值在生命周期内是否仅作为int使用,并且判断左值是否继续赋值给其他变量,其他变量是否也可以定义为int this.checkAllLocalsAroundLocal(stmt, leftOp, res, NumberCategory.int); } else if (rightOp instanceof AbstractExpr) { @@ -358,7 +532,7 @@ export class NumericSemanticCheck implements BaseChecker { return; } // 无论local的判定结果是什么,均需要进行自动修复类型注解为int或者number - this.addIssueReport(RuleCategory.NumericLiteral, issueInfo.numberCategory, issueInfo.issueReason, true, declaringStmt, local, undefined); + this.addIssueReport(RuleCategory.NumericLiteral, issueInfo.numberCategory, issueInfo.issueReason, true, declaringStmt, local); }); this.classFieldRes.forEach((fieldInfo, field) => { if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { @@ -511,13 +685,40 @@ export class NumericSemanticCheck implements BaseChecker { if (declaringStmt instanceof ArkAssignStmt && declaringStmt.getRightOp() instanceof ClosureFieldRef) { return true; } + + // 对于for (const i of arr)这样的写法,不能为i添加类型注解 + if (declaringStmt instanceof ArkAssignStmt) { + const rightOp = declaringStmt.getRightOp(); + if (!(rightOp instanceof ArkCastExpr)) { + return false; + } + const castOp = rightOp.getOp(); + if (!(castOp instanceof Local)) { + return false; + } + const castOpDeclaring = castOp.getDeclaringStmt(); + if (!(castOpDeclaring instanceof ArkAssignStmt)) { + return false; + } + const castOpRight = castOpDeclaring.getRightOp(); + if (!(castOpRight instanceof ArkInstanceFieldRef)) { + return false; + } + const fieldSig = castOpRight.getFieldSignature(); + if (fieldSig.getFieldName() === 'value') { + const declaringSig = fieldSig.getDeclaringSignature(); + if (declaringSig instanceof ClassSignature && declaringSig.getClassName() === 'IteratorYieldResult') { + return true; + } + } + } return false; } private isStmtContainsIntLiteral(stmt: Stmt): boolean { const uses = stmt.getUses(); for (const use of uses) { - if (use instanceof NumberConstant && !this.isNumberConstantWithDecimalPoint(use)) { + if (use instanceof NumberConstant && !this.isNumberConstantActuallyFloat(use)) { return true; } } @@ -638,7 +839,7 @@ export class NumericSemanticCheck implements BaseChecker { const args = invokeExpr.getArgs(); // 根据找到的对应arkts1.1中的SDK接口匹配到对应在arkts1.2中的SDK接口 - const ets2SdkSignature = this.getEts2SdkSignatureWithEts1Method(callMethod, args); + const ets2SdkSignature = this.getEts2SdkSignatureWithEts1Method(callMethod, args, true); if (ets2SdkSignature === null) { return null; } @@ -660,6 +861,82 @@ export class NumericSemanticCheck implements BaseChecker { return res; } + private checkSDKReturnType(invokeExpr: AbstractInvokeExpr): NumberCategory | null { + const callMethod = this.scene.getMethod(invokeExpr.getMethodSignature()); + if (callMethod === null || !SdkUtils.isMethodFromSdk(callMethod)) { + return null; + } + const args = invokeExpr.getArgs(); + + // 根据找到的对应arkts1.1中的SDK接口匹配到对应在arkts1.2中的SDK接口 + const ets2SdkSignature = this.getEts2SdkSignatureWithEts1Method(callMethod, args, false); + if (ets2SdkSignature === null) { + return null; + } + const returnType = ets2SdkSignature.getType(); + if (this.isLongType(returnType)) { + return NumberCategory.long; + } + if (this.isIntType(returnType)) { + return NumberCategory.int; + } + return null; + } + + private checkSDKFieldType(fieldRef: AbstractFieldRef): NumberCategory | null { + if (!SdkUtils.isFieldFromSdk(fieldRef) || !Utils.isNearlyNumberType(fieldRef.getType())) { + return null; + } + const ets1SdkFileSig = fieldRef.getFieldSignature().getDeclaringSignature().getDeclaringFileSignature(); + const ets2SdkFileSig = new FileSignature(ets1SdkFileSig.getProjectName(), ets1SdkFileSig.getFileName().replace('.d.ts', '.d.ets')); + const ets2SdkFileSigBak = new FileSignature(ets1SdkFileSig.getProjectName(), ets1SdkFileSig.getFileName()); + const ets2SdkFile = this.ets2SdkScene?.getFile(ets2SdkFileSig) ?? this.ets2SdkScene?.getFile(ets2SdkFileSigBak); + if (!ets2SdkFile) { + return null; + } + let ets2Field = SdkUtils.getSdkField(ets2SdkFile, fieldRef); + if (!ets2Field) { + return null; + } + if (this.isIntType(ets2Field.getType())) { + return NumberCategory.int; + } + if (this.isLongType(ets2Field.getType())) { + return NumberCategory.long; + } + return null; + } + + private matchEts1NumberEts2IntLongReturnSig(ets2Sigs: MethodSignature[], ets1Sig: MethodSignature): MethodSignature | null { + const ets1Params = ets1Sig.getMethodSubSignature().getParameters(); + for (const ets2Sig of ets2Sigs) { + let allParamMatched = true; + const ets2Params = ets2Sig.getMethodSubSignature().getParameters(); + if (ets2Params.length !== ets1Params.length) { + continue; + } + for (let i = 0; i < ets1Params.length; i++) { + const ets2ParamType = ets2Params[i].getType(); + const ets1ParamType = ets1Params[i].getType(); + if ( + ets2ParamType === ets1ParamType || + (ets1ParamType instanceof NumberType && (this.isIntType(ets2ParamType) || this.isLongType(ets2ParamType))) + ) { + continue; + } + allParamMatched = false; + break; + } + if (allParamMatched) { + const returnType = ets2Sig.getType(); + if (this.isLongType(returnType) || this.isIntType(returnType)) { + return ets2Sig; + } + } + } + return null; + } + private matchEts1NumberEts2IntLongMethodSig(ets2Sigs: MethodSignature[], ets1Sig: MethodSignature): MethodSignature | null { let intSDKMatched: MethodSignature | null = null; const ets1Params = ets1Sig.getMethodSubSignature().getParameters(); @@ -697,7 +974,8 @@ export class NumericSemanticCheck implements BaseChecker { return intSDKMatched; } - private getEts2SdkSignatureWithEts1Method(ets1SDK: ArkMethod, args: Value[], exactMatch: boolean = true): MethodSignature | null { + // checkArg = true is for checking SDK arg with int or long; otherwise is for checking SDK return with int or long + private getEts2SdkSignatureWithEts1Method(ets1SDK: ArkMethod, args: Value[], checkArg: boolean, exactMatch: boolean = true): MethodSignature | null { const ets2Sdks = this.ets2Sdks; if (ets2Sdks === undefined || ets2Sdks.length === 0) { return null; @@ -726,7 +1004,10 @@ export class NumericSemanticCheck implements BaseChecker { if (!exactMatch && declareSigs.length === 1) { return declareSigs[0]; } - return this.matchEts1NumberEts2IntLongMethodSig(declareSigs, ets1SigMatched); + if (checkArg) { + return this.matchEts1NumberEts2IntLongMethodSig(declareSigs, ets1SigMatched); + } + return this.matchEts1NumberEts2IntLongReturnSig(declareSigs, ets1SigMatched); } private getEts2SdkWithEts1SdkInfo(ets2File: ArkFile, ets1SDK: ArkMethod): ArkMethod | null { @@ -804,7 +1085,7 @@ export class NumericSemanticCheck implements BaseChecker { return IssueReason.RelatedWithNonETS2; } if (value instanceof NumberConstant) { - if (this.isNumberConstantWithDecimalPoint(value)) { + if (this.isNumberConstantActuallyFloat(value)) { return IssueReason.UsedWithOtherType; } return IssueReason.OnlyUsedAsIntLong; @@ -830,8 +1111,18 @@ export class NumericSemanticCheck implements BaseChecker { return IssueReason.Other; } - private isNumberConstantWithDecimalPoint(constant: NumberConstant): boolean { - return constant.getValue().includes('.'); + private isNumberConstantActuallyFloat(constant: NumberConstant): boolean { + const valueStr = constant.getValue(); + if (valueStr.includes('.') && !valueStr.includes('e')) { + // 数字字面量非科学计数的写法,并且有小数点,则一定是浮点数,1.0也认为是float + return true; + } + const num = Number(constant.getValue()); + if (isNaN(num)) { + // 超大数字字面量转换后是NaN,按照number处理 + return true; + } + return !Number.isInteger(num); } // 判断number constant是否为1.0、2.0这种可以转成1、2的整型形式 @@ -899,16 +1190,20 @@ export class NumericSemanticCheck implements BaseChecker { } if (stmt.getCfg().getDeclaringMethod().getLanguage() !== Language.ARKTS1_2) { - hasChecked.set(local, { issueReason: IssueReason.RelatedWithNonETS2, numberCategory: numberCategory }); + hasChecked.set(local, { issueReason: IssueReason.RelatedWithNonETS2, numberCategory: NumberCategory.number }); return IssueReason.RelatedWithNonETS2; } // 先将value加入map中,默认设置成false,避免后续递归查找阶段出现死循环,最后再根据查找结果绝对是否重新设置成true - hasChecked.set(local, { issueReason: IssueReason.Other, numberCategory: numberCategory }); + hasChecked.set(local, { issueReason: IssueReason.Other, numberCategory: NumberCategory.number }); const resWithLocalType = this.checkResWithLocalType(local, stmt); if (resWithLocalType) { - hasChecked.set(local, { issueReason: resWithLocalType, numberCategory: numberCategory }); + if (resWithLocalType === IssueReason.OnlyUsedAsIntLong) { + hasChecked.set(local, { issueReason: resWithLocalType, numberCategory: numberCategory }); + } else { + hasChecked.set(local, { issueReason: resWithLocalType, numberCategory: NumberCategory.number }); + } return resWithLocalType; } @@ -931,7 +1226,7 @@ export class NumericSemanticCheck implements BaseChecker { if (declaringStmt === null) { // local变量未找到定义语句,直接返回false,因为就算是能确认local仅当做int使用,也找不到定义语句去修改类型注解为int,所以后续检查都没有意义 logger.error(`Missing declaring stmt, local: ${local.getName()}`); - hasChecked.set(local, { issueReason: IssueReason.CannotFindAll, numberCategory: numberCategory }); + hasChecked.set(local, { issueReason: IssueReason.CannotFindAll, numberCategory: NumberCategory.number }); return IssueReason.CannotFindAll; } hasChecked.delete(local); @@ -981,13 +1276,17 @@ export class NumericSemanticCheck implements BaseChecker { private checkRelatedStmtForLocal(stmt: Stmt, local: Local, hasChecked: Map, numberCategory: NumberCategory): IssueInfo { if (stmt instanceof ArkAssignStmt && stmt.getLeftOp() === local) { const issueReason = this.checkValueOnlyUsedAsIntLong(stmt, stmt.getRightOp(), hasChecked, numberCategory); - return { issueReason, numberCategory }; + if (issueReason === IssueReason.OnlyUsedAsIntLong) { + return { issueReason, numberCategory }; + } else { + return { issueReason, numberCategory: NumberCategory.number }; + } } // 当前检查的local位于赋值语句的右边,若参与除法运算则看做double类型使用,若作为SDK入参依据SDK定义,其余运算、赋值等处理不会影响其自身从int -> number,所以不处理 if (stmt instanceof ArkAssignStmt && stmt.getLeftOp() !== local) { const rightOp = stmt.getRightOp(); if (rightOp instanceof ArkNormalBinopExpr && rightOp.getOperator() === NormalBinaryOperator.Division) { - return { issueReason: IssueReason.UsedWithOtherType, numberCategory }; + return { issueReason: IssueReason.UsedWithOtherType, numberCategory: NumberCategory.number }; } if (rightOp instanceof AbstractInvokeExpr) { const res = this.checkLocalUsedAsSDKArg(rightOp, local, hasChecked); @@ -1011,7 +1310,7 @@ export class NumericSemanticCheck implements BaseChecker { return { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory }; } logger.error(`Need to check new type of stmt: ${stmt.toString()}, method: ${stmt.getCfg().getDeclaringMethod().getSignature().toString()}`); - return { issueReason: IssueReason.Other, numberCategory }; + return { issueReason: IssueReason.Other, numberCategory: NumberCategory.number }; } // 判断local是否是SDK invoke expr的入参,且其类型是int或long,否则返回null @@ -1153,11 +1452,15 @@ export class NumericSemanticCheck implements BaseChecker { if (expr.getOperator() === NormalBinaryOperator.Division) { const op1 = expr.getOp1(); const op2 = expr.getOp2(); - if (op1 instanceof NumberConstant && !this.isNumberConstantWithDecimalPoint(op1)) { + if (op1 instanceof NumberConstant && !this.isNumberConstantActuallyFloat(op1)) { this.addIssueReport(RuleCategory.NumericLiteral, NumberCategory.number, IssueReason.UsedWithOtherType, true, stmt, op1); + } else if (op1 instanceof Local) { + hasChecked.set(op1, { issueReason: IssueReason.UsedWithOtherType, numberCategory: NumberCategory.number }); } - if (op2 instanceof NumberConstant && !this.isNumberConstantWithDecimalPoint(op2)) { + if (op2 instanceof NumberConstant && !this.isNumberConstantActuallyFloat(op2)) { this.addIssueReport(RuleCategory.NumericLiteral, NumberCategory.number, IssueReason.UsedWithOtherType, true, stmt, op2); + } else if (op2 instanceof Local) { + hasChecked.set(op2, { issueReason: IssueReason.UsedWithOtherType, numberCategory: NumberCategory.number }); } return IssueReason.UsedWithOtherType; } @@ -1186,7 +1489,7 @@ export class NumericSemanticCheck implements BaseChecker { if (SdkUtils.isMethodFromSdk(method)) { const ets2SDKSig = this.getEts2SdkSignatureWithEts1Method(method, expr.getArgs(), false); if (ets2SDKSig === null) { - return IssueReason.RelatedWithNonETS2; + return IssueReason.UsedWithOtherType; } if (this.isIntType(ets2SDKSig.getType()) || this.isLongType(ets2SDKSig.getType())) { return IssueReason.OnlyUsedAsIntLong; @@ -1259,19 +1562,22 @@ export class NumericSemanticCheck implements BaseChecker { return IssueReason.Other; } - private checkFieldRef(ref: AbstractRef, currentClassSig: ClassSignature, numberCategory: NumberCategory, hasChecked: Map): IssueReason { - const refType = ref.getType(); - if (!(ref instanceof AbstractFieldRef)) { - if (!Utils.isNearlyNumberType(refType)) { - if (refType instanceof UnknownType) { - return IssueReason.CannotFindAll; - } - return IssueReason.UsedWithOtherType; + private checkFieldRef( + fieldRef: AbstractFieldRef, + currentClassSig: ClassSignature, + numberCategory: NumberCategory, + hasChecked: Map + ): IssueReason { + if (SdkUtils.isFieldFromSdk(fieldRef)) { + const ets2FieldType = this.checkSDKFieldType(fieldRef); + if (ets2FieldType && (ets2FieldType === NumberCategory.int || ets2FieldType === NumberCategory.long)) { + return IssueReason.OnlyUsedAsIntLong; } - // 此处若想充分解析,需要在整个项目中找到该field的所有使用到的地方,效率很低,且很容易找漏,当前不做检查,直接返回false - return IssueReason.CannotFindAll; + return IssueReason.UsedWithOtherType; } - const fieldBase = ref.getFieldSignature().getDeclaringSignature(); + + const refType = fieldRef.getType(); + const fieldBase = fieldRef.getFieldSignature().getDeclaringSignature(); if (fieldBase instanceof NamespaceSignature) { return IssueReason.CannotFindAll; } @@ -1282,7 +1588,6 @@ export class NumericSemanticCheck implements BaseChecker { if (baseClass.getLanguage() !== Language.ARKTS1_2) { return IssueReason.RelatedWithNonETS2; } - // TODO: typeliteral是什么类型? if ( baseClass.getCategory() === ClassCategory.ENUM || baseClass.getCategory() === ClassCategory.OBJECT || @@ -1295,7 +1600,7 @@ export class NumericSemanticCheck implements BaseChecker { if (baseClass.getSignature().toString() !== currentClassSig.toString()) { return IssueReason.CannotFindAll; } - const field = baseClass.getField(ref.getFieldSignature()); + const field = baseClass.getField(fieldRef.getFieldSignature()); if (field === null) { return IssueReason.CannotFindAll; } @@ -1306,29 +1611,44 @@ export class NumericSemanticCheck implements BaseChecker { if (!Utils.isNearlyNumberType(refType)) { if (refType instanceof UnknownType) { const res = IssueReason.CannotFindAll; - this.classFieldRes.set(field, { issueReason: res, numberCategory: numberCategory }); + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); return res; } const res = IssueReason.UsedWithOtherType; - this.classFieldRes.set(field, { issueReason: res, numberCategory: numberCategory }); - return res; - } - if (field.containsModifier(ModifierType.READONLY)) { - // 先写入默认值,避免后续查找时出现死循环,得到结果后再进行替换 - this.classFieldRes.set(field, { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: numberCategory }); - const res = this.checkReadonlyFieldInitializer(field, baseClass, numberCategory, hasChecked); - this.classFieldRes.set(field, { issueReason: res, numberCategory: numberCategory }); + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); return res; } if (field.containsModifier(ModifierType.PRIVATE)) { + // 如果属性有setter方法,则无法找全其赋值的地方,无法判断是否为int,保守方式判定为number + // 如果属性有getter方法,则无法找全其使用的地方,如果有用作除法运算,则应该是number,保守方式判定为number + if (this.fieldWithSetter(field, baseClass) || this.fieldWithGetter(field, baseClass)) { + const res = IssueReason.CannotFindAll; + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); + return res; + } + if (field.containsModifier(ModifierType.READONLY)) { + // 先写入默认值,避免后续查找时出现死循环,得到结果后再进行替换 + this.classFieldRes.set(field, { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: numberCategory }); + const res = this.checkReadonlyFieldInitializer(field, baseClass, numberCategory, hasChecked); + if (res === IssueReason.OnlyUsedAsIntLong) { + this.classFieldRes.set(field, { issueReason: res, numberCategory: numberCategory }); + } else { + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); + } + return res; + } this.classFieldRes.set(field, { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: numberCategory }); const res = this.checkPrivateField(field, baseClass, numberCategory, hasChecked); - this.classFieldRes.set(field, { issueReason: res, numberCategory: numberCategory }); + if (res === IssueReason.OnlyUsedAsIntLong) { + this.classFieldRes.set(field, { issueReason: res, numberCategory: numberCategory }); + } else { + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); + } return res; } // 此处若想充分解析,需要在整个项目中找到该field的所有使用到的地方,效率很低,且很容易找漏,当前不做检查,直接返回false const res = IssueReason.CannotFindAll; - this.classFieldRes.set(field, { issueReason: res, numberCategory: numberCategory }); + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); return res; } @@ -1380,9 +1700,6 @@ export class NumericSemanticCheck implements BaseChecker { } private checkPrivateField(field: ArkField, baseClass: ArkClass, numberCategory: NumberCategory, hasChecked: Map): IssueReason { - if (this.fieldWithSetter(field, baseClass)) { - return IssueReason.CannotFindAll; - } const methods = baseClass.getMethods(true); for (const method of methods) { if (method.getName().startsWith('Set-') || method.getName().startsWith('Get-')) { @@ -1473,6 +1790,39 @@ export class NumericSemanticCheck implements BaseChecker { return false; } + private fieldWithGetter(field: ArkField, baseClass: ArkClass): boolean { + const methods = baseClass.getMethods(); + for (const method of methods) { + if (!method.getName().startsWith('Get-')) { + continue; + } + const stmts = method.getCfg()?.getStmts(); + if (stmts === undefined) { + continue; + } + for (const stmt of stmts) { + if (!(stmt instanceof ArkReturnStmt)) { + continue; + } + const op = stmt.getOp(); + if (op instanceof Local) { + const opDeclaringStmt = op.getDeclaringStmt(); + if (!(opDeclaringStmt instanceof ArkAssignStmt)) { + continue; + } + const rightOp = opDeclaringStmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceFieldRef)) { + continue; + } + if (field.getName() === rightOp.getFieldName()) { + return true; + } + } + } + } + return false; + } + private checkAllArgsOfParameter(stmt: Stmt, hasChecked: Map, numberCategory: NumberCategory): IssueReason { let checkAll = { value: true }; let visited: Set = new Set(); @@ -1622,30 +1972,22 @@ export class NumericSemanticCheck implements BaseChecker { } private getFieldIssueFromIssueList(field: ArkField): IssueReport | null { + const filePath = field.getDeclaringArkClass().getDeclaringArkFile().getFilePath(); const position: WarnInfo = { line: field.getOriginPosition().getLineNo(), startCol: field.getOriginPosition().getColNo(), endCol: field.getOriginPosition().getColNo(), filePath: field.getDeclaringArkClass().getDeclaringArkFile().getFilePath(), }; - const fixKeyPrefix = position.line + '%' + position.startCol + '%' + position.endCol + '%'; - for (const issue of this.issues) { - if (issue.defect.fixKey.startsWith(fixKeyPrefix)) { - return issue; - } - } - return null; + const mapKey = `${filePath}%${position.line}%${position.startCol}%${position.endCol}%${this.rule.ruleId}`; + return this.issuesMap.get(mapKey) ?? null; } private getLocalIssueFromIssueList(local: Local, stmt: Stmt): IssueReport | null { + const filePath = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile().getFilePath(); const position = getLineAndColumn(stmt, local, true); - const fixKeyPrefix = position.line + '%' + position.startCol + '%' + position.endCol + '%'; - for (const issue of this.issues) { - if (issue.defect.fixKey.startsWith(fixKeyPrefix)) { - return issue; - } - } - return null; + const mapKey = `${filePath}%${position.line}%${position.startCol}%${position.endCol}%${this.rule.ruleId}`; + return this.issuesMap.get(mapKey) ?? null; } private getWarnInfo(field?: ArkField, issueStmt?: Stmt, value?: Value): WarnInfo | null { @@ -1706,24 +2048,7 @@ export class NumericSemanticCheck implements BaseChecker { return null; } - private getDesc( - ruleCategory: RuleCategory, - reason: IssueReason, - numberCategory: NumberCategory, - couldAutofix: boolean, - issueStmt?: Stmt, - usedStmt?: Stmt - ): string | null { - if (ruleCategory === RuleCategory.SDKIntType) { - if (reason === IssueReason.OnlyUsedAsIntLong) { - if (usedStmt) { - return `It has relationship with the arg of SDK API in ${this.getUsedStmtDesc(usedStmt, issueStmt)} and only used as ${numberCategory}, should be defined as ${numberCategory} (${ruleCategory})`; - } - logger.error('Missing used stmt when getting issue description'); - return null; - } - return `The arg of SDK API should be ${numberCategory} here (${ruleCategory})`; - } + private getDesc(ruleCategory: RuleCategory, reason: IssueReason, couldAutofix: boolean): string | null { if (ruleCategory === RuleCategory.NumericLiteral) { if (reason === IssueReason.OnlyUsedAsIntLong) { return `It is used as ${NumberCategory.int} (${ruleCategory})`; @@ -1746,24 +2071,7 @@ export class NumericSemanticCheck implements BaseChecker { return null; } - private addIssueReport( - ruleCategory: RuleCategory, - numberCategory: NumberCategory, - reason: IssueReason, - couldAutofix: boolean, - issueStmt?: Stmt, - value?: Value, - field?: ArkField, - usedStmt?: Stmt - ): void { - const severity = this.rule.alert ?? this.metaData.severity; - let warnInfo = this.getWarnInfo(field, issueStmt, value); - let problem = this.getProblem(ruleCategory, reason); - let desc = this.getDesc(ruleCategory, reason, numberCategory, couldAutofix, issueStmt, usedStmt); - if (!warnInfo || !problem || !desc) { - return; - } - + private shouldSkipDuplicatedIssue(numberCategory: NumberCategory, field?: ArkField, value?: Value, issueStmt?: Stmt): boolean { // 添加新的issue之前需要检查一下已有issue,避免重复issue,或2个issue之间冲突,一个issue要改为int,一个issue要改为long let currentIssue: IssueReport | null = null; let issueCategory: NumberCategory | null = null; @@ -1782,23 +2090,60 @@ export class NumericSemanticCheck implements BaseChecker { } if (currentIssue && issueCategory) { const issueReason = this.getIssueReasonFromDefectInfo(currentIssue.defect); - if (issueReason !== null) { - if (issueReason === IssueReason.OnlyUsedAsIntLong) { - if (issueCategory !== NumberCategory.long && numberCategory === NumberCategory.long) { - // 删除掉之前的修复为int的,用本次即将add的新的issue替代 - const index = this.issues.indexOf(currentIssue); - if (index > -1) { - this.issues.splice(index, 1); - } - } else { - // 已有的issue已经足够进行自动修复处理,无需重复添加 - return; - } - } else { - // 已有的issue对非int进行修改,无需重复添加 - return; - } + if (issueReason === null) { + return false; + } + if (issueReason !== IssueReason.OnlyUsedAsIntLong) { + return true; + } + if (issueCategory !== NumberCategory.long && numberCategory === NumberCategory.long) { + // 删除掉之前的修复为int的,用本次即将add的新的issue替代 + this.issuesMap.delete(this.getIssuesMapKey(currentIssue.defect.mergeKey)); + return false; + } else { + // 已有的issue已经足够进行自动修复处理,无需重复添加 + return true; + } + } + return false; + } + + private getIssuesMapKey(mergeKey: string): string { + const lastIndex = mergeKey.lastIndexOf('%'); + return mergeKey.substring(0, lastIndex); + } + + private addIssueReportForSDKArg( + ruleCategory: RuleCategory, + numberCategory: NumberCategory, + reason: IssueReason, + couldAutofix: boolean, + issueStmt?: Stmt, + value?: Value, + field?: ArkField, + usedStmt?: Stmt + ): void { + const severity = this.rule.alert ?? this.metaData.severity; + let warnInfo = this.getWarnInfo(field, issueStmt, value); + let problem = this.getProblem(ruleCategory, reason); + if (!warnInfo || !problem) { + return; + } + let desc: string; + if (reason === IssueReason.OnlyUsedAsIntLong) { + if (usedStmt) { + desc = `It has relationship with the arg of SDK API in ${this.getUsedStmtDesc(usedStmt, issueStmt)} and only used as ${numberCategory}, should be defined as ${numberCategory} (${ruleCategory})`; + } else { + logger.error('Missing used stmt when getting issue description'); + return; } + } else { + desc = `The arg of SDK API should be ${numberCategory} here (${ruleCategory})`; + } + + const shouldSkip = this.shouldSkipDuplicatedIssue(numberCategory, field, value, issueStmt); + if (shouldSkip) { + return; } let defects = new Defects( @@ -1817,17 +2162,115 @@ export class NumericSemanticCheck implements BaseChecker { ); if (!couldAutofix) { - this.issues.push(new IssueReport(defects, undefined)); + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, undefined)); return; } - if (ruleCategory === RuleCategory.SDKIntType) { - const autofix = this.generateSDKRuleFix(warnInfo, reason, numberCategory, issueStmt, value, field); - if (autofix === null) { - // 此规则必须修复,若autofix为null,则表示无需修复,不添加issue - return; + const autofix = this.generateSDKArgRuleFix(warnInfo, reason, numberCategory, issueStmt, value, field); + if (autofix === null) { + // 此规则必须修复,若autofix为null,则表示无需修复,不添加issue + return; + } else { + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); + } + return; + } + + private addIssueReportForSDKReturnOrField( + ruleCategory: RuleCategory, + numberCategory: NumberCategory, + reason: IssueReason, + issueStmt?: Stmt, + value?: Value, + field?: ArkField, + usedStmt?: Stmt + ): void { + const severity = this.rule.alert ?? this.metaData.severity; + let warnInfo = this.getWarnInfo(field, issueStmt, value); + let problem = this.getProblem(ruleCategory, reason); + if (!warnInfo || !problem) { + return; + } + const shouldSkip = this.shouldSkipDuplicatedIssue(numberCategory, field, value, issueStmt); + if (shouldSkip) { + return; + } + + let desc: string; + if (reason === IssueReason.OnlyUsedAsIntLong) { + if (usedStmt) { + desc = `It has relationship with the SDK API in ${this.getUsedStmtDesc(usedStmt, issueStmt)} and only used as ${numberCategory}, should be defined as ${numberCategory} (${ruleCategory})`; } else { - this.issues.push(new IssueReport(defects, autofix)); + logger.error('Missing used stmt when getting issue description'); + return; } + } else { + desc = `It is used as number (${ruleCategory})`; + } + + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + true + ); + + const autofix = this.generateSDKReturnOrFieldRuleFix(warnInfo, numberCategory, issueStmt, field); + if (autofix === null) { + // 此规则必须修复,若autofix为null,则表示无需修复,不添加issue + return; + } else { + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); + } + return; + } + + private addIssueReport( + ruleCategory: RuleCategory, + numberCategory: NumberCategory, + reason: IssueReason, + couldAutofix: boolean, + issueStmt?: Stmt, + value?: Value, + field?: ArkField + ): void { + const severity = this.rule.alert ?? this.metaData.severity; + let warnInfo = this.getWarnInfo(field, issueStmt, value); + let problem = this.getProblem(ruleCategory, reason); + let desc = this.getDesc(ruleCategory, reason, couldAutofix); + if (!warnInfo || !problem || !desc) { + return; + } + + const shouldSkip = this.shouldSkipDuplicatedIssue(numberCategory, field, value, issueStmt); + if (shouldSkip) { + return; + } + + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + couldAutofix + ); + + if (!couldAutofix) { + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, undefined)); return; } if (ruleCategory === RuleCategory.NumericLiteral) { @@ -1836,7 +2279,7 @@ export class NumericSemanticCheck implements BaseChecker { // 此规则必须修复,若autofix为null,则表示无需修复,不添加issue return; } - this.issues.push(new IssueReport(defects, autofix)); + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); return; } if (ruleCategory === RuleCategory.ArrayIndex) { @@ -1844,9 +2287,9 @@ export class NumericSemanticCheck implements BaseChecker { const autofix = this.generateIntConstantIndexRuleFix(warnInfo, issueStmt, value); if (autofix === null) { defects.fixable = false; - this.issues.push(new IssueReport(defects, undefined)); + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, undefined)); } else { - this.issues.push(new IssueReport(defects, autofix)); + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); } } else { const autofix = this.generateNumericLiteralRuleFix(warnInfo, reason, issueStmt, value, field); @@ -1854,7 +2297,7 @@ export class NumericSemanticCheck implements BaseChecker { // 此规则必须修复,若autofix为null,则表示无需修复,不添加issue return; } - this.issues.push(new IssueReport(defects, autofix)); + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); } return; } @@ -1880,7 +2323,12 @@ export class NumericSemanticCheck implements BaseChecker { logger.error('Missing both issue stmt and field when generating auto fix info.'); return null; } - return AstTreeUtils.getASTNode(arkFile.getName(), arkFile.getCode()); + let sourceFile = this.sourceFiles.get(arkFile.getFileSignature()); + if (!sourceFile) { + sourceFile = AstTreeUtils.getASTNode(arkFile.getName(), arkFile.getCode()); + this.sourceFiles.set(arkFile.getFileSignature(), sourceFile); + } + return sourceFile; } private generateRuleFixForLocalDefine(sourceFile: ts.SourceFile, warnInfo: WarnInfo, numberCategory: NumberCategory): RuleFix | null { @@ -1994,7 +2442,7 @@ export class NumericSemanticCheck implements BaseChecker { return null; } - private generateSDKRuleFix( + private generateSDKArgRuleFix( warnInfo: WarnInfo, issueReason: IssueReason, numberCategory: NumberCategory, @@ -2076,6 +2524,17 @@ export class NumericSemanticCheck implements BaseChecker { } } + private generateSDKReturnOrFieldRuleFix(warnInfo: WarnInfo, numberCategory: NumberCategory, issueStmt?: Stmt, field?: ArkField): RuleFix | null { + const sourceFile = this.getSourceFile(field, issueStmt); + if (!sourceFile) { + return null; + } + if (field) { + return this.generateRuleFixForFieldDefine(sourceFile, warnInfo, numberCategory); + } + return this.generateRuleFixForLocalDefine(sourceFile, warnInfo, numberCategory); + } + private generateIntConstantIndexRuleFix(warnInfo: WarnInfo, issueStmt: Stmt, constant: NumberConstant): RuleFix | null { if (!this.isFloatActuallyInt(constant)) { return null; @@ -2120,7 +2579,7 @@ export class NumericSemanticCheck implements BaseChecker { if (value instanceof NumberConstant) { // 对整型字面量进行自动修复,转成浮点字面量,例如1->1.0 - if (this.isNumberConstantWithDecimalPoint(value)) { + if (this.isNumberConstantActuallyFloat(value)) { // 无需修复 return null; } diff --git a/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts b/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts index cb365aed60..728844baea 100644 --- a/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts +++ b/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts @@ -269,6 +269,7 @@ function buildScene(fileList: string[], checkEntry: CheckEntry): boolean { checkEntry.scene.buildSceneFromFiles(sceneConfig); logger.info('Build scene completed.'); checkEntry.scene.inferTypes(); + checkEntry.scene.inferTypes(); logger.info('Infer types completed.'); } catch (error) { logger.error('Build scene or infer types error: ', error); diff --git a/ets2panda/linter/homecheck/src/utils/common/SDKUtils.ts b/ets2panda/linter/homecheck/src/utils/common/SDKUtils.ts index 22343b644c..f094b9e132 100644 --- a/ets2panda/linter/homecheck/src/utils/common/SDKUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/common/SDKUtils.ts @@ -15,8 +15,9 @@ import { Sdk } from 'arkanalyzer/lib/Config'; import fs from 'fs'; -import { AnyType, ArkMethod, EnumValueType, MethodSignature, UnionType, Value } from 'arkanalyzer'; +import { AnyType, ArkField, ArkFile, ArkMethod, ClassSignature, EnumValueType, Local, MethodSignature, UnionType, Value } from 'arkanalyzer'; import { Utils } from './Utils'; +import { AbstractFieldRef, ArkNamespace, NamespaceSignature } from 'arkanalyzer/lib'; export class SdkUtils { static OhosSdkName = 'ohosSdk'; @@ -57,6 +58,11 @@ export class SdkUtils { return projectName === this.OhosSdkName || projectName === this.HmsSdkName; } + static isFieldFromSdk(fieldRef: AbstractFieldRef): boolean { + const projectName = fieldRef.getFieldSignature().getDeclaringSignature().getDeclaringFileSignature().getProjectName(); + return projectName === this.OhosSdkName || projectName === this.HmsSdkName; + } + static getSdkMatchedSignature(ets1SDK: ArkMethod, args: Value[]): MethodSignature | null { const declareSigs = ets1SDK.getDeclareSignatures(); if (declareSigs === null) { @@ -94,4 +100,36 @@ export class SdkUtils { } return ets1SigMatched; } + + static getSdkField(etsFile: ArkFile, fieldRef: AbstractFieldRef): ArkField | Local | null { + const declaringSig = fieldRef.getFieldSignature().getDeclaringSignature(); + if (declaringSig instanceof ClassSignature) { + const declaringNS = declaringSig.getDeclaringNamespaceSignature(); + if (!declaringNS) { + return etsFile?.getClassWithName(declaringSig.getClassName())?.getFieldWithName(fieldRef.getFieldName()) ?? null; + } + const namespace = this.getSdkNamespace(etsFile, declaringNS); + if (!namespace) { + return null; + } + return namespace.getClassWithName(declaringSig.getClassName())?.getFieldWithName(fieldRef.getFieldName()) ?? null; + } + const namespace = this.getSdkNamespace(etsFile, declaringSig); + if (!namespace) { + return null; + } + return namespace.getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals().get(fieldRef.getFieldName()) ?? null; + } + + static getSdkNamespace(etsFile: ArkFile, namespaceSig: NamespaceSignature): ArkNamespace | null { + const declaringNsSig = namespaceSig.getDeclaringNamespaceSignature(); + if (!declaringNsSig) { + return etsFile.getNamespace(namespaceSig); + } + const declaringNS = this.getSdkNamespace(etsFile, declaringNsSig); + if (!declaringNS) { + return null; + } + return declaringNS.getNamespace(namespaceSig); + } } diff --git a/ets2panda/linter/rule-config.json b/ets2panda/linter/rule-config.json index 2b4b13d656..d064920bc6 100644 --- a/ets2panda/linter/rule-config.json +++ b/ets2panda/linter/rule-config.json @@ -62,6 +62,7 @@ "arkts-no-class-omit-interface-optional-prop", "arkts-distinct-abstract-method-default-return-type", "arkts-class-no-signature-distinct-with-object-public-api", + "arkts-union-assignment-with-obj-literal-ambiguity", "arkts-no-sparse-array", "arkts-no-enum-prop-as-type", "arkts-no-ts-like-smart-type", @@ -72,11 +73,13 @@ "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", + "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 eb595308ca..2a49273753 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -384,6 +384,8 @@ cookBookTag[351] = 'The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)'; cookBookTag[352] = '1.2 Void cannot be combined. OnDestroy/onDisconnect (The return type of the method is now void | Promise) needs to be split into two interfaces. (sdk-ability-asynchronous-lifecycle)'; +cookBookTag[353] = + 'Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)'; cookBookTag[355] = 'Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)'; cookBookTag[356] = 'Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)'; cookBookTag[357] = 'Worker are not supported(arkts-no-need-stdlib-worker)'; @@ -432,6 +434,8 @@ 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)'; +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 d7d64f4e67..53b081f214 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -269,6 +269,7 @@ faultsAttrs[FaultID.SharedArrayBufferDeprecated] = new FaultAttributes(349); faultsAttrs[FaultID.SetCloneListDeprecated] = new FaultAttributes(350); faultsAttrs[FaultID.SetTransferListDeprecated] = new FaultAttributes(351); faultsAttrs[FaultID.SdkAbilityAsynchronousLifecycle] = new FaultAttributes(352); +faultsAttrs[FaultID.ObjectLiteralUnionNeedsCast] = new FaultAttributes(353); faultsAttrs[FaultID.LimitedStdLibNoSendableDecorator] = new FaultAttributes(355); faultsAttrs[FaultID.LimitedStdLibNoDoncurrentDecorator] = new FaultAttributes(356); faultsAttrs[FaultID.NoNeedStdlibWorker] = new FaultAttributes(357); @@ -305,3 +306,5 @@ 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); +faultsAttrs[FaultID.LargeNumericLiteral] = new FaultAttributes(410); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index eebe9aef41..6eb954570e 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -247,6 +247,7 @@ faultDesc[FaultID.SharedArrayBufferDeprecated] = 'SharedArrayBuffer is not suppo faultDesc[FaultID.SetCloneListDeprecated] = 'setCloneList is not supported'; faultDesc[FaultID.SetTransferListDeprecated] = 'setTransferList is not supported'; faultDesc[FaultID.SdkAbilityAsynchronousLifecycle] = '1.2 Void cannot be combined'; +faultDesc[FaultID.ObjectLiteralUnionNeedsCast] = 'Object literals require union member assertion'; faultDesc[FaultID.LimitedStdLibNoSendableDecorator] = 'Limited stdlib no sendable decorator'; faultDesc[FaultID.LimitedStdLibNoDoncurrentDecorator] = 'Limited stdlib no concurrent decorator'; faultDesc[FaultID.NoNeedStdlibWorker] = 'No need stdlib worker'; @@ -295,3 +296,5 @@ 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'; +faultDesc[FaultID.LargeNumericLiteral] = 'Numeric literal exceeds allowed range'; diff --git a/ets2panda/linter/src/lib/LinterRunner.ts b/ets2panda/linter/src/lib/LinterRunner.ts index 3696ab6898..cab8af9115 100644 --- a/ets2panda/linter/src/lib/LinterRunner.ts +++ b/ets2panda/linter/src/lib/LinterRunner.ts @@ -54,6 +54,7 @@ import { mergeArrayMaps } from './utils/functions/MergeArrayMaps'; import { clearPathHelperCache, pathContainsDirectory } from './utils/functions/PathHelper'; import { processSyncErr } from './utils/functions/ProcessWrite'; import type { LinterInputInfo } from './LinterInputInfo'; +import { collectCommonApiInfo } from './utils/functions/CommonApiInfo'; function prepareInputFilesList(cmdOptions: CommandLineOptions): string[] { let inputFiles = cmdOptions.inputFiles.map((x) => { @@ -120,6 +121,7 @@ function lintImpl(config: LinterConfig, migrationInfo?: MigrationInfo): LintRunR if (srcFile) { srcFiles.push(srcFile); } + collectCommonApiInfo(tsProgram); } const tscStrictDiagnostics = getTscDiagnostics(tscCompiledProgram, srcFiles); diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index 99bdbd2687..85947c13d6 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -246,6 +246,7 @@ export enum FaultID { SetCloneListDeprecated, SetTransferListDeprecated, SdkAbilityAsynchronousLifecycle, + ObjectLiteralUnionNeedsCast, LimitedStdLibNoSendableDecorator, LimitedStdLibNoDoncurrentDecorator, NoNeedStdlibWorker, @@ -294,6 +295,8 @@ export enum FaultID { BuiltinNarrowTypes, 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 c2f34353a2..e61b3a7a63 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -221,9 +221,10 @@ import { ERROR_TASKPOOL_PROP_LIST } from './utils/consts/ErrorProp'; import { COMMON_UNION_MEMBER_ACCESS_WHITELIST } from './utils/consts/ArktsWhiteApiPaths'; import type { BaseClassConstructorInfo, ConstructorParameter, ExtendedIdentifierInfo } from './utils/consts/Types'; import { ExtendedIdentifierType } from './utils/consts/Types'; -import { STRING_ERROR_LITERAL } from './utils/consts/Literals'; +import { COMPONENT_DECORATOR, SELECT_IDENTIFIER, SELECT_OPTIONS, STRING_ERROR_LITERAL } from './utils/consts/Literals'; import { ES_OBJECT } from './utils/consts/ESObject'; import { cookBookMsg } from './CookBookMsg'; +import { getCommonApiInfoMap } from './utils/functions/CommonApiInfo'; export class TypeScriptLinter extends BaseTypeScriptLinter { supportedStdCallApiChecker: SupportedStdCallApiChecker; @@ -1828,61 +1829,48 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!this.options.arkts2) { return; } + + // Safeguard: only process the outermost property access, not nested chains + if (ts.isPropertyAccessExpression(propertyAccessNode.parent)) { + return; + } + const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); const baseExprSym = baseExprType.aliasSymbol || baseExprType.getSymbol(); const symbolName = baseExprSym ? baseExprSym.name : this.tsTypeChecker.typeToString(baseExprType); + if (!baseExprType.isUnion() || COMMON_UNION_MEMBER_ACCESS_WHITELIST.has(symbolName)) { return; } - const allType = baseExprType.types; - const commonPropertyType = allType.filter((type) => { - return this.tsUtils.findProperty(type, propertyAccessNode.name.getText()) !== undefined; + + const allTypes = baseExprType.types; + const propName = propertyAccessNode.name.getText(); + + // Only keep union members that have the property + const typesWithProp = allTypes.filter((type) => { + return this.tsUtils.findProperty(type, propName) !== undefined; }); - const typeMap = new Map(); - if (commonPropertyType.length === allType.length) { - allType.forEach((type) => { - this.handleTypeMember(type, propertyAccessNode.name.getText(), typeMap); - }); - if (typeMap.size > 1) { - this.incrementCounters(propertyAccessNode, FaultID.AvoidUnionTypes); - } - } - } - private handleTypeMember( - type: ts.Type, - memberName: string, - typeMap: Map - ): void { - const propertySymbol = this.tsUtils.findProperty(type, memberName); - if (!propertySymbol?.declarations) { - return; - } - const propertyType = this.tsTypeChecker.getTypeOfSymbolAtLocation(propertySymbol, propertySymbol.declarations[0]); - const symbol = propertySymbol.valueDeclaration; - if (!symbol) { + if (typesWithProp.length !== allTypes.length) { + // Not all members have this property, nothing to check return; } - if (ts.isMethodDeclaration(symbol)) { - const returnType = this.getMethodReturnType(propertySymbol); - typeMap.set(returnType, memberName); - } else { - typeMap.set(propertyType, memberName); - } - } - private getMethodReturnType(symbol: ts.Symbol): string | undefined { - const declaration = symbol.valueDeclaration ?? (symbol.declarations?.[0] as ts.Node | undefined); - if (!declaration) { - return undefined; + // Extract the type of the property for each member + const propTypes: string[] = []; + for (const t of typesWithProp) { + const propSym = this.tsUtils.findProperty(t, propName); + if (propSym) { + const propType = this.tsTypeChecker.getTypeOfSymbolAtLocation(propSym, propertyAccessNode); + propTypes.push(this.tsTypeChecker.typeToString(propType)); + } } - const methodType = this.tsTypeChecker.getTypeOfSymbolAtLocation(symbol, declaration); - const signatures = methodType.getCallSignatures(); - if (signatures.length === 0) { - return 'void'; + + // If there's more than one distinct property type signature, flag it + const distinctPropTypes = new Set(propTypes); + if (distinctPropTypes.size > 1) { + this.incrementCounters(propertyAccessNode, FaultID.AvoidUnionTypes); } - const returnType = signatures[0].getReturnType(); - return this.tsTypeChecker.typeToString(returnType); } private handleLiteralAsPropertyName(node: ts.PropertyDeclaration | ts.PropertySignature): void { @@ -3840,6 +3828,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 +3837,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) { @@ -3996,6 +3994,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const classDecl = node.parent; if (!ts.isClassDeclaration(classDecl)) { + this.handleMethodInheritForCommonApi(node); return; } const isStatic = @@ -4015,6 +4014,16 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkIncompatibleFunctionTypes(node); } + private handleMethodInheritForCommonApi(node: ts.MethodDeclaration): void { + const commonApiInfos = getCommonApiInfoMap(); + commonApiInfos?.forEach((apiNode) => { + if (node.name.getText() === apiNode.name.getText()) { + this.checkMethodParameters(node, apiNode); + this.checkMethodReturnType(node, apiNode); + } + }); + } + private checkMethodType( allBaseTypes: ts.Type[], methodName: string, @@ -5570,102 +5579,64 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleNoDeprecatedApi(callExpr); this.handleFunctionReturnThisCall(callExpr); this.handlePromiseTupleGeneric(callExpr); - this.checkArgumentTypeOfCallExpr(callExpr, callSignature); + this.isSelectOfArkUI(callExpr, callSignature); this.handleTupleGeneric(callExpr); } - private checkArgumentTypeOfCallExpr(callExpr: ts.CallExpression, signature: ts.Signature | undefined): void { + private isSelectOfArkUI(callExpr: ts.CallExpression, signature: ts.Signature | undefined): void { if (!this.options.arkts2) { return; } - if (!signature) { - return; - } - const args = callExpr.arguments; - if (args.length === 0) { + if (callExpr.expression.getText() !== SELECT_IDENTIFIER) { return; } - for (const [idx, arg] of args.entries()) { - this.isArgumentAndParameterMatch(signature, arg, idx); - } - } - - private isArgumentAndParameterMatch(signature: ts.Signature, arg: ts.Expression, idx: number): void { - if (!ts.isPropertyAccessExpression(arg)) { - return; - } - - let rootObject = arg.expression; - - while (ts.isPropertyAccessExpression(rootObject)) { - rootObject = rootObject.expression; - } - - if (rootObject.kind !== ts.SyntaxKind.ThisKeyword) { + /* + * for some reason UI component methods signatures cannot be accessed through here, + * there should be no signature declaration of this callExpression, + * if there is signature declaration we will assume this is not an ArkUI component + */ + if (signature?.getDeclaration()) { return; } - const param = signature.parameters.at(idx); - if (!param) { - return; - } - const paramDecl = param.getDeclarations(); - if (!paramDecl || paramDecl.length === 0) { + const insideArkUi = this.isInComponentBlock(callExpr.getSourceFile()); + if (!insideArkUi) { return; } - const paramFirstDecl = paramDecl[0]; - if (!ts.isParameter(paramFirstDecl)) { + const args = callExpr.arguments; + if (args.length !== 1) { return; } - const paramTypeNode = paramFirstDecl.type; + const arg = args[0]; const argumentType = this.tsTypeChecker.getTypeAtLocation(arg); - if (!paramTypeNode) { - return; - } - - if (!paramTypeNode) { - return; - } - const argumentTypeString = this.tsTypeChecker.typeToString(argumentType); - if (ts.isUnionTypeNode(paramTypeNode)) { - this.checkUnionTypesMatching(arg, paramTypeNode, argumentTypeString); - } else { - this.checkSingleTypeMatching(paramTypeNode, arg, argumentTypeString); - } - } - private checkSingleTypeMatching(paramTypeNode: ts.TypeNode, arg: ts.Node, argumentTypeString: string): void { - const paramType = this.tsTypeChecker.getTypeFromTypeNode(paramTypeNode); - const paramTypeString = this.tsTypeChecker.typeToString(paramType); - if (TsUtils.isIgnoredTypeForParameterType(paramTypeString, paramType)) { + if (SELECT_OPTIONS.includes(argumentTypeString)) { return; } - if (argumentTypeString !== paramTypeString) { - this.incrementCounters(arg, FaultID.StructuralIdentity); - } + this.incrementCounters(arg, FaultID.StructuralIdentity); } - private checkUnionTypesMatching(arg: ts.Node, paramTypeNode: ts.UnionTypeNode, argumentTypeString: string): void { - let notMatching = true; - for (const type of paramTypeNode.types) { - const paramType = this.tsTypeChecker.getTypeFromTypeNode(type); - const paramTypeString = this.tsTypeChecker.typeToString(paramType); - notMatching = !TsUtils.isIgnoredTypeForParameterType(paramTypeString, paramType); - - if (argumentTypeString === paramTypeString) { - notMatching = false; + private isInComponentBlock(sourceFile: ts.SourceFile): boolean { + void this; + let isInside = false; + for (const statement of sourceFile.statements) { + statement.forEachChild((node) => { + if (node.getText() === COMPONENT_DECORATOR) { + isInside = true; + } + }); + if (isInside) { + break; } } - if (notMatching) { - this.incrementCounters(arg, FaultID.StructuralIdentity); - } + return isInside; } private handleTupleGeneric(callExpr: ts.CallExpression): void { @@ -6273,6 +6244,66 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkAssignmentMatching(tsArg, tsParamType, tsArg); } } + this.checkOnClickCallback(tsCallOrNewExpr); + } + +private checkOnClickCallback(tsCallOrNewExpr: ts.CallExpression | ts.NewExpression): void { + if (!tsCallOrNewExpr.arguments || tsCallOrNewExpr.arguments.length === 0 && this.options.arkts2) { + return; + } + + const isOnClick = + ts.isPropertyAccessExpression(tsCallOrNewExpr.expression) && tsCallOrNewExpr.expression.name.text === 'onClick'; + if (!isOnClick) { + return; + } + + const objType = this.tsTypeChecker.getTypeAtLocation(tsCallOrNewExpr.expression.expression); + const declNode = TsUtils.getDeclaration(objType.getSymbol()); + if (declNode) { + const fileName = declNode.getSourceFile().fileName; + if (!fileName.includes('@ohos/')) { + return; + } + } + + const callback = tsCallOrNewExpr.arguments[0]; + if (!ts.isArrowFunction(callback)) { + return; + } + + this.checkAsyncOrPromiseFunction(callback); + } + + private checkAsyncOrPromiseFunction(callback: ts.ArrowFunction): void { + const returnsPromise = this.checkReturnsPromise(callback); + const isAsync = callback.modifiers?.some((m) => { + return m.kind === ts.SyntaxKind.AsyncKeyword; + }); + + if (isAsync || returnsPromise) { + const startPos = callback.modifiers?.[0]?.getStart() ?? callback.getStart(); + const endPos = callback.body.getEnd(); + + const errorNode = { + getStart: () => { return startPos; }, + getEnd: () => { return endPos; }, + getSourceFile: () => { return callback.getSourceFile(); } + } as ts.Node; + + this.incrementCounters(errorNode, FaultID.IncompationbleFunctionType); + } + } + + private checkReturnsPromise(callback: ts.ArrowFunction): boolean { + const callbackType = this.tsTypeChecker.getTypeAtLocation(callback); + const signatures = this.tsTypeChecker.getSignaturesOfType(callbackType, ts.SignatureKind.Call); + if (signatures.length === 0) { + return false; + } + + const returnType = this.tsTypeChecker.getReturnTypeOfSignature(signatures[0]); + return !!returnType.getProperty('then'); } private static readonly LimitedApis = new Map | null; fault: FaultID }>([ @@ -7491,6 +7522,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { * 'arkts-no-structural-typing' check was missing in some scenarios, * in order not to cause incompatibility, * only need to strictly match the type of filling the check again + * + * Also delegates the object-literal → union rule to `handleObjectLiteralUnionArg`. */ private checkAssignmentMatching( contextNode: ts.Node, @@ -7499,6 +7532,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { isNewStructuralCheck: boolean = false ): void { const rhsType = this.tsTypeChecker.getTypeAtLocation(rhsExpr); + + // Object-literal to union rule (non-call contexts) + this.handleObjectLiteralUnionArg(lhsType, rhsExpr); + this.handleNoTuplesArrays(contextNode, lhsType, rhsType); this.handleArrayTypeImmutable(contextNode, lhsType, rhsType, rhsExpr); // check that 'sendable typeAlias' is assigned correctly @@ -7514,6 +7551,59 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkFunctionalTypeCompatibility(lhsType, rhsType, rhsExpr); } + /** + * Flags `{ ... }` used where the LHS type is a union with + * more than one non-nullish member and the object literal + * is not already asserted (e.g., `{...} as A`). + * Applies to variable initializers, assignments, call expressions and returns + * that route through `checkAssignmentMatching`. + */ + private handleObjectLiteralUnionArg(lhsType: ts.Type, rhsExpr: ts.Expression): void { + if (!this.options.arkts2) { + return; + } + + if (!ts.isObjectLiteralExpression(rhsExpr) || !lhsType?.isUnion()) { + return; + } + + // Already asserted/cast? Allowed. + const parent = rhsExpr.parent; + if (ts.isAsExpression(parent) || ts.isTypeAssertionExpression(parent)) { + return; + } + + // Allow nullish unions like 'T | null | undefined' + const nonNullishMembers = lhsType.types.filter((t) => { + return !TsUtils.isNullishType(t); + }); + if (nonNullishMembers.length <= 1) { + return; + } + + // Skip any types that are from standard lib + const nonStdlibMembers = nonNullishMembers.filter((t) => { + return !(t.getSymbol() && isStdLibrarySymbol(t.getSymbol())); + }); + + const hasClassOrInterfaceMember = nonStdlibMembers.some((t) => { + const sym = t.aliasSymbol ?? t.getSymbol(); + if (!sym) { + return false; + } + const decls = sym.getDeclarations() ?? []; + + return decls.some((d) => { + return ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d); + }); + }); + if (!hasClassOrInterfaceMember) { + return; + } + + this.incrementCounters(rhsExpr, FaultID.ObjectLiteralUnionNeedsCast); + } + private handleStructuralTyping( contextNode: ts.Node, lhsType: ts.Type, @@ -11066,6 +11156,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { errorMsg = `The "${name}" in SDK is no longer supported.(sdk-method-not-supported)`; } else if (faultID === FaultID.SdkCommonApiBehaviorChange) { errorMsg = `The "${name}" in SDK has been changed.(sdk-method-changed)`; + } else if (faultID === FaultID.NoDeprecatedApi) { + errorMsg = `The ArkUI interface "${name}" is deprecated (arkui-deprecated-interface)`; } return errorMsg; } @@ -11891,11 +11983,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private isTargetStorageType(storage: ts.Identifier, targetTypes: string[]): boolean { const decl = this.tsUtils.getDeclarationNode(storage); - if (!decl) { - if (targetTypes.includes(storage.getText())) { - return true; - } - return false; + if (!decl || decl.getSourceFile() !== storage.getSourceFile()) { + return targetTypes.includes(storage.getText()); } if (!ts.isVariableDeclaration(decl)) { @@ -12226,7 +12315,16 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { staticProps: Map, instanceProps: Map ): void { - forEachNodeInSubtree(body, (node) => { + const stopCondition = (node: ts.Node): boolean => { + return ( + ts.isFunctionDeclaration(node) || + ts.isFunctionExpression(node) || + ts.isMethodDeclaration(node) || + ts.isAccessor(node) || + ts.isArrowFunction(node) + ); + }; + const callback = (node: ts.Node): void => { if (!ts.isReturnStatement(node) || !node.expression) { return; } @@ -12234,7 +12332,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (ts.isPropertyAccessExpression(expr)) { return expr; } - if (ts.isCallExpression(expr) && ts.isPropertyAccessExpression(expr.expression)) { return expr.expression; } @@ -12258,7 +12355,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (isInstancePropertyAccess(node.expression)) { this.checkPropertyAccess(node, node.expression as ts.PropertyAccessExpression, instanceProps, methodReturnType); } - }); + }; + forEachNodeInSubtree(body, callback, stopCondition); } private checkPropertyAccess( @@ -12440,6 +12538,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) { @@ -14056,7 +14160,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { name, faultID, isSdkCommon || apiType === BUILTIN_TYPE ? undefined : autofix, - isSdkCommon ? TypeScriptLinter.getErrorMsgForSdkCommonApi(name.text, faultID) : undefined + isSdkCommon || apiType === undefined ? + TypeScriptLinter.getErrorMsgForSdkCommonApi(name.text, faultID) : + undefined ); } } @@ -14147,7 +14253,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } if (paramMatch) { - this.incrementCounters(expression, FaultID.NoDeprecatedApi); + this.incrementCounters( + expression, + FaultID.NoDeprecatedApi, + undefined, + TypeScriptLinter.getErrorMsgForSdkCommonApi(expression.getText(), FaultID.NoDeprecatedApi) + ); return; } } @@ -14412,7 +14523,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { errorNode, faultID, isSdkCommon || apiType === BUILTIN_TYPE ? undefined : autofix, - isSdkCommon ? TypeScriptLinter.getErrorMsgForSdkCommonApi(apiName, faultID) : undefined + isSdkCommon || apiType === undefined ? TypeScriptLinter.getErrorMsgForSdkCommonApi(apiName, faultID) : undefined ); } } diff --git a/ets2panda/linter/src/lib/autofixes/Autofixer.ts b/ets2panda/linter/src/lib/autofixes/Autofixer.ts index 91ff39cad5..8fec792915 100644 --- a/ets2panda/linter/src/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/src/lib/autofixes/Autofixer.ts @@ -209,7 +209,6 @@ export class Autofixer { * @param variableDeclarationMap - Map of property names to variable names. * @param newObjectName - Name of the new object to destructure. * @param declarationFlags - Flags for the variable declaration. - * @param printer - TypeScript printer instance. * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring text. */ @@ -217,7 +216,6 @@ export class Autofixer { variableDeclarationMap: Map, newObjectName: string, declarationFlags: ts.NodeFlags, - printer: ts.Printer, sourceFile: ts.SourceFile ): string { let destructElementText: string = ''; @@ -244,7 +242,7 @@ export class Autofixer { ); // Print the variable statement to text and append it - const text = printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); + const text = this.printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); destructElementText += text + this.getNewLine(); }); @@ -260,7 +258,7 @@ export class Autofixer { */ private genAutofixForObjDecls( variableDeclaration: ts.VariableDeclaration, - newObjectName: string | undefined, + newObjectName: string, destructElementText: string, isIdentifier: boolean ): Autofix[] | undefined { @@ -279,7 +277,7 @@ export class Autofixer { } else { // Create autofix suggestions for both variable name and destructuring variableNameReplaceText = { - replacementText: newObjectName as string, + replacementText: newObjectName, start: variableDeclaration.name.getStart(), end: variableDeclaration.name.getEnd() }; @@ -301,18 +299,18 @@ export class Autofixer { * @param variableDeclaration - The variable or parameter declaration to check for boundary conditions. * @returns A boolean indicating if the declaration passes the boundary checks. */ - private static passBoundaryCheckForObjDecls(variableDeclaration: ts.VariableDeclaration): boolean { + private static passBoundaryCheckForObjDecls(bindingPattern: ts.BindingPattern, intializer: ts.Expression): boolean { // Check if the fault ID is for a destructuring parameter or if the declaration has a spread operator if ( - TsUtils.destructuringDeclarationHasSpreadOperator(variableDeclaration.name as ts.BindingPattern) || - TsUtils.destructuringDeclarationHasDefaultValue(variableDeclaration.name as ts.BindingPattern) + TsUtils.destructuringDeclarationHasSpreadOperator(bindingPattern) || + TsUtils.destructuringDeclarationHasDefaultValue(bindingPattern) ) { return false; } // If the initializer is an object literal expression, check its properties - if (ts.isObjectLiteralExpression(variableDeclaration.initializer as ts.Node)) { - const len = (variableDeclaration.initializer as ts.ObjectLiteralExpression).properties.length; + if (ts.isObjectLiteralExpression(intializer)) { + const len = intializer.properties.length; if (len === 0) { // Return false if there are no properties return false; @@ -330,24 +328,32 @@ export class Autofixer { * @returns Array of autofix suggestions or undefined. */ fixObjectBindingPatternDeclarations(variableDeclaration: ts.VariableDeclaration): Autofix[] | undefined { - if (!Autofixer.passBoundaryCheckForObjDecls(variableDeclaration)) { + if (!ts.isObjectBindingPattern(variableDeclaration.name) || !variableDeclaration.initializer) { + return undefined; + } + + if (!Autofixer.passBoundaryCheckForObjDecls(variableDeclaration.name, variableDeclaration.initializer)) { return undefined; } + // Map to hold variable names and their corresponding property names const variableDeclarationMap: Map = new Map(); - // If the declaration is an object binding pattern, extract names - if (ts.isObjectBindingPattern(variableDeclaration.name)) { - variableDeclaration.name.elements.forEach((element) => { - if (!element.propertyName) { - variableDeclarationMap.set(element.name.getText(), element.name.getText()); - } else { - variableDeclarationMap.set((element.propertyName as ts.Identifier).text, element.name.getText()); + + // Extract property names + for (const element of variableDeclaration.name.elements) { + if (!element.propertyName) { + variableDeclarationMap.set(element.name.getText(), element.name.getText()); + } else { + if (!ts.isIdentifier(element.propertyName)) { + return undefined; } - }); + variableDeclarationMap.set(element.propertyName.text, element.name.getText()); + } } const sourceFile = variableDeclaration.getSourceFile(); let newObjectName: string | undefined; - const isIdentifier = ts.isIdentifier(variableDeclaration.initializer as ts.Node); + const isIdentifier = ts.isIdentifier(variableDeclaration.initializer); + // If it is identifer, use its text as the new object name; otherwise, generate a unique name if (isIdentifier) { newObjectName = variableDeclaration.initializer?.getText(); @@ -362,7 +368,6 @@ export class Autofixer { variableDeclarationMap, newObjectName, declarationFlags, - this.printer, sourceFile ); @@ -375,7 +380,6 @@ export class Autofixer { * @param variableNames - Array of variable names corresponding to array elements. * @param newArrayName - Name of the new array to destructure. * @param declarationFlags - Flags for the variable declaration. - * @param printer - TypeScript printer instance. * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring text. */ @@ -383,7 +387,6 @@ export class Autofixer { variableNames: string[], newArrayName: string, declarationFlags: ts.NodeFlags, - printer: ts.Printer, sourceFile: ts.SourceFile ): string { let destructElementText: string = ''; @@ -414,7 +417,7 @@ export class Autofixer { ); // Print the variable statement to text and append it - const text = printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); + const text = this.printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); destructElementText += text + this.getNewLine(); } @@ -430,7 +433,7 @@ export class Autofixer { */ private genAutofixForArrayDecls( variableDeclaration: ts.VariableDeclaration, - newArrayName: string | undefined, + newArrayName: string, destructElementText: string, isIdentifierOrElementAccess: boolean ): Autofix[] { @@ -449,7 +452,7 @@ export class Autofixer { } else { // Create autofix suggestions for both variable name and destructuring variableNameReplaceText = { - replacementText: newArrayName as string, + replacementText: newArrayName, start: variableDeclaration.name.getStart(), end: variableDeclaration.name.getEnd() }; @@ -472,27 +475,28 @@ export class Autofixer { * @returns A boolean indicating if the declaration passes the boundary checks. */ private static passBoundaryCheckForArrayDecls( - variableDeclaration: ts.VariableDeclaration, + bindingPattern: ts.ArrayBindingPattern, + initializer: ts.Expression, isArrayOrTuple: boolean ): boolean { // If it's not an array/tuple or the declaration has a spread operator in destructuring if ( !isArrayOrTuple || - TsUtils.destructuringDeclarationHasSpreadOperator(variableDeclaration.name as ts.BindingPattern) || - TsUtils.destructuringDeclarationHasDefaultValue(variableDeclaration.name as ts.BindingPattern) + TsUtils.destructuringDeclarationHasSpreadOperator(bindingPattern) || + TsUtils.destructuringDeclarationHasDefaultValue(bindingPattern) ) { // Return false if it fails the boundary check return false; } // Check if the array binding pattern has any empty elements - if (TsUtils.checkArrayBindingHasEmptyElement(variableDeclaration.name as ts.ArrayBindingPattern)) { + if (TsUtils.checkArrayBindingHasEmptyElement(bindingPattern)) { // Return false if it contains empty elements return false; } // Check if the initializer has the same dimension as expected - if (!TsUtils.isSameDimension(variableDeclaration.initializer as ts.Node)) { + if (!TsUtils.isSameDimension(initializer)) { return false; } @@ -511,28 +515,29 @@ export class Autofixer { variableDeclaration: ts.VariableDeclaration, isArrayOrTuple: boolean ): Autofix[] | undefined { - if (!Autofixer.passBoundaryCheckForArrayDecls(variableDeclaration, isArrayOrTuple)) { + if (!ts.isArrayBindingPattern(variableDeclaration.name) || !variableDeclaration.initializer) { return undefined; } - const variableNames: string[] = []; - // If the declaration is an array binding pattern, extract variable names - if (ts.isArrayBindingPattern(variableDeclaration.name)) { - variableDeclaration.name.elements.forEach((element) => { - variableNames.push(element.getText()); - }); + if ( + !Autofixer.passBoundaryCheckForArrayDecls( + variableDeclaration.name, + variableDeclaration.initializer, + isArrayOrTuple + ) + ) { + return undefined; } + const variableNames: string[] = Autofixer.getVarNamesFromArrayBindingPattern(variableDeclaration.name); - const sourceFile = variableDeclaration.getSourceFile(); let newArrayName: string | undefined = ''; // Check if the initializer is either an identifier or an element access expression const isIdentifierOrElementAccess = - ts.isIdentifier(variableDeclaration.initializer as ts.Node) || - ts.isElementAccessExpression(variableDeclaration.initializer as ts.Node); + ts.isIdentifier(variableDeclaration.initializer) || ts.isElementAccessExpression(variableDeclaration.initializer); // If it is, use its text as the new array name; otherwise, generate a unique name if (isIdentifierOrElementAccess) { - newArrayName = variableDeclaration.initializer?.getText(); + newArrayName = variableDeclaration.initializer.getText(); } else { - newArrayName = TsUtils.generateUniqueName(this.destructArrayNameGenerator, sourceFile); + newArrayName = TsUtils.generateUniqueName(this.destructArrayNameGenerator, variableDeclaration.getSourceFile()); } if (!newArrayName) { return undefined; @@ -545,8 +550,7 @@ export class Autofixer { variableNames, newArrayName, declarationFlags, - this.printer, - sourceFile + variableDeclaration.getSourceFile() ); // Generate and return autofix suggestions for the array declarations @@ -558,18 +562,26 @@ export class Autofixer { ); } + private static getVarNamesFromArrayBindingPattern(bindingPattern: ts.ArrayBindingPattern): string[] { + const variableNames: string[] = []; + if (ts.isArrayBindingPattern(bindingPattern)) { + bindingPattern.elements.forEach((element) => { + variableNames.push(element.getText()); + }); + } + return variableNames; + } + /** * Generates the text representation for destructuring assignments in an array. * @param variableNames - Array of variable names corresponding to array elements. * @param newArrayName - Name of the new array to use for destructuring. - * @param printer - TypeScript printer instance. * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring assignment text. */ private genDestructElementTextForArrayAssignment( variableNames: string[], - newArrayName: string | undefined, - printer: ts.Printer, + newArrayName: string, sourceFile: ts.SourceFile ): string { let destructElementText: string = ''; @@ -581,7 +593,7 @@ export class Autofixer { // Create an element access expression for the new array const elementAccessExpr = ts.factory.createElementAccessExpression( - ts.factory.createIdentifier(newArrayName as string), + ts.factory.createIdentifier(newArrayName), ts.factory.createNumericLiteral(i) ); @@ -596,7 +608,7 @@ export class Autofixer { const expressionStatement = ts.factory.createExpressionStatement(assignmentExpr); // Print the expression statement to text and append it - const text = printer.printNode(ts.EmitHint.Unspecified, expressionStatement, sourceFile); + const text = this.printer.printNode(ts.EmitHint.Unspecified, expressionStatement, sourceFile); destructElementText += text + this.getNewLine(); } @@ -612,7 +624,7 @@ export class Autofixer { */ private genAutofixForArrayAssignment( assignmentExpr: ts.BinaryExpression, - newArrayName: string | undefined, + newArrayName: string, destructElementText: string, isIdentifierOrElementAccess: boolean ): Autofix[] { @@ -659,21 +671,21 @@ export class Autofixer { isArrayOrTuple: boolean ): boolean { // Return false if the assignment is not for an array or tuple - if (!isArrayOrTuple) { + if (!isArrayOrTuple || !ts.isArrayLiteralExpression(assignmentExpr.left)) { return false; } // Check if the left side of the assignment is an array literal expression with a spread operator - if (TsUtils.destructuringAssignmentHasSpreadOperator(assignmentExpr.left as ts.ArrayLiteralExpression)) { + if (TsUtils.destructuringAssignmentHasSpreadOperator(assignmentExpr.left)) { return false; } - if (TsUtils.destructuringAssignmentHasDefaultValue(assignmentExpr.left as ts.ArrayLiteralExpression)) { + if (TsUtils.destructuringAssignmentHasDefaultValue(assignmentExpr.left)) { return false; } // Check if the left side of the assignment has an empty element - if (TsUtils.checkArrayLiteralHasEmptyElement(assignmentExpr.left as ts.ArrayLiteralExpression)) { + if (TsUtils.checkArrayLiteralHasEmptyElement(assignmentExpr.left)) { return false; } @@ -710,7 +722,7 @@ export class Autofixer { const sourceFile = assignmentExpr.getSourceFile(); let newArrayName: string | undefined = ''; const isIdentifierOrElementAccess = - ts.isIdentifier(assignmentExpr.right) || ts.isElementAccessExpression(assignmentExpr.right as ts.Node); + ts.isIdentifier(assignmentExpr.right) || ts.isElementAccessExpression(assignmentExpr.right); if (isIdentifierOrElementAccess) { newArrayName = assignmentExpr.right.getText(); } else { @@ -721,12 +733,7 @@ export class Autofixer { } // Generate the text for destructuring assignments - const destructElementText = this.genDestructElementTextForArrayAssignment( - variableNames, - newArrayName, - this.printer, - sourceFile - ); + const destructElementText = this.genDestructElementTextForArrayAssignment(variableNames, newArrayName, sourceFile); return this.genAutofixForArrayAssignment( assignmentExpr, @@ -741,25 +748,29 @@ export class Autofixer { * @param binaryExpr - The binary expression containing the object literal. * @returns An object containing the variable declaration map and needParentheses indicating if property initializers are object literals. */ - private static genTsVarDeclMapAndFlags(binaryExpr: ts.BinaryExpression): { - tsVarDeclMap: Map; - needParentheses: boolean[]; - } { + private static genTsVarDeclMapAndFlags(objLiteralExpr: ts.ObjectLiteralExpression): + | { + tsVarDeclMap: Map; + needParentheses: boolean[]; + } + | undefined { const tsVarDeclMap: Map = new Map(); const needParentheses: boolean[] = []; - // Check if the left side of the binary expression is an object literal - if (ts.isObjectLiteralExpression(binaryExpr.left)) { - binaryExpr.left.properties.forEach((property) => { - // Handle property assignments with initializer - if (ts.isPropertyAssignment(property)) { - tsVarDeclMap.set(property.name?.getText(), property.initializer.getText()); - needParentheses.push(ts.isObjectLiteralExpression(property.initializer)); - } else if (ts.isShorthandPropertyAssignment(property)) { - tsVarDeclMap.set(property.name?.getText(), property.name.getText()); - needParentheses.push(false); - } - }); + for (const property of objLiteralExpr.properties) { + // Handle property assignments with initializer + if (!property.name || !ts.isIdentifier(property.name)) { + return undefined; + } + if (ts.isPropertyAssignment(property)) { + tsVarDeclMap.set(property.name.getText(), property.initializer.getText()); + needParentheses.push(ts.isObjectLiteralExpression(property.initializer)); + } else if (ts.isShorthandPropertyAssignment(property)) { + tsVarDeclMap.set(property.name.getText(), property.name.getText()); + needParentheses.push(false); + } else { + return undefined; + } } return { tsVarDeclMap, needParentheses }; @@ -771,15 +782,13 @@ export class Autofixer { * @param needParentheses - Array of needParentheses indicating if property initializers are object literals. * @param newObjName - The name of the new object to use for destructuring. * @param binaryExpr - The binary expression representing the destructuring. - * @param printer - TypeScript printer instance for printing nodes. * @returns The generated text for destructuring assignments. */ private genDestructElementTextForObjAssignment( tsVarDeclMap: Map, needParentheses: boolean[], newObjName: string, - binaryExpr: ts.BinaryExpression, - printer: ts.Printer + binaryExpr: ts.BinaryExpression ): string { let destructElementText: string = ''; let index: number = 0; @@ -804,7 +813,7 @@ export class Autofixer { // Append the generated text for the destructuring assignment destructElementText += - printer.printNode(ts.EmitHint.Unspecified, statement, binaryExpr.getSourceFile()) + this.getNewLine(); + this.printer.printNode(ts.EmitHint.Unspecified, statement, binaryExpr.getSourceFile()) + this.getNewLine(); index++; }); @@ -816,14 +825,9 @@ export class Autofixer { * Creates the replacement text for the variable declaration name. * @param binaryExpr - The binary expression containing the object literal or call expression. * @param newObjName - The new object name to be used in the replacement. - * @param printer - TypeScript printer instance for printing nodes. * @returns The replacement text for the variable declaration name. */ - private static genDeclNameReplaceTextForObjAssignment( - binaryExpr: ts.BinaryExpression, - newObjName: string, - printer: ts.Printer - ): string { + private genDeclNameReplaceTextForObjAssignment(binaryExpr: ts.BinaryExpression, newObjName: string): string { let declNameReplaceText = ''; // create variableDeclList and get declNameReplaceText text @@ -834,7 +838,7 @@ export class Autofixer { binaryExpr.right ); const variableDeclList = ts.factory.createVariableDeclarationList([variableDecl], ts.NodeFlags.Let); - declNameReplaceText = printer.printNode(ts.EmitHint.Unspecified, variableDeclList, binaryExpr.getSourceFile()); + declNameReplaceText = this.printer.printNode(ts.EmitHint.Unspecified, variableDeclList, binaryExpr.getSourceFile()); return declNameReplaceText; } @@ -888,12 +892,16 @@ export class Autofixer { * @returns A boolean indicating if the assignment passes the boundary checks. */ private static passBoundaryCheckForObjAssignment(binaryExpr: ts.BinaryExpression): boolean { + if (!ts.isObjectLiteralExpression(binaryExpr.left)) { + return false; + } + // Check for spread operator in destructuring assignment on the left side - if (TsUtils.destructuringAssignmentHasSpreadOperator(binaryExpr.left as ts.ObjectLiteralExpression)) { + if (TsUtils.destructuringAssignmentHasSpreadOperator(binaryExpr.left)) { return false; } - if (TsUtils.destructuringAssignmentHasDefaultValue(binaryExpr.left as ts.ObjectLiteralExpression)) { + if (TsUtils.destructuringAssignmentHasDefaultValue(binaryExpr.left)) { return false; } @@ -915,8 +923,18 @@ export class Autofixer { if (!Autofixer.passBoundaryCheckForObjAssignment(binaryExpr)) { return undefined; } + + // Check if the left side of the binary expression is an object literal + if (!ts.isObjectLiteralExpression(binaryExpr.left)) { + return undefined; + } + // Create a mapping of variable declarations and needParentheses - const { tsVarDeclMap, needParentheses } = Autofixer.genTsVarDeclMapAndFlags(binaryExpr); + const varDeclMapFlags = Autofixer.genTsVarDeclMapAndFlags(binaryExpr.left); + if (!varDeclMapFlags) { + return undefined; + } + const { tsVarDeclMap, needParentheses } = varDeclMapFlags; const sourceFile = binaryExpr.getSourceFile(); let newObjName: string | undefined = ''; @@ -935,12 +953,11 @@ export class Autofixer { tsVarDeclMap, needParentheses, newObjName, - binaryExpr, - this.printer + binaryExpr ); // Create the replacement text for the variable declaration name - const declNameReplaceText = Autofixer.genDeclNameReplaceTextForObjAssignment(binaryExpr, newObjName, this.printer); + const declNameReplaceText = this.genDeclNameReplaceTextForObjAssignment(binaryExpr, newObjName); // Generate autofix suggestions return this.createAutofixForObjAssignment(binaryExpr, declNameReplaceText, destructElementText, isIdentifier); @@ -3733,7 +3750,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 +3777,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/src/lib/ts-compiler/ResolveSdks.ts b/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts index 290326c0fc..7ca65eeb23 100644 --- a/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts +++ b/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts @@ -35,6 +35,10 @@ export function readDeclareFiles(SdkPath: string): string[] { return []; } const declarationsFileNames: string[] = []; + const commonPath = path.resolve(SdkPath, './component/common.d.ts'); + if (fs.existsSync(commonPath)) { + declarationsFileNames.push(path.resolve(SdkPath, './component/common.d.ts')); + } const declarationsPath = path.resolve(SdkPath, './build-tools/ets-loader/declarations'); if (!fs.existsSync(declarationsPath)) { throw new Error('get wrong sdkDefaultApiPath, declarationsPath not found'); diff --git a/ets2panda/linter/src/lib/utils/TsUtils.ts b/ets2panda/linter/src/lib/utils/TsUtils.ts index 1eea1826ef..fb6fd7b7ff 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']); @@ -481,16 +481,26 @@ export class TsUtils { } static isNullableUnionType(type: ts.Type): boolean { - if (type.isUnion()) { - for (const t of type.types) { - if (!!(t.flags & ts.TypeFlags.Undefined) || !!(t.flags & ts.TypeFlags.Null)) { - return true; - } + if (!type.isUnion()) { + return false; + } + + for (const t of type.types) { + if (TsUtils.isNullishType(t)) { + return true; } } + return false; } + /** + * Returns true if the given type is `null` or `undefined`. + */ + static isNullishType(t: ts.Type): boolean { + return !!(t.flags & ts.TypeFlags.Undefined) || !!(t.flags & ts.TypeFlags.Null); + } + static isMethodAssignment(tsSymbol: ts.Symbol | undefined): boolean { return ( !!tsSymbol && (tsSymbol.flags & ts.SymbolFlags.Method) !== 0 && (tsSymbol.flags & ts.SymbolFlags.Assignment) !== 0 @@ -1701,6 +1711,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/ArkuiImportList.ts b/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts index f95f5d338f..d4b3959341 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts @@ -1596,6 +1596,7 @@ export const arkuiImportList: Set = new Set([ 'WithThemeOptions', 'WordBreak', 'WorkStateStyle', + 'wrapBuilder', 'WrappedBuilder', 'XComponent', 'XComponentAttribute', diff --git a/ets2panda/linter/src/lib/utils/consts/Literals.ts b/ets2panda/linter/src/lib/utils/consts/Literals.ts index df8054e343..56d16c0fe2 100644 --- a/ets2panda/linter/src/lib/utils/consts/Literals.ts +++ b/ets2panda/linter/src/lib/utils/consts/Literals.ts @@ -15,3 +15,6 @@ export const STRING_ERROR_LITERAL = 'Error'; export const CONCAT_ARRAY = 'ConcatArray'; +export const SELECT_IDENTIFIER = 'Select'; +export const SELECT_OPTIONS = ['Array', 'SelectOption[]']; +export const COMPONENT_DECORATOR = '@Component'; 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/src/lib/utils/functions/CommonApiInfo.ts b/ets2panda/linter/src/lib/utils/functions/CommonApiInfo.ts new file mode 100644 index 0000000000..cd7ad4f322 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/functions/CommonApiInfo.ts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import path from 'node:path'; +import * as ts from 'typescript'; +import { forEachNodeInSubtree } from './ForEachNodeInSubtree'; + +export const COMMON_FILE_NAME = 'common.d.ts'; +const commonApiInfoMap = new Set(); +function visitSourceFile(sf: ts.SourceFile | undefined): void { + if (!sf) { + return; + } + const callback = (node: ts.Node): void => { + const isSave = ts.isMethodDeclaration(node) && ts.isClassDeclaration(node.parent); + if (isSave) { + commonApiInfoMap.add(node); + } + }; + forEachNodeInSubtree(sf, callback); +} +export function collectCommonApiInfo(tsProgram: ts.Program): void { + const rootNames = tsProgram.getRootFileNames(); + rootNames.some((file) => { + if (path.basename(file) === COMMON_FILE_NAME) { + const commonSrcFile = tsProgram.getSourceFile(file); + visitSourceFile(commonSrcFile); + return true; + } + return false; + }); +} +export function getCommonApiInfoMap(): Set | undefined { + return commonApiInfoMap.size > 0 ? commonApiInfoMap : undefined; +} diff --git a/ets2panda/linter/src/testRunner/LintTest.ts b/ets2panda/linter/src/testRunner/LintTest.ts index 8661ed7c74..a1095833f1 100644 --- a/ets2panda/linter/src/testRunner/LintTest.ts +++ b/ets2panda/linter/src/testRunner/LintTest.ts @@ -61,7 +61,7 @@ export class LintTest { // Get actual test results. const fileProblems = actualLinterResult.problemsInfos.get(path.normalize(this.cmdOptions.inputFiles[0])); if (fileProblems === undefined) { - return true; + return false; } const actualResult = transformProblemInfos(fileProblems, this.testModeProps.mode); diff --git a/ets2panda/linter/test/builtin/builtin_array_negative.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_array_negative.ets.arkts2.json index 86ad8dac2f..bc4681ba74 100644 --- a/ets2panda/linter/test/builtin/builtin_array_negative.ets.arkts2.json +++ b/ets2panda/linter/test/builtin/builtin_array_negative.ets.arkts2.json @@ -1,398 +1,388 @@ -{ - "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": 15, - "column": 10, - "endLine": 15, - "endColumn": 21, - "problem": "LimitedStdLibNoImportConcurrency", - "suggest": "", - "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 16, - "endLine": 17, - "endColumn": 21, - "problem": "BuiltinNewCtor", - "suggest": "", - "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 16, - "endLine": 18, - "endColumn": 21, - "problem": "BuiltinNewCtor", - "suggest": "", - "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 6, - "endLine": 19, - "endColumn": 12, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 40, - "endLine": 21, - "endColumn": 45, - "problem": "BuiltinNewCtor", - "suggest": "", - "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 40, - "endLine": 22, - "endColumn": 45, - "problem": "BuiltinNewCtor", - "suggest": "", - "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 7, - "endLine": 23, - "endColumn": 13, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 21, - "endLine": 25, - "endColumn": 28, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 15, - "endLine": 26, - "endColumn": 20, - "problem": "BuiltinNewCtor", - "suggest": "", - "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", - "severity": "ERROR" - }, - { - "line": 29, - "column": 23, - "endLine": 29, - "endColumn": 29, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 12, - "endLine": 30, - "endColumn": 18, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 5, - "endLine": 30, - "endColumn": 9, - "problem": "BuiltinNewCtor", - "suggest": "", - "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 11, - "endLine": 34, - "endColumn": 17, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 35, - "endLine": 35, - "endColumn": 41, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 13, - "endLine": 37, - "endColumn": 19, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 14, - "endLine": 40, - "endColumn": 19, - "problem": "BuiltinNewCtor", - "suggest": "", - "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 1, - "endLine": 41, - "endColumn": 20, - "problem": "InteropCallReflect", - "suggest": "", - "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-d2s-static-reflect-on-dynamic-instance)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 9, - "endLine": 41, - "endColumn": 16, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 44, - "column": 13, - "endLine": 44, - "endColumn": 19, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 13, - "endLine": 45, - "endColumn": 19, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 46, - "endLine": 47, - "endColumn": 50, - "problem": "ExtendsExpression", - "suggest": "", - "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 7, - "endLine": 47, - "endColumn": 11, - "problem": "InterfaceFieldNotImplemented", - "suggest": "", - "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 3, - "endLine": 61, - "endColumn": 4, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 50, - "column": 21, - "endLine": 50, - "endColumn": 25, - "problem": "BuiltinNewCtor", - "suggest": "", - "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", - "severity": "ERROR" - }, - { - "line": 54, - "column": 21, - "endLine": 54, - "endColumn": 35, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 24, - "endLine": 56, - "endColumn": 46, - "problem": "IsOperator", - "suggest": "", - "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 21, - "endLine": 57, - "endColumn": 27, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 10, - "endLine": 59, - "endColumn": 22, - "problem": "MethodInheritRule", - "suggest": "", - "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", - "severity": "ERROR" - }, - { - "line": 64, - "column": 5, - "endLine": 64, - "endColumn": 43, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 64, - "column": 17, - "endLine": 64, - "endColumn": 34, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 5, - "endLine": 65, - "endColumn": 44, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 18, - "endLine": 65, - "endColumn": 35, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 66, - "column": 5, - "endLine": 66, - "endColumn": 44, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 66, - "column": 18, - "endLine": 66, - "endColumn": 35, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 5, - "endLine": 67, - "endColumn": 47, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 43, - "endLine": 68, - "endColumn": 60, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 13, - "endLine": 73, - "endColumn": 19, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - }, - { - "line": 76, - "column": 13, - "endLine": 76, - "endColumn": 19, - "problem": "BuiltinNarrowTypes", - "suggest": "", - "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", - "severity": "ERROR" - } - ] +{ + "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": 15, + "column": 10, + "endLine": 15, + "endColumn": 21, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 16, + "endLine": 18, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 6, + "endLine": 19, + "endColumn": 12, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 40, + "endLine": 21, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 40, + "endLine": 22, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 13, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 21, + "endLine": 25, + "endColumn": 28, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 15, + "endLine": 26, + "endColumn": 20, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 29, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 12, + "endLine": 30, + "endColumn": 18, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 9, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 11, + "endLine": 34, + "endColumn": 17, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 35, + "endLine": 35, + "endColumn": 41, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 14, + "endLine": 40, + "endColumn": 19, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 20, + "problem": "InteropCallReflect", + "suggest": "", + "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-d2s-static-reflect-on-dynamic-instance)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 9, + "endLine": 41, + "endColumn": 16, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 13, + "endLine": 44, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 13, + "endLine": 45, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 46, + "endLine": 47, + "endColumn": 50, + "problem": "ExtendsExpression", + "suggest": "", + "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 7, + "endLine": 47, + "endColumn": 11, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all fields in the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 61, + "endColumn": 4, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 21, + "endLine": 50, + "endColumn": 25, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 24, + "endLine": 56, + "endColumn": 46, + "problem": "IsOperator", + "suggest": "", + "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 21, + "endLine": 57, + "endColumn": 27, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 10, + "endLine": 59, + "endColumn": 22, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 5, + "endLine": 64, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 17, + "endLine": 64, + "endColumn": 34, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 18, + "endLine": 65, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 18, + "endLine": 66, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 43, + "endLine": 68, + "endColumn": 60, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 13, + "endLine": 73, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 13, + "endLine": 76, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/COMPONENT.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/COMPONENT.ets.arkts2.json index 93d213bafa..06b2a341bf 100644 --- a/ets2panda/linter/test/deprecatedapi/COMPONENT.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/COMPONENT.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 39, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"COMPONENT\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.arkts2.json index ad1e3864f5..b2dbe82230 100644 --- a/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 37, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"enableAlertBeforeBackPage\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/SM.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/SM.ets.arkts2.json index 33ab839a5d..646dee383a 100644 --- a/ets2panda/linter/test/deprecatedapi/SM.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/SM.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 39, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 42, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"XS\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 62, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 65, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SM\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/action_sheet.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/action_sheet.ets.arkts2.json index 16b900fecb..be8eddb1ac 100644 --- a/ets2panda/linter/test/deprecatedapi/action_sheet.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/action_sheet.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"show\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/alert_dialog.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/alert_dialog.ets.arkts2.json index 3d1c55b24e..f2ee34f045 100644 --- a/ets2panda/linter/test/deprecatedapi/alert_dialog.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/alert_dialog.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"show\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/animator.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/animator.ets.arkts2.json index 601d9cf1f7..9cc4016ef7 100644 --- a/ets2panda/linter/test/deprecatedapi/animator.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/animator.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 16, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"create\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets.arkts2.json index 5b5712b92b..cc96bf0126 100644 --- a/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 40, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"IsMutable\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 35, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Get\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 36, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Clear\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 39, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Delete\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 36, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Size\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets.arkts2.json index ab3b8aff13..1c07495231 100644 --- a/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 24, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"screenOnVisible\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/buttons.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/buttons.ets.arkts2.json index 30ea0fb4ec..ffbd574589 100644 --- a/ets2panda/linter/test/deprecatedapi/buttons.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/buttons.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 18, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"showDialog\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 8, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"title\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 10, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"message\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/common_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/common_api.ets.arkts2.json index 9c39cd8ef4..477f1080b2 100644 --- a/ets2panda/linter/test/deprecatedapi/common_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/common_api.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 26, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getX\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 46, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 82, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutBorderInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 112, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 31, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 44, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutBorderInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 34, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 24, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 31, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 54, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutBorderInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -141,7 +141,7 @@ "endColumn": 72, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"TransitionOptions\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 42, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"TransitionOptions\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -201,7 +201,7 @@ "endColumn": 11, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"onLayout\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -211,7 +211,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -221,7 +221,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -251,7 +251,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"onMeasure\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -261,7 +261,7 @@ "endColumn": 34, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -281,7 +281,7 @@ "endColumn": 30, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getX\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -291,7 +291,7 @@ "endColumn": 38, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getY\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -311,7 +311,7 @@ "endColumn": 38, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getY\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -321,7 +321,7 @@ "endColumn": 46, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getY\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -341,7 +341,7 @@ "endColumn": 32, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getX\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -351,7 +351,7 @@ "endColumn": 32, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getY\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -381,7 +381,7 @@ "endColumn": 39, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -401,7 +401,7 @@ "endColumn": 47, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LayoutBorderInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets.arkts2.json index 555d6690d4..73c734b101 100644 --- a/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 40, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getShared\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets.arkts2.json index 0a1fb129d6..7adf5115af 100644 --- a/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"init\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/custom_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/custom_api.ets.arkts2.json index a57cc4ca00..57081a47c2 100644 --- a/ets2panda/linter/test/deprecatedapi/custom_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/custom_api.ets.arkts2.json @@ -13,7 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ + "result": [ { "line": 17, "column": 1, @@ -31,7 +31,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PanelType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 29, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"CUSTOM\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -94,5 +94,5 @@ "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } - ] -} + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets.arkts2.json index 38f8794a0f..6b41b86aa5 100644 --- a/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 48, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getFontByName\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"registerFont\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 46, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getFontByName\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 49, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getSystemFontList\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 28, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"registerFont\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets.arkts2.json index 8759d20f20..3ed0edea9e 100644 --- a/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 37, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"enableAlertBeforeBackPage\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 17, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"clear\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets.arkts2.json index 55aa23cb17..e7d32ce03d 100644 --- a/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 20, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"EnvProp\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 43, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Keys\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 21, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"EnvProps\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/foldable_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/foldable_api.ets.arkts2.json index 9ecb29181d..272fe50def 100644 --- a/ets2panda/linter/test/deprecatedapi/foldable_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/foldable_api.ets.arkts2.json @@ -13,7 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ + "result": [ { "line": 17, "column": 1, @@ -31,7 +31,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PanelType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 31, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Foldable\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -94,5 +94,5 @@ "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } - ] -} + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/listitem_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/listitem_api.ets.arkts2.json index 8dc4094363..bc005af887 100644 --- a/ets2panda/linter/test/deprecatedapi/listitem_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/listitem_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Sticky\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 31, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"EditMode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets.arkts2.json index 2f8cfb118f..7eaba6bdbb 100644 --- a/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 35, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"rotate\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"copy\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 38, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"translate\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/minibar_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/minibar_api.ets.arkts2.json index 54931525a0..c6074fab7b 100644 --- a/ets2panda/linter/test/deprecatedapi/minibar_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/minibar_api.ets.arkts2.json @@ -13,7 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ + "result": [ { "line": 17, "column": 1, @@ -31,7 +31,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PanelType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 30, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Minibar\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -94,5 +94,5 @@ "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } - ] -} + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/navigator_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/navigator_api.ets.arkts2.json index 4694d18e5b..d89f2a2fbf 100644 --- a/ets2panda/linter/test/deprecatedapi/navigator_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/navigator_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 34, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavigatorAttribute\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 36, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavigatorAttribute\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 18, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"active\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavigatorAttribute\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 16, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Navigator\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 44, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavigatorAttribute\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 20, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"target\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 31, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"active\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.arkts2.json index bbfdaf93fa..57e2115493 100644 --- a/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 14, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"mode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 16, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouter\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 46, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PUSH_WITH_RECREATE\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 23, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"onStateChange\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 14, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"mode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 16, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouter\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"name\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 31, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"param\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 46, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PUSH_WITH_RECREATE\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 35, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -141,7 +141,7 @@ "endColumn": 43, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"REPLACE\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 46, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 20, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"mode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -171,7 +171,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -181,7 +181,7 @@ "endColumn": 38, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PUSH\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -191,7 +191,7 @@ "endColumn": 29, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"mode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -201,7 +201,7 @@ "endColumn": 42, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -211,7 +211,7 @@ "endColumn": 50, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"REPLACE\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -221,7 +221,7 @@ "endColumn": 41, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouterInterface\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -251,7 +251,7 @@ "endColumn": 32, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -281,7 +281,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"RouteInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -291,7 +291,7 @@ "endColumn": 48, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -331,7 +331,7 @@ "endColumn": 28, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"RouteInfo\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -351,7 +351,7 @@ "endColumn": 49, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -361,7 +361,7 @@ "endColumn": 40, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -371,7 +371,7 @@ "endColumn": 42, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NavRouterInterface\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/node_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/node_api.ets.arkts2.json index e2ed9c2a93..def7da8f2c 100644 --- a/ets2panda/linter/test/deprecatedapi/node_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/node_api.ets.arkts2.json @@ -13,7 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ + "result": [ { "line": 21, "column": 33, @@ -21,7 +21,7 @@ "endColumn": 37, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"NODE\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -64,5 +64,5 @@ "rule": "The ArkUI interface \"XComponent\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } - ] -} + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets.arkts2.json index 14b1f5d64e..ef40455b9c 100644 --- a/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PanelMode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Mini\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PanelMode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Half\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PanelMode\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Full\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets.arkts2.json index 61e8ea37de..561f0d678b 100644 --- a/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 31, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PersistProps\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 23, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Keys\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/prompts_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/prompts_api.ets.arkts2.json index 9e241a57f7..53b184dcb9 100644 --- a/ets2panda/linter/test/deprecatedapi/prompts_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/prompts_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 17, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"showToast\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 10, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"message\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 11, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"duration\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 9, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 18, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"showDialog\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 8, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"title\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 10, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"message\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"showActionMenu\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 10, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"buttons\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 18, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"showDialog\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -171,7 +171,7 @@ "endColumn": 8, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"title\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -181,7 +181,7 @@ "endColumn": 10, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"message\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -191,7 +191,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -201,7 +201,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.arkts2.json index 09884303b5..13f2b04663 100644 --- a/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 38, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"disableAlertBeforeBackPage\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 14, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"success\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 15, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"complete\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 19, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"replace\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 10, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"uri\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 13, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"params\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 17, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"clear\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/routerPush_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/routerPush_api.ets.arkts2.json index e5042c3137..75f13d8298 100644 --- a/ets2panda/linter/test/deprecatedapi/routerPush_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/routerPush_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"push\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/scroll_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/scroll_api.ets.arkts2.json index f32e2bf1c3..9ad6cbf5bf 100644 --- a/ets2panda/linter/test/deprecatedapi/scroll_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/scroll_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 41, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Free\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets.arkts2.json index 92cf38ee66..bb10d761e7 100644 --- a/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"setImageCacheCount\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets.arkts2.json index d8b65d5c64..b9b2d94b66 100644 --- a/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 30, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"setImageFileCacheSize\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets.arkts2.json index bb45649496..5238aea41b 100644 --- a/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"setImageRawDataCacheSize\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/showActionMenu.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/showActionMenu.ets.arkts2.json index b44f244961..3ac87ce66d 100644 --- a/ets2panda/linter/test/deprecatedapi/showActionMenu.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/showActionMenu.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"showActionMenu\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 10, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"buttons\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"showActionMenu\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 10, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"buttons\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 12, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/sizeType.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/sizeType.ets.arkts2.json index feb77417cc..832bb8301e 100644 --- a/ets2panda/linter/test/deprecatedapi/sizeType.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/sizeType.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 39, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 42, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"XS\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 37, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 40, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"XS\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 37, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 40, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SM\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 37, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 40, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"MD\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 37, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 40, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"LG\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets.arkts2.json index 969b9eb44b..be4383aba1 100644 --- a/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 71, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 74, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SM\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 44, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 47, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"XS\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json index 6423f82bd7..3799eb68a1 100644 --- a/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 51, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 29, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 39, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 23, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"top\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 26, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 52, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Stretch\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"left\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"right\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 27, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 36, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"selectedColor\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -141,7 +141,7 @@ "endColumn": 25, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"mask\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 28, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 37, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -171,7 +171,7 @@ "endColumn": 21, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"size\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -181,7 +181,7 @@ "endColumn": 43, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -191,7 +191,7 @@ "endColumn": 18, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"top\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -211,7 +211,7 @@ "endColumn": 31, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -221,7 +221,7 @@ "endColumn": 33, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -231,7 +231,7 @@ "endColumn": 50, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"AutoLinear\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -241,7 +241,7 @@ "endColumn": 35, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Stretch\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -251,7 +251,7 @@ "endColumn": 39, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"AUTO_LINEAR\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/temporary_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/temporary_api.ets.arkts2.json index 6a24afa2aa..e534260a3e 100644 --- a/ets2panda/linter/test/deprecatedapi/temporary_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/temporary_api.ets.arkts2.json @@ -13,7 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ + "result": [ { "line": 17, "column": 1, @@ -31,7 +31,7 @@ "endColumn": 22, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PanelType\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 32, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"Temporary\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -94,5 +94,5 @@ "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } - ] -} + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets.arkts2.json index 2e6eb36ba3..65983ca6ef 100644 --- a/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets.arkts2.json @@ -13,7 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ + "result": [ { "line": 17, "column": 1, @@ -31,7 +31,7 @@ "endColumn": 26, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"PanelHeight\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 39, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"WRAP_CONTENT\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { @@ -94,5 +94,5 @@ "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } - ] -} + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json b/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json index 4b9be812e4..d65993bf63 100644 --- a/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 31, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, { "line": 20, "column": 5, @@ -24,6 +34,16 @@ "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", "severity": "ERROR" }, + { + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 31, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, { "line": 22, "column": 5, @@ -34,6 +54,16 @@ "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", "severity": "ERROR" }, + { + "line": 24, + "column": 22, + "endLine": 24, + "endColumn": 37, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, { "line": 24, "column": 5, @@ -44,6 +74,16 @@ "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", "severity": "ERROR" }, + { + "line": 26, + "column": 17, + "endLine": 26, + "endColumn": 34, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, { "line": 26, "column": 5, diff --git a/ets2panda/linter/test/main/arkui-select.ets b/ets2panda/linter/test/main/arkui-select.ets new file mode 100644 index 0000000000..92b8ccbde7 --- /dev/null +++ b/ets2panda/linter/test/main/arkui-select.ets @@ -0,0 +1,61 @@ +/* + * 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. + */ + + @Component + export struct ConsumeDescendentComponent { + // 初始化一个颜色数组数据 + @State selectColors: ColorType[] = COLOR_SELECT_DATA; + // 和爷组件双向同步圆形颜色 + @Consume consumeCircleColor: Resource; + // 和爷组件双向同步Select的Index值 + @Consume currentSelectIndex: number; + private CONTEXT: common.UIAbilityContext = this.getUIContext()?.getHostContext() as common.UIAbilityContext;//修改 + + build() { + Column() { + // 点击查看源码 + ViewCodeText({ webSrc: $rawfile('ConsumeDescendentComponent.ets.html') }) + Row() { + Select(this.selectColors) + .selected(this.currentSelectIndex) + .value(getResourceString(this.CONTEXT, this.selectColors[this.currentSelectIndex as int].value)) //修改this.context + .fontColor($r('app.color.button_text_color')) + .font({ size: $r('app.float.tips_font_size') }) + .selectedOptionFont({ size: $r('app.float.tips_font_size') }) + .optionFont({ size: $r('app.float.tips_font_size') }) + .id('grandsonCompB') + .onSelect((index: number) => { + // 孙组件@Consume声明的数据页面更新,爷组件@Provide的数据页面同步更新 + this.currentSelectIndex = index; + this.consumeCircleColor = this.selectColors[index as int].color; + }) + Circle() + .size({ width: $r('app.float.circle_size'), height: $r('app.float.circle_size') }) + .fill(this.consumeCircleColor) + + }.justifyContent(FlexAlign.SpaceAround) + .width('100%') + .margin({ bottom: 6.0 }as Margin)//修改添加 as Margin + + Text($r('app.string.deepnest_descendent_titletwo')) + .fontColor($r('app.color.tips_font_color')) + .fontSize($r('app.float.button_text_size')) + .width('100%') + .textAlign(TextAlign.Center) + } + .padding(10.0) + .border({ radius: $r('app.float.component_radius'), color: Color.Red, width: $r('app.float.border_width') }) + } + } diff --git a/ets2panda/linter/test/main/arkui-select.ets.args.json b/ets2panda/linter/test/main/arkui-select.ets.args.json new file mode 100644 index 0000000000..aac366be5e --- /dev/null +++ b/ets2panda/linter/test/main/arkui-select.ets.args.json @@ -0,0 +1,19 @@ +{ + "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." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/arkui-select.ets.arkts2.json b/ets2panda/linter/test/main/arkui-select.ets.arkts2.json new file mode 100644 index 0000000000..29b9095e7e --- /dev/null +++ b/ets2panda/linter/test/main/arkui-select.ets.arkts2.json @@ -0,0 +1,288 @@ +{ + "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": 31, + "column": 18, + "endLine": 31, + "endColumn": 35, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 3, + "endLine": 16, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 6, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 6, + "endLine": 21, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Consume\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 34, + "endLine": 21, + "endColumn": 42, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Resource\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 6, + "endLine": 23, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Consume\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 32, + "endLine": 29, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$rawfile\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 11, + "endLine": 31, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Select\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 24, + "endLine": 34, + "endColumn": 26, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 27, + "endLine": 35, + "endColumn": 29, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 41, + "endLine": 36, + "endColumn": 43, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 33, + "endLine": 37, + "endColumn": 35, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 11, + "endLine": 44, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Circle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 28, + "endLine": 45, + "endColumn": 30, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 65, + "endLine": 45, + "endColumn": 67, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 26, + "endLine": 48, + "endColumn": 35, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 35, + "endLine": 50, + "endColumn": 41, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Margin\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 9, + "endLine": 52, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 14, + "endLine": 52, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 22, + "endLine": 53, + "endColumn": 24, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 21, + "endLine": 54, + "endColumn": 23, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 22, + "endLine": 56, + "endColumn": 31, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 25, + "endLine": 59, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 66, + "endLine": 59, + "endColumn": 71, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 84, + "endLine": 59, + "endColumn": 86, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" 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/arkui-select.ets.json b/ets2panda/linter/test/main/arkui-select.ets.json new file mode 100644 index 0000000000..ca88f857e9 --- /dev/null +++ b/ets2panda/linter/test/main/arkui-select.ets.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 diff --git a/ets2panda/linter/test/main/avoid_using_union_types.ets b/ets2panda/linter/test/main/avoid_using_union_types.ets index da1290b868..9b96d9dc4b 100644 --- a/ets2panda/linter/test/main/avoid_using_union_types.ets +++ b/ets2panda/linter/test/main/avoid_using_union_types.ets @@ -44,4 +44,10 @@ class E { tt() {} } let ab: D|E = new D(); -ab.tt(); \ No newline at end of file +ab.tt(); + +declare interface TextPickerResult { + value: string | string[]; +} +const result: TextPickerResult = { value: 'a' }; +result.value.toString() // no error - ok diff --git a/ets2panda/linter/test/main/builder_node.ets.arkts2.json b/ets2panda/linter/test/main/builder_node.ets.arkts2.json index e6bce3c58b..fa11de342c 100644 --- a/ets2panda/linter/test/main/builder_node.ets.arkts2.json +++ b/ets2panda/linter/test/main/builder_node.ets.arkts2.json @@ -294,6 +294,26 @@ "rule": "The ArkUI interface \"UIContext\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, + { + "line": 75, + "column": 31, + "endLine": 75, + "endColumn": 42, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 31, + "endLine": 77, + "endColumn": 42, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, { "line": 111, "column": 2, diff --git a/ets2panda/linter/test/main/class_static_init.ets b/ets2panda/linter/test/main/class_static_init.ets index c74ec693d9..05149dab13 100644 --- 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/call_expression_matching_argument.ets b/ets2panda/linter/test/main/destructuring_object_property_name.ets similarity index 37% rename from ets2panda/linter/test/main/call_expression_matching_argument.ets rename to ets2panda/linter/test/main/destructuring_object_property_name.ets index 08c34d7682..d6c9d7b8b0 100644 --- a/ets2panda/linter/test/main/call_expression_matching_argument.ets +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets @@ -13,58 +13,19 @@ * limitations under the License. */ -interface A { - value: string; -} - -interface Outer { - inner: A -} - -interface No { - inner: string -} - -class Test { - sv1: number = 1 - sv2: string = "some Value"; - sv3: boolean = true; - sv4: A = { value: "something" } - sv5: Outer = { inner: sv4 } - sv6: No = { inner: sv2 } - sv7: Array = [sv2, sv2, sv2]; - - someMethod() { - func(this.sv2) //error - func(this.sv4) //valid - func(this.sv6.inner) // error - func(this.sv5.inner) //valid - func2(this.sv2) //valid - func2(this.sv4) //valid - func3(this.sv2) //valid - func4(this.sv2, this.sv1) //valid - func5(this.sv7) //valid - } -} - - -function func(param: A) { - console.log(A); -} - -function func2(param: A | any) { - console.log(param); -} - -function func3(param: string | Promise) { - console.log(param); -} - -function func4(param: string, param2: any[]) { - console.log(param, ...param2); -} - -function func5(param: Array) { - param.forEach(elem => console.log(elem)) -} - +let obj = { + a: 1, + '2': 2, + 3: 3, + ['d']: 4 +}; + +let { a, a: a2 } = obj; // OK +let { '2': b } = obj; // Not fixable, support only identifiers as property names +let { 3: c } = obj; // Not fixable, support only identifiers as property names +let { ['d']: d } = obj; // Not fixable, support only identifiers as property names + +({ a, a: a2 } = obj); // OK +({ '2': b } = obj); // Not fixable, support only identifiers as property names +({ 3: c } = obj); // Not fixable, support only identifiers as property names +({ ['d']: d } = obj); // Not fixable, support only identifiers as property names \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_object_property_name.ets.args.json b/ets2panda/linter/test/main/destructuring_object_property_name.ets.args.json new file mode 100644 index 0000000000..12b3ca8dec --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets.args.json @@ -0,0 +1,20 @@ +{ + "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." + ], + "mode": { + "autofix": "", + "migrate": "" + } +} diff --git a/ets2panda/linter/test/main/destructuring_object_property_name.ets.autofix.json b/ets2panda/linter/test/main/destructuring_object_property_name.ets.autofix.json new file mode 100644 index 0000000000..8fe52e532a --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets.autofix.json @@ -0,0 +1,150 @@ +{ + "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": 16, + "column": 11, + "endLine": 16, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 4, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "autofix": [ + { + "replacementText": "let a2 = obj.a;\n", + "start": 658, + "end": 681, + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 19, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 2, + "endLine": 28, + "endColumn": 20, + "problem": "DestructuringAssignment", + "autofix": [ + { + "replacementText": "a2 = obj.a;\n", + "start": 932, + "end": 953, + "line": 28, + "column": 2, + "endLine": 28, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 2, + "endLine": 29, + "endColumn": 18, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 2, + "endLine": 30, + "endColumn": 16, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 4, + "endLine": 30, + "endColumn": 5, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 2, + "endLine": 31, + "endColumn": 20, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_object_property_name.ets.json b/ets2panda/linter/test/main/destructuring_object_property_name.ets.json new file mode 100644 index 0000000000..9e2606ae35 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets.json @@ -0,0 +1,128 @@ +{ + "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": 16, + "column": 11, + "endLine": 16, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 4, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 19, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 2, + "endLine": 28, + "endColumn": 20, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 2, + "endLine": 29, + "endColumn": 18, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 2, + "endLine": 30, + "endColumn": 16, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 4, + "endLine": 30, + "endColumn": 5, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 2, + "endLine": 31, + "endColumn": 20, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.ets b/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.ets new file mode 100644 index 0000000000..5c72f5222f --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.ets @@ -0,0 +1,33 @@ +/* + * 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. + */ + +let obj = { + a: 1, + '2': 2, + 3: 3, + ['d']: 4 +}; + +let a2 = obj.a; + // OK +let { '2': b } = obj; // Not fixable, support only identifiers as property names +let { 3: c } = obj; // Not fixable, support only identifiers as property names +let { ['d']: d } = obj; // Not fixable, support only identifiers as property names + +a2 = obj.a; + // OK +({ '2': b } = obj); // Not fixable, support only identifiers as property names +({ 3: c } = obj); // Not fixable, support only identifiers as property names +({ ['d']: d } = obj); // Not fixable, support only identifiers as property names \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.json b/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.json new file mode 100644 index 0000000000..f816a019b5 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.json @@ -0,0 +1,108 @@ +{ + "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": 16, + "column": 11, + "endLine": 16, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 4, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 19, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 2, + "endLine": 31, + "endColumn": 18, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 16, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 4, + "endLine": 32, + "endColumn": 5, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 2, + "endLine": 33, + "endColumn": 20, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/incompatible_function.ets b/ets2panda/linter/test/main/incompatible_function.ets index 4330949c71..1701ac0932 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets +++ b/ets2panda/linter/test/main/incompatible_function.ets @@ -134,4 +134,70 @@ class E { Dfun(a: X|Y): X { return a; } +} + +import { Entry, Text, Column, Component, Button, ClickEvent ,Image ,ShadowOptions} from '@ohos.arkui.component' +import { State } from '@ohos.arkui.stateManagement' +import hilog from '@ohos.hilog' +import util from '@ohos.util'; + +@Entry +@Component +struct MyStateSample { + @State stateVar: string = 'state var'; + message: string = 'var'; + + changeValue() { + this.getUIContext(); + this.stateVar += '~' + } + + build() { + Column(undefined) { + Text('Hello World').fontSize(20) + Button(this.message).backgroundColor('#FFFF00FF') + .onClick(async (e: ClickEvent) => { + let lock: AsyncLock = AsyncLock.request("lock_1"); + hilog.info(0x0000, 'testTag', 'On Click'); + let a = this.getUIContext(); + this.changeValue(); + + }) + Text(this.stateVar).fontSize(20) + .onClick((e: ClickEvent) => { + this.message += "~" + } as (event: ClickEvent) => void) + Child({ stateVar: this.stateVar }) + } + } +} + +interface CustomClickable { + onClick(handler: (event: ClickEvent) => void): this; +} + +function onClick(handler: (event: ClickEvent) => void): this { + return this.onClick((e: ClickEvent) => { + console.log('Before custom onClick'); + handler(e); + console.log('After custom onClick'); + }); +} + +// 将扩展方法附加到Button组件 +Button.extend({ onClick }); + +@Entry +@Component +struct MyComponent { + @State message: string = 'Click me'; + + build() { + Column() { + Button(this.message) + .onClick((e: ClickEvent) => { + this.message = 'Custom onClick worked!'; + }) + } + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json b/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json index 31c19f7df3..5b2f2475b0 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json +++ b/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json @@ -123,6 +123,106 @@ "suggest": "", "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" + }, + { + "line": 139, + "column": 1, + "endLine": 139, + "endColumn": 112, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 1, + "endLine": 140, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 1, + "endLine": 141, + "endColumn": 32, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 1, + "endLine": 142, + "endColumn": 31, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 159, + "column": 18, + "endLine": 165, + "endColumn": 10, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 15, + "endLine": 162, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 37, + "endLine": 169, + "endColumn": 41, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 50, + "endLine": 176, + "endColumn": 54, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 10, + "endLine": 180, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 57, + "endLine": 179, + "endColumn": 61, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/incompatible_function.ets.json b/ets2panda/linter/test/main/incompatible_function.ets.json index 2844fc25ba..e2e1afdc24 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets.json +++ b/ets2panda/linter/test/main/incompatible_function.ets.json @@ -13,5 +13,96 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 139, + "column": 1, + "endLine": 139, + "endColumn": 112, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 1, + "endLine": 140, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 1, + "endLine": 141, + "endColumn": 32, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 1, + "endLine": 142, + "endColumn": 31, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 159, + "column": 18, + "endLine": 165, + "endColumn": 10, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 15, + "endLine": 162, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 50, + "endLine": 176, + "endColumn": 54, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 10, + "endLine": 180, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 57, + "endLine": 179, + "endColumn": 61, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_5.ets.arkts2.json index ab357ad279..b4edf8e90e 100644 --- a/ets2panda/linter/test/main/interface_import_5.ets.arkts2.json +++ b/ets2panda/linter/test/main/interface_import_5.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 46, "problem": "NoDeprecatedApi", "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getContext\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/interface_import_5.ets.autofix.json b/ets2panda/linter/test/main/interface_import_5.ets.autofix.json index 0c7503cb10..1970edd683 100644 --- a/ets2panda/linter/test/main/interface_import_5.ets.autofix.json +++ b/ets2panda/linter/test/main/interface_import_5.ets.autofix.json @@ -32,7 +32,7 @@ } ], "suggest": "", - "rule": "ArkUI deprecated api check (arkui-no-deprecated-api)", + "rule": "The ArkUI interface \"getContext\" is deprecated (arkui-deprecated-interface)", "severity": "ERROR" }, { 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 100644 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/call_expression_matching_argument.ets.json b/ets2panda/linter/test/main/large_numeric_literal.ets.json similarity index 55% rename from ets2panda/linter/test/main/call_expression_matching_argument.ets.json rename to ets2panda/linter/test/main/large_numeric_literal.ets.json index f864fd1cc3..24907755d1 100644 --- a/ets2panda/linter/test/main/call_expression_matching_argument.ets.json +++ b/ets2panda/linter/test/main/large_numeric_literal.ets.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", + "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", @@ -15,23 +15,13 @@ ], "result": [ { - "line": 55, - "column": 27, - "endLine": 55, - "endColumn": 30, - "problem": "AnyType", + "line": 62, + "column": 18, + "endLine": 62, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 39, - "endLine": 63, - "endColumn": 42, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets b/ets2panda/linter/test/main/no_ts_like_smart_type.ets index 1c858dc1e1..78878b39c2 100644 --- a/ets2panda/linter/test/main/no_ts_like_smart_type.ets +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets @@ -231,4 +231,22 @@ export class N extends T { toString(): string { return this._t // legal } -} \ No newline at end of file +} + +type AsyncCB = () => T | Promise; + +class AsyncLock { + lockAsync(callback: AsyncCB): Promise { + } +} + +export class AB { + private count_: number = 0 + public lock_: AsyncLock = new AsyncLock(); + + public async getCount(): Promise { + return this.lock_.lockAsync(() => { + return this.count_; //legal + }) + } +} \ No newline at end of file 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/call_expression_matching_argument.ets.arkts2.json b/ets2panda/linter/test/main/optional_tuple_type.ets.arkts2.json similarity index 46% rename from ets2panda/linter/test/main/call_expression_matching_argument.ets.arkts2.json rename to ets2panda/linter/test/main/optional_tuple_type.ets.arkts2.json index 00147aa392..9be7efa7bf 100644 --- a/ets2panda/linter/test/main/call_expression_matching_argument.ets.arkts2.json +++ b/ets2panda/linter/test/main/optional_tuple_type.ets.arkts2.json @@ -15,43 +15,53 @@ ], "result": [ { - "line": 38, - "column": 14, - "endLine": 38, - "endColumn": 22, - "problem": "StructuralIdentity", + "line": 19, + "column": 36, + "endLine": 19, + "endColumn": 43, + "problem": "OptionalTupleType", "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", "severity": "ERROR" }, { - "line": 40, - "column": 14, - "endLine": 40, - "endColumn": 28, - "problem": "StructuralIdentity", + "line": 22, + "column": 46, + "endLine": 22, + "endColumn": 53, + "problem": "OptionalTupleType", "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", "severity": "ERROR" }, { - "line": 55, - "column": 27, - "endLine": 55, - "endColumn": 30, - "problem": "AnyType", + "line": 26, + "column": 18, + "endLine": 26, + "endColumn": 25, + "problem": "OptionalTupleType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", "severity": "ERROR" }, { - "line": 63, - "column": 39, - "endLine": 63, - "endColumn": 42, - "problem": "AnyType", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 33, + "problem": "OptionalTupleType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "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" } ] 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 diff --git a/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets new file mode 100644 index 0000000000..6f7975af87 --- /dev/null +++ b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets @@ -0,0 +1,123 @@ +/* + * 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. + */ + +// --------------------- +// Shared types +// --------------------- +interface IA { + value: number; + name?: string; +} + +interface IB { + value: number; +} + +class CA { + value: number = 1; +} + +class CB { + value: number = 1; +} + +// --------------------- +// Allowed Cases +// --------------------- + +// ----------- Allowed: simple type, no union ------------- +let ok1: IA = { value: 1 }; // OK — no union + +// ----------- Allowed: nullish unions -------------------- +let ok2: IA | null = { value: 1 }; // OK — null union +let ok3: IA | undefined = { value: 1 }; // OK — undefined union +let ok4: IA | null | undefined = { value: 1 }; // OK — null + undefined union + +// ----------- Allowed: casted unions ------------------------ +let ok5: IA | IB = { value: 1 } as IA; // OK — explicit cast + +// ----------- Built-in lib.* guard: should be allowed -------------------- +let ok6: Record | object[] = {}; // OK — both are lib.* types +let ok7: Promise | string[] = {}; // OK — Promise and Array are from lib.* + +// ----------- Other allowed scenarios --------------------- + +// Using 'as' cast +function ok8(): IA | CB { + return { value: 1 } as IA; // ok +} + +// Passing nullish or undefined unions — allowed +function ok9(a: IA | null | undefined) {} +ok9({ value: 42 }); // ok + +// Passing a variable declared as IA +const objIA: IA = { value: 1 }; +function ok10(a: IA | IB) { + console.log(a.value); +} +ok10(objIA); // ok + +// --------------------- +// Disallowed Cases +// --------------------- + +// ----------- Disallowed: simple union of interface + interface ------------ +let fail1: IA | IB = { value: 1 }; // ❌ Error — object literal into interface union + +// ----------- Disallowed: interface + class ----------------- +let fail2: IA | CA = { value: 1 }; // ❌ Error + +// ----------- Disallowed: simple union of class + class ------------------ +let fail3: CA | CB = { value: 1 }; // ❌ Error + +// ----------- Disallowed: with nullish in mixed but still failing -------------------- +let fail4: IA | IB | undefined = { value: 1 }; // ❌ Error — nullish doesn’t save it here + +// ----------- Disallowed: function return types --------------------- + +// Return object literal to interface|interface without cast +function err1(): IA | IB { + return { value: 1 }; // ❌ error +} + +// Return object literal to class|interface without cast +function err2(): CB | IA { + return { value: 1 }; // ❌ error +} + +// ----------- Disallowed: function param passing --------------------- + +// Pass object literal to interface|interface param without cast +function err3(a: IA | IB) { + console.log(a.value); +} +err3({ value: 42 }); // ❌ error + +// Pass object literal to class|class param without cast +function err4(a: CA | CB) { + console.log(a.value); +} +err4({ value: 10 }); // ❌ error + +// Mixed interface|class param without cast +function err5(a: IA | CB) { + console.log(a.value); +} +err5({ value: 5 }); // ❌ error + +// Nested in union with undefined — still error +function err6(a: IA | CB | undefined) {} +err6({ value: 99 }); // ❌ error diff --git a/ets2panda/linter/test/main/call_expression_matching_argument.ets.args.json b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.args.json similarity index 100% rename from ets2panda/linter/test/main/call_expression_matching_argument.ets.args.json rename to ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.args.json diff --git a/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.arkts2.json b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.arkts2.json new file mode 100644 index 0000000000..a5200e79a8 --- /dev/null +++ b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.arkts2.json @@ -0,0 +1,138 @@ +{ + "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": 53, + "column": 18, + "endLine": 53, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 36, + "endLine": 53, + "endColumn": 37, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 22, + "endLine": 78, + "endColumn": 34, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 22, + "endLine": 81, + "endColumn": 34, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 22, + "endLine": 84, + "endColumn": 34, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 34, + "endLine": 87, + "endColumn": 46, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 10, + "endLine": 93, + "endColumn": 22, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 10, + "endLine": 98, + "endColumn": 22, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 6, + "endLine": 107, + "endColumn": 19, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 6, + "endLine": 113, + "endColumn": 19, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 6, + "endLine": 119, + "endColumn": 18, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 6, + "endLine": 123, + "endColumn": 19, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.json b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.json new file mode 100644 index 0000000000..63a94f9a39 --- /dev/null +++ b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.json @@ -0,0 +1,38 @@ +{ + "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": 53, + "column": 18, + "endLine": 53, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 36, + "endLine": 53, + "endColumn": 37, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.arkts2.json b/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.arkts2.json index 211ffc2630..e81fd481df 100644 --- a/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.arkts2.json @@ -134,6 +134,16 @@ "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, + { + "line": 22, + "column": 59, + "endLine": 22, + "endColumn": 70, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, { "line": 23, "column": 24, @@ -144,6 +154,16 @@ "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, + { + "line": 23, + "column": 59, + "endLine": 23, + "endColumn": 70, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, { "line": 24, "column": 24, diff --git a/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.arkts2.json b/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.arkts2.json index 2b9f863f55..a9ac9aae35 100644 --- a/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.arkts2.json @@ -254,6 +254,26 @@ "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, + { + "line": 29, + "column": 58, + "endLine": 29, + "endColumn": 69, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 82, + "endLine": 29, + "endColumn": 93, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, { "line": 30, "column": 20, @@ -264,6 +284,26 @@ "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, + { + "line": 30, + "column": 58, + "endLine": 30, + "endColumn": 69, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 100, + "endLine": 30, + "endColumn": 111, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, { "line": 31, "column": 20, -- Gitee