• 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 * as fs from "fs"
18
19export class PropertyDescriptor {
20    constructor(public name: string, public decorators: string[]) {}
21}
22
23export class StructDescriptor {
24    constructor(public name: string, public properties: PropertyDescriptor[]) {}
25    static fromJSON(parsed: any): StructDescriptor[] {
26        return parsed.structs.map((struct: any) => new StructDescriptor(struct.name,
27            struct.properties.map((property: any) =>
28                new PropertyDescriptor(property.name, property.decorators)
29            )
30        ))
31    }
32
33    decoratorsFor(name: string): string[] | undefined {
34        return this.properties.find(it => it.name == name)?.decorators
35    }
36}
37
38export class StructTable {
39    structByName = new Map<string, StructDescriptor>()
40
41    findStruct(name: arkts.Identifier): StructDescriptor | undefined {
42        return this.structByName.get(name.name)
43    }
44    addStruct(declaration: arkts.ETSStructDeclaration) {
45        this.addDescriptor(this.toDescriptor(declaration))
46    }
47    addDescriptor(descriptor: StructDescriptor) {
48        this.structByName.set(descriptor.name, descriptor)
49    }
50    addDescriptors(descriptors: StructDescriptor[]) {
51        descriptors.forEach(it => this.addDescriptor(it))
52    }
53
54    toDescriptor(declaration: arkts.ETSStructDeclaration): StructDescriptor {
55        return new StructDescriptor(
56            declaration.definition?.ident?.name!,
57            declaration.definition!.body
58                .filter(arkts.isClassProperty)
59                .map((classProperty: arkts.ClassProperty) =>
60                    new PropertyDescriptor((classProperty.key as arkts.Identifier).name!,
61                            this.extractDecorators(classProperty))
62                )
63            )
64    }
65    extractDecorators(property: arkts.ClassProperty): string[] {
66        let decorators = property.decorators
67            .filter(it => arkts.isIdentifier(it.expr))
68            .map(it => (it.expr as arkts.Identifier).name!)
69        let annotations = property.annotations
70            .filter(it => arkts.isIdentifier(it.expr))
71            .map(it => (it.expr as arkts.Identifier).name!)
72        return decorators.concat(annotations)
73    }
74}
75
76export class StructRecorder extends arkts.AbstractVisitor {
77    constructor(private table: StructTable) {
78        super()
79        const database = "./structs.json"
80        if (fs.existsSync(database)) {
81            try {
82                table.addDescriptors(StructDescriptor.fromJSON(JSON.parse(fs.readFileSync(database, "utf-8"))))
83            } catch (e: any) {
84                console.log(e.stack)
85            }
86        }
87    }
88
89    visitor(node: arkts.AstNode): arkts.AstNode {
90        if (arkts.isETSStructDeclaration(node)) {
91            this.table.addStruct(node)
92        }
93        this.visitEachChild(node)
94        return node
95    }
96}
97