diff --git a/arkui-plugins/ui-syntax-plugins/rules/check-decorated-property-type.ts b/arkui-plugins/ui-syntax-plugins/rules/check-decorated-property-type.ts index e3d8f3446e02765464ef4d452751bcf75a36ce80..90c6a82eda041ef9e6a4a36cd1651ab4c8f68e70 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/check-decorated-property-type.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/check-decorated-property-type.ts @@ -23,15 +23,14 @@ import { const forbiddenUseStateTypeForDecorators: string[] = [ PresetDecorators.STATE, - PresetDecorators.PROP, + PresetDecorators.PROP_REF, PresetDecorators.LINK, PresetDecorators.PROVIDE, PresetDecorators.CONSUME, PresetDecorators.OBJECT_LINK, PresetDecorators.BUILDER_PARAM, - PresetDecorators.STORAGE_PROP, + PresetDecorators.STORAGE_PROP_REF, PresetDecorators.STORAGE_LINK, - PresetDecorators.LOCAL_STORAGE_PROP, PresetDecorators.LOCAL_STORAGE_LINK, ]; @@ -49,10 +48,6 @@ class CheckDecoratedPropertyTypeRule extends AbstractUISyntaxRule { if (!node.definition) { return; } - const componentDecorator = getAnnotationUsage(node, PresetDecorators.COMPONENT_V1); - if (!componentDecorator) { - return; - } node.definition.body.forEach(member => { this.checkDecoratedPropertyType(member, forbiddenUseStateTypeForDecorators, forbiddenUseStateType); }); diff --git a/arkui-plugins/ui-syntax-plugins/rules/component-componentV2-mix-use-check.ts b/arkui-plugins/ui-syntax-plugins/rules/component-componentV2-mix-use-check.ts index 6a1a271f815a3b30915018a8ff375d0f2e11cd00..70714c3b382345f43e170d7754cb75833dae0bbf 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/component-componentV2-mix-use-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/component-componentV2-mix-use-check.ts @@ -19,14 +19,13 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; const v1ComponentDecorators: string[] = [ PresetDecorators.STATE, - PresetDecorators.PROP, + PresetDecorators.PROP_REF, PresetDecorators.LINK, PresetDecorators.PROVIDE, PresetDecorators.CONSUME, PresetDecorators.STORAGE_LINK, - PresetDecorators.STORAGE_PROP, + PresetDecorators.STORAGE_PROP_REF, PresetDecorators.LOCAL_STORAGE_LINK, - PresetDecorators.LOCAL_STORAGE_PROP, ]; class ComponentComponentV2MixUseCheckRule extends AbstractUISyntaxRule { diff --git a/arkui-plugins/ui-syntax-plugins/rules/componentV2-state-usage-validation.ts b/arkui-plugins/ui-syntax-plugins/rules/componentV2-state-usage-validation.ts index 17c4bc4fc57617136ef3b1fe43f4aba3ba86a4fa..3aec12a85ba3d86f789b8d80e5c3f63270e9ee09 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/componentV2-state-usage-validation.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/componentV2-state-usage-validation.ts @@ -30,7 +30,7 @@ class ComponentV2StateUsageValidationRule extends AbstractUISyntaxRule { public setup(): Record { return { - multipleBuiltInDecorators: `The member property or method cannot be decorated by multiple built-in decorators.`, + multipleBuiltInDecorators: `The member property or method cannot be decorated by multiple built-in annotations.`, paramRequiresRequire: `When a variable decorated with '@Param' is not assigned a default value, it must also be decorated with '@Require'.`, requireOnlyWithParam: `In a struct decorated with '@ComponentV2', '@Require' can only be used with '@Param' or '@BuilderParam'.`, localNeedNoInit: `The '{{decoratorName}}' property '{{key}}' in the custom component '{{componentName}}' cannot be initialized here (forbidden to specify).`, diff --git a/arkui-plugins/ui-syntax-plugins/rules/computed-decorator-check.ts b/arkui-plugins/ui-syntax-plugins/rules/computed-decorator-check.ts index e47c33e7ffbe2c580f22ce86d51cc56fa94d5731..f48e5fa94073818d1bcabe9def55e143992d06b7 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/computed-decorator-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/computed-decorator-check.ts @@ -26,7 +26,7 @@ class ComputedDecoratorCheckRule extends AbstractUISyntaxRule { return { onlyOnGetter: `@Computed can only decorate 'GetAccessor'.`, onlyInObservedV2: `The '@Computed' can decorate only member method within a 'class' decorated with ObservedV2.`, - componentV2InStruct: `The '@Computed' decorator can only be used in a 'struct' decorated with ComponentV2.`, + componentV2InStruct: `The '@Computed' annotation can only be used in a 'struct' decorated with ComponentV2.`, noTwoWayBinding: `A property decorated by '@Computed' cannot be used with two-way bind syntax.`, computedMethodDefineSet: `A property decorated by '@Computed' cannot define a set method.` }; diff --git a/arkui-plugins/ui-syntax-plugins/rules/construct-parameter.ts b/arkui-plugins/ui-syntax-plugins/rules/construct-parameter.ts index 05e71cf2a59e22892af3c0892fc632374f6c01e9..9a4d5695c7fa398390b6991e3c00273a671646b3 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/construct-parameter.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/construct-parameter.ts @@ -27,7 +27,7 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; const disallowAssignedDecorators: string[] = [ PresetDecorators.REGULAR, PresetDecorators.LINK, PresetDecorators.OBJECT_LINK, PresetDecorators.BUILDER_PARAM, PresetDecorators.BUILDER, PresetDecorators.STATE, - PresetDecorators.PROP, PresetDecorators.PROVIDE, PresetDecorators.CONSUME, + PresetDecorators.PROP_REF, PresetDecorators.PROVIDE, PresetDecorators.CONSUME, PresetDecorators.BUILDER, ]; // The decorator structure prohibits initializing the assignment list @@ -35,15 +35,14 @@ const restrictedDecoratorInitializations: Map = new Map([ [PresetDecorators.REGULAR, [PresetDecorators.OBJECT_LINK, PresetDecorators.LINK]], [PresetDecorators.PROVIDE, [PresetDecorators.REGULAR]], [PresetDecorators.CONSUME, [PresetDecorators.REGULAR]], - [PresetDecorators.STORAGE_PROP, [PresetDecorators.REGULAR]], + [PresetDecorators.STORAGE_PROP_REF, [PresetDecorators.REGULAR]], [PresetDecorators.VARIABLE, [PresetDecorators.LINK]], [PresetDecorators.LOCAL_STORAGE_LINK, [PresetDecorators.REGULAR]], - [PresetDecorators.LOCAL_STORAGE_PROP, [PresetDecorators.REGULAR]], ]); // When there are multiple Decorators, filter out the Decorators that are not relevant to the rule const decoratorsFilter: string[] = [ - PresetDecorators.PROVIDE, PresetDecorators.CONSUME, PresetDecorators.STORAGE_PROP, - PresetDecorators.LOCAL_STORAGE_LINK, PresetDecorators.LOCAL_STORAGE_PROP, PresetDecorators.BUILDER_PARAM, + PresetDecorators.PROVIDE, PresetDecorators.CONSUME, PresetDecorators.STORAGE_PROP_REF, + PresetDecorators.LOCAL_STORAGE_LINK, PresetDecorators.BUILDER_PARAM, ]; class ConstructParameterRule extends AbstractUISyntaxRule { @@ -207,7 +206,7 @@ class ConstructParameterRule extends AbstractUISyntaxRule { return; } if (arkts.isIdentifier(property.value) && this.regularVariableList.includes(property.value.name)) { - this.context.report({ + this.report({ node: property, message: this.messages.constructParameter, data: { @@ -241,7 +240,7 @@ class ConstructParameterRule extends AbstractUISyntaxRule { if (arkts.isIdentifier(property.value)) { isBuilder = this.builderFunctionList.includes(property.value.name); if (this.builderFunctionList.includes(property.value.name) && childType !== PresetDecorators.BUILDER_PARAM) { - this.context.report({ + this.report({ node: property, message: this.messages.initializerIsBuilder, data: { @@ -252,7 +251,7 @@ class ConstructParameterRule extends AbstractUISyntaxRule { } } if (childType === PresetDecorators.BUILDER_PARAM && !isBuilder && !isBuilderInStruct) { - this.context.report({ + this.report({ node: property, message: this.messages.parameterIsBuilderParam, data: { @@ -298,7 +297,7 @@ class ConstructParameterRule extends AbstractUISyntaxRule { } if (restrictedDecoratorInitializations.has(parentType) && restrictedDecoratorInitializations.get(parentType)!.includes(childType)) { - this.context.report({ + this.report({ node: property, message: this.messages.constructParameter, data: { diff --git a/arkui-plugins/ui-syntax-plugins/rules/consumer-provider-decorator-check.ts b/arkui-plugins/ui-syntax-plugins/rules/consumer-provider-decorator-check.ts index a16e30adb9a2cd798b7e153ed9797277abac0592..740655e1c4457749878684dab850fcec2b94efff 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/consumer-provider-decorator-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/consumer-provider-decorator-check.ts @@ -24,8 +24,8 @@ class ConsumerProviderDecoratorCheckRule extends AbstractUISyntaxRule { public setup(): Record { return { providerAndConsumerOnlyOnProperty: `'@{{decorator}}' can only decorate member property.`, - multipleBuiltInDecorators: `The struct member variable can not be decorated by multiple built-in decorators.`, - providerAndConsumerOnlyInStruct: `The '@{{decorator}}' decorator can only be used with 'struct'.`, + multipleBuiltInDecorators: `The struct member variable can not be decorated by multiple built-in annotations.`, + providerAndConsumerOnlyInStruct: `The '@{{decorator}}' annotation can only be used with 'struct'.`, forbiddenInitialization: `The '@{{decorator}}' property '{{value}}' in the custom component '{{structName}}' cannot be initialized here (forbidden to specify).`, }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/entry-localstorage-check.ts b/arkui-plugins/ui-syntax-plugins/rules/entry-localstorage-check.ts index 118755b8c0907443feb34d8eade4e7a6dae0bfb9..366cbc1da4df40f6250bb9f168fb22717d205891 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/entry-localstorage-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/entry-localstorage-check.ts @@ -44,7 +44,7 @@ class EntryLocalStorageCheckRule extends AbstractUISyntaxRule { const propertyDecorators = getClassPropertyAnnotationNames(body); localStorageLinkUsed = propertyDecorators.some( decorator => decorator === PresetDecorators.LOCAL_STORAGE_LINK || - decorator === PresetDecorators.LOCAL_STORAGE_PROP); + decorator === PresetDecorators.STORAGE_PROP_REF); }); // If @LocalStorageLink is used but @Entry(storage) is missing, report error diff --git a/arkui-plugins/ui-syntax-plugins/rules/entry-struct-no-export.ts b/arkui-plugins/ui-syntax-plugins/rules/entry-struct-no-export.ts index 2802a8c0be4616a24834dce6cc2fbd24fab436f8..0bd71b7c732f221a3c47bda827c3165e3d20080d 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/entry-struct-no-export.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/entry-struct-no-export.ts @@ -20,7 +20,7 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; class EntryStructNoExportRule extends AbstractUISyntaxRule { public setup(): Record { return { - noExportWithEntry: `It's not a recommended way to export struct with '@Entry' decorator, which may cause ACE Engine error in component preview mode.`, + noExportWithEntry: `It's not a recommended way to export struct with '@Entry' annotation, which may cause ACE Engine error in component preview mode.`, }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/index.ts b/arkui-plugins/ui-syntax-plugins/rules/index.ts index 7e171a4a5a694bddda9f21741cd2dbfafebd1948..2a2aacc9f48de2637df26a63268b97c684776816 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/index.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/index.ts @@ -33,18 +33,15 @@ import MonitorDecoratorCheckRule from './monitor-decorator-check'; import NestedRelationshipRule from './nested-relationship'; import NestedReuseComponentCheckRule from './nested-reuse-component-check'; import NoChildInButtonRule from './no-child-in-button'; -import NoDuplicateDecoratorsRule from './no-duplicate-decorators'; import NoDuplicateEntryRule from './no-duplicate-entry'; import NoDuplicateIdRule from './no-duplicate-id'; import NoDuplicatePreviewRule from './no-duplicate-preview'; -import NoDuplicateStateManagerRule from './no-duplicate-state-manager'; import NoPropLinkObjectLinkInEntryRule from './no-prop-link-objectlink-in-entry'; import NoSameAsBuiltInAttributeRule from './no-same-as-built-in-attribute'; import ReuseAttributeCheckRule from './reuse-attribute-check'; import StructMissingDecoratorRule from './struct-missing-decorator'; import StructPropertyDecoratorRule from './struct-property-decorator'; import TrackDecoratorCheckRule from './track-decorator-check'; -import TypeDecoratorCheckRule from './type-decorator-check'; import ValidateBuildInStructRule from './validate-build-in-struct'; import WrapBuilderCheckRule from './wrap-builder-check'; import StructPropertyOptionalRule from './struct-property-optional'; @@ -87,18 +84,15 @@ const rules: Array = [ [NestedRelationshipRule, 'error'], [NestedReuseComponentCheckRule, 'error'], [NoChildInButtonRule, 'error'], - [NoDuplicateDecoratorsRule, 'warn'], [NoDuplicateEntryRule, 'error'], [NoDuplicateIdRule, 'warn'], [NoDuplicatePreviewRule, 'error'], - [NoDuplicateStateManagerRule, 'error'], [NoPropLinkObjectLinkInEntryRule, 'warn'], [NoSameAsBuiltInAttributeRule, 'error'], [ReuseAttributeCheckRule, 'error'], [StructMissingDecoratorRule, 'error'], [StructPropertyDecoratorRule, 'error'], [TrackDecoratorCheckRule, 'error'], - [TypeDecoratorCheckRule, 'error'], [ValidateBuildInStructRule, 'error'], [WrapBuilderCheckRule, 'error'], [StructPropertyOptionalRule, 'warn'], diff --git a/arkui-plugins/ui-syntax-plugins/rules/main-pages-entry-check.ts b/arkui-plugins/ui-syntax-plugins/rules/main-pages-entry-check.ts index 198852e073a158a12f78b8fd54249d76e8b185e2..d055b748fd80130234d418d63545361d6d1596ac 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/main-pages-entry-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/main-pages-entry-check.ts @@ -20,7 +20,7 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; class MainPagesEntryCheckRule extends AbstractUISyntaxRule { public setup(): Record { return { - mainPagesEntryCheck: `A page configured in 'main_pages. json or build-profile. json5' must have one and only one '@Entry' decorator. ` + mainPagesEntryCheck: `A page configured in 'main_pages. json or build-profile. json5' must have one and only one '@Entry' annotation. ` }; } public parsed(node: arkts.StructDeclaration): void { diff --git a/arkui-plugins/ui-syntax-plugins/rules/monitor-decorator-check.ts b/arkui-plugins/ui-syntax-plugins/rules/monitor-decorator-check.ts index a096d26da0189e931edb5e16e420a2d584806c7d..47c3053d5e13f156ed58803dff7455f10e88b44d 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/monitor-decorator-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/monitor-decorator-check.ts @@ -23,14 +23,14 @@ class MonitorDecoratorCheckRule extends AbstractUISyntaxRule { public setup(): Record { return { monitorUsedAlone: - `The member property or method can not be decorated by multiple built-in decorators.`, + `The member property or method can not be decorated by multiple built-in annotations.`, monitorUsedInObservedV2Class: `The '@Monitor' can decorate only member method within a 'class' decorated with @ObservedV2.`, monitorUsedInComponentV2Struct: - `The '@Monitor' decorator can only be used in a 'struct' decorated with '@ComponentV2'.`, + `The '@Monitor' annotation can only be used in a 'struct' decorated with '@ComponentV2'.`, monitorDecorateMethod: `@Monitor can only decorate method.`, - duplicatedMonitor: `Duplicate decorators for method are not allowed.`, + duplicatedMonitor: `Duplicate annotations for method are not allowed.`, }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/nested-reuse-component-check.ts b/arkui-plugins/ui-syntax-plugins/rules/nested-reuse-component-check.ts index 16fbec2976fecaee037acd7b252c817656359c3d..62f109253ea5b5f661f2f4e4fb3f985784a20298 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/nested-reuse-component-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/nested-reuse-component-check.ts @@ -49,7 +49,7 @@ class NestedReuseComponentCheckRule extends AbstractUISyntaxRule { for (const childNode of node.getChildren()) { // Check whether the type is struct if (!arkts.isStructDeclaration(childNode)) { - return; + continue; } // Get a list of annotations const annotationsList = childNode.definition.annotations; diff --git a/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-decorators.ts b/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-decorators.ts deleted file mode 100644 index 8277b9facf85aa813e7d9246e8272d8eeff7e280..0000000000000000000000000000000000000000 --- a/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-decorators.ts +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as arkts from '@koalaui/libarkts'; -import { getAnnotationName, PresetDecorators } from '../utils'; -import { AbstractUISyntaxRule } from './ui-syntax-rule'; - -//Unsupported decorators -const unsupportedDecorators = [ - PresetDecorators.ENTRY, - PresetDecorators.PREVIEW, -]; - -class NoDuplicateDecoratorsRule extends AbstractUISyntaxRule { - public setup(): Record { - return { - duplicateFunctionDecorators: `Duplicate '{{decoratorName}}' decorators for function are not allowed.`, - duplicateMethodDecorators: `Duplicate '{{decoratorName}}' decorators for method are not allowed.`, - duplicateStructDecorators: `Duplicate '{{decoratorName}}' decorators for struct are not allowed.`, - }; - } - - public parsed(node: arkts.AstNode): void { - if (arkts.isStructDeclaration(node)) { - this.checkForDuplicateStructDecorators(node); - } else if (arkts.isFunctionDeclaration(node)) { - this.checkForDuplicateFunctionDecorators(node); - } else if (arkts.isMethodDefinition(node)) { - this.checkForDuplicateMethodDecorators(node); - } - } - - private checkForDuplicateStructDecorators( - node: arkts.StructDeclaration - ): void { - // Initialize a map to record decorators and their occurrences - const decoratorCounts: Map = new Map(); - if (!node.definition || !node.definition.annotations) { - return; - } - // Record all decorators and their counts - node.definition.annotations.forEach((annotation) => { - const decoratorName = getAnnotationName(annotation); - if (unsupportedDecorators.includes(decoratorName)) { - return; - } - if (decoratorCounts.has(decoratorName)) { - const decoratorInfo = decoratorCounts.get(decoratorName)!; - decoratorInfo.count += 1; - decoratorInfo.annotations.push(annotation); - } else { - decoratorCounts.set(decoratorName, { count: 1, annotations: [annotation] }); - } - }); - - // Process decorators with more than one occurrence - decoratorCounts.forEach(({ count, annotations }, decoratorName) => { - if (count <= 1) { - return; - } - // Report errors for all occurrences except the last one - for (let i = 0; i < annotations.length - 1; i++) { - const prevAnnotation = annotations[i]; - this.reportStructDuplicateDecorator(prevAnnotation, decoratorName); - } - // For the last occurrence, report an error but do not provide a fix - const lastAnnotation = annotations[annotations.length - 1]; - this.report({ - node: lastAnnotation, - message: this.messages.duplicateStructDecorators, - data: { decoratorName }, - }); - }); - } - - private reportStructDuplicateDecorator( - annotation: arkts.AnnotationUsage, - decoratorName: string): void { - this.report({ - node: annotation, - message: this.messages.duplicateStructDecorators, - data: { decoratorName }, - fix: () => { - const startPosition = annotation.startPosition; - const endPosition = annotation.endPosition; - return { - range: [startPosition, endPosition], - code: '', - }; - }, - }); - } - - private checkForDuplicateFunctionDecorators( - functionNode: arkts.FunctionDeclaration - ): void { - const annotations = functionNode.annotations; - if (!annotations || annotations.length <= 1) { - return; - } - const decoratorCounts: Map = new Map(); - for (const annotation of annotations) { - const decoratorName = getAnnotationName(annotation); - if (unsupportedDecorators.includes(decoratorName)) { - continue; - } - if (decoratorCounts.has(decoratorName)) { - const info = decoratorCounts.get(decoratorName)!; - info.count += 1; - info.annotations.push(annotation); - } else { - decoratorCounts.set(decoratorName, { count: 1, annotations: [annotation] }); - } - } - decoratorCounts.forEach(({ count, annotations }, decoratorName) => { - if (count <= 1) { - return; - } - - // Keep the last one and delete the rest - for (let i = 0; i < annotations.length - 1; i++) { - this.reportFunctionDuplicateDecorator(annotations[i], decoratorName); - } - - // The last one doesn't provide a fix - const last = annotations[annotations.length - 1]; - this.report({ - node: last, - message: this.messages.duplicateFunctionDecorators, - data: { decoratorName }, - }); - }); - } - - private reportFunctionDuplicateDecorator( - annotation: arkts.AnnotationUsage, - decoratorName: string): void { - this.report({ - node: annotation, - message: this.messages.duplicateFunctionDecorators, - data: { decoratorName }, - fix: () => { - const startPosition = annotation.startPosition; - const endPosition = annotation.endPosition; - return { - range: [startPosition, endPosition], - code: '', - }; - }, - }); - } - - private checkForDuplicateMethodDecorators( - methodNode: arkts.MethodDefinition - ): void { - const annotations = methodNode.scriptFunction.annotations; - if (!annotations || annotations.length <= 1) { - return; - } - const decoratorCounts: Map = new Map(); - for (const annotation of annotations) { - const decoratorName = getAnnotationName(annotation); - if (unsupportedDecorators.includes(decoratorName)) { - continue; - } - if (decoratorCounts.has(decoratorName)) { - const info = decoratorCounts.get(decoratorName)!; - info.count += 1; - info.annotations.push(annotation); - } else { - decoratorCounts.set(decoratorName, { count: 1, annotations: [annotation] }); - } - } - decoratorCounts.forEach(({ count, annotations }, decoratorName) => { - if (count <= 1) { - return; - } - for (let i = 0; i < annotations.length - 1; i++) { - this.reportMethodDuplicateDecorator(annotations[i], decoratorName); - } - const last = annotations[annotations.length - 1]; - this.report({ - node: last, - message: this.messages.duplicateMethodDecorators, - data: { decoratorName }, - }); - }); - } - - private reportMethodDuplicateDecorator( - annotation: arkts.AnnotationUsage, - decoratorName: string): void { - this.report({ - node: annotation, - message: this.messages.duplicateMethodDecorators, - data: { decoratorName }, - fix: () => { - const startPosition = annotation.startPosition; - const endPosition = annotation.endPosition; - return { - range: [startPosition, endPosition], - code: '', - }; - }, - }); - } -}; - -export default NoDuplicateDecoratorsRule; \ No newline at end of file diff --git a/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-entry.ts b/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-entry.ts index 41e0a71e2ccc0d087652be5e19080dc88b6f6315..fae7ecc973f2b84291aa5248bc7c6d42cdc2dcc2 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-entry.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-entry.ts @@ -23,7 +23,7 @@ class NoDuplicateEntryRule extends AbstractUISyntaxRule { public setup(): Record { return { - duplicateEntry: `A page can't contain more then one '@Entry' decorator.`, + duplicateEntry: `A page can't contain more then one '@Entry' annotation.`, }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-preview.ts b/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-preview.ts index 35326c6d090e0ce6e0512d65498819960e6c2366..746f5dec3ff580aed38184f32ae64fb02877dab2 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-preview.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-preview.ts @@ -23,7 +23,7 @@ class NoDuplicatePreviewRule extends AbstractUISyntaxRule { public setup(): Record { return { - duplicateEntry: `A page can contain at most 10 '@Preview' decorators.`, + duplicateEntry: `A page can contain at most 10 '@Preview' annotations.`, }; } @@ -52,7 +52,11 @@ class NoDuplicatePreviewRule extends AbstractUISyntaxRule { this.reportError(previewDecoratorUsage); }); } else { - this.reportError(this.previewDecoratorUsages.at(this.previewDecoratorUsageIndex)!); + let previewDecoratorUsage = this.previewDecoratorUsages.at(this.previewDecoratorUsageIndex); + if (!previewDecoratorUsage) { + return; + } + this.reportError(previewDecoratorUsage); } this.previewDecoratorUsageIndex++; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-state-manager.ts b/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-state-manager.ts deleted file mode 100644 index e41aebcfcceefbec350f6356620a593e259f5288..0000000000000000000000000000000000000000 --- a/arkui-plugins/ui-syntax-plugins/rules/no-duplicate-state-manager.ts +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as arkts from '@koalaui/libarkts'; -import { getClassPropertyAnnotationNames, getIdentifierName, PresetDecorators, getAnnotationUsage } from '../utils'; -import { AbstractUISyntaxRule } from './ui-syntax-rule'; - -const stateManagementDecorator = { - STATE: PresetDecorators.STATE, - PROP: PresetDecorators.PROP, - LINK: PresetDecorators.LINK, - PROVIDE: PresetDecorators.PROVIDER, - CONSUME: PresetDecorators.CONSUME -}; - -const CLASS_PROPERTY_ANNOTATION_ONE: number = 1; - -class NoDuplicateStateManagerRule extends AbstractUISyntaxRule { - public setup(): Record { - return { - duplicateState: `The property '{{attributeName}}' cannot have multiple state management decorators.`, - }; - } - - public parsed(node: arkts.AstNode): void { - if (!arkts.isStructDeclaration(node)) { - return; - } - - // If it's a struct for @ComponentV2, the check is skipped - const componentV2Decorator = getAnnotationUsage(node, PresetDecorators.COMPONENT_V2); - if (componentV2Decorator) { - return; - } - - this.checkForDuplicateStateDecorators(node); - } - - // Check that the properties in the struct are not reused with state management-related decorators - private checkForDuplicateStateDecorators(node: arkts.StructDeclaration): void { - node.definition.body.forEach((body) => { - if (!arkts.isClassProperty(body)) { - return; - } - - const propertyDecorators = getClassPropertyAnnotationNames(body); - // Filter the decorators to get those related to state management - const stateDecorators = propertyDecorators.filter(decorator => - Object.values(stateManagementDecorator).includes(decorator) - ); - - const propertyNameNode = body.key; - if (!propertyNameNode || !arkts.isIdentifier(propertyNameNode)) { - return; - } - - const attributeName = getIdentifierName(propertyNameNode); - if (stateDecorators.length > CLASS_PROPERTY_ANNOTATION_ONE) { - this.report({ - node: propertyNameNode, - message: this.messages.duplicateState, - data: { attributeName }, - }); - } - }); - } -} - -export default NoDuplicateStateManagerRule; diff --git a/arkui-plugins/ui-syntax-plugins/rules/no-prop-link-objectlink-in-entry.ts b/arkui-plugins/ui-syntax-plugins/rules/no-prop-link-objectlink-in-entry.ts index b9f7772e65a909f06cefea04aa383d1b46771e4c..03eb874d57347139c8c2e36ffc375935805f29fe 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/no-prop-link-objectlink-in-entry.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/no-prop-link-objectlink-in-entry.ts @@ -17,7 +17,7 @@ import * as arkts from '@koalaui/libarkts'; import { getAnnotationUsage, PresetDecorators } from '../utils'; import { AbstractUISyntaxRule } from './ui-syntax-rule'; -const invalidDecorators = [PresetDecorators.PROP, PresetDecorators.LINK, PresetDecorators.OBJECT_LINK]; +const invalidDecorators = [PresetDecorators.PROP_REF, PresetDecorators.LINK, PresetDecorators.OBJECT_LINK]; class NoPropLinkObjectLinkInEntryRule extends AbstractUISyntaxRule { public setup(): Record { diff --git a/arkui-plugins/ui-syntax-plugins/rules/observedV2-trace-usage-validation.ts b/arkui-plugins/ui-syntax-plugins/rules/observedV2-trace-usage-validation.ts index 1185160a5bc079358af74e5dca932b9b2742b550..9a0ca19e137edfdb5269497a6e053ad7c5a8d57d 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/observedV2-trace-usage-validation.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/observedV2-trace-usage-validation.ts @@ -22,12 +22,12 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; class ObservedV2TraceUsageValidationRule extends AbstractUISyntaxRule { public setup(): Record { return { - observedV2DecoratorError: `The '@ObservedV2' decorator can only be used in 'class'.`, - traceDecoratorError: `The '@Trace' decorator can only be used in 'class'.`, - traceMemberVariableError: `The '@Trace' decorator can only decorate member variables within a 'class' decorated with '@ObservedV2'.`, + observedV2DecoratorError: `The '@ObservedV2' annotation can only be used in 'class'.`, + traceDecoratorError: `The '@Trace' annotation can only be used in 'class'.`, + traceMemberVariableError: `The '@Trace' annotation can only decorate member variables within a 'class' decorated with '@ObservedV2'.`, //The repair logic is different, if there is v1, update to v2 - traceMustUsedWithObservedV2: `The '@Trace' decorator can only be used within a 'class' decorated with 'ObservedV2'.`, - traceMustUsedWithObservedV2Update: `The '@Trace' decorator can only be used within a 'class' decorated with 'ObservedV2'.`, + traceMustUsedWithObservedV2: `The '@Trace' annotation can only be used within a 'class' decorated with 'ObservedV2'.`, + traceMustUsedWithObservedV2Update: `The '@Trace' annotation can only be used within a 'class' decorated with 'ObservedV2'.`, }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/old-new-decorator-mix-use-check.ts b/arkui-plugins/ui-syntax-plugins/rules/old-new-decorator-mix-use-check.ts index 478ac72c0e4282ba5fc82c18ade880481fb706a3..5726d15cdcc375de6f784ef274d2c84be7cf6359 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/old-new-decorator-mix-use-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/old-new-decorator-mix-use-check.ts @@ -20,15 +20,14 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; class OldNewDecoratorMixUseCheckRule extends AbstractUISyntaxRule { private static readonly oldV1Decorators: string[] = [ PresetDecorators.STATE, - PresetDecorators.PROP, + PresetDecorators.PROP_REF, PresetDecorators.LINK, PresetDecorators.PROVIDE, PresetDecorators.CONSUME, PresetDecorators.WATCH, PresetDecorators.STORAGE_LINK, - PresetDecorators.STORAGE_PROP, + PresetDecorators.STORAGE_PROP_REF, PresetDecorators.LOCAL_STORAGE_LINK, - PresetDecorators.LOCAL_STORAGE_PROP, PresetDecorators.OBJECT_LINK, ]; @@ -45,7 +44,7 @@ class OldNewDecoratorMixUseCheckRule extends AbstractUISyntaxRule { public setup(): Record { return { - oldAndNewDecoratorsMixUse: `The '@{{decoratorName}}' decorator can only be used in a 'struct' decorated with '@{{component}}'.`, + oldAndNewDecoratorsMixUse: `The '@{{decoratorName}}' annotation can only be used in a 'struct' decorated with '@{{component}}'.`, }; } public parsed(node: arkts.StructDeclaration): void { diff --git a/arkui-plugins/ui-syntax-plugins/rules/once-decorator-check.ts b/arkui-plugins/ui-syntax-plugins/rules/once-decorator-check.ts index 1625f32ad9f69ee68f141be830d93ee95642baa3..cd59caad895f9d24d01900eb2c73eafe8066bced 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/once-decorator-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/once-decorator-check.ts @@ -20,10 +20,10 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; class OnceDecoratorCheckRule extends AbstractUISyntaxRule { public setup(): Record { return { - invalidUsage: `The '@Once' decorator can only be used in a 'struct' decorated with '@ComponentV2'.`, + invalidUsage: `The '@Once' annotation can only be used in a 'struct' decorated with '@ComponentV2'.`, invalidMemberDecorate: `'@Once' can only decorate member property.`, invalidDecorator: `When a variable decorated with '@Once', it must also be decorated with '@Param'.`, - invalidNOtInStruct: `'@Once' decorator can only be used with 'struct'.` + invalidNOtInStruct: `'@Once' annotation can only be used with 'struct'.` }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/property-type.ts b/arkui-plugins/ui-syntax-plugins/rules/property-type.ts index 62f2275001643e666e00d6f319b985dcc5032cca..1c70f2d3987260fc7acdbeb920a8020ff8901365 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/property-type.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/property-type.ts @@ -19,12 +19,12 @@ import { PresetDecorators, TypeFlags, getIdentifierName, findDecorator, hasAnnot const v1DecoratorMustHasType = [ PresetDecorators.STATE, - PresetDecorators.PROP, + PresetDecorators.PROP_REF, PresetDecorators.LINK, PresetDecorators.OBJECT_LINK, PresetDecorators.PROVIDE, PresetDecorators.CONSUME, - PresetDecorators.STORAGE_PROP, + PresetDecorators.STORAGE_PROP_REF, PresetDecorators.STORAGE_LINK, PresetDecorators.WATCH, ]; @@ -38,8 +38,8 @@ const v2DecoratorMustHasType = [ ]; const propertyPropDecorator = [ - PresetDecorators.PROP, - PresetDecorators.STORAGE_PROP, + PresetDecorators.PROP_REF, + PresetDecorators.STORAGE_PROP_REF, ]; const SimpleTypesUnSupported = [ diff --git a/arkui-plugins/ui-syntax-plugins/rules/require-decorator-regular.ts b/arkui-plugins/ui-syntax-plugins/rules/require-decorator-regular.ts index f761fba6b7aaabaca44de159c18d427ba17b9689..ad303653d522139f890044127b24f62c04613b98 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/require-decorator-regular.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/require-decorator-regular.ts @@ -20,7 +20,7 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; const allowedDecorators = [ PresetDecorators.STATE, PresetDecorators.PROVIDE, - PresetDecorators.PROP, + PresetDecorators.PROP_REF, PresetDecorators.PARAM, PresetDecorators.BUILDER_PARAM ]; @@ -28,7 +28,7 @@ const allowedDecorators = [ class RequireDecoratorRegularRule extends AbstractUISyntaxRule { public setup(): Record { return { - invalidUsage: `The @Require decorator can only be used on a regular variable or a variable decorated by @State, @Provide, @Prop, @Param, or @BuilderParam.`, + invalidUsage: `The @Require annotation can only be used on a regular variable or a variable decorated by @State, @Provide, @Prop, @Param, or @BuilderParam.`, invalidPrivateWithRequire: `Property '{{propertyName}}' can not be decorated with both {{decoratorName}} and private.`, }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/reusable-component-in-V2-check.ts b/arkui-plugins/ui-syntax-plugins/rules/reusable-component-in-V2-check.ts index 31a38e4b2c175d0c186a27d3399243c71298605b..57901a88dfde794231e4ce14ecf7e125cfe9935c 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/reusable-component-in-V2-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/reusable-component-in-V2-check.ts @@ -42,7 +42,7 @@ class ReusableComponentInV2CheckRule extends AbstractUISyntaxRule { for (const childNode of node.getChildren()) { // Check whether the type is struct if (!arkts.isStructDeclaration(childNode)) { - return; + continue; } const reusableV1Decorator = getAnnotationUsage(childNode, PresetDecorators.REUSABLE_V1); const structName = childNode.definition?.ident?.name; diff --git a/arkui-plugins/ui-syntax-plugins/rules/reusableV2-decorator-check.ts b/arkui-plugins/ui-syntax-plugins/rules/reusableV2-decorator-check.ts index 03d65bdd221b98d934fc70b21486ab594bb5510e..24a7ca87ced670eeea904ec783d851b98cdb357d 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/reusableV2-decorator-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/reusableV2-decorator-check.ts @@ -20,7 +20,7 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; class ReusableV2DecoratorCheckRule extends AbstractUISyntaxRule { public setup(): Record { return { - conflictingDecorators: `The '@Reusable' and '@ReusableV2' decorators cannot be applied simultaneously.`, + conflictingDecorators: `The '@Reusable' and '@ReusableV2' annotations cannot be applied simultaneously.`, invalidDecoratorUsage: `@ReusableV2 is only applicable to custom components decorated by @ComponentV2.`, }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/struct-missing-decorator.ts b/arkui-plugins/ui-syntax-plugins/rules/struct-missing-decorator.ts index 6a81d555cf522be2864e4cdb4c18a86518b3e0e3..11b48a21938957acdad946cfc2bf4c112ea0236a 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/struct-missing-decorator.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/struct-missing-decorator.ts @@ -20,7 +20,7 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; class StructMissingDecoratorRule extends AbstractUISyntaxRule { public setup(): Record { return { - missingComponentDecorator: `Decorator '@Component', '@ComponentV2', or '@CustomDialog' is missing for struct '{{structName}}'.` + missingComponentDecorator: `Annotation '@Component', '@ComponentV2', or '@CustomDialog' is missing for struct '{{structName}}'.` }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/struct-property-decorator.ts b/arkui-plugins/ui-syntax-plugins/rules/struct-property-decorator.ts index 9831b0d24c5a4ec1da5b010e9e34de7759979096..caac4a335fb730ccf980dfb3f0f1651ab226834c 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/struct-property-decorator.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/struct-property-decorator.ts @@ -20,21 +20,20 @@ import { AbstractUISyntaxRule } from './ui-syntax-rule'; const decorators: string[] = [ PresetDecorators.BUILDER_PARAM, PresetDecorators.STATE, - PresetDecorators.PROP, + PresetDecorators.PROP_REF, PresetDecorators.LINK, PresetDecorators.OBJECT_LINK, - PresetDecorators.STORAGE_PROP, + PresetDecorators.STORAGE_PROP_REF, PresetDecorators.STORAGE_LINK, PresetDecorators.WATCH, PresetDecorators.LOCAL_STORAGE_LINK, - PresetDecorators.LOCAL_STORAGE_PROP, PresetDecorators.REQUIRE, ]; class StructPropertyDecoratorRule extends AbstractUISyntaxRule { public setup(): Record { return { - invalidStaticUsage: `The static variable of struct cannot be used together with built-in decorators.` + invalidStaticUsage: `The static variable of struct cannot be used together with built-in annotations.` }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/struct-property-optional.ts b/arkui-plugins/ui-syntax-plugins/rules/struct-property-optional.ts index e84a63d7ab3ad7ff2607578c722dcc5f8aad5a48..899df9874574b7b907bcde59e9989e1034b60e4c 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/struct-property-optional.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/struct-property-optional.ts @@ -53,7 +53,7 @@ class StructPropertyOptionalRule extends AbstractUISyntaxRule { const nodeKey = node.key; const nodeValue = node.value; // Check whether the prop decorator has an initial value, and no alarm will be generated if there is an initial value - if (decoratorName === PresetDecorators.PROP && nodeKey && !nodeValue) { + if (decoratorName === PresetDecorators.PROP_REF && nodeKey && !nodeValue) { this.report({ node: nodeKey, message: this.messages.propertyOptional, diff --git a/arkui-plugins/ui-syntax-plugins/rules/struct-variable-initialization.ts b/arkui-plugins/ui-syntax-plugins/rules/struct-variable-initialization.ts index 325f64266e0570ba480a365b8a5f268adac725db..c3942a7a36fb8587527c8238a8c4baea984beae4 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/struct-variable-initialization.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/struct-variable-initialization.ts @@ -21,9 +21,8 @@ import { PresetDecorators, findDecorator } from '../utils'; const mustInitializeDecorators = [ PresetDecorators.STATE, PresetDecorators.STORAGE_LINK, - PresetDecorators.STORAGE_PROP, + PresetDecorators.STORAGE_PROP_REF, PresetDecorators.LOCAL_STORAGE_LINK, - PresetDecorators.LOCAL_STORAGE_PROP, PresetDecorators.PROVIDE, ]; // Disables a list of decorators that are initialized locally diff --git a/arkui-plugins/ui-syntax-plugins/rules/track-decorator-check.ts b/arkui-plugins/ui-syntax-plugins/rules/track-decorator-check.ts index 1cf71f9f1095d92e53b0334087826f33c71453d9..9178bfafcbcec1fd1f0af870b89cdc637da7bd40 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/track-decorator-check.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/track-decorator-check.ts @@ -20,8 +20,8 @@ import { PresetDecorators, findDecorator, getClassDeclarationAnnotation } from ' class TrackDecoratorCheckRule extends AbstractUISyntaxRule { public setup(): Record { return { - trackOnClassMemberOnly: `The '@Track' decorator can decorate only member variables of a class.`, - trackMustUsedWithObserved: `'@Track' cannot be used with classes decorated by '@ObservedV2'. Use the '@Trace' decorator instead.`, + trackOnClassMemberOnly: `The '@Track' annotation can decorate only member variables of a class.`, + trackMustUsedWithObserved: `'@Track' cannot be used with classes decorated by '@ObservedV2'. Use the '@Trace' annotation instead.`, }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/type-decorator-check.ts b/arkui-plugins/ui-syntax-plugins/rules/type-decorator-check.ts deleted file mode 100644 index fe9556e3c4a7f3461192de2c53416d2669958626..0000000000000000000000000000000000000000 --- a/arkui-plugins/ui-syntax-plugins/rules/type-decorator-check.ts +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as arkts from '@koalaui/libarkts'; -import { getAnnotationName, PresetDecorators, findDecorator, getClassDeclarationAnnotation } from '../utils'; -import { AbstractUISyntaxRule } from './ui-syntax-rule'; - -class TypeDecoratorCheckRule extends AbstractUISyntaxRule { - public setup(): Record { - return { - invalidType: `The @Type decorator is not allowed here. It must be used in a class.`, - invalidDecoratorWith: `The @Type decorator can not be used within a 'class' decorated with @Observed.`, - invalidTypeMember: `The @Type decorator is not allowed here. It can only decorate properties of a class.` - }; - } - - public parsed(node: arkts.AstNode): void { - - this.checkTypeOnlyForClass(node); - - // Check the decorator on the class - if (arkts.isClassDeclaration(node)) { - this.checkObservedAndTypeConflict(node); - } - - if (arkts.isScriptFunction(node)) { - this.validateScriptFunctionForTypeDecorator(node); - } - } - - // rule1: @Type can only be used for class - private checkTypeOnlyForClass(node: arkts.AstNode): void { - if (arkts.isStructDeclaration(node)) { - node.definition?.body.forEach(member => { - if (arkts.isClassProperty(member)) { - this.validateDecorator(member, PresetDecorators.TYPE); - } - if (arkts.isMethodDefinition(member)) { - this.validateDecorator(member.scriptFunction, PresetDecorators.TYPE); - } - }); - return; - } - - // function/ variable/ interface/ type alias declaration - if (arkts.isFunctionDeclaration(node) || - arkts.isVariableDeclaration(node) || - arkts.isTSInterfaceDeclaration(node) || - arkts.isTSTypeAliasDeclaration(node) - ) { - this.validateDecorator(node, PresetDecorators.TYPE); - } - } - - // rule2: Conflict between @Type and @Observed - private checkObservedAndTypeConflict( - node: arkts.ClassDeclaration, - ): void { - let typeDecorator: arkts.AnnotationUsage | undefined; - node.definition?.body.forEach(member => { - if (arkts.isClassProperty(member)) { - typeDecorator = findDecorator(member, PresetDecorators.TYPE); - } - }); - const annotation = getClassDeclarationAnnotation(node, PresetDecorators.OBSERVED_V1); - if (typeDecorator && annotation) { - this.reportObservedAndTypeDecoratorConflict(typeDecorator); - } - } - - // rule3: @TypeCannot be used for function members - private validateScriptFunctionForTypeDecorator( - node: arkts.ScriptFunction, - ): void { - const typeDecorator = findDecorator(node, PresetDecorators.TYPE); - this.reportInvalidTypeDecorator(typeDecorator); - } - - private validateDecorator( - node: arkts.ClassProperty | arkts.VariableDeclaration | arkts.FunctionDeclaration | - arkts.ScriptFunction | arkts.TSInterfaceDeclaration | arkts.TSTypeAliasDeclaration, - decoratorName: string - ): void { - const decorator = findDecorator(node, decoratorName); - if (!decorator) { - return; - } - - this.report({ - node: decorator, - message: this.messages.invalidType, - fix: (decorator) => { - const startPosition = decorator.startPosition; - const endPosition = decorator.endPosition; - return { - range: [startPosition, endPosition], - code: '' - }; - } - }); - } - - private reportObservedAndTypeDecoratorConflict( - typeDecorator: arkts.AnnotationUsage | undefined, - ): void { - if (!typeDecorator) { - return; - } - this.report({ - node: typeDecorator, - message: this.messages.invalidDecoratorWith, - fix: () => { - const startPosition = typeDecorator.startPosition; - const endPosition = typeDecorator.endPosition; - return { - range: [startPosition, endPosition], - code: '' - }; - } - }); - } - - private reportInvalidTypeDecorator( - typeDecorator: arkts.AnnotationUsage | undefined, - ): void { - if (!typeDecorator) { - return; - } - this.report({ - node: typeDecorator, - message: this.messages.invalidTypeMember, - fix: (typeDecorator) => { - const startPosition = typeDecorator.startPosition; - const endPosition = typeDecorator.endPosition; - return { - range: [startPosition, endPosition], - code: '' - }; - } - }); - } -} - -export default TypeDecoratorCheckRule; \ No newline at end of file diff --git a/arkui-plugins/ui-syntax-plugins/rules/validate-decorator-target.ts b/arkui-plugins/ui-syntax-plugins/rules/validate-decorator-target.ts index e16040792dd860efe205b7df54fe6f048fa7c739..3d70a3ce3dc513963683b612653669670b8a4838 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/validate-decorator-target.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/validate-decorator-target.ts @@ -31,14 +31,13 @@ const structOnlyDecorators = [ // Can only be used with decorators for property const propertyOnlyDecorators = [ PresetDecorators.STATE, - PresetDecorators.PROP, + PresetDecorators.PROP_REF, PresetDecorators.LINK, PresetDecorators.PROVIDE, PresetDecorators.CONSUME, PresetDecorators.STORAGE_LINK, - PresetDecorators.STORAGE_PROP, + PresetDecorators.STORAGE_PROP_REF, PresetDecorators.LOCAL_STORAGE_LINK, - PresetDecorators.LOCAL_STORAGE_PROP, PresetDecorators.LOCAL, PresetDecorators.PARAM, PresetDecorators.EVENT, @@ -54,7 +53,7 @@ const propertyOnlyDecorators = [ class ValidateDecoratorTargetRule extends AbstractUISyntaxRule { public setup(): Record { return { - decoratorOnlyWithStruct: `The '@{{decoratorName}}' decorator can only be used with 'struct'.`, + decoratorOnlyWithStruct: `The '@{{decoratorName}}' annotation can only be used with 'struct'.`, decoratorOnlyWithMemberProperty: `'@{{decoratorName}}' can only decorate member property.` }; } diff --git a/arkui-plugins/ui-syntax-plugins/rules/variable-initialization-via-component-constructor.ts b/arkui-plugins/ui-syntax-plugins/rules/variable-initialization-via-component-constructor.ts index 892e4cdf3e699386b185f5f6f7675bbe26760fb6..29c7209c60e4cd87849d9c913e9831d1361e375e 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/variable-initialization-via-component-constructor.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/variable-initialization-via-component-constructor.ts @@ -25,17 +25,16 @@ class VariableInitializationViaComponentConstructorRule extends AbstractUISyntax [PresetDecorators.REQUIRE], [PresetDecorators.REQUIRE, PresetDecorators.STATE], [PresetDecorators.REQUIRE, PresetDecorators.PROVIDE], - [PresetDecorators.REQUIRE, PresetDecorators.PROP], + [PresetDecorators.REQUIRE, PresetDecorators.PROP_REF], [PresetDecorators.REQUIRE, PresetDecorators.BUILDER_PARAM], [PresetDecorators.REQUIRE, PresetDecorators.PARAM] ]; private static readonly notAllowInitInConstructorDecorators: string[][] = [ [PresetDecorators.STORAGE_LINK], - [PresetDecorators.STORAGE_PROP], + [PresetDecorators.STORAGE_PROP_REF], [PresetDecorators.CONSUME], [PresetDecorators.LOCAL_STORAGE_LINK], - [PresetDecorators.LOCAL_STORAGE_PROP] ]; public setup(): Record { diff --git a/arkui-plugins/ui-syntax-plugins/utils/index.ts b/arkui-plugins/ui-syntax-plugins/utils/index.ts index 13726b871d8283eda106ada3af5e52728f4f21ef..34866868fb6a7fdcd7a59809038816d487fa7e5b 100644 --- a/arkui-plugins/ui-syntax-plugins/utils/index.ts +++ b/arkui-plugins/ui-syntax-plugins/utils/index.ts @@ -91,15 +91,14 @@ export const PresetDecorators = { PREVIEW: 'Preview', STATE: 'State', PARAM: 'Param', - PROP: 'Prop', + PROP_REF: 'PropRef', PROVIDE: 'Provide', PROVIDER: 'Provider', LINK: 'Link', LOCAL: 'Local', OBJECT_LINK: 'ObjectLink', - STORAGE_PROP: 'StorageProp', + STORAGE_PROP_REF: 'StoragePropRef', STORAGE_LINK: 'StorageLink', - LOCAL_STORAGE_PROP: 'LocalStorageProp', LOCAL_STORAGE_LINK: 'LocalStorageLink', REQUIRE: 'Require', REUSABLE_V1: 'Reusable',