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 getValueInAnnotation, 25 DecoratorNames, 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 ConsumeTranslator 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 'ConsumeDecoratedVariable', 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 alias = getValueInAnnotation(this.property, DecoratorNames.CONSUME); 96 const assign: arkts.AssignmentExpression = arkts.factory.createAssignmentExpression( 97 generateThisBacking(newName), 98 arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_SUBSTITUTION, 99 factory.generateInitConsumeCall(originalName, this.property, alias ?? originalName) 100 ); 101 return arkts.factory.createExpressionStatement(assign); 102 } 103} 104