KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > AbstractSootMethodRef


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2004 Ondrej Lhotak
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 package soot;
21 import java.util.*;
22 import soot.util.*;
23
24 /** Representation of a reference to a method as it appears in a class file.
25  * Note that the method directly referred to may not actually exist; the
26  * actual target of the reference is determined according to the resolution
27  * procedure in the Java Virtual Machine Specification, 2nd ed, section 5.4.3.3.
28  */

29
30 class AbstractSootMethodRef implements SootMethodRef {
31     public AbstractSootMethodRef(
32             SootClass declaringClass,
33             String JavaDoc 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 JavaDoc( "Attempt to create SootMethodRef with null class" );
45         if( name == null ) throw new RuntimeException JavaDoc( "Attempt to create SootMethodRef with null name" );
46         if( parameterTypes == null ) throw new RuntimeException JavaDoc( "Attempt to create SootMethodRef with null parameterTypes" );
47         if( returnType == null ) throw new RuntimeException JavaDoc( "Attempt to create SootMethodRef with null returnType" );
48     }
49
50     private final SootClass declaringClass;
51     private final String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc toString() {
87             StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
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 JavaDoc 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 JavaDoc toString() {
139         return getSignature();
140     }
141 }
142
Popular Tags