• 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';
17
18export function annotation(name: string): arkts.AnnotationUsage {
19    const ident: arkts.Identifier = arkts.factory.createIdentifier(name).setAnnotationUsage();
20    const annotation: arkts.AnnotationUsage = arkts.factory.createAnnotationUsage(ident);
21
22    annotation.modifiers = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_ANNOTATION_USAGE;
23    ident.parent = annotation;
24
25    return annotation;
26}
27
28export function isAnnotation(node: arkts.AnnotationUsage, annoName: string) {
29    return node.expr !== undefined && arkts.isIdentifier(node.expr) && node.expr.name === annoName;
30}
31
32export function removeAnnotationByName(
33    annotations: readonly arkts.AnnotationUsage[],
34    annoName: string
35): arkts.AnnotationUsage[] {
36    return annotations.filter((it) => !isAnnotation(it, annoName));
37}
38
39export function expectName(node: arkts.AstNode | undefined): string {
40    if (!node) {
41        throw new Error('Expected an identifier, got empty node');
42    }
43    if (!arkts.isIdentifier(node)) {
44        throw new Error('Expected an identifier, got: ' + arkts.nodeType(node).toString());
45    }
46    return node.name;
47}
48
49export function mangle(value: string): string {
50    return `__${value}`;
51}
52
53export function backingField(originalName: string): string {
54    return mangle(`backing_${originalName}`);
55}
56
57export function filterDefined<T>(value: (T | undefined)[]): T[] {
58    return value.filter((it: T | undefined): it is T => it != undefined);
59}
60
61export function collect<T>(...value: (ReadonlyArray<T> | T | undefined)[]): T[] {
62    const empty: (T | undefined)[] = [];
63    return filterDefined(empty.concat(...value));
64}
65
66export function matchPrefix(prefixCollection: (string | RegExp)[], name: string): boolean {
67    for (const prefix of prefixCollection) {
68        let regex: RegExp;
69
70        if (typeof prefix === 'string') {
71            regex = new RegExp('^' + prefix);
72        } else {
73            regex = new RegExp('^' + prefix.source);
74        }
75
76        if (regex.test(name)) {
77            return true;
78        }
79    }
80    return false;
81}
82
83export function updateStructMetadata(
84    structInfo: arkts.StructInfo,
85    propertyName: string,
86    properties: string[],
87    modifiers: arkts.Es2pandaModifierFlags,
88    hasStateManagementType?: boolean
89): arkts.StructInfo {
90    const metadata: Record<string, arkts.StructVariableMetadata> = structInfo.metadata ?? {};
91    metadata[propertyName] = {
92        name: propertyName,
93        properties,
94        modifiers,
95        hasStateManagementType,
96    };
97    structInfo.metadata = metadata;
98    return structInfo;
99}
100
101export function moveToFront<T>(arr: T[], idx: number): T[] {
102    if (idx < 0 || idx >= arr.length) {
103        throw new Error(`Index ${idx} is out of bounds for array of length ${arr.length}`);
104    }
105
106    const copy = [...arr];
107    const [item] = copy.splice(idx, 1);
108    return [item, ...copy];
109}