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 { getAnnotationUsage, PresetDecorators } from '../utils'; 18import { UISyntaxRule, UISyntaxRuleContext } from './ui-syntax-rule'; 19 20const MAX_ENTRY_DECORATOR_COUNT = 1; 21function checkDuplicateEntry(node: arkts.AstNode, context: UISyntaxRuleContext): void { 22 if (arkts.nodeType(node) !== arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_MODULE) { 23 return; 24 } 25 let entryDecoratorUsages: arkts.AnnotationUsage[] = []; 26 node.getChildren().forEach((child) => { 27 if (!arkts.isStructDeclaration(child)) { 28 return; 29 } 30 const entryDecoratorUsage = getAnnotationUsage( 31 child, 32 PresetDecorators.ENTRY, 33 ); 34 if (entryDecoratorUsage) { 35 entryDecoratorUsages.push(entryDecoratorUsage); 36 } 37 }); 38 // If more than one entry decorator is recorded, an error is reported 39 if (entryDecoratorUsages.length <= MAX_ENTRY_DECORATOR_COUNT) { 40 return; 41 } 42 entryDecoratorUsages.forEach((entryDocoratorUsage) => { 43 context.report({ 44 node: entryDocoratorUsage, 45 message: rule.messages.duplicateEntry, 46 fix: (entryDocoratorUsage) => { 47 const startPosition = arkts.getStartPosition(entryDocoratorUsage); 48 const endPosition = arkts.getEndPosition(entryDocoratorUsage); 49 return { 50 range: [startPosition, endPosition], 51 code: '', 52 }; 53 } 54 }); 55 }); 56} 57 58const rule: UISyntaxRule = { 59 name: 'no-duplicate-entry', 60 messages: { 61 duplicateEntry: `An ArkTS file can contain only one '@Entry' decorator.`, 62 }, 63 setup(context) { 64 return { 65 parsed: (node): void => { 66 checkDuplicateEntry(node, context); 67 }, 68 }; 69 }, 70}; 71 72export default rule;