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 { ArkClass } from '../../core/model/ArkClass'; 17import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; 18import { BasePrinter, Dump } from '../base/BasePrinter'; 19import { ArkIRFieldPrinter } from './ArkIRFieldPrinter'; 20import { ArkIRMethodPrinter } from './ArkIRMethodPrinter'; 21 22/** 23 * @category save 24 */ 25export class ArkIRClassPrinter extends BasePrinter { 26 protected cls: ArkClass; 27 28 public constructor(cls: ArkClass, indent: string = '') { 29 super(indent); 30 this.cls = cls; 31 } 32 33 public getLine(): number { 34 return this.cls.getLine(); 35 } 36 37 public dump(): string { 38 this.printer.clear(); 39 40 const commentsMetadata = this.cls.getMetadata(ArkMetadataKind.LEADING_COMMENTS); 41 if (commentsMetadata instanceof CommentsMetadata) { 42 this.printComments(commentsMetadata); 43 } 44 45 this.printDecorator(this.cls.getDecorators()); 46 // print export class name<> + extends c0 implements x1, x2 { 47 this.printer 48 .writeIndent() 49 .writeSpace(this.modifiersToString(this.cls.getModifiers())) 50 .write(`${this.classOriginTypeToString(this.cls.getCategory())} `); 51 52 this.printer.write(this.cls.getName()); 53 54 const genericsTypes = this.cls.getGenericsTypes(); 55 if (genericsTypes) { 56 this.printer.write(`<${genericsTypes.map(v => v.toString()).join(', ')}>`); 57 } 58 if (this.cls.getSuperClassName() && !this.cls.hasComponentDecorator()) { 59 this.printer.write(` extends ${this.cls.getSuperClassName()}`); 60 } 61 if (this.cls.getImplementedInterfaceNames().length > 0) { 62 this.printer.write(` implements ${this.cls.getImplementedInterfaceNames().join(', ')}`); 63 } 64 65 this.printer.writeLine(' {'); 66 this.printer.incIndent(); 67 let items: Dump[] = []; 68 69 let fieldItems = this.printFields(); 70 fieldItems.sort((a, b) => a.getLine() - b.getLine()); 71 items.push(...fieldItems); 72 73 let methodItems = this.printMethods(); 74 methodItems.sort((a, b) => a.getLine() - b.getLine()); 75 items.push(...methodItems); 76 let isFirstMethod = true; 77 let hasField = false; 78 items.forEach((v): void => { 79 if (v instanceof ArkIRMethodPrinter) { 80 if (!isFirstMethod || hasField) { 81 this.printer.writeLine(''); 82 } else { 83 isFirstMethod = false; 84 } 85 } else if (v instanceof ArkIRFieldPrinter) { 86 hasField = true; 87 } 88 this.printer.write(v.dump()); 89 }); 90 91 this.printer.decIndent(); 92 this.printer.writeIndent().writeLine('}'); 93 94 return this.printer.toString(); 95 } 96 97 protected printMethods(): Dump[] { 98 let items: Dump[] = []; 99 for (let method of this.cls.getMethods(true)) { 100 items.push(new ArkIRMethodPrinter(method, this.printer.getIndent())); 101 } 102 return items; 103 } 104 105 private printFields(): Dump[] { 106 let items: Dump[] = []; 107 for (let field of this.cls.getFields()) { 108 items.push(new ArkIRFieldPrinter(field, this.printer.getIndent())); 109 } 110 return items; 111 } 112} 113