1 19 20 package soot; 21 import java.util.*; 22 import soot.util.*; 23 24 29 30 class AbstractSootMethodRef implements SootMethodRef { 31 public AbstractSootMethodRef( 32 SootClass declaringClass, 33 String name, 34 List parameterTypes, 35 Type returnType, 36 boolean isStatic) { 37 this.declaringClass = declaringClass; 38 this.name = name; 39 List l = new ArrayList(); 40 l.addAll(parameterTypes); 41 this.parameterTypes = Collections.unmodifiableList(l); 42 this.returnType = returnType; 43 this.isStatic = isStatic; 44 if( declaringClass == null ) throw new RuntimeException ( "Attempt to create SootMethodRef with null class" ); 45 if( name == null ) throw new RuntimeException ( "Attempt to create SootMethodRef with null name" ); 46 if( parameterTypes == null ) throw new RuntimeException ( "Attempt to create SootMethodRef with null parameterTypes" ); 47 if( returnType == null ) throw new RuntimeException ( "Attempt to create SootMethodRef with null returnType" ); 48 } 49 50 private final SootClass declaringClass; 51 private final String name; 52 private final List parameterTypes; 53 private final Type returnType; 54 private final boolean isStatic; 55 56 private NumberedString subsig; 57 58 public SootClass declaringClass() { return declaringClass; } 59 public String name() { return name; } 60 public List parameterTypes() { return parameterTypes; } 61 public Type returnType() { return returnType; } 62 public boolean isStatic() { return isStatic; } 63 64 public NumberedString getSubSignature() { 65 if( subsig == null ) { 66 subsig = Scene.v().getSubSigNumberer().findOrAdd( 67 SootMethod.getSubSignature( name, parameterTypes, returnType )); 68 } 69 return subsig; 70 } 71 72 public String getSignature() { 73 return SootMethod.getSignature(declaringClass, name, parameterTypes, returnType); 74 } 75 76 public Type parameterType(int i) { 77 return (Type) parameterTypes.get(i); 78 } 79 80 public class ClassResolutionFailedException extends ResolutionFailedException { 81 public ClassResolutionFailedException() { 82 super("Class "+declaringClass+" doesn't have method "+name+ 83 "("+parameterTypes+")"+" : "+returnType+ 84 "; failed to resolve in superclasses and interfaces" ); 85 } 86 public String toString() { 87 StringBuffer ret = new StringBuffer (); 88 ret.append(super.toString()); 89 resolve(ret); 90 return ret.toString(); 91 } 92 } 93 94 public SootMethod resolve() { 95 return resolve(null); 96 } 97 private SootMethod checkStatic(SootMethod ret) { 98 if( ret.isStatic() != isStatic()) { 99 throw new ResolutionFailedException( "Resolved "+this+" to "+ret+" which has wrong static-ness" ); 100 } 101 return ret; 102 } 103 private SootMethod resolve(StringBuffer trace) { 104 SootClass cl = declaringClass; 105 while(true) { 106 if(trace != null) trace.append( 107 "Looking in "+cl+" which has methods "+cl.getMethods()+"\n" ); 108 if( cl.declaresMethod( getSubSignature() ) ) 109 return checkStatic(cl.getMethod( getSubSignature() )); 110 if(Scene.v().allowsPhantomRefs() && cl.isPhantom()) 111 { 112 SootMethod m = new SootMethod(name, parameterTypes, returnType, isStatic()?Modifier.STATIC:0); 113 m.setPhantom(true); 114 cl.addMethod(m); 115 return checkStatic(m); 116 } 117 if( cl.hasSuperclass() ) cl = cl.getSuperclass(); 118 else break; 119 } 120 cl = declaringClass; 121 while(true) { 122 LinkedList queue = new LinkedList(); 123 queue.addAll( cl.getInterfaces() ); 124 while( !queue.isEmpty() ) { 125 SootClass iface = (SootClass) queue.removeFirst(); 126 if(trace != null) trace.append( 127 "Looking in "+iface+" which has methods "+iface.getMethods()+"\n" ); 128 if( iface.declaresMethod( getSubSignature() ) ) 129 return checkStatic(iface.getMethod( getSubSignature() )); 130 queue.addAll( iface.getInterfaces() ); 131 } 132 if( cl.hasSuperclass() ) cl = cl.getSuperclass(); 133 else break; 134 } 135 if( trace == null )throw new ClassResolutionFailedException(); 136 return null; 137 } 138 public String toString() { 139 return getSignature(); 140 } 141 } 142 | Popular Tags |