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