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 { AbstractVisitor } from '../common/abstract-visitor'; 18import { hasBuilderLambdaAnnotation } from './builder-lambda-translators/utils'; 19 20interface ComponentInfo { 21 argsNum: number; 22} 23 24type ComponentCollection = Map<string, ComponentInfo>; 25 26export class NameCollector extends AbstractVisitor { 27 private components: ComponentCollection; 28 private static instance: NameCollector; 29 30 private constructor() { 31 super(); 32 this.components = new Map(); 33 } 34 35 static getInstance(): NameCollector { 36 if (!this.instance) { 37 this.instance = new NameCollector(); 38 } 39 return this.instance; 40 } 41 42 getComponents(): string[] { 43 return Array.from(this.components.keys()); 44 } 45 46 getComponentInfo(componentName: string): ComponentInfo | undefined { 47 return this.components.get(componentName); 48 } 49 50 collectInfoFromComponentFunction(component: arkts.ScriptFunction): void { 51 if (!component.id) return; 52 53 const name: string = component.id.name; 54 const argsNum: number = component.params.length; 55 this.components.set(name, { argsNum }); 56 } 57 58 reset(): void { 59 super.reset(); 60 this.components.clear(); 61 } 62 63 findComponentFunction(node: arkts.FunctionDeclaration): arkts.ScriptFunction | undefined { 64 const isDeclareAndExport: boolean = arkts.hasModifierFlag( 65 node, 66 arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE | arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_EXPORT 67 ); 68 if (!isDeclareAndExport) return undefined; 69 70 const isComponentBuilder = hasBuilderLambdaAnnotation(node); 71 if (!isComponentBuilder) return undefined; 72 if (!node.scriptFunction.id) return undefined; 73 74 return node.scriptFunction; 75 } 76 77 visitor(node: arkts.AstNode): arkts.AstNode { 78 const newNode = this.visitEachChild(node); 79 if (arkts.isFunctionDeclaration(newNode)) { 80 const component = this.findComponentFunction(newNode); 81 if (!!component) { 82 this.collectInfoFromComponentFunction(component); 83 } 84 } 85 return newNode; 86 } 87} 88