• 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
18import { backingField, expectName } from '../../common/arkts-utils';
19import { PropertyTranslator } from './base';
20import { GetterSetter, InitializerConstructor } from './types';
21import { DecoratorNames, generateToRecord } from './utils';
22
23function getLocalStorageLinkValueStr(node: arkts.AstNode): string | undefined {
24    if (!arkts.isClassProperty(node) || !node.value) return undefined;
25    return arkts.isStringLiteral(node.value) ? node.value.str : undefined;
26}
27
28function getLocalStorageLinkAnnotationValue(anno: arkts.AnnotationUsage): string | undefined {
29    const isStorageLinkAnnotation: boolean =
30        !!anno.expr && arkts.isIdentifier(anno.expr) && anno.expr.name === DecoratorNames.LOCAL_STORAGE_LINK;
31
32    if (isStorageLinkAnnotation && anno.properties.length === 1) {
33        return getLocalStorageLinkValueStr(anno.properties.at(0)!);
34    }
35    return undefined;
36}
37
38function getLocalStorageLinkValueInAnnotation(node: arkts.ClassProperty): string | undefined {
39    const annotations: readonly arkts.AnnotationUsage[] = node.annotations;
40
41    for (let i = 0; i < annotations.length; i++) {
42        const anno: arkts.AnnotationUsage = annotations[i];
43        const str: string | undefined = getLocalStorageLinkAnnotationValue(anno);
44        if (!!str) {
45            return str;
46        }
47    }
48
49    return undefined;
50}
51
52export class LocalStorageLinkTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter {
53    translateMember(): arkts.AstNode[] {
54        const originalName: string = expectName(this.property.key);
55        const newName: string = backingField(originalName);
56
57        this.cacheTranslatedInitializer(newName, originalName); // TODO: need to release cache after some point...
58        return this.translateWithoutInitializer(newName, originalName);
59    }
60
61    cacheTranslatedInitializer(newName: string, originalName: string): void {
62        const currentStructInfo: arkts.StructInfo = arkts.GlobalInfo.getInfoInstance().getStructInfo(this.structName);
63        const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName);
64        currentStructInfo.initializeBody.push(initializeStruct);
65
66        if (currentStructInfo.isReusable) {
67            const toRecord = generateToRecord(newName, originalName);
68            currentStructInfo.toRecordBody.push(toRecord);
69        }
70
71        arkts.GlobalInfo.getInfoInstance().setStructInfo(this.structName, currentStructInfo);
72    }
73
74    generateInitializeStruct(newName: string, originalName: string): arkts.AstNode {
75        const localStorageLinkValueStr: string | undefined = getLocalStorageLinkValueInAnnotation(this.property);
76        if (!localStorageLinkValueStr) {
77            throw new Error('LocalStorageLink required only one value!!'); // TODO: replace this with proper error message.
78        }
79
80        const call = arkts.factory.createCallExpression(
81            arkts.factory.createIdentifier('StorageLinkState'),
82            this.property.typeAnnotation ? [this.property.typeAnnotation] : [],
83            [
84                arkts.factory.createMemberExpression(
85                    arkts.factory.createThisExpression(),
86                    arkts.factory.createIdentifier('_entry_local_storage_'),
87                    arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS,
88                    false,
89                    false
90                ),
91                arkts.factory.createStringLiteral(localStorageLinkValueStr),
92                this.property.value ?? arkts.factory.createUndefinedLiteral(),
93            ]
94        );
95
96        return arkts.factory.createAssignmentExpression(
97            arkts.factory.createMemberExpression(
98                arkts.factory.createThisExpression(),
99                arkts.factory.createIdentifier(newName),
100                arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS,
101                false,
102                false
103            ),
104            arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_SUBSTITUTION,
105            call
106        );
107    }
108}
109