From 4ad7ed4394f408b89b438b3e1d90b057bcecdc2f Mon Sep 17 00:00:00 2001 From: sniperc96 Date: Thu, 11 Sep 2025 20:13:46 +0800 Subject: [PATCH] 0911_sync_0702_to_0728 Signed-off-by: sniperc96 Change-Id: Ic1c1867f2488b834a34f06204502ba313c68310e --- .../rules/entry-componentv2-invalid-params.ts | 65 +++++++++++++++++++ .../ui-syntax-plugins/rules/index.ts | 2 + .../rules/old-new-decorator-mix-use-check.ts | 42 +++++++++++- 3 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 arkui-plugins/ui-syntax-plugins/rules/entry-componentv2-invalid-params.ts diff --git a/arkui-plugins/ui-syntax-plugins/rules/entry-componentv2-invalid-params.ts b/arkui-plugins/ui-syntax-plugins/rules/entry-componentv2-invalid-params.ts new file mode 100644 index 000000000..0aa95b242 --- /dev/null +++ b/arkui-plugins/ui-syntax-plugins/rules/entry-componentv2-invalid-params.ts @@ -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. + */ + +import * as arkts from '@koalaui/libarkts'; +import { getAnnotationUsage, PresetDecorators } from '../utils'; +import { AbstractUISyntaxRule } from './ui-syntax-rule'; + +const ENTRY_STORAGE: string = 'storage'; +const ENTRY_USE_SHARED_STORAGE = 'useSharedStorage'; + +class EntryComponentV2InvalidParamsRule extends AbstractUISyntaxRule { + public setup(): Record { + return { + invalidEntryParams: `The "@ComponentV2" decorator cannot be used together with the "@Entry" decorator that has "storage" or "useSharedStorage" parameters.` + }; + } + + public parsed(node: arkts.AstNode): void { + if (!arkts.isStructDeclaration(node)) { + return; + } + + const componentV2DecoratorUsage = getAnnotationUsage(node, PresetDecorators.COMPONENT_V2); + if (!componentV2DecoratorUsage) { + return; + } + + const entryDecoratorUsage = getAnnotationUsage(node, PresetDecorators.ENTRY); + if (!entryDecoratorUsage) { + return; + } + + const entryDecoratorhasInvalidParams = this.checkEntryDecoratorHasInvalidParams(entryDecoratorUsage); + if (entryDecoratorhasInvalidParams) { + this.report({ + node: entryDecoratorUsage, + message: this.messages.invalidEntryParams, + }); + } + } + + private checkEntryDecoratorHasInvalidParams(entryDecorator: arkts.AnnotationUsage): boolean { + return entryDecorator.properties.some((property) => { + if (arkts.isClassProperty(property) && property.key && arkts.isIdentifier(property.key)) { + const propertyName = property.key.name; + return propertyName === ENTRY_STORAGE || propertyName === ENTRY_USE_SHARED_STORAGE; + } + return false; + }); + } +} + +export default EntryComponentV2InvalidParamsRule; \ No newline at end of file diff --git a/arkui-plugins/ui-syntax-plugins/rules/index.ts b/arkui-plugins/ui-syntax-plugins/rules/index.ts index 6fdab3812..c20774408 100644 --- a/arkui-plugins/ui-syntax-plugins/rules/index.ts +++ b/arkui-plugins/ui-syntax-plugins/rules/index.ts @@ -67,6 +67,7 @@ import OldNewDecoratorMixUseCheckRule from './old-new-decorator-mix-use-check'; import RequireDecoratorRegularRule from './require-decorator-regular'; import ReusableComponentInV2CheckRule from './reusable-component-in-V2-check'; import SpecificComponentChildrenRule from './specific-component-children'; +import EntryComponentV2StorageRule from './entry-componentv2-invalid-params'; const rules: Array = [ [AttributeNoInvokeRule, 'warn'], @@ -122,6 +123,7 @@ const rules: Array = [ [RequireDecoratorRegularRule, 'warn'], [ReusableComponentInV2CheckRule, 'warn'], [SpecificComponentChildrenRule, 'error'], + [EntryComponentV2StorageRule, 'error'] ]; export default rules; \ No newline at end of file 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 ce916bb83..308daf6ff 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 @@ -47,10 +47,16 @@ class OldNewDecoratorMixUseCheckRule extends AbstractUISyntaxRule { oldAndNewDecoratorsMixUse: `The '@{{decoratorName}}' annotation can only be used in a 'struct' decorated with '@{{component}}'.`, }; } - public parsed(node: arkts.StructDeclaration): void { - if (!arkts.isStructDeclaration(node)) { - return; + + public parsed(node: arkts.StructDeclaration | arkts.ClassDeclaration): void { + if (arkts.isStructDeclaration(node)) { + this.handleStructDeclaration(node); + } else if (arkts.isClassDeclaration(node)) { + this.handleClassDeclaration(node); } + } + + private handleStructDeclaration(node: arkts.StructDeclaration): void { // Gets the decorator version of a custom component const componentV2Decorator = getAnnotationUsage(node, PresetDecorators.COMPONENT_V2); const componentDecorator = getAnnotationUsage(node, PresetDecorators.COMPONENT_V1); @@ -74,6 +80,24 @@ class OldNewDecoratorMixUseCheckRule extends AbstractUISyntaxRule { }); } + private handleClassDeclaration(node: arkts.ClassDeclaration): void { + node.definition?.body.forEach((property) => { + if (!arkts.isClassProperty(property)) { + return; + } + const newDecorator = this.findPropertyDecorator(property, OldNewDecoratorMixUseCheckRule.newV2decorators); + const oldDecorator = this.findPropertyDecorator(property, OldNewDecoratorMixUseCheckRule.oldV1Decorators); + // Check that the new decorator is not used in struct + if (newDecorator) { + this.reportError(newDecorator, PresetDecorators.COMPONENT_V2); + } + // Check that the old decorator is not used in struct + if (oldDecorator) { + this.reportError(oldDecorator, PresetDecorators.COMPONENT_V1); + } + }); + } + private findPropertyDecorator( node: arkts.ClassProperty, decoratorList: string[] @@ -131,6 +155,18 @@ class OldNewDecoratorMixUseCheckRule extends AbstractUISyntaxRule { }, }); } + + private reportError(errorDecorator: arkts.AnnotationUsage, componentName: string): void { + const propertyDecoratorName = getAnnotationName(errorDecorator); + this.report({ + node: errorDecorator, + message: this.messages.oldAndNewDecoratorsMixUse, + data: { + decoratorName: propertyDecoratorName, + component: componentName + } + }); + } } export default OldNewDecoratorMixUseCheckRule; \ No newline at end of file -- Gitee