• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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