| 21 | import matcher.type.Signature.MethodSignature; |
| 22 | |
| 23 | public final class MethodInstance extends MemberInstance<MethodInstance> implements ParentInstance { |
| 24 | /** |
| 25 | * Create a shared unknown method. |
| 26 | */ |
| 27 | MethodInstance(ClassInstance cls, String origName, String desc, boolean isStatic) { |
| 28 | this(cls, origName, desc, null, false, -1, isStatic); |
| 29 | } |
| 30 | |
| 31 | /** |
| 32 | * Create a known method. |
| 33 | */ |
| 34 | MethodInstance(ClassInstance cls, String origName, String desc, MethodNode asmNode, boolean nameObfuscated, int position) { |
| 35 | this(cls, origName, desc, asmNode, nameObfuscated, position, (asmNode.access & Opcodes.ACC_STATIC) != 0); |
| 36 | } |
| 37 | |
| 38 | private MethodInstance(ClassInstance cls, String origName, String desc, MethodNode asmNode, boolean nameObfuscated, int position, boolean isStatic) { |
| 39 | super(cls, getId(origName, desc), origName, nameObfuscated, position, isStatic); |
| 40 | |
| 41 | try { |
| 42 | this.real = asmNode != null; |
| 43 | this.access = asmNode != null ? asmNode.access : approximateAccess(isStatic); |
| 44 | this.args = gatherArgs(this, desc, asmNode); |
| 45 | this.vars = cls.isInput() ? gatherVars(this, asmNode) : emptyVars; |
| 46 | this.retType = cls.getEnv().getCreateClassInstance(Type.getReturnType(desc).getDescriptor()); |
| 47 | this.signature = asmNode == null || asmNode.signature == null || !cls.isInput() ? null : MethodSignature.parse(asmNode.signature, cls.getEnv()); |
| 48 | this.asmNode = !cls.getEnv().isShared() ? asmNode : null; |
| 49 | } catch (InvalidSharedEnvQueryException e) { |
| 50 | throw e.checkOrigin(cls); |
| 51 | } |
| 52 | |
| 53 | classRefs.add(retType); |
| 54 | retType.methodTypeRefs.add(this); |
| 55 | } |
| 56 | |
| 57 | private static int approximateAccess(boolean isStatic) { |
| 58 | int ret = Opcodes.ACC_PUBLIC; |
| 59 | if (isStatic) ret |= Opcodes.ACC_STATIC; |
| 60 | |
| 61 | return ret; |
| 62 | } |
| 63 | |
| 64 | private static MethodVarInstance[] gatherArgs(MethodInstance method, String desc, MethodNode asmNode) { |
| 65 | Type[] argTypes = Type.getArgumentTypes(desc); |
| 66 | if (argTypes.length == 0) return emptyVars; |
| 67 | |
| 68 | MethodVarInstance[] args = new MethodVarInstance[argTypes.length]; |
| 69 | List<LocalVariableNode> locals; |
| 70 | InsnList il; |
| 71 | AbstractInsnNode firstInsn; |
| 72 | |
| 73 | if (asmNode != null) { |
| 74 | locals = asmNode.localVariables; |
| 75 | il = asmNode.instructions; |
| 76 | firstInsn = il.getFirst(); |
| 77 | } else { |
| 78 | locals = null; |
| 79 | il = null; |
| 80 | firstInsn = null; |
nothing calls this directly
no test coverage detected