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 { getAnnotationName } from '../utils'; 18import { UISyntaxRule, UISyntaxRuleContext } from './ui-syntax-rule'; 19 20const allowedDecorators = new Set(['Extend', 'Builder', 'Styles']); 21 22function validateFunctionDecorator(node: arkts.EtsScript, context: UISyntaxRuleContext): void { 23 node.statements.forEach((statement) => { 24 // If the node is not a function declaration, it is returned 25 if (!arkts.isFunctionDeclaration(statement)) { 26 return; 27 } 28 const annotations = statement.annotations; 29 // If there is no annotation, go straight back 30 if (!annotations) { 31 return; 32 } 33 // Check that each annotation is in the list of allowed decorators 34 annotations.forEach((annotation) => { 35 const decoratorName = getAnnotationName(annotation); 36 // rule1: misuse of decorator, only '@Extend', '@Builder' , '@Styles' decorators allowed on global functions 37 if (!allowedDecorators.has(decoratorName)) { 38 context.report({ 39 node: annotation, 40 message: rule.messages.invalidDecorator, 41 data: { 42 decoratorName, 43 }, 44 }); 45 } 46 }); 47 }); 48} 49 50const rule: UISyntaxRule = { 51 name: 'one-decorator-on-function-method', 52 messages: { 53 invalidDecorator: `misuse of '@{{decoratorName}}' decorator, only '@Extend', '@Builder' and '@Styles' decorators allowed on global functions.`, 54 }, 55 setup(context) { 56 return { 57 parsed: (node: arkts.AstNode): void => { 58 // If the node is not an ETS script, it is returned directly 59 if (!arkts.isEtsScript(node)) { 60 return; 61 } 62 validateFunctionDecorator(node, context); 63 }, 64 }; 65 }, 66}; 67 68export default rule; 69