1/* 2 * Copyright (c) 2021-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 16package std.core; 17 18native function TypeAPIMethodInvoke(methodType: MethodType, recv: NullishType, args: FixedArray<NullishType>): NullishType 19native function TypeAPIMethodInvokeConstructor(methodType: MethodType, args: FixedArray<NullishType>): Object 20 21/** 22 * Represents method of class or interface 23 */ 24export final class Method extends Object { 25 private methodType: MethodType | undefined // not undefined if already created 26 private name: string = "" 27 private attributes: int 28 private accessMod: byte 29 30 private constructor () {} 31 32 /** 33 * Returns function type of this method 34 * 35 * @returns method's {@link MethodType} 36 */ 37 public getType(): MethodType { 38 return this.methodType! 39 } 40 41 public getName(): string { 42 return this.name 43 } 44 45 public isInherited(): boolean { 46 return (this.attributes & Attributes.INHERITED) != 0 47 } 48 49 public isStatic(): boolean { 50 return (this.attributes & Attributes.STATIC) != 0 51 } 52 53 public isFinal(): boolean { 54 // TODO(shumilov-petr): not implemented in front-end 55 return (this.attributes & Attributes.FINAL) != 0 56 } 57 58 public isAbstract(): boolean { 59 return (this.attributes & Attributes.ABSTRACT) != 0 60 } 61 62 public isConstructor(): boolean { 63 return (this.attributes & Attributes.CONSTRUCTOR) != 0 64 } 65 66 public isGetter(): boolean { 67 return (this.attributes & Attributes.GETTER) != 0 68 } 69 70 public isSetter(): boolean { 71 return (this.attributes & Attributes.SETTER) != 0 72 } 73 74 public override toString(): string { 75 return this.getName() + ": " + this.getType().toString() 76 } 77 78 public invoke(recv: NullishType, args: FixedArray<NullishType>): NullishType { 79 const isCtor = this.isConstructor() 80 const isStatic = this.isStatic() 81 if ((isStatic || isCtor) != (recv == null)) { 82 throw new Error("reciever may be null only for static/ctor methods") 83 } 84 const thisType = this.getType() 85 if (thisType.getParametersNum() != args.length) { 86 throw new Error("arguments length mismatch " + thisType.getParametersNum() + " != " + args.length) 87 } 88 let convertedArgs: FixedArray<NullishType> = new NullishType[args.length] 89 for (let i = 0; i < convertedArgs.length; i++) { 90 convertedArgs[i] = thisType.getParameter(i).getType().convertObject(args[i]) 91 } 92 if (isCtor) { 93 return TypeAPIMethodInvokeConstructor(this.methodType!, convertedArgs) 94 } else { 95 if (!isStatic) { 96 recv = thisType.getReceiverType().convertObject(recv) 97 } 98 return TypeAPIMethodInvoke(this.methodType!, recv, convertedArgs) 99 } 100 } 101 102 public getAttributes(): int { 103 return this.attributes 104 } 105 106 public getAccessModifier(): int { 107 return this.accessMod 108 } 109 110 public equals(oth: NullishType): boolean { 111 return oth instanceof Method && 112 this.methodType!.equals((oth as Method).methodType!) && 113 this.name == (oth as Method).name && 114 this.accessMod == (oth as Method).accessMod && 115 this.attributes == (oth as Method).attributes 116 } 117} 118