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
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
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
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
155 c.prepare();
156
157 return c.getDeclaredMethod(methodName);
158 }
159 }
160