View Javadoc

1   package joeq.Compiler.Analysis.IPSSA.Utils;
2   
3   import java.util.StringTokenizer;
4   import joeq.Class.PrimordialClassLoader;
5   import joeq.Class.jq_Class;
6   import joeq.Class.jq_Method;
7   import joeq.Compiler.Analysis.FlowInsensitive.MethodSummary.Node;
8   import joeq.Compiler.Analysis.IPA.PAResultSelector;
9   import joeq.Compiler.Analysis.IPSSA.IPSSABuilder;
10  import joeq.Compiler.Analysis.IPSSA.SSADefinition;
11  import jwutil.util.Assert;
12  import net.sf.javabdd.TypedBDDFactory.TypedBDD;
13  
14  /***
15   * Allows referring to analysis objects in a simple textual fashion.
16   * Implementation provide parsing facilities.
17   * @see AnalysisObjectSpec.PAObjectSpec
18   * @see AnalysisObjectSpec.IPSSAObjectSpec
19   * @version $Id: AnalysisObjectSpec.java 2250 2005-04-29 07:41:11Z joewhaley $
20   * */
21  public abstract class AnalysisObjectSpec {
22      /*** Some pre-defined object types. Implementations provide more. */
23      static final String RETURN = "return";
24      static final String PARAM  = "param";                       
25  
26      String _type;
27      String[] _args;
28  
29      private AnalysisObjectSpec(String type, String[] args){
30          _type = type;
31          _args = (String[])args.clone();
32      }                
33  
34      public static class PAObjectSpec extends AnalysisObjectSpec {
35          TypedBDD _bdd;
36          PAResultSelector _sel;
37                  
38          PAObjectSpec(PAResultSelector sel, String type, String args[]){
39              super(type, args);
40              
41              _sel  = sel;
42              _bdd = null;
43          }
44          public static PAObjectSpec create(PAResultSelector sel, String line) {
45              // parse the object
46              StringTokenizer tok = new StringTokenizer(line, " ");
47              Assert._assert(tok.hasMoreTokens());
48              String type = tok.nextToken();
49              String[] args = new String[tok.countTokens()];
50              for(int i = 0; tok.hasMoreTokens(); i++) {
51                  args[i] = tok.nextToken();
52              }
53                      
54              return new PAObjectSpec(sel, type, args);
55          }
56                  
57          public TypedBDD getBDD() throws UnknownAnalysisObjectExeption {
58              if(_bdd != null) {
59                  return _bdd;
60              }
61                      
62              // different depending on type
63              if(_type.equals(RETURN)) {
64                  jq_Method method = getMethodByName(_args[0], _args[1]);
65                          
66                  _bdd = _sel.getReturnBDD(method); 
67              }else
68              if(_type.equals(PARAM)) {
69                  jq_Method method = getMethodByName(_args[0], _args[1]);
70                  int paramIndex = Integer.parseInt(_args[2]);
71                  _bdd = _sel.getFormalParamBDD(method, paramIndex);
72              }else {
73                  throw new UnknownAnalysisObjectExeption("Unknown type " + _type);
74              }
75                      
76              return _bdd;
77          }
78                  
79           public Node getNode() throws UnknownAnalysisObjectExeption  {
80              return _sel.getNode(getBDD());
81          }
82                  
83          public String toString() {
84              return _type + " [" + _args.toString() + "]";
85          }
86      }
87      
88      public static class IPSSAObjectSpec extends AnalysisObjectSpec {
89          static final String DEFINITION = "definition";
90          
91          SSADefinition _definition;
92          IPSSABuilder _builder;
93          
94          IPSSAObjectSpec(IPSSABuilder builder, String type, String args[]){
95              super(type, args);
96              
97              _builder = builder;            
98              _definition = null;
99          }
100         
101         public static IPSSAObjectSpec create(IPSSABuilder builder, String line) {
102             // parse the object
103             StringTokenizer tok = new StringTokenizer(line, " ");
104             Assert._assert(tok.hasMoreTokens());
105             String type = tok.nextToken();
106             
107             String[] args = new String[tok.countTokens()];
108             for(int i = 0; tok.hasMoreTokens(); i++) {
109                 args[i] = tok.nextToken();
110             }
111                     
112             return new IPSSAObjectSpec(builder, type, args);
113         }
114         
115         public SSADefinition getDefinition() throws UnknownAnalysisObjectExeption {
116             if(_definition != null) {
117                 return _definition;
118             }
119             if(_type.equals(RETURN)) {
120                 _definition = null;
121             }else
122             if(_type.equals(PARAM)) {
123                 _definition = null;
124             }else
125             if(_type.equals(DEFINITION)) {
126                 _definition = SSADefinition.Helper.lookupDefinition(_args[0]);
127                 if(_definition == null) {
128                     throw new UnknownAnalysisObjectExeption("Can't find definition " + _args[0]);
129                 }
130             }else {
131                 throw new UnknownAnalysisObjectExeption("Unknown type " + _type);
132             }                  
133             
134             return _definition;  
135         }
136     }
137     
138     public static class UnknownAnalysisObjectExeption extends Exception {               
139         /***
140          * Version ID for serialization.
141          */
142         private static final long serialVersionUID = 3762257417945362481L;
143 
144         public UnknownAnalysisObjectExeption(String msg) {             
145              super(msg);
146          }
147     }
148     
149     static jq_Method getMethodByName(String className, String methodName) {   
150         if (className.endsWith(".properties")) return null;
151         if (className.endsWith(".class")) className = className.substring(0, className.length()-6);
152         String classdesc = "L"+className+";";
153         jq_Class c = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType(classdesc);
154         //System.err.println("Preparing class " + c);
155         c.prepare();
156             
157         return c.getDeclaredMethod(methodName);
158     }    
159 }
160