• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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