• 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 {
19    generateToRecord,
20    createGetter,
21    createSetter2,
22    generateThisBacking,
23    generateGetOrSetCall,
24    getValueInProvideAnnotation,
25    ProvideOptions,
26} from './utils';
27import { PropertyTranslator } from './base';
28import { GetterSetter, InitializerConstructor } from './types';
29import { backingField, expectName } from '../../common/arkts-utils';
30import { createOptionalClassProperty } from '../utils';
31import { factory } from './factory';
32
33export class ProvideTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter {
34    translateMember(): arkts.AstNode[] {
35        const originalName: string = expectName(this.property.key);
36        const newName: string = backingField(originalName);
37        this.cacheTranslatedInitializer(newName, originalName); // TODO: need to release cache after some point...
38        return this.translateWithoutInitializer(newName, originalName);
39    }
40
41    cacheTranslatedInitializer(newName: string, originalName: string): void {
42        const currentStructInfo: arkts.StructInfo = arkts.GlobalInfo.getInfoInstance().getStructInfo(this.structName);
43        const initializeStruct: arkts.AstNode = this.generateInitializeStruct(originalName, newName);
44        currentStructInfo.initializeBody.push(initializeStruct);
45        if (currentStructInfo.isReusable) {
46            const toRecord = generateToRecord(newName, originalName);
47            currentStructInfo.toRecordBody.push(toRecord);
48        }
49        arkts.GlobalInfo.getInfoInstance().setStructInfo(this.structName, currentStructInfo);
50    }
51
52    translateWithoutInitializer(newName: string, originalName: string): arkts.AstNode[] {
53        const field: arkts.ClassProperty = createOptionalClassProperty(
54            newName,
55            this.property,
56            'ProvideDecoratedVariable',
57            arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE
58        );
59        const thisValue: arkts.Expression = generateThisBacking(newName, false, true);
60        const thisGet: arkts.CallExpression = generateGetOrSetCall(thisValue, 'get');
61        const thisSet: arkts.ExpressionStatement = arkts.factory.createExpressionStatement(
62            generateGetOrSetCall(thisValue, 'set')
63        );
64        const getter: arkts.MethodDefinition = this.translateGetter(
65            originalName,
66            this.property.typeAnnotation,
67            thisGet
68        );
69        const setter: arkts.MethodDefinition = this.translateSetter(
70            originalName,
71            this.property.typeAnnotation,
72            thisSet
73        );
74
75        return [field, getter, setter];
76    }
77
78    translateGetter(
79        originalName: string,
80        typeAnnotation: arkts.TypeNode | undefined,
81        returnValue: arkts.Expression
82    ): arkts.MethodDefinition {
83        return createGetter(originalName, typeAnnotation, returnValue);
84    }
85
86    translateSetter(
87        originalName: string,
88        typeAnnotation: arkts.TypeNode | undefined,
89        statement: arkts.AstNode
90    ): arkts.MethodDefinition {
91        return createSetter2(originalName, typeAnnotation, statement);
92    }
93
94    generateInitializeStruct(originalName: string, newName: string): arkts.AstNode {
95        const options: undefined | ProvideOptions = getValueInProvideAnnotation(this.property);
96        const alias: string = options?.alias ?? originalName;
97        const allowOverride: boolean = options?.allowOverride ?? false;
98        const assign: arkts.AssignmentExpression = arkts.factory.createAssignmentExpression(
99            generateThisBacking(newName),
100            arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_SUBSTITUTION,
101            factory.generateAddProvideVarCall(originalName, this.property, alias, allowOverride)
102        );
103        return arkts.factory.createExpressionStatement(assign);
104    }
105}
106