• 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';
18import * as path from 'path';
19
20export const PresetDecorators = {
21  BUILDER_PARAM: 'BuilderParam',
22  COMPONENT_V1: 'Component',
23  COMPONENT_V2: 'ComponentV2',
24  COMPUTED: 'Computed',
25  CONSUME: 'Consume',
26  CONSUMER: 'Consumer',
27  CUSTOM_DIALOG: 'CustomDialog',
28  ENTRY: 'Entry',
29  EVENT: 'Event',
30  PREVIEW: 'Preview',
31  STATE: 'State',
32  PARAM: 'Param',
33  PROP: 'Prop',
34  PROVIDE: 'Provide',
35  PROVIDER: 'Provider',
36  LINK: 'Link',
37  LOCAL: 'Local',
38  OBJECT_LINK: 'ObjectLink',
39  STORAGE_PROP: 'StorageProp',
40  STORAGE_LINK: 'StorageLink',
41  LOCAL_STORAGE_PROP: 'LocalStorageProp',
42  LOCAL_STORAGE_LINK: 'LocalStorageLink',
43  REQUIRE: 'Require',
44  REUSABLE_V1: 'Reusable',
45  REUSABLE_V2: 'ReusableV2',
46  OBSERVED_V1: 'Observed',
47  OBSERVED_V2: 'ObservedV2',
48  TYPE: 'Type',
49  WATCH: 'Watch',
50  BUILDER: 'Builder',
51  TRACK: 'Track',
52  TRACE: 'Trace',
53  ONCE: 'Once',
54  MONITOR: 'Monitor',
55  LOCAL_BUILDER: 'LocalBuilder',
56};
57
58const PUBLIC_PROPERTY_MODIFIERS: Number = 4;
59const PROTECTED_PROPERTY_MODIFIERS: Number = 8;
60const PRIVATE_PROPERTY_MODIFIERS: Number = 16;
61export function getIdentifierName(node: arkts.AstNode): string {
62  if (!arkts.isIdentifier(node)) {
63    throw new Error(`Except a Identifier type!`);
64  }
65  return node.name;
66}
67
68export function getAnnotationName(annotation: arkts.AnnotationUsage): string {
69  if (!annotation.expr) {
70    throw new Error(`The expr property does not exist!`);
71  }
72  return getIdentifierName(annotation.expr);
73}
74
75export function getAnnotationUsage(
76  declaration: arkts.StructDeclaration,
77  annotationName: string,
78): arkts.AnnotationUsage | undefined {
79  return declaration.definition.annotations.find(
80    (annotation) =>
81      annotation.expr &&
82      arkts.isIdentifier(annotation.expr) &&
83      annotation.expr.name === annotationName,
84  );
85}
86
87export function getClassAnnotationUsage(
88  declaration: arkts.ClassDeclaration,
89  annotationName: string,
90): arkts.AnnotationUsage | undefined {
91  if (!declaration.definition || !declaration.definition.annotations) {
92    return undefined;
93  }
94  return declaration.definition.annotations.find(
95    (annotation) =>
96      annotation.expr &&
97      ((arkts.isIdentifier(annotation.expr) && annotation.expr.name === annotationName) ||
98        (arkts.isCallExpression(annotation.expr) &&
99          arkts.isIdentifier(annotation.expr) &&
100          annotation.expr.name === annotationName))
101  );
102}
103
104
105
106export function getClassPropertyName(property: arkts.ClassProperty): string {
107  return getIdentifierName(property.key);
108}
109
110export function getClassPropertyType(property: arkts.ClassProperty): string {
111  return property.typeAnnotation.dumpSrc();
112}
113
114export function getClassPropertyAnnotationNames(
115  property: arkts.ClassProperty,
116): string[] {
117  return property.annotations.map((annotation) =>
118    getAnnotationName(annotation),
119  );
120}
121
122export function isPublicClassProperty(property: arkts.ClassProperty): boolean {
123  // todo 使用接口实现
124  return property.modifiers === PUBLIC_PROPERTY_MODIFIERS;
125}
126
127export function isPrivateClassProperty(property: arkts.ClassProperty): boolean {
128  // todo 使用接口实现
129  return property.modifiers === PRIVATE_PROPERTY_MODIFIERS;
130}
131
132export function isProtectedlassProperty(property: arkts.ClassProperty): boolean {
133  // todo 使用接口实现
134  return property.modifiers === PROTECTED_PROPERTY_MODIFIERS;
135}
136
137export class MultiMap<K, V> {
138  private readonly map: Map<K, V[]>;
139  constructor() {
140    this.map = new Map();
141  }
142  /**
143   * Add key-value pairs to MultiMap
144   * @param key key
145   * @param value value
146   */
147  add(key: K, value: V): void {
148    if (!this.map.has(key)) {
149      this.map.set(key, []);
150    }
151    this.map.get(key)!.push(value);
152  }
153
154  /**
155   * Gets all the values of the specified key
156   * @param key key
157   * @returns An array of values, which returns an empty array if the key does not exist
158   */
159  get(key: K): V[] {
160    return this.map.get(key) || [];
161  }
162
163  /**
164   * Check if the specified key exists in the MultiMap
165   * @param key key
166   * @returns Whether it exists
167   */
168  has(key: K): boolean {
169    return this.map.has(key);
170  }
171}
172
173interface ComponentJson {
174  name: string;
175  atomic?: boolean;
176  attrs: string[];
177}
178
179export function getContainerComponents(dirPath: string): Set<string> {
180  const resultSet = new Set<string>();
181  const absolutePath = path.resolve(__dirname, dirPath);
182
183  if (!fs.existsSync(absolutePath)) {
184    throw new Error(`Directory does not exist: ${absolutePath}`);
185  }
186  // Read all files in the directory
187  const files = fs.readdirSync(absolutePath);
188
189  files.forEach(file => {
190    if (path.extname(file) === '.json') {
191      const filePath = path.join(absolutePath, file);
192      const fileContent = fs.readFileSync(filePath, 'utf-8');
193      const componentJson: ComponentJson = JSON.parse(fileContent);
194      if ((!componentJson.atomic || componentJson.atomic !== true) && (componentJson.name)) {
195        resultSet.add(componentJson.name);
196      }
197    }
198  });
199  return resultSet;
200}