1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import * as arkts from '@koalaui/libarkts'; 17import { getClassPropertyAnnotationNames } from '../utils'; 18import { UISyntaxRule, UISyntaxRuleContext } from './ui-syntax-rule'; 19 20export const stateManagementDecorator = { 21 STATE: 'State', 22 PROP: 'Prop', 23 LINK: 'Link', 24 PROVIDE: 'Provide', 25 CONSUME: 'Consume' 26}; 27 28const CLASS_PROPERTY_ANNOTATION_ONE: number = 1; 29function duplicateState( 30 node: arkts.StructDeclaration, 31 context: UISyntaxRuleContext 32): void { 33 node.definition.body.forEach(body => { 34 if (arkts.isClassProperty(body)) { 35 // Get the list of decorators 36 const propertyDecorators = getClassPropertyAnnotationNames(body); 37 // Filter the decorators to get those related to state management 38 const stateDecorators = propertyDecorators.filter(decorator => 39 Object.values(stateManagementDecorator).includes(decorator) 40 ); 41 const propertyNameNode = body.key; 42 const attributeName = body.key?.dumpSrc(); 43 if (!propertyNameNode || !attributeName) { 44 return; 45 } 46 if (stateDecorators.length > CLASS_PROPERTY_ANNOTATION_ONE) { 47 context.report({ 48 node: propertyNameNode, 49 message: rule.messages.duplicateState, 50 data: { attributeName }, 51 }); 52 } 53 } 54 }); 55} 56 57const rule: UISyntaxRule = { 58 name: 'no-duplicate-state-manager', 59 messages: { 60 duplicateState: `This attribute '{{attributeName}}' cannot have mutilate state management decorators. <ArkTSCheck>`, 61 }, 62 setup(context) { 63 return { 64 parsed: (node): void => { 65 if (!arkts.isStructDeclaration(node)) { 66 return; 67 } 68 duplicateState(node, context); 69 }, 70 }; 71 }, 72}; 73 74export default rule; 75