1/* 2 * Copyright (c) 2024-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 { ArkField, FieldCategory } from '../ArkField'; 17import { ArkFile } from '../ArkFile'; 18import { ArkMethod } from '../ArkMethod'; 19import { ArkNamespace } from '../ArkNamespace'; 20import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; 21import ts, { ParameterDeclaration } from 'ohos-typescript'; 22import { ArkClass, ClassCategory } from '../ArkClass'; 23import { buildArkMethodFromArkClass, buildDefaultArkMethodFromArkClass, buildInitMethod, checkAndUpdateMethod } from './ArkMethodBuilder'; 24import { buildDecorators, buildGenericType, buildHeritageClauses, buildModifiers, buildTypeParameters, tsNode2Type } from './builderUtils'; 25import { buildGetAccessor2ArkField, buildIndexSignature2ArkField, buildProperty2ArkField } from './ArkFieldBuilder'; 26import { ArkIRTransformer } from '../../common/ArkIRTransformer'; 27import { ArkAssignStmt, ArkInvokeStmt, Stmt } from '../../base/Stmt'; 28import { ArkInstanceFieldRef } from '../../base/Ref'; 29import { 30 ANONYMOUS_CLASS_DELIMITER, 31 ANONYMOUS_CLASS_PREFIX, 32 DEFAULT_ARK_CLASS_NAME, 33 INSTANCE_INIT_METHOD_NAME, 34 STATIC_BLOCK_METHOD_NAME_PREFIX, 35 STATIC_INIT_METHOD_NAME, 36} from '../../common/Const'; 37import { IRUtils } from '../../common/IRUtils'; 38import { ClassSignature, FieldSignature, MethodSignature, MethodSubSignature } from '../ArkSignature'; 39import { ArkSignatureBuilder } from './ArkSignatureBuilder'; 40import { FullPosition, LineColPosition } from '../../base/Position'; 41import { Type, UnknownType, VoidType } from '../../base/Type'; 42import { BodyBuilder } from './BodyBuilder'; 43import { ArkStaticInvokeExpr } from '../../base/Expr'; 44 45const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkClassBuilder'); 46 47export type ClassLikeNode = 48 | ts.ClassDeclaration 49 | ts.InterfaceDeclaration 50 | ts.EnumDeclaration 51 | ts.ClassExpression 52 | ts.TypeLiteralNode 53 | ts.StructDeclaration 54 | ts.ObjectLiteralExpression; 55 56type ClassLikeNodeWithMethod = 57 | ts.ClassDeclaration 58 | ts.InterfaceDeclaration 59 | ts.EnumDeclaration 60 | ts.ClassExpression 61 | ts.TypeLiteralNode 62 | ts.StructDeclaration; 63 64export function buildDefaultArkClassFromArkFile(arkFile: ArkFile, defaultClass: ArkClass, astRoot: ts.SourceFile): void { 65 defaultClass.setDeclaringArkFile(arkFile); 66 defaultClass.setCategory(ClassCategory.CLASS); 67 buildDefaultArkClass(defaultClass, astRoot); 68} 69 70export function buildDefaultArkClassFromArkNamespace( 71 arkNamespace: ArkNamespace, 72 defaultClass: ArkClass, 73 nsNode: ts.ModuleDeclaration, 74 sourceFile: ts.SourceFile 75): void { 76 defaultClass.setDeclaringArkNamespace(arkNamespace); 77 defaultClass.setDeclaringArkFile(arkNamespace.getDeclaringArkFile()); 78 buildDefaultArkClass(defaultClass, sourceFile, nsNode); 79} 80 81export function buildNormalArkClassFromArkMethod(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { 82 const namespace = cls.getDeclaringArkNamespace(); 83 if (namespace) { 84 buildNormalArkClassFromArkNamespace(clsNode, namespace, cls, sourceFile, declaringMethod); 85 } else { 86 buildNormalArkClassFromArkFile(clsNode, cls.getDeclaringArkFile(), cls, sourceFile, declaringMethod); 87 } 88} 89 90export function buildNormalArkClassFromArkFile( 91 clsNode: ClassLikeNode, 92 arkFile: ArkFile, 93 cls: ArkClass, 94 sourceFile: ts.SourceFile, 95 declaringMethod?: ArkMethod 96): void { 97 cls.setDeclaringArkFile(arkFile); 98 cls.setCode(clsNode.getText(sourceFile)); 99 const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, clsNode.getStart(sourceFile)); 100 cls.setLine(line + 1); 101 cls.setColumn(character + 1); 102 103 buildNormalArkClass(clsNode, cls, sourceFile, declaringMethod); 104 arkFile.addArkClass(cls); 105} 106 107export function buildNormalArkClassFromArkNamespace( 108 clsNode: ClassLikeNode, 109 arkNamespace: ArkNamespace, 110 cls: ArkClass, 111 sourceFile: ts.SourceFile, 112 declaringMethod?: ArkMethod 113): void { 114 cls.setDeclaringArkNamespace(arkNamespace); 115 cls.setDeclaringArkFile(arkNamespace.getDeclaringArkFile()); 116 cls.setCode(clsNode.getText(sourceFile)); 117 const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, clsNode.getStart(sourceFile)); 118 cls.setLine(line + 1); 119 cls.setColumn(character + 1); 120 121 buildNormalArkClass(clsNode, cls, sourceFile, declaringMethod); 122 arkNamespace.addArkClass(cls); 123} 124 125function buildDefaultArkClass(cls: ArkClass, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration): void { 126 const defaultArkClassSignature = new ClassSignature( 127 DEFAULT_ARK_CLASS_NAME, 128 cls.getDeclaringArkFile().getFileSignature(), 129 cls.getDeclaringArkNamespace()?.getSignature() || null 130 ); 131 cls.setSignature(defaultArkClassSignature); 132 133 genDefaultArkMethod(cls, sourceFile, node); 134} 135 136function genDefaultArkMethod(cls: ArkClass, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration): void { 137 let defaultMethod = new ArkMethod(); 138 buildDefaultArkMethodFromArkClass(cls, defaultMethod, sourceFile, node); 139 cls.setDefaultArkMethod(defaultMethod); 140} 141 142export function buildNormalArkClass(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { 143 switch (clsNode.kind) { 144 case ts.SyntaxKind.StructDeclaration: 145 buildStruct2ArkClass(clsNode, cls, sourceFile, declaringMethod); 146 break; 147 case ts.SyntaxKind.ClassDeclaration: 148 buildClass2ArkClass(clsNode, cls, sourceFile, declaringMethod); 149 break; 150 case ts.SyntaxKind.ClassExpression: 151 buildClass2ArkClass(clsNode, cls, sourceFile, declaringMethod); 152 break; 153 case ts.SyntaxKind.InterfaceDeclaration: 154 buildInterface2ArkClass(clsNode, cls, sourceFile, declaringMethod); 155 break; 156 case ts.SyntaxKind.EnumDeclaration: 157 buildEnum2ArkClass(clsNode, cls, sourceFile, declaringMethod); 158 break; 159 case ts.SyntaxKind.TypeLiteral: 160 buildTypeLiteralNode2ArkClass(clsNode, cls, sourceFile, declaringMethod); 161 break; 162 case ts.SyntaxKind.ObjectLiteralExpression: 163 buildObjectLiteralExpression2ArkClass(clsNode, cls, sourceFile, declaringMethod); 164 break; 165 default: 166 } 167 IRUtils.setComments(cls, clsNode, sourceFile, cls.getDeclaringArkFile().getScene().getOptions()); 168} 169 170function init4InstanceInitMethod(cls: ArkClass): void { 171 const instanceInit = new ArkMethod(); 172 instanceInit.setDeclaringArkClass(cls); 173 instanceInit.setIsGeneratedFlag(true); 174 const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(INSTANCE_INIT_METHOD_NAME); 175 methodSubSignature.setReturnType(VoidType.getInstance()); 176 const methodSignature = new MethodSignature(instanceInit.getDeclaringArkClass().getSignature(), methodSubSignature); 177 instanceInit.setImplementationSignature(methodSignature); 178 instanceInit.setLineCol(0); 179 180 checkAndUpdateMethod(instanceInit, cls); 181 cls.addMethod(instanceInit); 182 cls.setInstanceInitMethod(instanceInit); 183} 184 185function init4StaticInitMethod(cls: ArkClass): void { 186 const staticInit = new ArkMethod(); 187 staticInit.setDeclaringArkClass(cls); 188 staticInit.setIsGeneratedFlag(true); 189 const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(STATIC_INIT_METHOD_NAME); 190 methodSubSignature.setReturnType(VoidType.getInstance()); 191 const methodSignature = new MethodSignature(staticInit.getDeclaringArkClass().getSignature(), methodSubSignature); 192 staticInit.setImplementationSignature(methodSignature); 193 staticInit.setLineCol(0); 194 195 checkAndUpdateMethod(staticInit, cls); 196 cls.addMethod(staticInit); 197 cls.setStaticInitMethod(staticInit); 198} 199 200function buildStruct2ArkClass(clsNode: ts.StructDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { 201 const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); 202 const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); 203 cls.setSignature(classSignature); 204 205 if (clsNode.typeParameters) { 206 buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach(typeParameter => { 207 cls.addGenericType(typeParameter); 208 }); 209 } 210 211 initHeritage(buildHeritageClauses(clsNode.heritageClauses), cls); 212 213 cls.setModifiers(buildModifiers(clsNode)); 214 cls.setDecorators(buildDecorators(clsNode, sourceFile)); 215 216 cls.setCategory(ClassCategory.STRUCT); 217 init4InstanceInitMethod(cls); 218 init4StaticInitMethod(cls); 219 buildArkClassMembers(clsNode, cls, sourceFile); 220} 221 222function buildClass2ArkClass(clsNode: ts.ClassDeclaration | ts.ClassExpression, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { 223 const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); 224 const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); 225 cls.setSignature(classSignature); 226 227 if (clsNode.typeParameters) { 228 buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach(typeParameter => { 229 cls.addGenericType(typeParameter); 230 }); 231 } 232 233 initHeritage(buildHeritageClauses(clsNode.heritageClauses), cls); 234 235 cls.setModifiers(buildModifiers(clsNode)); 236 cls.setDecorators(buildDecorators(clsNode, sourceFile)); 237 238 cls.setCategory(ClassCategory.CLASS); 239 init4InstanceInitMethod(cls); 240 init4StaticInitMethod(cls); 241 buildArkClassMembers(clsNode, cls, sourceFile); 242} 243 244function initHeritage(heritageClauses: Map<string, string>, cls: ArkClass): void { 245 let superName = ''; 246 for (let [key, value] of heritageClauses) { 247 if (value === ts.SyntaxKind[ts.SyntaxKind.ExtendsKeyword]) { 248 superName = key; 249 break; 250 } 251 } 252 cls.addHeritageClassName(superName); 253 for (let key of heritageClauses.keys()) { 254 cls.addHeritageClassName(key); 255 } 256} 257 258function buildInterface2ArkClass(clsNode: ts.InterfaceDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { 259 const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); 260 const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); 261 cls.setSignature(classSignature); 262 263 if (clsNode.typeParameters) { 264 buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach(typeParameter => { 265 cls.addGenericType(typeParameter); 266 }); 267 } 268 269 initHeritage(buildHeritageClauses(clsNode.heritageClauses), cls); 270 271 cls.setModifiers(buildModifiers(clsNode)); 272 cls.setDecorators(buildDecorators(clsNode, sourceFile)); 273 274 cls.setCategory(ClassCategory.INTERFACE); 275 276 buildArkClassMembers(clsNode, cls, sourceFile); 277} 278 279function buildEnum2ArkClass(clsNode: ts.EnumDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { 280 const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); 281 const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); 282 cls.setSignature(classSignature); 283 284 cls.setModifiers(buildModifiers(clsNode)); 285 cls.setDecorators(buildDecorators(clsNode, sourceFile)); 286 287 cls.setCategory(ClassCategory.ENUM); 288 289 init4StaticInitMethod(cls); 290 buildArkClassMembers(clsNode, cls, sourceFile); 291} 292 293function buildTypeLiteralNode2ArkClass(clsNode: ts.TypeLiteralNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { 294 const className = genClassName('', cls, declaringMethod); 295 const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); 296 cls.setSignature(classSignature); 297 298 cls.setCategory(ClassCategory.TYPE_LITERAL); 299 if (ts.isTypeAliasDeclaration(clsNode.parent) && clsNode.parent.typeParameters) { 300 buildTypeParameters(clsNode.parent.typeParameters, sourceFile, cls).forEach(typeParameter => { 301 cls.addGenericType(typeParameter); 302 }); 303 } 304 buildArkClassMembers(clsNode, cls, sourceFile); 305} 306 307function buildObjectLiteralExpression2ArkClass( 308 clsNode: ts.ObjectLiteralExpression, 309 cls: ArkClass, 310 sourceFile: ts.SourceFile, 311 declaringMethod?: ArkMethod 312): void { 313 const className = genClassName('', cls, declaringMethod); 314 const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); 315 cls.setSignature(classSignature); 316 317 cls.setCategory(ClassCategory.OBJECT); 318 319 let arkMethods: ArkMethod[] = []; 320 321 init4InstanceInitMethod(cls); 322 const instanceIRTransformer = new ArkIRTransformer(sourceFile, cls.getInstanceInitMethod()); 323 const instanceFieldInitializerStmts: Stmt[] = []; 324 clsNode.properties.forEach(property => { 325 if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isSpreadAssignment(property)) { 326 const arkField = buildProperty2ArkField(property, sourceFile, cls); 327 if (ts.isPropertyAssignment(property)) { 328 getInitStmts(instanceIRTransformer, arkField, property.initializer); 329 arkField.getInitializer().forEach(stmt => instanceFieldInitializerStmts.push(stmt)); 330 } 331 } else { 332 let arkMethod = new ArkMethod(); 333 arkMethod.setDeclaringArkClass(cls); 334 buildArkMethodFromArkClass(property, cls, arkMethod, sourceFile); 335 } 336 }); 337 buildInitMethod(cls.getInstanceInitMethod(), instanceFieldInitializerStmts, instanceIRTransformer.getThisLocal()); 338 arkMethods.forEach(mtd => { 339 checkAndUpdateMethod(mtd, cls); 340 cls.addMethod(mtd); 341 }); 342} 343 344function genClassName(declaringName: string, cls: ArkClass, declaringMethod?: ArkMethod): string { 345 if (!declaringName) { 346 const declaringArkNamespace = cls.getDeclaringArkNamespace(); 347 const num = declaringArkNamespace ? declaringArkNamespace.getAnonymousClassNumber() : cls.getDeclaringArkFile().getAnonymousClassNumber(); 348 declaringName = ANONYMOUS_CLASS_PREFIX + num; 349 } 350 const suffix = declaringMethod ? ANONYMOUS_CLASS_DELIMITER + declaringMethod.getDeclaringArkClass().getName() + '.' + declaringMethod.getName() : ''; 351 return declaringName + suffix; 352} 353 354function buildArkClassMembers(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile): void { 355 if (ts.isObjectLiteralExpression(clsNode)) { 356 return; 357 } 358 buildMethodsForClass(clsNode, cls, sourceFile); 359 const staticBlockMethodSignatures = buildStaticBlocksForClass(clsNode, cls, sourceFile); 360 let instanceIRTransformer: ArkIRTransformer; 361 let staticIRTransformer: ArkIRTransformer; 362 if (ts.isClassDeclaration(clsNode) || ts.isClassExpression(clsNode) || ts.isStructDeclaration(clsNode)) { 363 instanceIRTransformer = new ArkIRTransformer(sourceFile, cls.getInstanceInitMethod()); 364 staticIRTransformer = new ArkIRTransformer(sourceFile, cls.getStaticInitMethod()); 365 } 366 if (ts.isEnumDeclaration(clsNode)) { 367 staticIRTransformer = new ArkIRTransformer(sourceFile, cls.getStaticInitMethod()); 368 } 369 const staticInitStmts: Stmt[] = []; 370 const instanceInitStmts: Stmt[] = []; 371 let staticBlockId = 0; 372 clsNode.members.forEach(member => { 373 if ( 374 ts.isMethodDeclaration(member) || 375 ts.isConstructorDeclaration(member) || 376 ts.isMethodSignature(member) || 377 ts.isConstructSignatureDeclaration(member) || 378 ts.isAccessor(member) || 379 ts.isCallSignatureDeclaration(member) 380 ) { 381 // these node types have been handled at the beginning of this function by calling buildMethodsForClass 382 return; 383 } else if (ts.isPropertyDeclaration(member) || ts.isPropertySignature(member)) { 384 const arkField = buildProperty2ArkField(member, sourceFile, cls); 385 if (ts.isClassDeclaration(clsNode) || ts.isClassExpression(clsNode) || ts.isStructDeclaration(clsNode)) { 386 if (arkField.isStatic()) { 387 getInitStmts(staticIRTransformer, arkField, member.initializer); 388 arkField.getInitializer().forEach(stmt => staticInitStmts.push(stmt)); 389 } else { 390 if (!instanceIRTransformer) { 391 console.log(clsNode.getText(sourceFile)); 392 } 393 getInitStmts(instanceIRTransformer, arkField, member.initializer); 394 arkField.getInitializer().forEach(stmt => instanceInitStmts.push(stmt)); 395 } 396 } 397 } else if (ts.isEnumMember(member)) { 398 const arkField = buildProperty2ArkField(member, sourceFile, cls); 399 getInitStmts(staticIRTransformer, arkField, member.initializer); 400 arkField.getInitializer().forEach(stmt => staticInitStmts.push(stmt)); 401 } else if (ts.isIndexSignatureDeclaration(member)) { 402 buildIndexSignature2ArkField(member, sourceFile, cls); 403 } else if (ts.isClassStaticBlockDeclaration(member)) { 404 const currStaticBlockMethodSig = staticBlockMethodSignatures[staticBlockId++]; 405 const staticBlockInvokeExpr = new ArkStaticInvokeExpr(currStaticBlockMethodSig, []); 406 staticInitStmts.push(new ArkInvokeStmt(staticBlockInvokeExpr)); 407 } else if (ts.isSemicolonClassElement(member)) { 408 logger.trace('Skip these members.'); 409 } else { 410 logger.warn(`Please contact developers to support new member in class: ${cls.getSignature().toString()}, member: ${member.getText()}!`); 411 } 412 }); 413 if (ts.isClassDeclaration(clsNode) || ts.isClassExpression(clsNode) || ts.isStructDeclaration(clsNode)) { 414 buildInitMethod(cls.getInstanceInitMethod(), instanceInitStmts, instanceIRTransformer!.getThisLocal()); 415 buildInitMethod(cls.getStaticInitMethod(), staticInitStmts, staticIRTransformer!.getThisLocal()); 416 } 417 if (ts.isEnumDeclaration(clsNode)) { 418 buildInitMethod(cls.getStaticInitMethod(), staticInitStmts, staticIRTransformer!.getThisLocal()); 419 } 420} 421 422function buildMethodsForClass(clsNode: ClassLikeNodeWithMethod, cls: ArkClass, sourceFile: ts.SourceFile): void { 423 clsNode.members.forEach(member => { 424 if ( 425 ts.isMethodDeclaration(member) || 426 ts.isConstructorDeclaration(member) || 427 ts.isMethodSignature(member) || 428 ts.isConstructSignatureDeclaration(member) || 429 ts.isAccessor(member) || 430 ts.isCallSignatureDeclaration(member) 431 ) { 432 let mthd: ArkMethod = new ArkMethod(); 433 buildArkMethodFromArkClass(member, cls, mthd, sourceFile); 434 if (ts.isGetAccessor(member)) { 435 buildGetAccessor2ArkField(member, mthd, sourceFile); 436 } else if (ts.isConstructorDeclaration(member)) { 437 buildParameterProperty2ArkField(member.parameters, cls, sourceFile); 438 } 439 } 440 }); 441} 442 443// params of constructor method may have modifiers such as public or private to directly define class properties with constructor 444function buildParameterProperty2ArkField(params: ts.NodeArray<ParameterDeclaration>, cls: ArkClass, sourceFile: ts.SourceFile): void { 445 if (params.length === 0) { 446 return; 447 } 448 params.forEach(parameter => { 449 if (parameter.modifiers === undefined || !ts.isIdentifier(parameter.name)) { 450 return; 451 } 452 let field = new ArkField(); 453 field.setDeclaringArkClass(cls); 454 455 field.setCode(parameter.getText(sourceFile)); 456 field.setCategory(FieldCategory.PARAMETER_PROPERTY); 457 field.setOriginPosition(LineColPosition.buildFromNode(parameter, sourceFile)); 458 459 let fieldName = parameter.name.text; 460 let fieldType: Type; 461 if (parameter.type) { 462 fieldType = buildGenericType(tsNode2Type(parameter.type, sourceFile, field), field); 463 } else { 464 fieldType = UnknownType.getInstance(); 465 } 466 const fieldSignature = new FieldSignature(fieldName, cls.getSignature(), fieldType, false); 467 field.setSignature(fieldSignature); 468 field.setModifiers(buildModifiers(parameter)); 469 if (parameter.questionToken) { 470 field.setQuestionToken(true); 471 } 472 cls.addField(field); 473 }); 474} 475 476function buildStaticBlocksForClass(clsNode: ClassLikeNodeWithMethod, cls: ArkClass, sourceFile: ts.SourceFile): MethodSignature[] { 477 let staticInitBlockId = 0; 478 const staticBlockMethodSignatures: MethodSignature[] = []; 479 clsNode.members.forEach(member => { 480 if (ts.isClassStaticBlockDeclaration(member)) { 481 const staticBlockMethod = new ArkMethod(); 482 staticBlockMethod.setDeclaringArkClass(cls); 483 staticBlockMethod.setIsGeneratedFlag(true); 484 staticBlockMethod.setCode(member.getText(sourceFile)); 485 const methodName = STATIC_BLOCK_METHOD_NAME_PREFIX + staticInitBlockId++; 486 const methodSubSignature = new MethodSubSignature(methodName, [], VoidType.getInstance(), true); 487 const methodSignature = new MethodSignature(cls.getSignature(), methodSubSignature); 488 staticBlockMethodSignatures.push(methodSignature); 489 staticBlockMethod.setImplementationSignature(methodSignature); 490 const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, member.getStart(sourceFile)); 491 staticBlockMethod.setLine(line + 1); 492 staticBlockMethod.setColumn(character + 1); 493 494 let bodyBuilder = new BodyBuilder(staticBlockMethod.getSignature(), member, staticBlockMethod, sourceFile); 495 staticBlockMethod.setBodyBuilder(bodyBuilder); 496 497 cls.addMethod(staticBlockMethod); 498 } 499 }); 500 return staticBlockMethodSignatures; 501} 502 503function getInitStmts(transformer: ArkIRTransformer, field: ArkField, initNode?: ts.Node): void { 504 if (initNode) { 505 const stmts: Stmt[] = []; 506 let { value: initValue, valueOriginalPositions: initPositions, stmts: initStmts } = transformer.tsNodeToValueAndStmts(initNode); 507 initStmts.forEach(stmt => stmts.push(stmt)); 508 if (IRUtils.moreThanOneAddress(initValue)) { 509 ({ value: initValue, valueOriginalPositions: initPositions, stmts: initStmts } = transformer.generateAssignStmtForValue(initValue, initPositions)); 510 initStmts.forEach(stmt => stmts.push(stmt)); 511 } 512 513 const fieldRef = new ArkInstanceFieldRef(transformer.getThisLocal(), field.getSignature()); 514 const fieldRefPositions = [FullPosition.DEFAULT, FullPosition.DEFAULT]; 515 const assignStmt = new ArkAssignStmt(fieldRef, initValue); 516 assignStmt.setOperandOriginalPositions([...fieldRefPositions, ...initPositions]); 517 stmts.push(assignStmt); 518 519 const fieldSourceCode = field.getCode(); 520 const fieldOriginPosition = field.getOriginPosition(); 521 for (const stmt of stmts) { 522 stmt.setOriginPositionInfo(fieldOriginPosition); 523 stmt.setOriginalText(fieldSourceCode); 524 } 525 field.setInitializer(stmts); 526 if (field.getType() instanceof UnknownType) { 527 field.getSignature().setType(initValue.getType()); 528 } 529 } 530} 531