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 { ArkParameterRef, ArkThisRef } from '../base/Ref'; 17import { ArkAssignStmt, ArkReturnStmt, Stmt } from '../base/Stmt'; 18import { 19 AliasType, 20 ClassType, 21 EnumValueType, 22 FunctionType, 23 GenericType, 24 LiteralType, 25 Type, 26 UnionType 27} from '../base/Type'; 28import { Value } from '../base/Value'; 29import { Cfg } from '../graph/Cfg'; 30import { ViewTree } from '../graph/ViewTree'; 31import { ArkBody } from './ArkBody'; 32import { ArkClass, ClassCategory } from './ArkClass'; 33import { MethodSignature, MethodSubSignature } from './ArkSignature'; 34import { BodyBuilder } from './builder/BodyBuilder'; 35import { ArkExport, ExportType } from './ArkExport'; 36import { ANONYMOUS_METHOD_PREFIX, DEFAULT_ARK_METHOD_NAME, LEXICAL_ENV_NAME_PREFIX } from '../common/Const'; 37import { getColNo, getLineNo, LineCol, setCol, setLine } from '../base/Position'; 38import { ArkBaseModel, ModifierType } from './ArkBaseModel'; 39import { ArkError, ArkErrorCode } from '../common/ArkError'; 40import { CALL_BACK } from '../common/EtsConst'; 41import { Constant } from '../base/Constant'; 42import { Local } from '../base/Local'; 43import { ArkFile, Language } from './ArkFile'; 44import { CONSTRUCTOR_NAME } from '../common/TSConst'; 45import { MethodParameter } from './builder/ArkMethodBuilder'; 46import { TypeInference } from '../common/TypeInference'; 47 48export const arkMethodNodeKind = [ 49 'MethodDeclaration', 50 'Constructor', 51 'FunctionDeclaration', 52 'GetAccessor', 53 'SetAccessor', 54 'ArrowFunction', 55 'FunctionExpression', 56 'MethodSignature', 57 'ConstructSignature', 58 'CallSignature', 59]; 60 61/** 62 * @category core/model 63 */ 64export class ArkMethod extends ArkBaseModel implements ArkExport { 65 private code?: string; 66 private declaringArkClass!: ArkClass; 67 // used for the nested function to locate its outer function 68 private outerMethod?: ArkMethod; 69 70 private genericTypes?: GenericType[]; 71 72 private methodDeclareSignatures?: MethodSignature[]; 73 private methodDeclareLineCols?: LineCol[]; 74 75 private methodSignature?: MethodSignature; 76 private lineCol?: LineCol; 77 78 private body?: ArkBody; 79 private viewTree?: ViewTree; 80 81 private bodyBuilder?: BodyBuilder; 82 83 private isGeneratedFlag: boolean = false; 84 private asteriskToken: boolean = false; 85 private questionToken: boolean = false; 86 87 constructor() { 88 super(); 89 } 90 91 /** 92 * Returns the program language of the file where this method defined. 93 */ 94 public getLanguage(): Language { 95 return this.getDeclaringArkClass().getLanguage(); 96 } 97 98 public getExportType(): ExportType { 99 return ExportType.METHOD; 100 } 101 102 public getName(): string { 103 return this.getSignature().getMethodSubSignature().getMethodName(); 104 } 105 106 /** 107 * Returns the codes of method as a **string.** 108 * @returns the codes of method. 109 */ 110 public getCode(): string | undefined { 111 return this.code; 112 } 113 114 public setCode(code: string): void { 115 this.code = code; 116 } 117 118 /** 119 * Get all lines of the method's declarations or null if the method has no seperated declaration. 120 * @returns null or the lines of the method's declarations with number type. 121 */ 122 public getDeclareLines(): number[] | null { 123 if (this.methodDeclareLineCols === undefined) { 124 return null; 125 } 126 let lines: number[] = []; 127 this.methodDeclareLineCols.forEach(lineCol => { 128 lines.push(getLineNo(lineCol)); 129 }); 130 return lines; 131 } 132 133 /** 134 * Get all columns of the method's declarations or null if the method has no seperated declaration. 135 * @returns null or the columns of the method's declarations with number type. 136 */ 137 public getDeclareColumns(): number[] | null { 138 if (this.methodDeclareLineCols === undefined) { 139 return null; 140 } 141 let columns: number[] = []; 142 this.methodDeclareLineCols.forEach(lineCol => { 143 columns.push(getColNo(lineCol)); 144 }); 145 return columns; 146 } 147 148 /** 149 * Set lines and columns of the declarations with number type inputs and then encoded them to LineCol type. 150 * The length of lines and columns should be the same otherwise they cannot be encoded together. 151 * @param lines - the number of lines. 152 * @param columns - the number of columns. 153 * @returns 154 */ 155 public setDeclareLinesAndCols(lines: number[], columns: number[]): void { 156 if (lines?.length !== columns?.length) { 157 return; 158 } 159 this.methodDeclareLineCols = []; 160 lines.forEach((line, index) => { 161 let lineCol: LineCol = 0; 162 lineCol = setLine(lineCol, line); 163 lineCol = setCol(lineCol, columns[index]); 164 (this.methodDeclareLineCols as LineCol[]).push(lineCol); 165 }); 166 } 167 168 /** 169 * Set lineCols of the declarations directly with LineCol type input. 170 * @param lineCols - the encoded lines and columns with LineCol type. 171 * @returns 172 */ 173 public setDeclareLineCols(lineCols: LineCol[]): void { 174 this.methodDeclareLineCols = lineCols; 175 } 176 177 /** 178 * Get encoded lines and columns of the method's declarations or null if the method has no seperated declaration. 179 * @returns null or the encoded lines and columns of the method's declarations with LineCol type. 180 */ 181 public getDeclareLineCols(): LineCol[] | null { 182 return this.methodDeclareLineCols ?? null; 183 } 184 185 /** 186 * Get line of the method's implementation or null if the method has no implementation. 187 * @returns null or the number of the line. 188 */ 189 public getLine(): number | null { 190 if (this.lineCol === undefined) { 191 return null; 192 } 193 return getLineNo(this.lineCol); 194 } 195 196 /** 197 * Set line of the implementation with line number input. 198 * The line number will be encoded together with the original column number. 199 * @param line - the line number of the method implementation. 200 * @returns 201 */ 202 public setLine(line: number): void { 203 if (this.lineCol === undefined) { 204 this.lineCol = 0; 205 } 206 this.lineCol = setLine(this.lineCol, line); 207 } 208 209 /** 210 * Get column of the method's implementation or null if the method has no implementation. 211 * @returns null or the number of the column. 212 */ 213 public getColumn(): number | null { 214 if (this.lineCol === undefined) { 215 return null; 216 } 217 return getColNo(this.lineCol); 218 } 219 220 /** 221 * Set column of the implementation with column number input. 222 * The column number will be encoded together with the original line number. 223 * @param column - the column number of the method implementation. 224 * @returns 225 */ 226 public setColumn(column: number): void { 227 if (this.lineCol === undefined) { 228 this.lineCol = 0; 229 } 230 this.lineCol = setCol(this.lineCol, column); 231 } 232 233 /** 234 * Get encoded line and column of the method's implementation or null if the method has no implementation. 235 * @returns null or the encoded line and column of the method's implementation with LineCol type. 236 */ 237 public getLineCol(): LineCol | null { 238 return this.lineCol ?? null; 239 } 240 241 /** 242 * Set lineCol of the implementation directly with LineCol type input. 243 * @param lineCol - the encoded line and column with LineCol type. 244 * @returns 245 */ 246 public setLineCol(lineCol: LineCol): void { 247 this.lineCol = lineCol; 248 } 249 250 /** 251 * Returns the declaring class of the method. 252 * @returns The declaring class of the method. 253 */ 254 public getDeclaringArkClass(): ArkClass { 255 return this.declaringArkClass; 256 } 257 258 public setDeclaringArkClass(declaringArkClass: ArkClass): void { 259 this.declaringArkClass = declaringArkClass; 260 } 261 262 public getDeclaringArkFile(): ArkFile { 263 return this.declaringArkClass.getDeclaringArkFile(); 264 } 265 266 public isDefaultArkMethod(): boolean { 267 return this.getName() === DEFAULT_ARK_METHOD_NAME; 268 } 269 270 public isAnonymousMethod(): boolean { 271 return this.getName().startsWith(ANONYMOUS_METHOD_PREFIX); 272 } 273 274 public getParameters(): MethodParameter[] { 275 return this.getSignature().getMethodSubSignature().getParameters(); 276 } 277 278 public getReturnType(): Type { 279 return this.getSignature().getType(); 280 } 281 282 /** 283 * Get all declare signatures. 284 * The results could be null if there is no seperated declaration of the method. 285 * @returns null or the method declare signatures. 286 */ 287 public getDeclareSignatures(): MethodSignature[] | null { 288 return this.methodDeclareSignatures ?? null; 289 } 290 291 /** 292 * Get the index of the matched method declare signature among all declare signatures. 293 * The index will be -1 if there is no matched signature found. 294 * @param targetSignature - the target declare signature want to search. 295 * @returns -1 or the index of the matched signature. 296 */ 297 public getDeclareSignatureIndex(targetSignature: MethodSignature): number { 298 let declareSignatures = this.methodDeclareSignatures; 299 if (declareSignatures === undefined) { 300 return -1; 301 } 302 for (let i = 0; i < declareSignatures.length; i++) { 303 if (declareSignatures[i].isMatch(targetSignature)) { 304 return i; 305 } 306 } 307 return -1; 308 } 309 310 /** 311 * Get the method signature of the implementation. 312 * The signature could be null if the method is only a declaration which body is undefined. 313 * @returns null or the method implementation signature. 314 */ 315 public getImplementationSignature(): MethodSignature | null { 316 return this.methodSignature ?? null; 317 } 318 319 /** 320 * Get the method signature of the implementation or the first declaration if there is no implementation. 321 * For a method, the implementation and declaration signatures must not be undefined at the same time. 322 * A {@link MethodSignature} includes: 323 * - Class Signature: indicates which class this method belong to. 324 * - Method SubSignature: indicates the detail info of this method such as method name, parameters, returnType, etc. 325 * @returns The method signature. 326 * @example 327 * 1. Get the signature of method mtd. 328 329 ```typescript 330 let signature = mtd.getSignature(); 331 // ... ... 332 ``` 333 */ 334 public getSignature(): MethodSignature { 335 return this.methodSignature ?? (this.methodDeclareSignatures as MethodSignature[])[0]; 336 } 337 338 /** 339 * Set signatures of all declarations. 340 * It will reset the declaration signatures if they are already defined before. 341 * @param signatures - one signature or a list of signatures. 342 * @returns 343 */ 344 public setDeclareSignatures(signatures: MethodSignature | MethodSignature[]): void { 345 if (Array.isArray(signatures)) { 346 this.methodDeclareSignatures = signatures; 347 } else { 348 this.methodDeclareSignatures = [signatures]; 349 } 350 } 351 352 /** 353 * Reset signature of one declaration with the specified index. 354 * Will do nothing if the index doesn't exist. 355 * @param signature - new signature want to set. 356 * @param index - index of signature want to set. 357 * @returns 358 */ 359 public setDeclareSignatureWithIndex(signature: MethodSignature, index: number): void { 360 if (this.methodDeclareSignatures === undefined || this.methodDeclareSignatures.length <= index) { 361 return; 362 } 363 this.methodDeclareSignatures[index] = signature; 364 } 365 366 /** 367 * Set signature of implementation. 368 * It will reset the implementation signature if it is already defined before. 369 * @param signature - signature of implementation. 370 * @returns 371 */ 372 public setImplementationSignature(signature: MethodSignature): void { 373 this.methodSignature = signature; 374 } 375 376 public getSubSignature(): MethodSubSignature { 377 return this.getSignature().getMethodSubSignature(); 378 } 379 380 public getGenericTypes(): GenericType[] | undefined { 381 return this.genericTypes; 382 } 383 384 public isGenericsMethod(): boolean { 385 return this.genericTypes !== undefined; 386 } 387 388 public setGenericTypes(genericTypes: GenericType[]): void { 389 this.genericTypes = genericTypes; 390 } 391 392 public getBodyBuilder(): BodyBuilder | undefined { 393 return this.bodyBuilder; 394 } 395 396 /** 397 * Get {@link ArkBody} of a Method. 398 * A {@link ArkBody} contains the CFG and actual instructions or operations to be executed for a method. 399 * It is analogous to the body of a function or method in high-level programming languages, 400 * which contains the statements and expressions that define what the function does. 401 * @returns The {@link ArkBody} of a method. 402 * @example 403 * 1. Get cfg or stmt through ArkBody. 404 405 ```typescript 406 let cfg = this.scene.getMethod()?.getBody().getCfg(); 407 const body = arkMethod.getBody() 408 ``` 409 410 2. Get local variable through ArkBody. 411 412 ```typescript 413 arkClass.getDefaultArkMethod()?.getBody().getLocals.forEach(local=>{...}) 414 let locals = arkFile().getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals(); 415 ``` 416 */ 417 public getBody(): ArkBody | undefined { 418 return this.body; 419 } 420 421 public setBody(body: ArkBody): void { 422 this.body = body; 423 } 424 425 /** 426 * Get the CFG (i.e., control flow graph) of a method. 427 * The CFG is a graphical representation of all possible control flow paths within a method's body. 428 * A CFG consists of blocks, statements and goto control jumps. 429 * @returns The CFG (i.e., control flow graph) of a method. 430 * @example 431 * 1. get stmt through ArkBody cfg. 432 433 ```typescript 434 body = arkMethod.getBody(); 435 const cfg = body.getCfg(); 436 for (const threeAddressStmt of cfg.getStmts()) { 437 ... ... 438 } 439 ``` 440 441 2. get blocks through ArkBody cfg. 442 443 ```typescript 444 const body = arkMethod.getBody(); 445 const blocks = [...body.getCfg().getBlocks()]; 446 for (let i=0; i<blocks.length; i++) { 447 const block = blocks[i]; 448 ... ... 449 for (const stmt of block.getStmts()) { 450 ... ... 451 } 452 let text = "next;" 453 for (const next of block.getSuccessors()) { 454 text += blocks.indexOf(next) + ' '; 455 } 456 // ... ... 457 } 458 ``` 459 */ 460 public getCfg(): Cfg | undefined { 461 return this.body?.getCfg(); 462 } 463 464 public getOriginalCfg(): Cfg | undefined { 465 return undefined; 466 } 467 468 public getParameterRefs(): ArkParameterRef[] | null { 469 let paramRefs: ArkParameterRef[] = []; 470 const blocks = this.getBody()?.getCfg().getBlocks(); 471 if (blocks === undefined) { 472 return null; 473 } 474 const stmts = Array.from(blocks)[0].getStmts(); 475 for (let stmt of stmts) { 476 if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof ArkParameterRef) { 477 paramRefs.push((stmt as ArkAssignStmt).getRightOp() as ArkParameterRef); 478 } 479 } 480 return paramRefs; 481 } 482 483 public getParameterInstances(): Value[] { 484 // 获取方法体中参数Local实例 485 let stmts: Stmt[] = []; 486 if (this.getCfg()) { 487 const cfg = this.getCfg() as Cfg; 488 cfg.getStmts().forEach(stmt => stmts.push(stmt)); 489 } 490 let results: Value[] = []; 491 for (let stmt of stmts) { 492 if (stmt instanceof ArkAssignStmt) { 493 if (stmt.getRightOp() instanceof ArkParameterRef) { 494 results.push((stmt as ArkAssignStmt).getLeftOp()); 495 } 496 } 497 if (results.length === this.getParameters().length) { 498 return results; 499 } 500 } 501 return results; 502 } 503 504 public getThisInstance(): Value | null { 505 // 获取方法体中This实例 506 let stmts: Stmt[] = []; 507 if (this.getCfg()) { 508 const cfg = this.getCfg() as Cfg; 509 cfg.getStmts().forEach(stmt => stmts.push(stmt)); 510 } 511 for (let stmt of stmts) { 512 if (stmt instanceof ArkAssignStmt) { 513 if (stmt.getRightOp() instanceof ArkThisRef) { 514 return stmt.getLeftOp(); 515 } 516 } 517 } 518 return null; 519 } 520 521 public getReturnValues(): Value[] { 522 // 获取方法体中return值实例 523 let resultValues: Value[] = []; 524 this.getCfg() 525 ?.getStmts() 526 .forEach(stmt => { 527 if (stmt instanceof ArkReturnStmt) { 528 resultValues.push(stmt.getOp()); 529 } 530 }); 531 return resultValues; 532 } 533 534 public getReturnStmt(): Stmt[] { 535 return this.getCfg()! 536 .getStmts() 537 .filter(stmt => stmt instanceof ArkReturnStmt); 538 } 539 540 public setViewTree(viewTree: ViewTree): void { 541 this.viewTree = viewTree; 542 } 543 544 public getViewTree(): ViewTree | undefined { 545 return this.viewTree; 546 } 547 548 public hasViewTree(): boolean { 549 return this.viewTree !== undefined; 550 } 551 552 public setBodyBuilder(bodyBuilder: BodyBuilder): void { 553 this.bodyBuilder = bodyBuilder; 554 if (this.getDeclaringArkFile().getScene().buildClassDone()) { 555 this.buildBody(); 556 } 557 } 558 559 public freeBodyBuilder(): void { 560 this.bodyBuilder = undefined; 561 } 562 563 public buildBody(): void { 564 if (this.bodyBuilder) { 565 const arkBody: ArkBody | null = this.bodyBuilder.build(); 566 if (arkBody) { 567 this.setBody(arkBody); 568 arkBody.getCfg().setDeclaringMethod(this); 569 if (this.getOuterMethod() === undefined) { 570 this.bodyBuilder.handleGlobalAndClosure(); 571 } 572 } 573 } 574 } 575 576 public isGenerated(): boolean { 577 return this.isGeneratedFlag; 578 } 579 580 public setIsGeneratedFlag(isGeneratedFlag: boolean): void { 581 this.isGeneratedFlag = isGeneratedFlag; 582 } 583 584 public getAsteriskToken(): boolean { 585 return this.asteriskToken; 586 } 587 588 public setAsteriskToken(asteriskToken: boolean): void { 589 this.asteriskToken = asteriskToken; 590 } 591 592 public validate(): ArkError { 593 const declareSignatures = this.getDeclareSignatures(); 594 const declareLineCols = this.getDeclareLineCols(); 595 const signature = this.getImplementationSignature(); 596 const lineCol = this.getLineCol(); 597 598 if (declareSignatures === null && signature === null) { 599 return { 600 errCode: ArkErrorCode.METHOD_SIGNATURE_UNDEFINED, 601 errMsg: 'methodDeclareSignatures and methodSignature are both undefined.', 602 }; 603 } 604 if ((declareSignatures === null) !== (declareLineCols === null)) { 605 return { 606 errCode: ArkErrorCode.METHOD_SIGNATURE_LINE_UNMATCHED, 607 errMsg: 'methodDeclareSignatures and methodDeclareLineCols are not matched.', 608 }; 609 } 610 if (declareSignatures !== null && declareLineCols !== null && declareSignatures.length !== declareLineCols.length) { 611 return { 612 errCode: ArkErrorCode.METHOD_SIGNATURE_LINE_UNMATCHED, 613 errMsg: 'methodDeclareSignatures and methodDeclareLineCols are not matched.', 614 }; 615 } 616 if ((signature === null) !== (lineCol === null)) { 617 return { 618 errCode: ArkErrorCode.METHOD_SIGNATURE_LINE_UNMATCHED, 619 errMsg: 'methodSignature and lineCol are not matched.', 620 }; 621 } 622 return this.validateFields(['declaringArkClass']); 623 } 624 625 public matchMethodSignature(args: Value[]): MethodSignature { 626 const signatures = this.methodDeclareSignatures?.filter(f => { 627 const parameters = f.getMethodSubSignature().getParameters(); 628 const max = parameters.length; 629 let min = 0; 630 while (min < max && !parameters[min].isOptional()) { 631 min++; 632 } 633 return args.length >= min && args.length <= max; 634 }); 635 return ( 636 signatures?.find(p => this.isMatched(p.getMethodSubSignature().getParameters(), args)) ?? 637 signatures?.[0] ?? 638 this.getSignature() 639 ); 640 } 641 642 private isMatched(parameters: MethodParameter[], args: Value[], isArrowFunc: boolean = false): boolean { 643 for (let i = 0; i < parameters.length; i++) { 644 if (!args[i]) { 645 return isArrowFunc ? true : parameters[i].isOptional(); 646 } 647 const paramType = parameters[i].getType(); 648 const isMatched = this.matchParam(paramType, args[i]); 649 if (!isMatched) { 650 return false; 651 } else if (paramType instanceof EnumValueType || paramType instanceof LiteralType) { 652 return true; 653 } 654 } 655 return true; 656 } 657 658 private matchParam(paramType: Type, arg: Value): boolean { 659 if (paramType instanceof EnumValueType || paramType instanceof LiteralType) { 660 arg = ArkMethod.parseArg(arg); 661 } 662 const argType = arg.getType(); 663 if (paramType instanceof AliasType && !(argType instanceof AliasType)) { 664 paramType = TypeInference.replaceAliasType(paramType); 665 } 666 if (paramType instanceof UnionType) { 667 return !!paramType.getTypes().find(p => this.matchParam(p, arg)); 668 } else if (argType instanceof FunctionType && paramType instanceof FunctionType) { 669 if (argType.getMethodSignature().getParamLength() > paramType.getMethodSignature().getParamLength()) { 670 return false; 671 } 672 const parameters = paramType.getMethodSignature().getMethodSubSignature().getParameters(); 673 const args = argType.getMethodSignature().getMethodSubSignature().getParameters().filter(p => !p.getName().startsWith(LEXICAL_ENV_NAME_PREFIX)); 674 return this.isMatched(parameters, args, true); 675 } else if (paramType instanceof ClassType && paramType.getClassSignature().getClassName().includes(CALL_BACK)) { 676 return argType instanceof FunctionType; 677 } else if (paramType instanceof LiteralType && arg instanceof Constant) { 678 return ( 679 arg.getValue().replace(/[\"|\']/g, '') === 680 paramType 681 .getLiteralName() 682 .toString() 683 .replace(/[\"|\']/g, '') 684 ); 685 } else if (paramType instanceof ClassType && argType instanceof EnumValueType) { 686 return paramType.getClassSignature() === argType.getFieldSignature().getDeclaringSignature(); 687 } else if (paramType instanceof EnumValueType) { 688 if (argType instanceof EnumValueType) { 689 return paramType.getFieldSignature() === argType.getFieldSignature(); 690 } else if (argType.constructor === paramType.getConstant()?.getType().constructor && arg instanceof Constant) { 691 return paramType.getConstant()?.getValue() === arg.getValue(); 692 } 693 } 694 return argType.constructor === paramType.constructor; 695 } 696 697 private static parseArg(arg: Value): Value { 698 if (arg instanceof Local) { 699 const stmt = arg.getDeclaringStmt(); 700 const argType = arg.getType(); 701 if (argType instanceof EnumValueType && argType.getConstant()) { 702 arg = argType.getConstant()!; 703 } else if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof Constant) { 704 arg = stmt.getRightOp(); 705 } 706 } 707 return arg; 708 } 709 710 public getOuterMethod(): ArkMethod | undefined { 711 return this.outerMethod; 712 } 713 714 public setOuterMethod(method: ArkMethod): void { 715 this.outerMethod = method; 716 } 717 718 public getFunctionLocal(name: string): Local | null { 719 const local = this.getBody()?.getLocals().get(name); 720 return local?.getType() instanceof FunctionType ? local : null; 721 } 722 723 public setQuestionToken(questionToken: boolean): void { 724 this.questionToken = questionToken; 725 } 726 727 public getQuestionToken(): boolean { 728 return this.questionToken; 729 } 730 731 // For class method, if there is no public/private/protected access modifier, it is actually public 732 public isPublic(): boolean { 733 if ( 734 !this.containsModifier(ModifierType.PUBLIC) && 735 !this.containsModifier(ModifierType.PRIVATE) && 736 !this.containsModifier(ModifierType.PROTECTED) && 737 !this.getDeclaringArkClass().isDefaultArkClass() && 738 !this.isGenerated() && 739 !this.isAnonymousMethod() && 740 this.getName() !== CONSTRUCTOR_NAME && 741 this.getDeclaringArkClass().getCategory() === ClassCategory.CLASS 742 ) { 743 return true; 744 } 745 return this.containsModifier(ModifierType.PUBLIC); 746 } 747} 748