KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > javaToJimple > JimpleBodyBuilder


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2004 Jennifer 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
21
22 package soot.javaToJimple;
23
24 import java.util.*;
25
26 import soot.SootFieldRef;
27
28 public class JimpleBodyBuilder extends AbstractJimpleBodyBuilder {
29
30
31     public JimpleBodyBuilder(){
32         //ext(null);
33
//base(this);
34
}
35     
36     
37     ArrayList exceptionTable; // list of exceptions
38
Stack endControlNoop = new Stack(); // for break
39
Stack condControlNoop = new Stack(); // continue
40
Stack monitorStack; // for synchronized blocks
41
Stack tryStack; // for try stmts in case of returns
42
Stack catchStack; // for catch stmts in case of returns
43

44     Stack trueNoop = new Stack();
45     Stack falseNoop = new Stack();
46     
47     HashMap labelBreakMap; // for break label --> nop to jump to
48
HashMap labelContinueMap; // for continue label --> nop to jump to
49
//Stack labelStack;
50
//String lastLabel;
51
HashMap labelMap;
52     HashMap localsMap = new HashMap(); // localInst --> soot local
53

54     HashMap getThisMap = new HashMap(); // type --> local to ret
55
soot.Local specialThisLocal; // === body.getThisLocal();
56
soot.Local outerClassParamLocal; // outer class this
57

58     private int paramRefCount = 0; // counter for param ref stmts
59

60     LocalGenerator lg; // for generated locals not in orig src
61

62     /**
63      * Jimple Body Creation
64      */

65     public soot.jimple.JimpleBody createJimpleBody(polyglot.ast.Block block, List formals, soot.SootMethod sootMethod){
66      
67         createBody(sootMethod);
68
69         lg = new LocalGenerator(body);
70         // create this formal except for static methods
71
if (!soot.Modifier.isStatic(sootMethod.getModifiers())) {
72
73             soot.RefType type = sootMethod.getDeclaringClass().getType();
74             specialThisLocal = soot.jimple.Jimple.v().newLocal("this", type);
75             body.getLocals().add(specialThisLocal);
76                                                 
77             soot.jimple.ThisRef thisRef = soot.jimple.Jimple.v().newThisRef(type);
78             
79             soot.jimple.Stmt thisStmt = soot.jimple.Jimple.v().newIdentityStmt(specialThisLocal, thisRef);
80             body.getUnits().add(thisStmt);
81             
82             // this is causing problems - no this in java code -> no tags
83
//Util.addLineTag(thisStmt, block);
84
}
85         
86         int formalsCounter = 0;
87         
88         //create outer class this param ref for inner classes except for static inner classes - this is not needed
89
int outerIndex = sootMethod.getDeclaringClass().getName().lastIndexOf("$");
90         int classMod = sootMethod.getDeclaringClass().getModifiers();
91             
92         if ((outerIndex != -1) && (sootMethod.getName().equals("<init>")) && sootMethod.getDeclaringClass().declaresFieldByName("this$0")){
93
94             // we know its an inner non static class can get outer class
95
// from field ref of the this$0 field
96
soot.SootClass outerClass = ((soot.RefType)sootMethod.getDeclaringClass().getFieldByName("this$0").getType()).getSootClass();
97             soot.Local outerLocal = lg.generateLocal(outerClass.getType());
98             
99             soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(outerClass.getType(), formalsCounter);
100             paramRefCount++;
101             soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(outerLocal, paramRef);
102             stmt.addTag(new soot.tagkit.EnclosingTag());
103             body.getUnits().add(stmt);
104             
105             ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).setOuterClassThisInit(outerLocal);
106             outerClassParamLocal = outerLocal;
107             formalsCounter++;
108         }
109
110         // handle formals
111
if (formals != null) {
112             ArrayList formalNames = new ArrayList();
113             Iterator formalsIt = formals.iterator();
114             while (formalsIt.hasNext()) {
115                 polyglot.ast.Formal formal = (polyglot.ast.Formal)formalsIt.next();
116                 createFormal(formal, formalsCounter);
117                 formalNames.add(formal.name());
118                 formalsCounter++;
119             }
120             body.getMethod().addTag(new soot.tagkit.ParamNamesTag(formalNames));
121         }
122         
123         // handle final local params
124
ArrayList finalsList = ((PolyglotMethodSource)body.getMethod().getSource()).getFinalsList();
125         if (finalsList != null){
126             Iterator finalsIt = finalsList.iterator();
127             while (finalsIt.hasNext()){
128                 soot.SootField sf = (soot.SootField)finalsIt.next();
129                 soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(sf.getType(), formalsCounter);
130                 paramRefCount++;
131                 soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(lg.generateLocal(sf.getType()), paramRef);
132                 body.getUnits().add(stmt);
133                 formalsCounter++;
134             }
135         }
136         
137         createBlock(block);
138
139         
140         // if method is <clinit> handle static field inits
141
if (sootMethod.getName().equals("<clinit>")){
142             
143             handleAssert(sootMethod);
144             handleStaticFieldInits(sootMethod);
145             handleStaticInitializerBlocks(sootMethod);
146         }
147        
148         // determine if body has a return stmt
149
boolean hasReturn = false;
150         if (block != null) {
151             Iterator it = block.statements().iterator();
152             while (it.hasNext()){
153                 Object JavaDoc next = it.next();
154                 if (next instanceof polyglot.ast.Return){
155                     hasReturn = true;
156                 }
157             }
158         }
159     
160         soot.Type retType = body.getMethod().getReturnType();
161         // only do this if noexplicit return
162
if ((!hasReturn) && (retType instanceof soot.VoidType)) {
163             soot.jimple.Stmt retStmt = soot.jimple.Jimple.v().newReturnVoidStmt();
164             body.getUnits().add(retStmt);
165         }
166
167         // add exceptions from exceptionTable
168
if (exceptionTable != null) {
169             Iterator trapsIt = exceptionTable.iterator();
170             while (trapsIt.hasNext()){
171                 body.getTraps().add((soot.Trap)trapsIt.next());
172             }
173         }
174         return body;
175     
176     }
177
178     private void handleAssert(soot.SootMethod sootMethod){
179         if (!((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).hasAssert()) return;
180         ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).addAssertInits(body);
181     }
182
183     /**
184      * adds any needed field inits
185      */

186     private void handleFieldInits(soot.SootMethod sootMethod) {
187             
188         ArrayList fieldInits = ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).getFieldInits();
189         if (fieldInits != null) {
190             handleFieldInits(fieldInits);
191         }
192     }
193
194     protected void handleFieldInits(ArrayList fieldInits){
195         Iterator fieldInitsIt = fieldInits.iterator();
196         while (fieldInitsIt.hasNext()) {
197             polyglot.ast.FieldDecl field = (polyglot.ast.FieldDecl)fieldInitsIt.next();
198             String JavaDoc fieldName = field.name();
199             polyglot.ast.Expr initExpr = field.init();
200             soot.SootClass currentClass = body.getMethod().getDeclaringClass();
201             soot.SootFieldRef sootField = soot.Scene.v().makeFieldRef(currentClass, fieldName, Util.getSootType(field.type().type()), field.flags().isStatic());
202                 
203             soot.Local base = specialThisLocal;
204                    
205             soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(base, sootField);
206                 
207             soot.Value sootExpr;
208             if (initExpr instanceof polyglot.ast.ArrayInit) {
209                 sootExpr = getArrayInitLocal((polyglot.ast.ArrayInit)initExpr, field.type().type());
210             }
211             else {
212                 //System.out.println("field init expr: "+initExpr);
213
sootExpr = base().createExpr(initExpr);
214                 //System.out.println("soot expr: "+sootExpr);
215
}
216             if (sootExpr instanceof soot.jimple.ConditionExpr) {
217                 sootExpr = handleCondBinExpr((soot.jimple.ConditionExpr)sootExpr);
218             }
219                 
220             soot.jimple.AssignStmt assign;
221             if (sootExpr instanceof soot.Local){
222                 assign = soot.jimple.Jimple.v().newAssignStmt(fieldRef, (soot.Local)sootExpr);
223             }
224             else if (sootExpr instanceof soot.jimple.Constant){
225                 assign = soot.jimple.Jimple.v().newAssignStmt(fieldRef, (soot.jimple.Constant)sootExpr);
226             }
227             else {
228                 throw new RuntimeException JavaDoc("fields must assign to local or constant only");
229             }
230             body.getUnits().add(assign);
231             Util.addLnPosTags(assign, initExpr.position());
232             Util.addLnPosTags(assign.getRightOpBox(), initExpr.position());
233         }
234     }
235         
236
237     /**
238      * adds this field for the outer class
239      */

240     private void handleOuterClassThisInit(soot.SootMethod sootMethod) {
241         // static inner classes are different
242
if (body.getMethod().getDeclaringClass().declaresFieldByName("this$0")){
243             soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, body.getMethod().getDeclaringClass().getFieldByName("this$0").makeRef());
244             soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(fieldRef, outerClassParamLocal);
245             body.getUnits().add(stmt);
246         }
247     }
248     
249
250     
251     /**
252      * adds any needed static field inits
253      */

254     private void handleStaticFieldInits(soot.SootMethod sootMethod) {
255             
256         ArrayList staticFieldInits = ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).getStaticFieldInits();
257         if (staticFieldInits != null) {
258             Iterator staticFieldInitsIt = staticFieldInits.iterator();
259             while (staticFieldInitsIt.hasNext()) {
260                 polyglot.ast.FieldDecl field = (polyglot.ast.FieldDecl)staticFieldInitsIt.next();
261                 String JavaDoc fieldName = field.name();
262                 polyglot.ast.Expr initExpr = field.init();
263                 soot.SootClass currentClass = body.getMethod().getDeclaringClass();
264                 soot.SootFieldRef sootField = soot.Scene.v().makeFieldRef(currentClass, fieldName, Util.getSootType(field.type().type()), field.flags().isStatic());
265                 soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newStaticFieldRef(sootField);
266                 
267                 //System.out.println("initExpr: "+initExpr);
268
soot.Value sootExpr;
269                 if (initExpr instanceof polyglot.ast.ArrayInit) {
270                     sootExpr = getArrayInitLocal((polyglot.ast.ArrayInit)initExpr, field.type().type());
271                 }
272                 else {
273                     //System.out.println("field init expr: "+initExpr);
274
sootExpr = base().createExpr(initExpr);
275                     //System.out.println("soot expr: "+sootExpr);
276

277                     if (sootExpr instanceof soot.jimple.ConditionExpr) {
278                         sootExpr = handleCondBinExpr((soot.jimple.ConditionExpr)sootExpr);
279                     }
280                 }
281
282                 soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(fieldRef, sootExpr);
283
284                 body.getUnits().add(assign);
285                 Util.addLnPosTags(assign, initExpr.position());
286                 
287             }
288         }
289     }
290
291     /**
292      * init blocks get created within init methods in Jimple
293      */

294     private void handleInitializerBlocks(soot.SootMethod sootMethod) {
295         ArrayList initializerBlocks = ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).getInitializerBlocks();
296
297         if (initializerBlocks != null) {
298             
299             handleStaticBlocks(initializerBlocks);
300         }
301     }
302
303     protected void handleStaticBlocks(ArrayList initializerBlocks){
304         Iterator initBlocksIt = initializerBlocks.iterator();
305         while (initBlocksIt.hasNext()) {
306             createBlock((polyglot.ast.Block)initBlocksIt.next());
307         }
308     }
309     
310     /**
311      * static init blocks get created in clinit methods in Jimple
312      */

313     private void handleStaticInitializerBlocks(soot.SootMethod sootMethod) {
314         ArrayList staticInitializerBlocks = ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).getStaticInitializerBlocks();
315
316         if (staticInitializerBlocks != null) {
317         
318             Iterator staticInitBlocksIt = staticInitializerBlocks.iterator();
319             while (staticInitBlocksIt.hasNext()) {
320                 createBlock((polyglot.ast.Block)staticInitBlocksIt.next());
321             }
322         }
323     }
324
325     /**
326      * create body and make it be active
327      */

328     private void createBody(soot.SootMethod sootMethod) {
329         body = soot.jimple.Jimple.v().newBody(sootMethod);
330         sootMethod.setActiveBody(body);
331         
332     }
333     
334
335     /**
336      * Block creation
337      */

338     private void createBlock(polyglot.ast.Block block){
339         
340         if (block == null) return;
341         
342         // handle stmts
343
Iterator it = block.statements().iterator();
344         while (it.hasNext()){
345             Object JavaDoc next = it.next();
346             if (next instanceof polyglot.ast.Stmt){
347                 createStmt((polyglot.ast.Stmt)next);
348             }
349             else {
350                 throw new RuntimeException JavaDoc("Unexpected - Unhandled Node");
351             }
352         }
353     }
354     
355     /**
356      * Catch Formal creation - method parameters
357      */

358     private soot.Local createCatchFormal(polyglot.ast.Formal formal){
359
360         soot.Type sootType = Util.getSootType(formal.type().type());
361         soot.Local formalLocal = createLocal(formal.localInstance());
362         soot.jimple.CaughtExceptionRef exceptRef = soot.jimple.Jimple.v().newCaughtExceptionRef();
363         soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(formalLocal, exceptRef);
364         body.getUnits().add(stmt);
365
366         Util.addLnPosTags(stmt, formal.position());
367         Util.addLnPosTags(((soot.jimple.IdentityStmt) stmt).getRightOpBox(), formal.position());
368
369         ArrayList names = new ArrayList();
370         names.add(formal.name());
371         stmt.addTag(new soot.tagkit.ParamNamesTag(names));
372         return formalLocal;
373     }
374         
375     /**
376      * Formal creation - method parameters
377      */

378     private void createFormal(polyglot.ast.Formal formal, int counter){
379
380         soot.Type sootType = Util.getSootType(formal.type().type());
381         soot.Local formalLocal = createLocal(formal.localInstance());
382         soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(sootType, counter);
383         paramRefCount++;
384         soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(formalLocal, paramRef);
385         
386         body.getUnits().add(stmt);
387         
388         Util.addLnPosTags(((soot.jimple.IdentityStmt) stmt).getRightOpBox(), formal.position());
389         Util.addLnPosTags(stmt, formal.position());
390
391     }
392
393     /**
394      * Literal Creation
395      */

396     private soot.Value createLiteral(polyglot.ast.Lit lit) {
397         if (lit instanceof polyglot.ast.IntLit) {
398             polyglot.ast.IntLit intLit = (polyglot.ast.IntLit)lit;
399             long litValue = intLit.value();
400             if (intLit.kind() == polyglot.ast.IntLit.INT) {
401                 return soot.jimple.IntConstant.v((int)litValue);
402             }
403             else {
404                 //System.out.println(litValue);
405
return soot.jimple.LongConstant.v(litValue);
406             }
407         }
408         else if (lit instanceof polyglot.ast.StringLit) {
409             String JavaDoc litValue = ((polyglot.ast.StringLit)lit).value();
410             return soot.jimple.StringConstant.v(litValue);
411         }
412         else if (lit instanceof polyglot.ast.NullLit) {
413             return soot.jimple.NullConstant.v();
414         }
415         else if (lit instanceof polyglot.ast.FloatLit) {
416             polyglot.ast.FloatLit floatLit = (polyglot.ast.FloatLit)lit;
417             double litValue = floatLit.value();
418             if (floatLit.kind() == polyglot.ast.FloatLit.DOUBLE) {
419                 return soot.jimple.DoubleConstant.v(floatLit.value());
420             }
421             else {
422                 return soot.jimple.FloatConstant.v((float)(floatLit.value()));
423             }
424         }
425         else if (lit instanceof polyglot.ast.CharLit) {
426             char litValue = ((polyglot.ast.CharLit)lit).value();
427             return soot.jimple.IntConstant.v(litValue);
428         }
429         else if (lit instanceof polyglot.ast.BooleanLit) {
430             boolean litValue = ((polyglot.ast.BooleanLit)lit).value();
431             if (litValue) return soot.jimple.IntConstant.v(1);
432             else return soot.jimple.IntConstant.v(0);
433         }
434         else if (lit instanceof polyglot.ast.ClassLit){
435             return getSpecialClassLitLocal((polyglot.ast.ClassLit)lit);
436         }
437         else {
438             throw new RuntimeException JavaDoc("Unknown Literal - Unhandled: "+lit.getClass());
439         }
440     }
441     
442     /**
443      * Local Creation
444      */

445    
446     // this should be used for polyglot locals and formals
447
private soot.Local createLocal(polyglot.types.LocalInstance localInst) {
448        
449         soot.Type sootType = Util.getSootType(localInst.type());
450         String JavaDoc name = localInst.name();
451         soot.Local sootLocal = createLocal(name, sootType);
452         
453         localsMap.put(new polyglot.util.IdentityKey(localInst), sootLocal);
454         return sootLocal;
455     }
456     
457     // this should be used for generated locals only
458
private soot.Local createLocal(String JavaDoc name, soot.Type sootType) {
459         soot.Local sootLocal = soot.jimple.Jimple.v().newLocal(name, sootType);
460         body.getLocals().add(sootLocal);
461         return sootLocal;
462     }
463
464     /**
465      * Local Retreival
466      */

467     private soot.Local getLocal(polyglot.ast.Local local) {
468
469         return getLocal(local.localInstance());
470     }
471     
472     /**
473      * Local Retreival
474      */

475     private soot.Local getLocal(polyglot.types.LocalInstance li) {
476         
477         if (localsMap.containsKey(new polyglot.util.IdentityKey(li))){
478             soot.Local sootLocal = (soot.Local)localsMap.get(new polyglot.util.IdentityKey(li));
479             return sootLocal;
480         }
481         else if (body.getMethod().getDeclaringClass().declaresField("val$"+li.name(), Util.getSootType(li.type()))){
482             soot.Local fieldLocal = generateLocal(li.type());
483             soot.SootFieldRef field = soot.Scene.v().makeFieldRef(body.getMethod().getDeclaringClass(), "val$"+li.name(), Util.getSootType(li.type()), false);
484             soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, field);
485             soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(fieldLocal, fieldRef);
486             body.getUnits().add(assign);
487             return fieldLocal;
488         }
489         /*else {
490             throw new RuntimeException("Trying unsuccessfully to get local: "+li.name());
491         }*/

492         else {
493             //else create access meth in outer for val$fieldname
494
// get the this$0 field to find the type of an outer class - has
495
// to have one because local/anon inner can't declare static
496
// memebers so for deepnesting not in static context for these
497
// cases
498

499             soot.SootClass currentClass = body.getMethod().getDeclaringClass();
500             boolean fieldFound = false;
501             
502             while (!fieldFound){
503                 if (!currentClass.declaresFieldByName("this$0")){
504                     throw new RuntimeException JavaDoc("Trying to get field val$"+li.name()+" from some outer class but can't access the outer class of: "+currentClass.getName()+"!"+" current class contains fields: "+currentClass.getFields());
505                 }
506                 soot.SootClass outerClass = ((soot.RefType)currentClass.getFieldByName("this$0").getType()).getSootClass();
507                 // look for field of type li.type and name val$li.name in outer
508
// class
509
if (outerClass.declaresField("val$"+li.name(), Util.getSootType(li.type()))){
510                     fieldFound = true;
511                 }
512                 currentClass = outerClass;
513                 // repeat until found in some outer class
514
}
515             // create and add accessor to that outer class (indic as current)
516
soot.SootMethod methToInvoke = makeLiFieldAccessMethod(currentClass, li);
517             
518             // invoke and return
519
// generate a local that corresponds to the invoke of that meth
520
ArrayList methParams = new ArrayList();
521             methParams.add(getThis(currentClass.getType()));
522         
523             soot.Local res = Util.getPrivateAccessFieldInvoke(methToInvoke.makeRef(), methParams, body, lg);
524             return res;
525         }
526     }
527     
528     private soot.SootMethod makeLiFieldAccessMethod(soot.SootClass classToInvoke, polyglot.types.LocalInstance li){
529         String JavaDoc name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00";
530         ArrayList paramTypes = new ArrayList();
531         paramTypes.add(classToInvoke.getType());
532         
533         soot.SootMethod meth = new soot.SootMethod(name, paramTypes, Util.getSootType(li.type()), soot.Modifier.STATIC);
534
535         classToInvoke.addMethod(meth);
536         PrivateFieldAccMethodSource src = new PrivateFieldAccMethodSource(
537         Util.getSootType(li.type()),
538         "val$"+li.name(),
539         false,
540                 classToInvoke
541         );
542         meth.setActiveBody(src.getBody(meth, null));
543         meth.addTag(new soot.tagkit.SyntheticTag());
544         return meth;
545     }
546     
547     /**
548      * Stmt creation
549      */

550     protected void createStmt(polyglot.ast.Stmt stmt) {
551         //System.out.println("stmt: "+stmt.getClass());
552
if (stmt instanceof polyglot.ast.Eval) {
553             base().createExpr(((polyglot.ast.Eval)stmt).expr());
554         }
555         else if (stmt instanceof polyglot.ast.If) {
556            createIf2((polyglot.ast.If)stmt);
557         }
558         else if (stmt instanceof polyglot.ast.LocalDecl) {
559             createLocalDecl((polyglot.ast.LocalDecl)stmt);
560         }
561         else if (stmt instanceof polyglot.ast.Block) {
562             createBlock((polyglot.ast.Block)stmt);
563         }
564         else if (stmt instanceof polyglot.ast.While) {
565             createWhile2((polyglot.ast.While)stmt);
566         }
567         else if (stmt instanceof polyglot.ast.Do) {
568             createDo2((polyglot.ast.Do)stmt);
569         }
570         else if (stmt instanceof polyglot.ast.For) {
571             createForLoop2((polyglot.ast.For)stmt);
572         }
573         else if (stmt instanceof polyglot.ast.Switch) {
574             createSwitch((polyglot.ast.Switch)stmt);
575         }
576         else if (stmt instanceof polyglot.ast.Return) {
577             createReturn((polyglot.ast.Return)stmt);
578         }
579         else if (stmt instanceof polyglot.ast.Branch) {
580             createBranch((polyglot.ast.Branch)stmt);
581         }
582         else if (stmt instanceof polyglot.ast.ConstructorCall) {
583             createConstructorCall((polyglot.ast.ConstructorCall)stmt);
584         }
585         else if (stmt instanceof polyglot.ast.Empty) {
586             // do nothing empty stmt
587
}
588         else if (stmt instanceof polyglot.ast.Throw) {
589             createThrow((polyglot.ast.Throw)stmt);
590         }
591         else if (stmt instanceof polyglot.ast.Try) {
592             createTry((polyglot.ast.Try)stmt);
593         }
594         else if (stmt instanceof polyglot.ast.Labeled) {
595             createLabeled((polyglot.ast.Labeled)stmt);
596         }
597         else if (stmt instanceof polyglot.ast.Synchronized) {
598             createSynchronized((polyglot.ast.Synchronized)stmt);
599         }
600         else if (stmt instanceof polyglot.ast.Assert) {
601             createAssert((polyglot.ast.Assert)stmt);
602         }
603         else if (stmt instanceof polyglot.ast.LocalClassDecl) {
604             createLocalClassDecl((polyglot.ast.LocalClassDecl)stmt);
605         }
606         else {
607             throw new RuntimeException JavaDoc("Unhandled Stmt: "+stmt.getClass());
608         }
609     }
610     
611     private boolean needSootIf(soot.Value sootCond){
612         if (sootCond instanceof soot.jimple.IntConstant){
613             if (((soot.jimple.IntConstant)sootCond).value == 1){
614                 return false;
615             }
616         }
617         return true;
618     }
619     
620     /**
621      * If Stmts Creation - only add line-number tags to if (the other
622      * stmts needing tags are created elsewhere
623      */

624     /*private void createIf(polyglot.ast.If ifExpr){
625
626         // create true/false noops to handle cond and/or
627         trueNoop.push(soot.jimple.Jimple.v().newNopStmt());
628         falseNoop.push(soot.jimple.Jimple.v().newNopStmt());
629         
630         // handle cond
631         polyglot.ast.Expr condition = ifExpr.cond();
632         soot.Value sootCond = base().createExpr(condition);
633
634         // pop true false noops right away
635         soot.jimple.Stmt tNoop = (soot.jimple.Stmt)trueNoop.pop();
636         soot.jimple.Stmt fNoop = (soot.jimple.Stmt)falseNoop.pop();
637         
638         boolean needIf = needSootIf(sootCond);
639         if (!(sootCond instanceof soot.jimple.ConditionExpr)) {
640             sootCond = soot.jimple.Jimple.v().newEqExpr(sootCond, soot.jimple.IntConstant.v(0));
641         }
642         else {
643             sootCond = reverseCondition((soot.jimple.ConditionExpr)sootCond);
644             sootCond = handleDFLCond((soot.jimple.ConditionExpr)sootCond);
645         }
646        
647         // add if
648         soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
649        
650         if (needIf) {
651             soot.jimple.IfStmt ifStmt = soot.jimple.Jimple.v().newIfStmt(sootCond, noop1);
652             body.getUnits().add(ifStmt);
653             // add line and pos tags
654             Util.addLnPosTags(ifStmt.getConditionBox(), condition.position());
655             Util.addLnPosTags(ifStmt, condition.position());
656         }
657     
658         // add true nop
659         body.getUnits().add(tNoop);
660         
661         // add consequence
662         polyglot.ast.Stmt consequence = ifExpr.consequent();
663         createStmt(consequence);
664     
665         soot.jimple.Stmt noop2 = null;
666         if (ifExpr.alternative() != null){
667             noop2 = soot.jimple.Jimple.v().newNopStmt();
668             soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2);
669             body.getUnits().add(goto1);
670         }
671       
672         body.getUnits().add(noop1);
673         
674         // add false nop
675         body.getUnits().add(fNoop);
676         
677         
678         // handle alternative
679         polyglot.ast.Stmt alternative = ifExpr.alternative();
680         if (alternative != null){
681             createStmt(alternative);
682             body.getUnits().add(noop2);
683         }
684         
685
686     }*/

687     
688     /**
689      * If Stmts Creation - only add line-number tags to if (the other
690      * stmts needing tags are created elsewhere
691      */

692     private void createIf2(polyglot.ast.If ifExpr){
693             
694         soot.jimple.NopStmt endTgt = soot.jimple.Jimple.v().newNopStmt();
695         soot.jimple.NopStmt brchTgt = soot.jimple.Jimple.v().newNopStmt();
696
697         // handle cond
698
polyglot.ast.Expr condition = ifExpr.cond();
699         createBranchingExpr(condition, brchTgt, false);
700
701         // add consequence
702
polyglot.ast.Stmt consequence = ifExpr.consequent();
703         createStmt(consequence);
704     
705         soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(endTgt);
706         body.getUnits().add(goto1);
707       
708         
709         body.getUnits().add(brchTgt);
710         
711         // handle alternative
712
polyglot.ast.Stmt alternative = ifExpr.alternative();
713         if (alternative != null){
714             createStmt(alternative);
715         }
716         body.getUnits().add(endTgt);
717         
718
719     }
720
721     private void createBranchingExpr(polyglot.ast.Expr expr, soot.jimple.Stmt tgt, boolean boto){
722         if (expr instanceof polyglot.ast.Binary && ((polyglot.ast.Binary)expr).operator() == polyglot.ast.Binary.COND_AND){
723             polyglot.ast.Binary cond_and = (polyglot.ast.Binary)expr;
724             if (boto){
725                 soot.jimple.Stmt t1 = soot.jimple.Jimple.v().newNopStmt();
726                 createBranchingExpr(cond_and.left(), t1, false);
727                 createBranchingExpr(cond_and.right(), tgt, true);
728                 body.getUnits().add(t1);
729             }
730             else {
731                 createBranchingExpr(cond_and.left(), tgt, false);
732                 createBranchingExpr(cond_and.right(), tgt, false);
733             }
734         }
735         else if (expr instanceof polyglot.ast.Binary && ((polyglot.ast.Binary)expr).operator() == polyglot.ast.Binary.COND_OR){
736             polyglot.ast.Binary cond_or = (polyglot.ast.Binary)expr;
737             if (boto){
738                 createBranchingExpr(cond_or.left(), tgt, true);
739                 createBranchingExpr(cond_or.right(), tgt, true);
740             }
741             else {
742                 soot.jimple.Stmt t1 = soot.jimple.Jimple.v().newNopStmt();
743                 createBranchingExpr(cond_or.left(), t1, true);
744                 createBranchingExpr(cond_or.right(), tgt, false);
745                 body.getUnits().add(t1);
746             }
747             
748         }
749         else if (expr instanceof polyglot.ast.Unary && ((polyglot.ast.Unary)expr).operator() == polyglot.ast.Unary.NOT){
750             polyglot.ast.Unary not = (polyglot.ast.Unary)expr;
751             createBranchingExpr(not.expr(), tgt, !boto);
752         }
753         else {
754             soot.Value sootCond = base().createExpr(expr);
755
756             boolean needIf = needSootIf(sootCond);
757             if (!(sootCond instanceof soot.jimple.ConditionExpr)) {
758                 if (!boto){
759                     sootCond = soot.jimple.Jimple.v().newEqExpr(sootCond, soot.jimple.IntConstant.v(0));
760                 }
761                 else {
762                     sootCond = soot.jimple.Jimple.v().newNeExpr(sootCond, soot.jimple.IntConstant.v(0));
763                 }
764             }
765             
766             else {
767                 sootCond = handleDFLCond((soot.jimple.ConditionExpr)sootCond);
768                 if (!boto){
769                     sootCond = reverseCondition((soot.jimple.ConditionExpr)sootCond);
770                 }
771             }
772                     
773             if (needIf) {
774                 soot.jimple.IfStmt ifStmt = soot.jimple.Jimple.v().newIfStmt(sootCond, tgt);
775                 body.getUnits().add(ifStmt);
776                 // add line and pos tags
777
Util.addLnPosTags(ifStmt.getConditionBox(), expr.position());
778                 Util.addLnPosTags(ifStmt, expr.position());
779             }
780             /*else {
781                 soot.jimple.GotoStmt gotoStmt = soot.jimple.Jimple.v().newGotoStmt(tgt);
782                 body.getUnits().add(gotoStmt);
783                 // add line and pos tags
784                 Util.addLnPosTags(gotoStmt, expr.position());
785             }*/

786         }
787     }
788     
789     /**
790      * While Stmts Creation
791      */

792     /*private void createWhile(polyglot.ast.While whileStmt){
793
794         // create true/false noops to handle cond and/or
795         trueNoop.push(soot.jimple.Jimple.v().newNopStmt());
796         falseNoop.push(soot.jimple.Jimple.v().newNopStmt());
797    
798         soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
799         soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
800
801         // these are for break and continue
802         endControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
803         condControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
804         
805         body.getUnits().add(noop2);
806         
807         // handle cond
808         soot.jimple.Stmt continueStmt = (soot.jimple.Stmt)condControlNoop.pop();
809         body.getUnits().add(continueStmt);
810         condControlNoop.push(continueStmt);
811         
812         polyglot.ast.Expr condition = whileStmt.cond();
813         soot.Value sootCond = base().createExpr(condition);
814         soot.jimple.Stmt tNoop = (soot.jimple.Stmt)trueNoop.pop();
815         soot.jimple.Stmt fNoop = (soot.jimple.Stmt)falseNoop.pop();
816         boolean needIf = needSootIf(sootCond);
817         if (!(sootCond instanceof soot.jimple.ConditionExpr)) {
818             sootCond = soot.jimple.Jimple.v().newEqExpr(sootCond, soot.jimple.IntConstant.v(0));
819         }
820         else {
821             sootCond = reverseCondition((soot.jimple.ConditionExpr)sootCond);
822             sootCond = handleDFLCond((soot.jimple.ConditionExpr)sootCond);
823         }
824
825         if (needIf){
826             soot.jimple.IfStmt ifStmt = soot.jimple.Jimple.v().newIfStmt(sootCond, noop1);
827         
828             body.getUnits().add(ifStmt);
829             Util.addLnPosTags(ifStmt.getConditionBox(), condition.position());
830             Util.addLnPosTags(ifStmt, condition.position());
831         }
832         
833         body.getUnits().add(tNoop);
834         createStmt(whileStmt.body());
835         soot.jimple.GotoStmt gotoLoop = soot.jimple.Jimple.v().newGotoStmt(noop2);
836         body.getUnits().add(gotoLoop);
837
838         body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop()));
839         body.getUnits().add(noop1);
840         body.getUnits().add(fNoop);
841         condControlNoop.pop();
842     }*/

843     
844     /**
845      * While Stmts Creation
846      */

847     private void createWhile2(polyglot.ast.While whileStmt){
848
849    
850         soot.jimple.Stmt brchTgt = soot.jimple.Jimple.v().newNopStmt();
851         soot.jimple.Stmt beginTgt = soot.jimple.Jimple.v().newNopStmt();
852
853         body.getUnits().add(beginTgt);
854         
855         // these are for break and continue
856
endControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
857         condControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
858         
859         // handle cond
860
soot.jimple.Stmt continueStmt = (soot.jimple.Stmt)condControlNoop.pop();
861         body.getUnits().add(continueStmt);
862         condControlNoop.push(continueStmt);
863         
864         polyglot.ast.Expr condition = whileStmt.cond();
865         createBranchingExpr(condition, brchTgt, false);
866         createStmt(whileStmt.body());
867         soot.jimple.GotoStmt gotoLoop = soot.jimple.Jimple.v().newGotoStmt(beginTgt);
868         body.getUnits().add(gotoLoop);
869
870         
871         body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop()));
872         body.getUnits().add(brchTgt);
873         condControlNoop.pop();
874     }
875     
876     /**
877      * DoWhile Stmts Creation
878      */

879     /*private void createDo(polyglot.ast.Do doStmt){
880         
881         // create true/false noops to handle cond and/or
882         soot.jimple.Stmt tNoop = soot.jimple.Jimple.v().newNopStmt();
883         soot.jimple.Stmt fNoop = soot.jimple.Jimple.v().newNopStmt();
884    
885         soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
886         body.getUnits().add(noop1);
887         
888         // add true noop - for cond and/or
889         body.getUnits().add(tNoop);
890         
891         // these are for break and continue
892         endControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
893         condControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
894         
895         // handle body
896         createStmt(doStmt.body());
897                 
898         // handle cond
899         soot.jimple.Stmt continueStmt = (soot.jimple.Stmt)condControlNoop.pop();
900         body.getUnits().add(continueStmt);
901         condControlNoop.push(continueStmt);
902         
903         // handle label continue
904         //if ((labelContinueMap != null) && (labelContinueMap.containsKey(lastLabel))){
905         if (labelMap != null && labelMap.containsKey(doStmt)){
906             body.getUnits().add((soot.jimple.Stmt)labelMap.get(doStmt));
907         }
908         /*if ((labelContinueMap != null) && (labelStack != null) && (!labelStack.isEmpty()) && (labelContinueMap.containsKey(((LabelKey)labelStack.peek()).label()))){
909             body.getUnits().add((soot.jimple.Stmt)labelContinueMap.get(((LabelKey)labelStack.peek()).label()));
910         }*/

911         
912        /* trueNoop.push(tNoop);
913         falseNoop.push(fNoop);
914         
915         polyglot.ast.Expr condition = doStmt.cond();
916         soot.Value sootCond = base().createExpr(condition);
917         
918         trueNoop.pop();
919         
920         boolean needIf = needSootIf(sootCond);
921         if (!(sootCond instanceof soot.jimple.ConditionExpr)) {
922             sootCond = soot.jimple.Jimple.v().newNeExpr(sootCond, soot.jimple.IntConstant.v(0));
923         }
924         else {
925             sootCond = handleDFLCond((soot.jimple.ConditionExpr)sootCond);
926         }
927         if (needIf){
928             soot.jimple.IfStmt ifStmt = soot.jimple.Jimple.v().newIfStmt(sootCond, noop1);
929             body.getUnits().add(ifStmt);
930             Util.addPosTag(ifStmt.getConditionBox(), condition.position());
931             Util.addLnPosTags(ifStmt, condition.position());
932         }
933         else {
934             soot.jimple.GotoStmt gotoIf = soot.jimple.Jimple.v().newGotoStmt(noop1);
935             body.getUnits().add(gotoIf);
936         }
937         body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop()));
938         condControlNoop.pop();
939         body.getUnits().add(falseNoop.pop());
940     }*/

941     
942     /**
943      * DoWhile Stmts Creation
944      */

945     private void createDo2(polyglot.ast.Do doStmt){
946         
947    
948         soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
949         body.getUnits().add(noop1);
950         
951         // these are for break and continue
952
endControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
953         condControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
954         
955         // handle body
956
createStmt(doStmt.body());
957                 
958         // handle cond
959
soot.jimple.Stmt continueStmt = (soot.jimple.Stmt)condControlNoop.pop();
960         body.getUnits().add(continueStmt);
961         condControlNoop.push(continueStmt);
962         
963         if (labelMap != null && labelMap.containsKey(doStmt)){
964             body.getUnits().add((soot.jimple.Stmt)labelMap.get(doStmt));
965         }
966         
967         polyglot.ast.Expr condition = doStmt.cond();
968        
969         createBranchingExpr(condition, noop1, true);
970         
971         body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop()));
972         condControlNoop.pop();
973     }
974     
975     /**
976      * For Loop Stmts Creation
977      */

978     /*private void createForLoop(polyglot.ast.For forStmt){
979         
980         // create true/false noops to handle cond and/or
981         soot.jimple.Stmt tNoop = soot.jimple.Jimple.v().newNopStmt();
982         soot.jimple.Stmt fNoop = soot.jimple.Jimple.v().newNopStmt();
983         
984         // these ()are for break and continue
985         endControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
986         condControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
987         
988         // handle for inits
989         Iterator initsIt = forStmt.inits().iterator();
990         while (initsIt.hasNext()){
991             createStmt((polyglot.ast.Stmt)initsIt.next());
992         }
993         soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
994         soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
995         
996         body.getUnits().add(noop2);
997         
998         // handle cond
999         
1000        polyglot.ast.Expr condition = forStmt.cond();
1001        if (condition != null) {
1002            trueNoop.push(tNoop);
1003            falseNoop.push(fNoop);
1004            soot.Value sootCond = base().createExpr(condition);
1005            trueNoop.pop();
1006            falseNoop.pop();
1007            
1008            boolean needIf = needSootIf(sootCond);
1009            if (!(sootCond instanceof soot.jimple.ConditionExpr)) {
1010                sootCond = soot.jimple.Jimple.v().newEqExpr(sootCond, soot.jimple.IntConstant.v(0));
1011            }
1012            else {
1013                sootCond = reverseCondition((soot.jimple.ConditionExpr)sootCond);
1014                sootCond = handleDFLCond((soot.jimple.ConditionExpr)sootCond);
1015            }
1016            if (needIf){
1017                soot.jimple.IfStmt ifStmt = soot.jimple.Jimple.v().newIfStmt(sootCond, noop1);
1018        
1019                // add cond
1020                body.getUnits().add(ifStmt);
1021        
1022                // add line and pos tags
1023                Util.addLnPosTags(ifStmt.getConditionBox(), condition.position());
1024                Util.addLnPosTags(ifStmt, condition.position());
1025            }
1026            //else {
1027            // soot.jimple.GotoStmt gotoIf = soot.jimple.Jimple.v().newGotoStmt(noop1);
1028            // body.getUnits().add(gotoIf);
1029            //}
1030            
1031        }
1032        //else {
1033        // soot.jimple.Stmt goto2 = soot.jimple.Jimple.v().newGotoStmt(noop1);
1034        // body.getUnits().add(goto2);
1035           
1036        //}
1037        
1038        
1039        // handle body
1040        //soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
1041        //soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2);
1042        //body.getUnits().add(goto1);
1043        //body.getUnits().add(noop1);
1044        body.getUnits().add(tNoop);
1045        createStmt(forStmt.body());
1046        
1047        // handle continue
1048        body.getUnits().add((soot.jimple.Stmt)(condControlNoop.pop()));
1049
1050        // handle label continue
1051        //if ((labelContinueMap != null) && (labelContinueMap.containsKey(lastLabel))){
1052        if (labelMap != null && labelMap.containsKey(forStmt)){
1053            body.getUnits().add((soot.jimple.Stmt)labelMap.get(forStmt));
1054        }
1055        
1056        /*if ((labelContinueMap != null) && (labelStack != null) && (!labelStack.isEmpty()) && (labelContinueMap.containsKey(((LabelKey)labelStack.peek()).label()))){
1057            body.getUnits().add((soot.jimple.Stmt)labelContinueMap.get(((LabelKey)labelStack.peek()).label()));
1058            //System.out.println("lastLabel: "+lastLabel);
1059            //if (!body.getUnits().contains((soot.jimple.Stmt)labelContinueMap.get(lastLabel))){
1060              // body.getUnits().add((soot.jimple.Stmt)labelContinueMap.get(lastLabel));
1061            //}
1062        }*/

1063        
1064        // handle iters
1065
/* Iterator itersIt = forStmt.iters().iterator();
1066        //System.out.println("for iters: "+forStmt.iters());
1067        while (itersIt.hasNext()){
1068            createStmt((polyglot.ast.Stmt)itersIt.next());
1069        }
1070        soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2);
1071        body.getUnits().add(goto1);
1072        //body.getUnits().add(noop2);
1073        
1074        // handle cond
1075        
1076        /*polyglot.ast.Expr condition = forStmt.cond();
1077        if (condition != null) {
1078            soot.Value sootCond = base().createExpr(condition);
1079            boolean needIf = needSootIf(sootCond);
1080            if (!(sootCond instanceof soot.jimple.ConditionExpr)) {
1081                sootCond = soot.jimple.Jimple.v().newNeExpr(sootCond, soot.jimple.IntConstant.v(0));
1082            }
1083            else {
1084                sootCond = handleDFLCond((soot.jimple.ConditionExpr)sootCond);
1085            }
1086            if (needIf){
1087                soot.jimple.IfStmt ifStmt = soot.jimple.Jimple.v().newIfStmt(sootCond, noop1);
1088        
1089                // add cond
1090                body.getUnits().add(ifStmt);
1091        
1092                // add line and pos tags
1093                Util.addLnPosTags(ifStmt.getConditionBox(), condition.position());
1094                Util.addLnPosTags(ifStmt, condition.position());
1095            }
1096            else {
1097                soot.jimple.GotoStmt gotoIf = soot.jimple.Jimple.v().newGotoStmt(noop1);
1098                body.getUnits().add(gotoIf);
1099            }
1100            
1101        }
1102        else {
1103            soot.jimple.Stmt goto2 = soot.jimple.Jimple.v().newGotoStmt(noop1);
1104            body.getUnits().add(goto2);
1105           
1106        }*/

1107       /* body.getUnits().add(noop1);
1108        body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop()));
1109        body.getUnits().add(fNoop);
1110        
1111    }*/

1112    
1113    /**
1114     * For Loop Stmts Creation
1115     */

1116    private void createForLoop2(polyglot.ast.For forStmt){
1117        
1118        // these ()are for break and continue
1119
endControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
1120        condControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
1121        
1122        // handle for inits
1123
Iterator initsIt = forStmt.inits().iterator();
1124        while (initsIt.hasNext()){
1125            createStmt((polyglot.ast.Stmt)initsIt.next());
1126        }
1127        soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
1128        soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
1129        
1130        body.getUnits().add(noop2);
1131        
1132        // handle cond
1133

1134        polyglot.ast.Expr condition = forStmt.cond();
1135        if (condition != null) {
1136            createBranchingExpr(condition, noop1, false);
1137        }
1138        createStmt(forStmt.body());
1139        
1140        // handle continue
1141
body.getUnits().add((soot.jimple.Stmt)(condControlNoop.pop()));
1142
1143        if (labelMap != null && labelMap.containsKey(forStmt)){
1144            body.getUnits().add((soot.jimple.Stmt)labelMap.get(forStmt));
1145        }
1146        
1147        // handle iters
1148
Iterator itersIt = forStmt.iters().iterator();
1149        while (itersIt.hasNext()){
1150            createStmt((polyglot.ast.Stmt)itersIt.next());
1151        }
1152        soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2);
1153        body.getUnits().add(goto1);
1154        body.getUnits().add(noop1);
1155        body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop()));
1156        
1157    }
1158    
1159    /**
1160     * Local Decl Creation
1161     */

1162    private void createLocalDecl(polyglot.ast.LocalDecl localDecl) {
1163      
1164        //System.out.println("local decl: "+localDecl);
1165
String JavaDoc name = localDecl.name();
1166        polyglot.types.LocalInstance localInst = localDecl.localInstance();
1167        soot.Value lhs = createLocal(localInst);
1168        polyglot.ast.Expr expr = localDecl.init();
1169        if (expr != null) {
1170            //System.out.println("expr: "+expr+" get type: "+expr.getClass());
1171
soot.Value rhs;
1172            if (expr instanceof polyglot.ast.ArrayInit){
1173                //System.out.println("creating array from localdecl: "+localInst.type());
1174
rhs = getArrayInitLocal((polyglot.ast.ArrayInit)expr, localInst.type());
1175            }
1176            else {
1177                //System.out.println("create local decl: "+expr+" is a: "+expr.getClass());
1178
rhs = base().createExpr(expr);
1179                //System.out.println("rhs is: "+rhs+" is a: "+rhs.getClass());
1180
}
1181            if (rhs instanceof soot.jimple.ConditionExpr) {
1182                rhs = handleCondBinExpr((soot.jimple.ConditionExpr)rhs);
1183            }
1184            //System.out.println("rhs: "+rhs);
1185
soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(lhs, rhs);
1186            body.getUnits().add(stmt);
1187            //Util.addLineTag(stmt, localDecl);
1188
Util.addLnPosTags(stmt, localDecl.position());
1189            // this is a special case for position tags
1190
if ( localDecl.position() != null){
1191                Util.addLnPosTags(stmt.getLeftOpBox(), localDecl.position().line(), localDecl.position().endLine(), localDecl.position().endColumn()-name.length(), localDecl.position().endColumn());
1192                if (expr != null){
1193                    Util.addLnPosTags(stmt, localDecl.position().line(), expr.position().endLine(), localDecl.position().column(), expr.position().endColumn());
1194                }
1195                else {
1196                    Util.addLnPosTags(stmt, localDecl.position().line(), localDecl.position().endLine(), localDecl.position().column(), localDecl.position().endColumn());
1197                }
1198            }
1199            else {
1200            }
1201            if (expr != null){
1202                Util.addLnPosTags(stmt.getRightOpBox(), expr.position());
1203            }
1204        }
1205    }
1206    
1207    /**
1208     * Switch Stmts Creation
1209     */

1210    private void createSwitch(polyglot.ast.Switch switchStmt) {
1211       
1212
1213        polyglot.ast.Expr value = switchStmt.expr();
1214        soot.Value sootValue = base().createExpr(value);
1215        
1216        if (switchStmt.elements().size() == 0) return;
1217        
1218        soot.jimple.Stmt defaultTarget = null;
1219     
1220        polyglot.ast.Case [] caseArray = new polyglot.ast.Case[switchStmt.elements().size()];
1221        soot.jimple.Stmt [] targetsArray = new soot.jimple.Stmt[switchStmt.elements().size()];
1222        
1223        ArrayList targets = new ArrayList();
1224        HashMap targetsMap = new HashMap();
1225        int counter = 0;
1226        Iterator it = switchStmt.elements().iterator();
1227        while (it.hasNext()) {
1228            Object JavaDoc next = it.next();
1229            if (next instanceof polyglot.ast.Case) {
1230                soot.jimple.Stmt noop = soot.jimple.Jimple.v().newNopStmt();
1231                if (!((polyglot.ast.Case)next).isDefault()){
1232                    targets.add(noop);
1233                    caseArray[counter] = (polyglot.ast.Case)next;
1234                    targetsArray[counter] = noop;
1235                    counter++;
1236                    targetsMap.put(next, noop);
1237                }
1238                else {
1239                    defaultTarget = noop;
1240                }
1241            }
1242        }
1243        
1244        // sort targets map
1245
int lowIndex = 0;
1246        int highIndex = 0;
1247
1248       
1249        for (int i = 0; i < counter; i++) {
1250            for (int j = i+1; j < counter; j++) {
1251                if (caseArray[j].value() < caseArray[i].value()) {
1252                    polyglot.ast.Case tempCase = caseArray[i];
1253                    soot.jimple.Stmt tempTarget = targetsArray[i];
1254                    caseArray[i] = caseArray[j];
1255                    targetsArray[i] = targetsArray[j];
1256                    caseArray[j] = tempCase;
1257                    targetsArray[j] = tempTarget;
1258                }
1259            }
1260        }
1261        
1262        ArrayList sortedTargets = new ArrayList();
1263
1264        for (int i = 0; i < counter; i++) {
1265            sortedTargets.add(targetsArray[i]);
1266        }
1267            
1268        // deal with default
1269
boolean hasDefaultTarget = true;
1270        if (defaultTarget == null) {
1271            soot.jimple.Stmt noop = soot.jimple.Jimple.v().newNopStmt();
1272            defaultTarget = noop;
1273            hasDefaultTarget = false;
1274            
1275        }
1276        
1277        // lookup or tableswitch
1278
soot.jimple.Stmt sootSwitchStmt;
1279        if (isLookupSwitch(switchStmt)) {
1280        
1281            ArrayList values = new ArrayList();
1282            for (int i = 0; i < counter; i++) {
1283                if (!caseArray[i].isDefault()) {
1284                    values.add(soot.jimple.IntConstant.v((int)caseArray[i].value()));
1285                }
1286            }
1287
1288            
1289            soot.jimple.LookupSwitchStmt lookupStmt = soot.jimple.Jimple.v().newLookupSwitchStmt(sootValue, values, sortedTargets, defaultTarget);
1290       
1291            Util.addLnPosTags(lookupStmt.getKeyBox(), value.position());
1292            sootSwitchStmt = lookupStmt;
1293        
1294        }
1295        else {
1296            long lowVal = 0;
1297            long highVal = 0;
1298            boolean unknown = true;
1299
1300            it = switchStmt.elements().iterator();
1301            while (it.hasNext()){
1302                Object JavaDoc next = it.next();
1303                if (next instanceof polyglot.ast.Case) {
1304                    if (!((polyglot.ast.Case)next).isDefault()){
1305                        long temp = ((polyglot.ast.Case)next).value();
1306                        if (unknown){
1307                            highVal = temp;
1308                            lowVal = temp;
1309                            unknown = false;
1310                        }
1311                        if (temp > highVal) {
1312                            highVal = temp;
1313                        }
1314                        if (temp < lowVal) {
1315                            lowVal = temp;
1316                        }
1317                    }
1318                }
1319                
1320            }
1321
1322            soot.jimple.TableSwitchStmt tableStmt = soot.jimple.Jimple.v().newTableSwitchStmt(sootValue, (int)lowVal, (int)highVal, sortedTargets, defaultTarget);
1323
1324            Util.addLnPosTags(tableStmt.getKeyBox(), value.position());
1325            sootSwitchStmt = tableStmt;
1326
1327        }
1328        
1329        body.getUnits().add(sootSwitchStmt);
1330
1331        Util.addLnPosTags(sootSwitchStmt, switchStmt.position());
1332        endControlNoop.push(soot.jimple.Jimple.v().newNopStmt());
1333        
1334        it = switchStmt.elements().iterator();
1335        Iterator targetsIt = targets.iterator();
1336
1337        while (it.hasNext()){
1338            Object JavaDoc next = it.next();
1339            if (next instanceof polyglot.ast.Case) {
1340                if (!((polyglot.ast.Case)next).isDefault()){
1341                    body.getUnits().add((soot.jimple.Stmt)targetsMap.get(next));
1342                }
1343                else {
1344                    body.getUnits().add(defaultTarget);
1345                }
1346            }
1347            else {
1348                polyglot.ast.SwitchBlock blockStmt = (polyglot.ast.SwitchBlock)next;
1349                createBlock(blockStmt);
1350                
1351            }
1352        }
1353        
1354        if (!hasDefaultTarget) {
1355            body.getUnits().add(defaultTarget);
1356        }
1357        body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop()));
1358    }
1359
1360    /**
1361     * Determine if switch should be lookup or table - this doesn't
1362     * always get the same result as javac
1363     * lookup: non-table
1364     * table: sequential (no gaps)
1365     */

1366    private boolean isLookupSwitch(polyglot.ast.Switch switchStmt){
1367
1368        int lowest = 0;
1369        int highest = 0;
1370        int counter = 0;
1371        Iterator it = switchStmt.elements().iterator();
1372        while (it.hasNext()){
1373            Object JavaDoc next = it.next();
1374            if (next instanceof polyglot.ast.Case) {
1375                polyglot.ast.Case caseStmt = (polyglot.ast.Case)next;
1376                if (caseStmt.isDefault()) continue;
1377                int caseValue = (int)caseStmt.value();
1378                if (caseValue <= lowest || counter == 0 ) {
1379                    lowest = caseValue;
1380                }
1381                if (caseValue >= highest || counter == 0) {
1382                    highest = caseValue;
1383                }
1384                counter++;
1385            }
1386        }
1387
1388        if ((counter-1) == (highest - lowest)) return false;
1389        return true;
1390    }
1391    
1392    /**
1393     * Branch Stmts Creation
1394     */

1395    private void createBranch(polyglot.ast.Branch branchStmt){
1396        
1397        //handle finally blocks before branch if inside try block
1398
if (tryStack != null && !tryStack.isEmpty()){
1399            polyglot.ast.Try currentTry = (polyglot.ast.Try)tryStack.pop();
1400            if (currentTry.finallyBlock() != null){
1401                createBlock(currentTry.finallyBlock());
1402                tryStack.push(currentTry);
1403            }
1404            else {
1405                tryStack.push(currentTry);
1406            }
1407        }
1408       
1409        //handle finally blocks before branch if inside catch block
1410
if (catchStack != null && !catchStack.isEmpty()){
1411            polyglot.ast.Try currentTry = (polyglot.ast.Try)catchStack.pop();
1412            if (currentTry.finallyBlock() != null){
1413                createBlock(currentTry.finallyBlock());
1414                catchStack.push(currentTry);
1415            }
1416            else {
1417                catchStack.push(currentTry);
1418            }
1419        }
1420        
1421        body.getUnits().add(soot.jimple.Jimple.v().newNopStmt());
1422        if (branchStmt.kind() == polyglot.ast.Branch.BREAK){
1423            if (branchStmt.label() == null) {
1424                soot.jimple.Stmt gotoEndNoop = (soot.jimple.Stmt)endControlNoop.pop();
1425                soot.jimple.Stmt gotoEnd = soot.jimple.Jimple.v().newGotoStmt(gotoEndNoop);
1426                endControlNoop.push(gotoEndNoop);
1427                body.getUnits().add(gotoEnd);
1428                Util.addLnPosTags(gotoEnd, branchStmt.position());
1429            }
1430            else {
1431                soot.jimple.Stmt gotoLabel = soot.jimple.Jimple.v().newGotoStmt((soot.jimple.Stmt)labelBreakMap.get(branchStmt.label()));
1432                body.getUnits().add(gotoLabel);
1433                Util.addLnPosTags(gotoLabel, branchStmt.position());
1434            }
1435        }
1436        else if (branchStmt.kind() == polyglot.ast.Branch.CONTINUE){
1437            if (branchStmt.label() == null) {
1438                soot.jimple.Stmt gotoCondNoop = (soot.jimple.Stmt)condControlNoop.pop();
1439                soot.jimple.Stmt gotoCond = soot.jimple.Jimple.v().newGotoStmt(gotoCondNoop);
1440                condControlNoop.push(gotoCondNoop);
1441                body.getUnits().add(gotoCond);
1442                Util.addLnPosTags(gotoCond, branchStmt.position());
1443            }
1444            else {
1445                soot.jimple.Stmt gotoLabel = soot.jimple.Jimple.v().newGotoStmt((soot.jimple.Stmt)labelContinueMap.get(branchStmt.label()));
1446                body.getUnits().add(gotoLabel);
1447                Util.addLnPosTags(gotoLabel, branchStmt.position());
1448            }
1449            
1450        }
1451
1452    }
1453
1454    /**
1455     * Labeled Stmt Creation
1456     */

1457    private void createLabeled(polyglot.ast.Labeled labeledStmt){
1458        String JavaDoc label = labeledStmt.label();
1459        //lastLabel = label;
1460
polyglot.ast.Stmt stmt = labeledStmt.statement();
1461
1462        soot.jimple.Stmt noop = soot.jimple.Jimple.v().newNopStmt();
1463        //System.out.println("labeled stmt type: "+stmt.getClass());
1464
if (!(stmt instanceof polyglot.ast.For) && !(stmt instanceof polyglot.ast.Do)){
1465            body.getUnits().add(noop);
1466        }
1467        /*else {
1468            if (labelStack == null){
1469                labelStack = new Stack();
1470            }
1471            labelStack.push(new LabelKey(label, noop));
1472        }*/

1473
1474        if (labelMap == null){
1475            labelMap = new HashMap();
1476        }
1477
1478        labelMap.put(stmt, noop);
1479        
1480
1481        if (labelBreakMap == null) {
1482            labelBreakMap = new HashMap();
1483        }
1484
1485        if (labelContinueMap == null) {
1486            labelContinueMap = new HashMap();
1487        }
1488        
1489        labelContinueMap.put(label, noop);
1490        soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
1491        labelBreakMap.put(label, noop2);
1492        
1493        createStmt(stmt);
1494
1495        /*if (labelStack != null && !labelStack.isEmpty() && (stmt instanceof polyglot.ast.For || stmt instanceof polyglot.ast.Do)){
1496            labelStack.pop();
1497        }*/

1498        
1499        body.getUnits().add(noop2);
1500        
1501        // the idea here is to make a map of labels to the first
1502
// jimple stmt of the stmt (a noop) to be created - so
1503
// there is something to look up for breaks and continues
1504
// with labels
1505
}
1506
1507    /*class LabelKey{
1508
1509        public LabelKey(String label, soot.jimple.Stmt noop){
1510            this.label = label;
1511            this.noop = noop;
1512        }
1513        private String label;
1514        public String label(){
1515            return label;
1516        }
1517        private soot.jimple.Stmt noop;
1518        public soot.jimple.Stmt noop(){
1519            return noop;
1520        }
1521    }*/

1522    
1523    /**
1524     * Assert Stmt Creation
1525     */

1526    private void createAssert(polyglot.ast.Assert assertStmt) {
1527        
1528        // check if assertions are disabled
1529
soot.Local testLocal = lg.generateLocal(soot.BooleanType.v());
1530        soot.SootFieldRef assertField = soot.Scene.v().makeFieldRef(body.getMethod().getDeclaringClass(), "$assertionsDisabled", soot.BooleanType.v(), true);
1531        soot.jimple.FieldRef assertFieldRef = soot.jimple.Jimple.v().newStaticFieldRef(assertField);
1532        soot.jimple.AssignStmt fieldAssign = soot.jimple.Jimple.v().newAssignStmt(testLocal, assertFieldRef);
1533        body.getUnits().add(fieldAssign);
1534        
1535        soot.jimple.NopStmt nop1 = soot.jimple.Jimple.v().newNopStmt();
1536        soot.jimple.ConditionExpr cond1 = soot.jimple.Jimple.v().newNeExpr(testLocal, soot.jimple.IntConstant.v(0));
1537        soot.jimple.IfStmt testIf = soot.jimple.Jimple.v().newIfStmt(cond1, nop1);
1538        body.getUnits().add(testIf);
1539
1540        // actual cond test
1541
if ((assertStmt.cond() instanceof polyglot.ast.BooleanLit) && (!((polyglot.ast.BooleanLit)assertStmt.cond()).value())){
1542            // don't makeif
1543
}
1544        else {
1545            soot.Value sootCond = base().createExpr(assertStmt.cond());
1546            boolean needIf = needSootIf(sootCond);
1547            if (!(sootCond instanceof soot.jimple.ConditionExpr)) {
1548                sootCond = soot.jimple.Jimple.v().newEqExpr(sootCond, soot.jimple.IntConstant.v(1));
1549            }
1550            else {
1551                sootCond = handleDFLCond((soot.jimple.ConditionExpr)sootCond);
1552            }
1553       
1554            if (needIf){
1555                // add if
1556
soot.jimple.IfStmt ifStmt = soot.jimple.Jimple.v().newIfStmt(sootCond, nop1);
1557                body.getUnits().add(ifStmt);
1558
1559                Util.addLnPosTags(ifStmt.getConditionBox(), assertStmt.cond().position());
1560                Util.addLnPosTags(ifStmt, assertStmt.position());
1561            }
1562        }
1563        
1564        // assertion failure code
1565
soot.Local failureLocal = lg.generateLocal(soot.RefType.v("java.lang.AssertionError"));
1566        soot.jimple.NewExpr newExpr = soot.jimple.Jimple.v().newNewExpr(soot.RefType.v("java.lang.AssertionError"));
1567        soot.jimple.AssignStmt newAssign = soot.jimple.Jimple.v().newAssignStmt(failureLocal, newExpr);
1568        body.getUnits().add(newAssign);
1569
1570        soot.SootMethodRef methToInvoke;
1571        ArrayList paramTypes = new ArrayList();
1572        ArrayList params = new ArrayList();
1573        if (assertStmt.errorMessage() != null){
1574            soot.Value errorExpr = base().createExpr(assertStmt.errorMessage());
1575            if (errorExpr instanceof soot.jimple.ConditionExpr) {
1576                errorExpr = handleCondBinExpr((soot.jimple.ConditionExpr)errorExpr);
1577            }
1578            soot.Type errorType = errorExpr.getType();
1579           
1580            if (assertStmt.errorMessage().type().isChar()){
1581                errorType = soot.CharType.v();
1582            }
1583            if (errorType instanceof soot.IntType) {
1584                paramTypes.add(soot.IntType.v());
1585            }
1586            else if (errorType instanceof soot.LongType){
1587                paramTypes.add(soot.LongType.v());
1588            }
1589            else if (errorType instanceof soot.FloatType){
1590                paramTypes.add(soot.FloatType.v());
1591            }
1592            else if (errorType instanceof soot.DoubleType){
1593                paramTypes.add(soot.DoubleType.v());
1594            }
1595            else if (errorType instanceof soot.CharType){
1596                paramTypes.add(soot.CharType.v());
1597            }
1598            else if (errorType instanceof soot.BooleanType){
1599                paramTypes.add(soot.BooleanType.v());
1600            }
1601            else if (errorType instanceof soot.ShortType){
1602                paramTypes.add(soot.IntType.v());
1603            }
1604            else if (errorType instanceof soot.ByteType){
1605                paramTypes.add(soot.IntType.v());
1606            }
1607            else {
1608                paramTypes.add(soot.Scene.v().getSootClass("java.lang.Object").getType());
1609            }
1610            
1611            params.add(errorExpr);
1612        }
1613        methToInvoke = soot.Scene.v().makeMethodRef( soot.Scene.v().getSootClass("java.lang.AssertionError"), "<init>", paramTypes, soot.VoidType.v(), false);
1614        
1615        soot.jimple.SpecialInvokeExpr invokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(failureLocal, methToInvoke, params);
1616        soot.jimple.InvokeStmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(invokeExpr);
1617        body.getUnits().add(invokeStmt);
1618        
1619        
1620        if (assertStmt.errorMessage() != null){
1621            Util.addLnPosTags(invokeExpr.getArgBox(0), assertStmt.errorMessage().position());
1622        }
1623
1624        soot.jimple.ThrowStmt throwStmt = soot.jimple.Jimple.v().newThrowStmt(failureLocal);
1625        body.getUnits().add(throwStmt);
1626
1627        // end
1628
body.getUnits().add(nop1);
1629        
1630    }
1631    
1632    /**
1633     * Synchronized Stmt Creation
1634     */

1635    private void createSynchronized(polyglot.ast.Synchronized synchStmt) {
1636        soot.Value sootExpr = base().createExpr(synchStmt.expr());
1637        
1638        soot.jimple.EnterMonitorStmt enterMon = soot.jimple.Jimple.v().newEnterMonitorStmt(sootExpr);
1639        body.getUnits().add(enterMon);
1640        
1641        if (monitorStack == null){
1642            monitorStack = new Stack();
1643        }
1644        monitorStack.push(sootExpr);
1645        
1646        Util.addLnPosTags(enterMon.getOpBox(), synchStmt.expr().position());
1647        Util.addLnPosTags(enterMon, synchStmt.expr().position());
1648        
1649        soot.jimple.Stmt startNoop = soot.jimple.Jimple.v().newNopStmt();
1650        body.getUnits().add(startNoop);
1651        
1652        createBlock(synchStmt.body());
1653
1654        soot.jimple.ExitMonitorStmt exitMon = soot.jimple.Jimple.v().newExitMonitorStmt(sootExpr);
1655        body.getUnits().add(exitMon);
1656
1657        monitorStack.pop();
1658        Util.addLnPosTags(exitMon.getOpBox(), synchStmt.expr().position());
1659        Util.addLnPosTags(exitMon, synchStmt.expr().position());
1660        
1661        soot.jimple.Stmt endSynchNoop = soot.jimple.Jimple.v().newNopStmt();
1662        soot.jimple.Stmt gotoEnd = soot.jimple.Jimple.v().newGotoStmt(endSynchNoop);
1663
1664        soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt();
1665        body.getUnits().add(endNoop);
1666        
1667        body.getUnits().add(gotoEnd);
1668
1669        soot.jimple.Stmt catchAllBeforeNoop = soot.jimple.Jimple.v().newNopStmt();
1670        body.getUnits().add(catchAllBeforeNoop);
1671
1672        // catch all
1673
soot.Local formalLocal = lg.generateLocal(soot.RefType.v("java.lang.Throwable"));
1674            
1675        soot.jimple.CaughtExceptionRef exceptRef = soot.jimple.Jimple.v().newCaughtExceptionRef();
1676        soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(formalLocal, exceptRef);
1677        body.getUnits().add(stmt);
1678
1679        // catch
1680
soot.jimple.Stmt catchBeforeNoop = soot.jimple.Jimple.v().newNopStmt();
1681        body.getUnits().add(catchBeforeNoop);
1682        
1683        soot.Local local = lg.generateLocal(soot.RefType.v("java.lang.Throwable"));
1684        
1685        soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(local, formalLocal);
1686
1687        body.getUnits().add(assign);
1688        soot.jimple.ExitMonitorStmt catchExitMon = soot.jimple.Jimple.v().newExitMonitorStmt(sootExpr);
1689        
1690        body.getUnits().add(catchExitMon);
1691        Util.addLnPosTags(catchExitMon.getOpBox(), synchStmt.expr().position());
1692        
1693        soot.jimple.Stmt catchAfterNoop = soot.jimple.Jimple.v().newNopStmt();
1694        body.getUnits().add(catchAfterNoop);
1695        
1696        // throw
1697
soot.jimple.Stmt throwStmt = soot.jimple.Jimple.v().newThrowStmt(local);
1698        body.getUnits().add(throwStmt);
1699      
1700        
1701        body.getUnits().add(endSynchNoop);
1702
1703        addToExceptionList(startNoop, endNoop, catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable"));
1704        addToExceptionList(catchBeforeNoop, catchAfterNoop, catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable"));
1705                
1706    }
1707    
1708    /**
1709     * Return Stmts Creation
1710     */

1711    private void createReturn(polyglot.ast.Return retStmt) {
1712        polyglot.ast.Expr expr = retStmt.expr();
1713        soot.Value sootLocal = null;
1714        if (expr != null){
1715            sootLocal = base().createExpr(expr);
1716        }
1717        
1718        // handle monitor exits before return if necessary
1719
if (monitorStack != null){
1720            Stack putBack = new Stack();
1721            while (!monitorStack.isEmpty()){
1722                soot.Local exitVal = (soot.Local)monitorStack.pop();
1723                putBack.push(exitVal);
1724                soot.jimple.ExitMonitorStmt emStmt = soot.jimple.Jimple.v().newExitMonitorStmt(exitVal);
1725                body.getUnits().add(emStmt);
1726            }
1727            while(!putBack.isEmpty()){
1728                monitorStack.push(putBack.pop());
1729            }
1730        }
1731        
1732        //handle finally blocks before return if inside try block
1733
if (tryStack != null && !tryStack.isEmpty()){
1734            polyglot.ast.Try currentTry = (polyglot.ast.Try)tryStack.pop();
1735            if (currentTry.finallyBlock() != null){
1736                createBlock(currentTry.finallyBlock());
1737                tryStack.push(currentTry);
1738                // if return stmt contains a return don't create the other return
1739
//ReturnStmtChecker rsc = new ReturnStmtChecker();
1740
//currentTry.finallyBlock().visit(rsc);
1741
//if (rsc.hasRet()){
1742
// return;
1743
//}
1744
}
1745            else {
1746                tryStack.push(currentTry);
1747            }
1748        }
1749       
1750        //handle finally blocks before return if inside catch block
1751
if (catchStack != null && !catchStack.isEmpty()){
1752            polyglot.ast.Try currentTry = (polyglot.ast.Try)catchStack.pop();
1753            if (currentTry.finallyBlock() != null){
1754                createBlock(currentTry.finallyBlock());
1755                catchStack.push(currentTry);
1756                // if return stmt contains a return don't create the other return
1757
// extra return remove with some Soot phase
1758
//ReturnStmtChecker rsc = new ReturnStmtChecker();
1759
//currentTry.finallyBlock().visit(rsc);
1760
//if (rsc.hasRet()){
1761
// return;
1762
//}
1763
}
1764            else {
1765                catchStack.push(currentTry);
1766            }
1767        }
1768        
1769        // return
1770
if (expr == null) {
1771            soot.jimple.Stmt retStmtVoid = soot.jimple.Jimple.v().newReturnVoidStmt();
1772            body.getUnits().add(retStmtVoid);
1773            Util.addLnPosTags(retStmtVoid, retStmt.position());
1774        }
1775        else {
1776            //soot.Value sootLocal = createExpr(expr);
1777
if (sootLocal instanceof soot.jimple.ConditionExpr) {
1778                sootLocal = handleCondBinExpr((soot.jimple.ConditionExpr)sootLocal);
1779            }
1780            soot.jimple.ReturnStmt retStmtLocal = soot.jimple.Jimple.v().newReturnStmt(sootLocal);
1781            body.getUnits().add(retStmtLocal);
1782            Util.addLnPosTags(retStmtLocal.getOpBox(), expr.position());
1783            Util.addLnPosTags(retStmtLocal, retStmt.position());
1784        }
1785    }
1786    
1787    /**
1788     * Throw Stmt Creation
1789     */

1790    private void createThrow(polyglot.ast.Throw throwStmt){
1791        soot.Value toThrow = base().createExpr(throwStmt.expr());
1792        soot.jimple.ThrowStmt throwSt = soot.jimple.Jimple.v().newThrowStmt(toThrow);
1793        body.getUnits().add(throwSt);
1794        Util.addLnPosTags(throwSt, throwStmt.position());
1795        Util.addLnPosTags(throwSt.getOpBox(), throwStmt.expr().position());
1796    }
1797   
1798    /**
1799     * Try Stmt Creation
1800     */

1801    private void createTry(polyglot.ast.Try tryStmt) {
1802    
1803        polyglot.ast.Block finallyBlock = tryStmt.finallyBlock();
1804        
1805        if (finallyBlock == null) {
1806            createTryCatch(tryStmt);
1807        }
1808        else {
1809            createTryCatchFinally(tryStmt);
1810        }
1811    }
1812
1813    /**
1814     * handles try/catch (try/catch/finally is separate for simplicity)
1815     */

1816    private void createTryCatch(polyglot.ast.Try tryStmt){
1817        
1818        // try
1819
polyglot.ast.Block tryBlock = tryStmt.tryBlock();
1820        
1821        // this nop is for the fromStmt of try
1822
soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
1823        body.getUnits().add(noop1);
1824       
1825        if (tryStack == null){
1826            tryStack = new Stack();
1827        }
1828        tryStack.push(tryStmt);
1829        createBlock(tryBlock);
1830        tryStack.pop();
1831        
1832        // this nop is for the toStmt of try
1833
soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
1834        body.getUnits().add(noop2);
1835    
1836        // create end nop for after entire try/catch
1837
soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt();
1838
1839        soot.jimple.Stmt tryEndGoto = soot.jimple.Jimple.v().newGotoStmt(endNoop);
1840        body.getUnits().add(tryEndGoto);
1841        
1842        Iterator it = tryStmt.catchBlocks().iterator();
1843        while (it.hasNext()) {
1844            
1845            soot.jimple.Stmt noop3 = soot.jimple.Jimple.v().newNopStmt();
1846            body.getUnits().add(noop3);
1847
1848            // create catch stmts
1849
polyglot.ast.Catch catchBlock = (polyglot.ast.Catch)it.next();
1850            
1851            // create catch ref
1852
createCatchFormal(catchBlock.formal());
1853          
1854            if (catchStack == null){
1855                catchStack = new Stack();
1856            }
1857            catchStack.push(tryStmt);
1858            createBlock(catchBlock.body());
1859            catchStack.pop();
1860        
1861            soot.jimple.Stmt catchEndGoto = soot.jimple.Jimple.v().newGotoStmt(endNoop);
1862            body.getUnits().add(catchEndGoto);
1863        
1864
1865            soot.Type sootType = Util.getSootType(catchBlock.catchType());
1866           
1867            addToExceptionList(noop1, noop2, noop3, soot.Scene.v().getSootClass(sootType.toString()));
1868            
1869        }
1870
1871        body.getUnits().add(endNoop);
1872    }
1873
1874    /**
1875     * handles try/catch/finally (try/catch is separate for simplicity)
1876     */

1877    private void createTryCatchFinally(polyglot.ast.Try tryStmt){
1878       
1879        HashMap gotoMap = new HashMap();
1880        
1881        // try
1882
polyglot.ast.Block tryBlock = tryStmt.tryBlock();
1883        
1884        // this nop is for the fromStmt of try
1885
soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
1886        body.getUnits().add(noop1);
1887        
1888        if (tryStack == null){
1889            tryStack = new Stack();
1890        }
1891        tryStack.push(tryStmt);
1892        createBlock(tryBlock);
1893        tryStack.pop();
1894        
1895        // this nop is for the toStmt of try
1896
soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
1897        body.getUnits().add(noop2);
1898    
1899        // create end nop for after entire try/catch
1900
soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt();
1901        
1902        // to finally
1903
soot.jimple.Stmt tryGotoFinallyNoop = soot.jimple.Jimple.v().newNopStmt();
1904
1905        body.getUnits().add(tryGotoFinallyNoop);
1906        soot.jimple.Stmt tryFinallyNoop = soot.jimple.Jimple.v().newNopStmt();
1907        
1908        soot.jimple.Stmt tryGotoFinally = soot.jimple.Jimple.v().newGotoStmt(tryFinallyNoop);
1909        body.getUnits().add(tryGotoFinally);
1910        
1911        // goto end stmts
1912
soot.jimple.Stmt beforeEndGotoNoop = soot.jimple.Jimple.v().newNopStmt();
1913        body.getUnits().add(beforeEndGotoNoop);
1914        soot.jimple.Stmt tryEndGoto = soot.jimple.Jimple.v().newGotoStmt(endNoop);
1915        body.getUnits().add(tryEndGoto);
1916        
1917        gotoMap.put(tryFinallyNoop, beforeEndGotoNoop);
1918            
1919
1920       
1921        // catch section
1922
soot.jimple.Stmt catchAllBeforeNoop = soot.jimple.Jimple.v().newNopStmt();
1923        Iterator it = tryStmt.catchBlocks().iterator();
1924        while (it.hasNext()) {
1925            
1926            soot.jimple.Stmt noop3 = soot.jimple.Jimple.v().newNopStmt();
1927            body.getUnits().add(noop3);
1928
1929            // create catch stmts
1930
polyglot.ast.Catch catchBlock = (polyglot.ast.Catch)it.next();
1931            
1932            // create catch ref
1933
soot.jimple.Stmt catchRefNoop = soot.jimple.Jimple.v().newNopStmt();
1934            body.getUnits().add(catchRefNoop);
1935            
1936            createCatchFormal(catchBlock.formal());
1937          
1938            soot.jimple.Stmt catchStmtsNoop = soot.jimple.Jimple.v().newNopStmt();
1939            body.getUnits().add(catchStmtsNoop);
1940
1941            if (catchStack == null){
1942                catchStack = new Stack();
1943            }
1944            catchStack.push(tryStmt);
1945            createBlock(catchBlock.body());
1946            catchStack.pop();
1947        
1948            // to finally
1949
soot.jimple.Stmt catchGotoFinallyNoop = soot.jimple.Jimple.v().newNopStmt();
1950            body.getUnits().add(catchGotoFinallyNoop);
1951            soot.jimple.Stmt catchFinallyNoop = soot.jimple.Jimple.v().newNopStmt();
1952        
1953            soot.jimple.Stmt catchGotoFinally = soot.jimple.Jimple.v().newGotoStmt(catchFinallyNoop);
1954            body.getUnits().add(catchGotoFinally);
1955            
1956            // goto end stmts
1957
soot.jimple.Stmt beforeCatchEndGotoNoop = soot.jimple.Jimple.v().newNopStmt();
1958            body.getUnits().add(beforeCatchEndGotoNoop);
1959            soot.jimple.Stmt catchEndGoto = soot.jimple.Jimple.v().newGotoStmt(endNoop);
1960            body.getUnits().add(catchEndGoto);
1961        
1962
1963            gotoMap.put(catchFinallyNoop, beforeCatchEndGotoNoop);
1964
1965            soot.Type sootType = Util.getSootType(catchBlock.catchType());
1966           
1967            addToExceptionList(noop1, noop2, noop3, soot.Scene.v().getSootClass(sootType.toString()));
1968            addToExceptionList(catchStmtsNoop, beforeCatchEndGotoNoop, catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable"));
1969        }
1970        
1971        // catch all ref
1972
soot.Local formalLocal = lg.generateLocal(soot.RefType.v("java.lang.Throwable"));
1973            
1974        body.getUnits().add(catchAllBeforeNoop);
1975        soot.jimple.CaughtExceptionRef exceptRef = soot.jimple.Jimple.v().newCaughtExceptionRef();
1976        soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(formalLocal, exceptRef);
1977        body.getUnits().add(stmt);
1978
1979        // catch all assign
1980
soot.jimple.Stmt beforeCatchAllAssignNoop = soot.jimple.Jimple.v().newNopStmt();
1981        body.getUnits().add(beforeCatchAllAssignNoop);
1982        soot.Local catchAllAssignLocal = lg.generateLocal(soot.RefType.v("java.lang.Throwable"));
1983        soot.jimple.Stmt catchAllAssign = soot.jimple.Jimple.v().newAssignStmt(catchAllAssignLocal, formalLocal);
1984
1985        body.getUnits().add(catchAllAssign);
1986
1987        // catch all finally
1988
soot.jimple.Stmt catchAllFinallyNoop = soot.jimple.Jimple.v().newNopStmt();
1989        soot.jimple.Stmt catchAllGotoFinally = soot.jimple.Jimple.v().newGotoStmt(catchAllFinallyNoop);
1990        body.getUnits().add(catchAllGotoFinally);
1991
1992        // catch all throw
1993
soot.jimple.Stmt catchAllBeforeThrowNoop = soot.jimple.Jimple.v().newNopStmt();
1994        body.getUnits().add(catchAllBeforeThrowNoop);
1995        soot.jimple.Stmt throwStmt = soot.jimple.Jimple.v().newThrowStmt(catchAllAssignLocal);
1996        throwStmt.addTag(new soot.tagkit.ThrowCreatedByCompilerTag());
1997        body.getUnits().add(throwStmt);
1998
1999        gotoMap.put(catchAllFinallyNoop, catchAllBeforeThrowNoop);
2000        
2001        // catch all goto end
2002
soot.jimple.Stmt catchAllGotoEnd = soot.jimple.Jimple.v().newGotoStmt(endNoop);
2003        body.getUnits().add(catchAllGotoEnd);
2004        
2005        addToExceptionList(beforeCatchAllAssignNoop, catchAllBeforeThrowNoop ,catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable"));
2006        
2007        // create finally's
2008
Iterator finallyIt = gotoMap.keySet().iterator();
2009        while (finallyIt.hasNext()) {
2010        
2011            soot.jimple.Stmt noopStmt = (soot.jimple.Stmt)finallyIt.next();
2012            body.getUnits().add(noopStmt);
2013
2014            createBlock(tryStmt.finallyBlock());
2015            soot.jimple.Stmt backToStmt = (soot.jimple.Stmt)gotoMap.get(noopStmt);
2016            soot.jimple.Stmt backToGoto = soot.jimple.Jimple.v().newGotoStmt(backToStmt);
2017            body.getUnits().add(backToGoto);
2018        }
2019        body.getUnits().add(endNoop);
2020    
2021        addToExceptionList(noop1, beforeEndGotoNoop, catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable"));
2022    }
2023
2024    /**
2025     * add exceptions to a list that gets added at end of method
2026     */

2027    private void addToExceptionList(soot.jimple.Stmt from, soot.jimple.Stmt to, soot.jimple.Stmt with, soot.SootClass exceptionClass) {
2028        if (exceptionTable == null) {
2029            exceptionTable = new ArrayList();
2030        }
2031        soot.Trap trap = soot.jimple.Jimple.v().newTrap(exceptionClass, from, to, with);
2032        exceptionTable.add(trap);
2033    }
2034    
2035    public soot.jimple.Constant createConstant(polyglot.ast.Expr expr){
2036        Object JavaDoc constantVal = expr.constantValue();
2037        //System.out.println("expr: "+expr);
2038

2039        return getConstant(constantVal, expr.type());
2040    }
2041    
2042    /**
2043     * Expression Creation
2044     */

2045    protected soot.Value createExpr(polyglot.ast.Expr expr){
2046        //System.out.println("create expr: "+expr+" type: "+expr.getClass());
2047
// maybe right here check if expr has constant val and return that
2048
// instead
2049
if (expr.isConstant() && expr.constantValue() != null && expr.type() != null && !(expr instanceof polyglot.ast.Binary && expr.type().toString().equals("java.lang.String")) ){
2050            return createConstant(expr);
2051        }
2052        if (expr instanceof polyglot.ast.Assign) {
2053            return getAssignLocal((polyglot.ast.Assign)expr);
2054        }
2055        else if (expr instanceof polyglot.ast.Lit) {
2056            return createLiteral((polyglot.ast.Lit)expr);
2057        }
2058        else if (expr instanceof polyglot.ast.Local) {
2059            return getLocal((polyglot.ast.Local)expr);
2060        }
2061        else if (expr instanceof polyglot.ast.Binary) {
2062            return getBinaryLocal((polyglot.ast.Binary)expr);
2063        }
2064        else if (expr instanceof polyglot.ast.Unary) {
2065            return getUnaryLocal((polyglot.ast.Unary)expr);
2066        }
2067        else if (expr instanceof polyglot.ast.Cast) {
2068            return getCastLocal((polyglot.ast.Cast)expr);
2069        }
2070        //else if (expr instanceof polyglot.ast.ArrayInit) {
2071
// array init are special and get created elsewhere
2072
//}
2073
else if (expr instanceof polyglot.ast.ArrayAccess) {
2074            return getArrayRefLocal((polyglot.ast.ArrayAccess)expr);
2075        }
2076        else if (expr instanceof polyglot.ast.NewArray) {
2077            return getNewArrayLocal((polyglot.ast.NewArray)expr);
2078        }
2079        else if (expr instanceof polyglot.ast.Call) {
2080            return getCallLocal((polyglot.ast.Call)expr);
2081        }
2082        else if (expr instanceof polyglot.ast.New) {
2083            return getNewLocal((polyglot.ast.New)expr);
2084        }
2085        else if (expr instanceof polyglot.ast.Special) {
2086            return getSpecialLocal((polyglot.ast.Special)expr);
2087        }
2088        else if (expr instanceof polyglot.ast.Instanceof) {
2089            return getInstanceOfLocal((polyglot.ast.Instanceof)expr);
2090        }
2091        else if (expr instanceof polyglot.ast.Conditional) {
2092            return getConditionalLocal((polyglot.ast.Conditional)expr);
2093        }
2094        else if (expr instanceof polyglot.ast.Field) {
2095            return getFieldLocal((polyglot.ast.Field)expr);
2096        }
2097        else {
2098            throw new RuntimeException JavaDoc("Unhandled Expression: "+expr);
2099        }
2100       
2101    }
2102
2103    protected soot.Local handlePrivateFieldUnarySet(polyglot.ast.Unary unary){
2104        polyglot.ast.Field fLeft = (polyglot.ast.Field)unary.expr();
2105        
2106        soot.Value base = base().getBaseLocal(fLeft.target());
2107        soot.Value fieldGetLocal = getPrivateAccessFieldLocal(fLeft, base);
2108
2109        soot.Local tmp = generateLocal(fLeft.type());
2110        soot.jimple.AssignStmt stmt1 = soot.jimple.Jimple.v().newAssignStmt(tmp, fieldGetLocal);
2111        body.getUnits().add(stmt1);
2112        Util.addLnPosTags(stmt1, unary.position());
2113        
2114        soot.Value incVal = base().getConstant(Util.getSootType(fLeft.type()), 1);
2115       
2116        soot.jimple.BinopExpr binExpr;
2117        if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.POST_INC){
2118            binExpr = soot.jimple.Jimple.v().newAddExpr(tmp, incVal);
2119        }
2120        else {
2121            binExpr = soot.jimple.Jimple.v().newSubExpr(tmp, incVal);
2122        }
2123       
2124        soot.Local tmp2 = generateLocal(fLeft.type());
2125        soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(tmp2, binExpr);
2126        body.getUnits().add(assign);
2127           
2128        if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.PRE_DEC){
2129            return base().handlePrivateFieldSet(fLeft, tmp2, base);
2130        }
2131        else {
2132            base().handlePrivateFieldSet(fLeft, tmp2, base);
2133            return tmp;
2134        }
2135    }
2136    
2137    protected soot.Local handlePrivateFieldAssignSet(polyglot.ast.Assign assign){
2138        polyglot.ast.Field fLeft = (polyglot.ast.Field)assign.left();
2139        //soot.Value right = createExpr(assign.right());
2140

2141        // if assign is not = but +=, -=, *=, /=, >>=, >>>-, <<=, %=,
2142
// |= &= or ^= then compute it all into a local first
2143
//if (assign.operator() != polyglot.ast.Assign.ASSIGN){
2144
// in this cas can cast to local (never a string const here
2145
// as it has to be a lhs
2146
soot.Value right;
2147        soot.Value fieldBase = base().getBaseLocal(fLeft.target());
2148        if (assign.operator() == polyglot.ast.Assign.ASSIGN){
2149            right = base().getSimpleAssignRightLocal(assign);
2150        }
2151        else if ((assign.operator() == polyglot.ast.Assign.ADD_ASSIGN) && assign.type().toString().equals("java.lang.String")){
2152            right = getStringConcatAssignRightLocal(assign);
2153        }
2154        else {
2155            // here the lhs is a private field and needs to use get call
2156
soot.Local leftLocal = getPrivateAccessFieldLocal(fLeft, fieldBase);
2157            //soot.Local leftLocal = (soot.Local)base().createExpr(fLeft);
2158
right = base().getAssignRightLocal(assign, leftLocal);
2159        }
2160       
2161        return handlePrivateFieldSet(fLeft, right, fieldBase);
2162    }
2163
2164    protected soot.Local handlePrivateFieldSet(polyglot.ast.Expr expr, soot.Value right, soot.Value base){
2165        // in normal j2j its always a field (and checked before call)
2166
// only has an expr for param for extensibility
2167
polyglot.ast.Field fLeft = (polyglot.ast.Field)expr;
2168        soot.SootClass containClass = ((soot.RefType)Util.getSootType(fLeft.target().type())).getSootClass();
2169        soot.SootMethod methToUse = addSetAccessMeth(containClass, fLeft, right);
2170        ArrayList params = new ArrayList();
2171        if (!fLeft.flags().isStatic()){
2172            // this is the this ref if needed
2173
//params.add(getThis(Util.getSootType(fLeft.target().type())));
2174
params.add(base);
2175        }
2176        params.add(right);
2177        soot.jimple.InvokeExpr invoke = soot.jimple.Jimple.v().newStaticInvokeExpr(methToUse.makeRef(), params);
2178        soot.Local retLocal = lg.generateLocal(right.getType());
2179        soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invoke);
2180        body.getUnits().add(assignStmt);
2181
2182        return retLocal;
2183    }
2184    
2185    private soot.SootMethod addSetAccessMeth(soot.SootClass conClass, polyglot.ast.Field field, soot.Value param){
2186        if ((InitialResolver.v().getPrivateFieldSetAccessMap() != null) && (InitialResolver.v().getPrivateFieldSetAccessMap().containsKey(new polyglot.util.IdentityKey(field.fieldInstance())))){
2187            return (soot.SootMethod)InitialResolver.v().getPrivateFieldSetAccessMap().get(new polyglot.util.IdentityKey(field.fieldInstance()));
2188        }
2189        String JavaDoc name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00";
2190        ArrayList paramTypes = new ArrayList();
2191        if (!field.flags().isStatic()){
2192            // add this param type
2193
paramTypes.add(conClass.getType());
2194            //paramTypes.add(Util.getSootType(field.target().type()));
2195
}
2196        soot.Type retType;
2197        paramTypes.add(Util.getSootType(field.type()));
2198        retType = Util.getSootType(field.type());
2199        /*if (param.getType() instanceof soot.NullType){
2200            paramTypes.add(soot.RefType.v("java.lang.Object"));
2201            retType = soot.RefType.v("java.lang.Object");
2202        }
2203        else {
2204            paramTypes.add(param.getType());
2205            retType = param.getType();
2206        }*/

2207        soot.SootMethod meth = new soot.SootMethod(name, paramTypes, retType, soot.Modifier.STATIC);
2208        PrivateFieldSetMethodSource pfsms = new PrivateFieldSetMethodSource(
2209        Util.getSootType(field.type()),
2210        field.name(),
2211        field.flags().isStatic()
2212        );
2213        
2214        
2215        conClass.addMethod(meth);
2216        meth.setActiveBody(pfsms.getBody(meth, null));
2217
2218        InitialResolver.v().addToPrivateFieldSetAccessMap(field, meth);
2219        meth.addTag(new soot.tagkit.SyntheticTag());
2220        return meth;
2221    }
2222
2223    private soot.SootMethod addGetFieldAccessMeth(soot.SootClass conClass, polyglot.ast.Field field){
2224        if ((InitialResolver.v().getPrivateFieldGetAccessMap() != null) && (InitialResolver.v().getPrivateFieldGetAccessMap().containsKey(new polyglot.util.IdentityKey(field.fieldInstance())))){
2225            return (soot.SootMethod)InitialResolver.v().getPrivateFieldGetAccessMap().get(new polyglot.util.IdentityKey(field.fieldInstance()));
2226        }
2227        String JavaDoc name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00";
2228        ArrayList paramTypes = new ArrayList();
2229        if (!field.flags().isStatic()){
2230            // add this param type
2231
paramTypes.add(conClass.getType());//(soot.Local)getBaseLocal(field.target()));
2232
//paramTypes.add(Util.getSootType(field.target().type()));
2233
}
2234        soot.SootMethod meth = new soot.SootMethod(name, paramTypes, Util.getSootType(field.type()), soot.Modifier.STATIC);
2235        PrivateFieldAccMethodSource pfams = new PrivateFieldAccMethodSource(
2236            Util.getSootType(field.type()),
2237            field.name(),
2238            field.flags().isStatic(),
2239            conClass
2240        );
2241        
2242        
2243        conClass.addMethod(meth);
2244        meth.setActiveBody(pfams.getBody(meth, null));
2245
2246        InitialResolver.v().addToPrivateFieldGetAccessMap(field, meth);
2247        meth.addTag(new soot.tagkit.SyntheticTag());
2248        return meth;
2249    }
2250
2251    private soot.SootMethod addGetMethodAccessMeth(soot.SootClass conClass, polyglot.ast.Call call){
2252        if ((InitialResolver.v().getPrivateMethodGetAccessMap() != null) && (InitialResolver.v().getPrivateMethodGetAccessMap().containsKey(new polyglot.util.IdentityKey(call.methodInstance())))){
2253            return (soot.SootMethod)InitialResolver.v().getPrivateMethodGetAccessMap().get(new polyglot.util.IdentityKey(call.methodInstance()));
2254        }
2255        String JavaDoc name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00";
2256        ArrayList paramTypes = new ArrayList();
2257        if (!call.methodInstance().flags().isStatic()){
2258            // add this param type
2259
//paramTypes.add(Util.getSootType(call.methodInstance().container()));
2260
paramTypes.add(conClass.getType());
2261        }
2262        ArrayList sootParamsTypes = getSootParamsTypes(call);
2263        paramTypes.addAll(sootParamsTypes);
2264        soot.SootMethod meth = new soot.SootMethod(name, paramTypes, Util.getSootType(call.methodInstance().returnType()), soot.Modifier.STATIC);
2265        PrivateMethodAccMethodSource pmams = new PrivateMethodAccMethodSource(
2266            call.methodInstance()
2267        );
2268        
2269        
2270        conClass.addMethod(meth);
2271        meth.setActiveBody(pmams.getBody(meth, null));
2272
2273        InitialResolver.v().addToPrivateMethodGetAccessMap(call, meth);
2274        meth.addTag(new soot.tagkit.SyntheticTag());
2275        return meth;
2276    }
2277
2278    
2279
2280    protected soot.Value getAssignRightLocal(polyglot.ast.Assign assign, soot.Local leftLocal){
2281    
2282        if (assign.operator() == polyglot.ast.Assign.ASSIGN){
2283            return base().getSimpleAssignRightLocal(assign);
2284        }
2285        else if (assign.operator() == polyglot.ast.Assign.ADD_ASSIGN && assign.type().toString().equals("java.lang.String")){
2286            return getStringConcatAssignRightLocal(assign);
2287        }
2288        else {
2289            return getComplexAssignRightLocal(assign, leftLocal);
2290        }
2291    }
2292
2293    protected soot.Value getSimpleAssignRightLocal(polyglot.ast.Assign assign){
2294        boolean repush = false;
2295        soot.jimple.Stmt tNoop = null;
2296        soot.jimple.Stmt fNoop = null;
2297        if (!trueNoop.empty() && !falseNoop.empty()){
2298            tNoop = (soot.jimple.Stmt)trueNoop.pop();
2299            fNoop = (soot.jimple.Stmt)falseNoop.pop();
2300            repush = true;
2301        }
2302        
2303        soot.Value right = base().createExpr(assign.right());
2304        
2305        if (repush){
2306            trueNoop.push(tNoop);
2307            falseNoop.push(fNoop);
2308        }
2309        
2310        if (right instanceof soot.jimple.ConditionExpr) {
2311            right = handleCondBinExpr((soot.jimple.ConditionExpr)right);
2312        }
2313        return right;
2314    }
2315
2316    private soot.Local getStringConcatAssignRightLocal(polyglot.ast.Assign assign){
2317        soot.Local sb = (soot.Local)createStringBuffer(assign);
2318        sb = generateAppends(assign.left(), sb);
2319        sb = generateAppends(assign.right(), sb);
2320        soot.Local rLocal = createToString(sb, assign);
2321        return rLocal;
2322    }
2323
2324    private soot.Local getComplexAssignRightLocal(polyglot.ast.Assign assign, soot.Local leftLocal){
2325        soot.Value right = base().createExpr(assign.right());
2326        if (right instanceof soot.jimple.ConditionExpr) {
2327            right = handleCondBinExpr((soot.jimple.ConditionExpr)right);
2328        }
2329        
2330        soot.jimple.BinopExpr binop = null;
2331        if (assign.operator() == polyglot.ast.Assign.ADD_ASSIGN) {
2332            binop = soot.jimple.Jimple.v().newAddExpr(leftLocal, right);
2333        }
2334        else if (assign.operator() == polyglot.ast.Assign.SUB_ASSIGN){
2335            binop = soot.jimple.Jimple.v().newSubExpr(leftLocal, right);
2336        }
2337        else if (assign.operator() == polyglot.ast.Assign.MUL_ASSIGN) {
2338            binop = soot.jimple.Jimple.v().newMulExpr(leftLocal, right);
2339        }
2340        else if (assign.operator() == polyglot.ast.Assign.DIV_ASSIGN) {
2341            binop = soot.jimple.Jimple.v().newDivExpr(leftLocal, right);
2342        }
2343        else if (assign.operator() == polyglot.ast.Assign.MOD_ASSIGN) {
2344            binop = soot.jimple.Jimple.v().newRemExpr(leftLocal, right);
2345        }
2346        else if (assign.operator() == polyglot.ast.Assign.SHL_ASSIGN) {
2347            binop = soot.jimple.Jimple.v().newShlExpr(leftLocal, right);
2348        }
2349        else if (assign.operator() == polyglot.ast.Assign.SHR_ASSIGN) {
2350            binop = soot.jimple.Jimple.v().newShrExpr(leftLocal, right);
2351        }
2352        else if (assign.operator() == polyglot.ast.Assign.USHR_ASSIGN) {
2353            binop = soot.jimple.Jimple.v().newUshrExpr(leftLocal, right);
2354        }
2355        else if (assign.operator() == polyglot.ast.Assign.BIT_AND_ASSIGN) {
2356            binop = soot.jimple.Jimple.v().newAndExpr(leftLocal, right);
2357        }
2358        else if (assign.operator() == polyglot.ast.Assign.BIT_OR_ASSIGN) {
2359            binop = soot.jimple.Jimple.v().newOrExpr(leftLocal, right);
2360        }
2361        else if (assign.operator() == polyglot.ast.Assign.BIT_XOR_ASSIGN) {
2362            binop = soot.jimple.Jimple.v().newXorExpr(leftLocal, right);
2363        }
2364
2365        soot.Local retLocal = lg.generateLocal(leftLocal.getType());
2366        soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, binop);
2367        body.getUnits().add(assignStmt);
2368            
2369        Util.addLnPosTags(binop.getOp1Box(), assign.left().position());
2370        Util.addLnPosTags(binop.getOp2Box(), assign.right().position());
2371        
2372        return retLocal;
2373    }
2374
2375    private soot.Value getSimpleAssignLocal(polyglot.ast.Assign assign){
2376        soot.jimple.AssignStmt stmt;
2377        soot.Value left = base().createLHS(assign.left());
2378        
2379        soot.Value right = base().getSimpleAssignRightLocal(assign);
2380        stmt = soot.jimple.Jimple.v().newAssignStmt(left, right);
2381        body.getUnits().add(stmt);
2382        Util.addLnPosTags(stmt, assign.position());
2383        Util.addLnPosTags(stmt.getRightOpBox(), assign.right().position());
2384        Util.addLnPosTags(stmt.getLeftOpBox(), assign.left().position());
2385        if (left instanceof soot.Local){
2386            return left;
2387        }
2388        else {
2389            return right;
2390        }
2391    
2392    }
2393    
2394    private soot.Value getStrConAssignLocal(polyglot.ast.Assign assign){
2395        soot.jimple.AssignStmt stmt;
2396        soot.Value left = base().createLHS(assign.left());
2397        
2398        soot.Value right = getStringConcatAssignRightLocal(assign);
2399        stmt = soot.jimple.Jimple.v().newAssignStmt(left, right);
2400        body.getUnits().add(stmt);
2401        Util.addLnPosTags(stmt, assign.position());
2402        Util.addLnPosTags(stmt.getRightOpBox(), assign.right().position());
2403        Util.addLnPosTags(stmt.getLeftOpBox(), assign.left().position());
2404        if (left instanceof soot.Local){
2405            return left;
2406        }
2407        else {
2408            return right;
2409        }
2410    
2411    }
2412    
2413    /**
2414     * Assign Expression Creation
2415     */

2416    protected soot.Value getAssignLocal(polyglot.ast.Assign assign) {
2417        
2418        // handle private access field assigns
2419
//HashMap accessMap = ((PolyglotMethodSource)body.getMethod().getSource()).getPrivateAccessMap();
2420
// if assigning to a field and the field is private and its not in
2421
// this class (then it had better be in some outer class and will
2422
// be handled as such)
2423
if (base().needsAccessor(assign.left())){
2424        //if ((assign.left() instanceof polyglot.ast.Field) && (needsPrivateAccessor((polyglot.ast.Field)assign.left()) || needsProtectedAccessor((polyglot.ast.Field)assign.left()))){
2425
//((polyglot.ast.Field)assign.left()).fieldInstance().flags().isPrivate() && !Util.getSootType(((polyglot.ast.Field)assign.left()).fieldInstance().container()).equals(body.getMethod().getDeclaringClass().getType())){
2426
return base().handlePrivateFieldAssignSet(assign);
2427        }
2428
2429        if (assign.operator() == polyglot.ast.Assign.ASSIGN){
2430            return getSimpleAssignLocal(assign);
2431        }
2432       
2433        if ((assign.operator() == polyglot.ast.Assign.ADD_ASSIGN) && assign.type().toString().equals("java.lang.String")){
2434            return getStrConAssignLocal(assign);
2435        }
2436        
2437        soot.jimple.AssignStmt stmt;
2438        soot.Value left = base().createLHS(assign.left());
2439        soot.Value left2 = (soot.Value)left.clone();
2440        
2441        soot.Local leftLocal;
2442        if (left instanceof soot.Local){
2443            leftLocal = (soot.Local)left;
2444            
2445        }
2446        else {
2447            leftLocal = lg.generateLocal(left.getType());
2448            soot.jimple.AssignStmt stmt1 = soot.jimple.Jimple.v().newAssignStmt(leftLocal, left);
2449            body.getUnits().add(stmt1);
2450            Util.addLnPosTags(stmt1, assign.position());
2451        }
2452        
2453        
2454        soot.Value right = base().getAssignRightLocal(assign, leftLocal);
2455        soot.jimple.AssignStmt stmt2 = soot.jimple.Jimple.v().newAssignStmt(leftLocal, right);
2456        body.getUnits().add(stmt2);
2457        Util.addLnPosTags(stmt2, assign.position());
2458        Util.addLnPosTags(stmt2.getRightOpBox(), assign.right().position());
2459        Util.addLnPosTags(stmt2.getLeftOpBox(), assign.left().position());
2460        
2461        if (!(left instanceof soot.Local)) {
2462            soot.jimple.AssignStmt stmt3 = soot.jimple.Jimple.v().newAssignStmt(left2, leftLocal);
2463            body.getUnits().add(stmt3);
2464            Util.addLnPosTags(stmt3, assign.position());
2465            Util.addLnPosTags(stmt3.getRightOpBox(), assign.right().position());
2466            Util.addLnPosTags(stmt3.getLeftOpBox(), assign.left().position());
2467        }
2468        
2469        return leftLocal;
2470        
2471    }
2472
2473    
2474    /**
2475     * Field Expression Creation - LHS
2476     */

2477    private soot.Value getFieldLocalLeft(polyglot.ast.Field field){
2478        polyglot.ast.Receiver receiver = field.target();
2479        if ((field.name().equals("length")) && (receiver.type() instanceof polyglot.types.ArrayType)){
2480            return getSpecialArrayLengthLocal(field);
2481        }
2482        else {
2483            return getFieldRef(field);
2484        }
2485    }
2486   
2487    /**
2488     * Field Expression Creation
2489     */

2490    private soot.Value getFieldLocal(polyglot.ast.Field field){
2491   
2492        
2493        polyglot.ast.Receiver receiver = field.target();
2494        soot.javaToJimple.PolyglotMethodSource ms = (soot.javaToJimple.PolyglotMethodSource)body.getMethod().getSource();
2495        
2496        if ((field.name().equals("length")) && (receiver.type() instanceof polyglot.types.ArrayType)){
2497            return getSpecialArrayLengthLocal(field);
2498        }
2499        else if (field.name().equals("class")){
2500            throw new RuntimeException JavaDoc("Should go through ClassLit");
2501        }
2502        else if (base().needsAccessor(field)){
2503        //else if (needsPrivateAccessor(field) || needsProtectedAccessor(field)){
2504
//((field.fieldInstance().flags().isPrivate() && !Util.getSootType(field.fieldInstance().container()).equals(body.getMethod().getDeclaringClass().getType())) ||()){
2505

2506            soot.Value base = base().getBaseLocal(field.target());
2507            return getPrivateAccessFieldLocal(field, base);
2508        }
2509        if ((field.target() instanceof polyglot.ast.Special) && (((polyglot.ast.Special)field.target()).kind() == polyglot.ast.Special.SUPER) && (((polyglot.ast.Special)field.target()).qualifier() != null)){
2510                return getSpecialSuperQualifierLocal(field);
2511        }
2512        else if (shouldReturnConstant(field)){
2513            
2514            return getReturnConstant(field);
2515            // in this case don't return fieldRef but a string constant
2516
}
2517        else {
2518
2519            soot.jimple.FieldRef fieldRef = getFieldRef(field);
2520            soot.Local baseLocal = generateLocal(field.type());
2521            soot.jimple.AssignStmt fieldAssignStmt = soot.jimple.Jimple.v().newAssignStmt(baseLocal, fieldRef);
2522            
2523            body.getUnits().add(fieldAssignStmt);
2524            Util.addLnPosTags(fieldAssignStmt, field.position());
2525            Util.addLnPosTags(fieldAssignStmt.getRightOpBox(), field.position());
2526            return baseLocal;
2527        }
2528    }
2529
2530    protected boolean needsAccessor(polyglot.ast.Expr expr){
2531        if (!(expr instanceof polyglot.ast.Field) && !(expr instanceof polyglot.ast.Call)) return false;
2532        else {
2533            if (expr instanceof polyglot.ast.Field){
2534                return needsAccessor(((polyglot.ast.Field)expr).fieldInstance());
2535            }
2536            else {
2537                return needsAccessor(((polyglot.ast.Call)expr).methodInstance());
2538            }
2539        }
2540    }
2541
2542    /**
2543     * needs accessors:
2544     * when field or meth is private and in some other class
2545     * when field or meth is protected and in
2546     */

2547    protected boolean needsAccessor(polyglot.types.MemberInstance inst){
2548        if (inst.flags().isPrivate()){
2549            if (!Util.getSootType(inst.container()).equals(body.getMethod().getDeclaringClass().getType())){
2550                return true;
2551            }
2552        }
2553        else if (inst.flags().isProtected()){
2554            if (Util.getSootType(inst.container()).equals(body.getMethod().getDeclaringClass().getType())){
2555                return false;
2556            }
2557            soot.SootClass currentClass = body.getMethod().getDeclaringClass();
2558            if (currentClass.getSuperclass().getType().equals(Util.getSootType(inst.container()))){
2559                return false;
2560            }
2561            while (currentClass.hasOuterClass()){
2562                currentClass = currentClass.getOuterClass();
2563                if (Util.getSootType(inst.container()).equals(currentClass.getType())){
2564                    return false;
2565                }
2566                else if (Util.getSootType(inst.container()).equals(currentClass.getSuperclass().getType())){
2567                    return true;
2568                }
2569            }
2570            return false;
2571        }
2572        
2573        return false;
2574    }
2575
2576    /**
2577     * needs a private access method if field is private and in
2578     * some other class
2579     */

2580    /*protected boolean needsPrivateAccessor(polyglot.ast.Field field){
2581        if (field.fieldInstance().flags().isPrivate()){
2582            if (!Util.getSootType(field.fieldInstance().container()).equals(body.getMethod().getDeclaringClass().getType())){
2583                return true;
2584            }
2585        }
2586        return false;
2587    }*/

2588
2589    /**
2590     * needs a protected access method if field is protected and in
2591     * a super class of the outer class of the innerclass trying to access
2592     * the field (ie not in self or in outer of self)
2593     */

2594    /*protected boolean needsProtectedAccessor(polyglot.ast.Field field){
2595        //return false;
2596        if (field.fieldInstance().flags().isProtected()){
2597            if (Util.getSootType(field.fieldInstance().container()).equals(body.getMethod().getDeclaringClass().getType())){
2598                return false;
2599            }
2600            soot.SootClass currentClass = body.getMethod().getDeclaringClass();
2601            while (currentClass.hasOuterClass()){
2602                currentClass = currentClass.getOuterClass();
2603                if (Util.getSootType(field.fieldInstance().container()).equals(currentClass.getType())){
2604                    return false;
2605                }
2606                else if (Util.getSootType(field.fieldInstance().container()).equals(currentClass.getSuperclass().getType())){
2607                    return true;
2608                }
2609            }
2610            return false;
2611        }
2612        return false;
2613        /*
2614        if (field.fieldInstance().flags().isProtected()){
2615            if (!Util.getSootType(field.fieldInstance().container()).equals(body.getMethod().getDeclaringClass().getType())){
2616                soot.SootClass checkClass = body.getMethod().getDeclaringClass();
2617                while (checkClass.hasOuterClass()){
2618                    checkClass = checkClass.getOuterClass();
2619                    if (Util.getSootType(field.fieldInstance().container()).equals(checkClass.getType())){
2620                        return false;
2621                    }
2622                
2623                }
2624                return true;
2625            }
2626        }
2627        return false;*/

2628    //}
2629

2630
2631    private soot.jimple.Constant getReturnConstant(polyglot.ast.Field field){
2632        return getConstant(field.constantValue(), field.type());
2633    }
2634    
2635    private soot.jimple.Constant getConstant(Object JavaDoc constVal, polyglot.types.Type type){
2636        //System.out.println("getConstant: "+constVal);
2637
if (constVal instanceof String JavaDoc){
2638            return soot.jimple.StringConstant.v((String JavaDoc)constVal);
2639        }
2640        else if (constVal instanceof Boolean JavaDoc){
2641            boolean val = ((Boolean JavaDoc)constVal).booleanValue();
2642            return soot.jimple.IntConstant.v(val ? 1 : 0);
2643        }
2644        else if (type.isChar()){
2645            char val;
2646          
2647            if (constVal instanceof Integer JavaDoc){
2648                val = (char)((Integer JavaDoc)constVal).intValue();
2649            }
2650            else {
2651                val = ((Character JavaDoc)constVal).charValue();
2652            }
2653            //System.out.println("val: "+val);
2654
return soot.jimple.IntConstant.v(val);
2655        }
2656        else {
2657            Number JavaDoc num = (Number JavaDoc)constVal;
2658            //System.out.println("num: "+num);
2659
num = createConstantCast(type, num);
2660            //System.out.println("num: "+num);
2661
if (num instanceof Long JavaDoc) {
2662                //System.out.println(((Long)num).longValue());
2663
return soot.jimple.LongConstant.v(((Long JavaDoc)num).longValue());
2664            }
2665            else if (num instanceof Double JavaDoc) {
2666                return soot.jimple.DoubleConstant.v(((Double JavaDoc)num).doubleValue());
2667            }
2668            else if (num instanceof Float JavaDoc) {
2669                return soot.jimple.FloatConstant.v(((Float JavaDoc)num).floatValue());
2670            }
2671            else if (num instanceof Byte JavaDoc) {
2672                return soot.jimple.IntConstant.v(((Byte JavaDoc)num).byteValue());
2673            }
2674            else if (num instanceof Short JavaDoc) {
2675                return soot.jimple.IntConstant.v(((Short JavaDoc)num).shortValue());
2676            }
2677            else {
2678                return soot.jimple.IntConstant.v(((Integer JavaDoc)num).intValue());
2679            }
2680        }
2681    }
2682   
2683    private Number JavaDoc createConstantCast(polyglot.types.Type fieldType, Number JavaDoc constant) {
2684        if (constant instanceof Integer JavaDoc){
2685            if (fieldType.isDouble()){
2686                return new Double JavaDoc((double)((Integer JavaDoc)constant).intValue());
2687            }
2688            else if (fieldType.isFloat()){
2689                return new Float JavaDoc((float)((Integer JavaDoc)constant).intValue());
2690            }
2691            else if (fieldType.isLong()){
2692                return new Long JavaDoc((long)((Integer JavaDoc)constant).intValue());
2693            }
2694        }
2695        return constant;
2696    }
2697    
2698    private boolean shouldReturnConstant(polyglot.ast.Field field){
2699        if (field.isConstant() && field.constantValue() != null) {
2700            return true;
2701        }
2702        return false;
2703    }
2704    
2705    /**
2706     * creates a field ref
2707     */

2708    protected soot.jimple.FieldRef getFieldRef(polyglot.ast.Field field) {
2709       
2710        soot.SootClass receiverClass = ((soot.RefType)Util.getSootType(field.target().type())).getSootClass();
2711        soot.SootFieldRef receiverField = soot.Scene.v().makeFieldRef(receiverClass, field.name(), Util.getSootType(field.type()), field.flags().isStatic());
2712         
2713        soot.jimple.FieldRef fieldRef;
2714        if (field.fieldInstance().flags().isStatic()) {
2715            fieldRef = soot.jimple.Jimple.v().newStaticFieldRef(receiverField);
2716        }
2717        else {
2718            soot.Local base;
2719                base = (soot.Local)base().getBaseLocal(field.target());
2720            fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(base, receiverField);
2721        }
2722            
2723        if (field.target() instanceof polyglot.ast.Local && fieldRef instanceof soot.jimple.InstanceFieldRef){
2724            Util.addLnPosTags(((soot.jimple.InstanceFieldRef)fieldRef).getBaseBox(), field.target().position());
2725        }
2726        return fieldRef;
2727    }
2728
2729    /**
2730     * For Inner Classes - to access private fields of their outer class
2731     */

2732    private soot.Local getPrivateAccessFieldLocal(polyglot.ast.Field field, soot.Value base) {
2733    
2734        // need to add access method
2735
// if private add to the containing class
2736
// but if its protected then add to outer class - not containing
2737
// class because in this case the containing class is the super class
2738

2739        soot.SootMethod toInvoke;
2740        soot.SootClass invokeClass;
2741        if (field.fieldInstance().flags().isPrivate()){
2742            toInvoke = addGetFieldAccessMeth(((soot.RefType)Util.getSootType(field.fieldInstance().container())).getSootClass(), field);
2743            invokeClass = ((soot.RefType)Util.getSootType(field.fieldInstance().container())).getSootClass();
2744        }
2745        else {
2746            if (InitialResolver.v().hierarchy() == null){
2747                InitialResolver.v().hierarchy(new soot.FastHierarchy());
2748            }
2749            soot.SootClass containingClass = ((soot.RefType)Util.getSootType(field.fieldInstance().container())).getSootClass();
2750            soot.SootClass addToClass;
2751            if (body.getMethod().getDeclaringClass().hasOuterClass()){
2752                addToClass = body.getMethod().getDeclaringClass().getOuterClass();
2753            
2754                while (!InitialResolver.v().hierarchy().canStoreType(containingClass.getType(), addToClass.getType())){
2755                    if (addToClass.hasOuterClass()){
2756                        addToClass = addToClass.getOuterClass();
2757                    }
2758                    else {
2759                        break;
2760                    }
2761                }
2762            }
2763            else{
2764                addToClass = containingClass;
2765            }
2766            invokeClass = addToClass;
2767            toInvoke = addGetFieldAccessMeth(addToClass, field);
2768        }
2769        
2770        ArrayList params = new ArrayList();
2771        if (!field.fieldInstance().flags().isStatic()) {
2772            params.add(base);
2773            /*if (field.target() instanceof polyglot.ast.Expr){
2774                params.add((soot.Local)base().getBaseLocal(field.target()));
2775            }
2776            else if (body.getMethod().getDeclaringClass().declaresFieldByName("this$0")){
2777                params.add(getThis(invokeClass.getType()));
2778            }
2779            else {
2780                soot.Local local = (soot.Local)base().getBaseLocal(field.target());
2781                params.add(local);
2782            }*/

2783            
2784            //(soot.Local)getBaseLocal(field.target()));
2785
/*if (Util.getSootType(field.target().type()).equals(invokeClass.getType())){
2786               */

2787            //params.add(getThis(invokeClass.getType()));//(soot.Local)getBaseLocal(field.target()));
2788
//}
2789
/*else {*/
2790                
2791            //soot.Local local = (soot.Local)getBaseLocal(field.target());
2792

2793            //params.add(getThis(invokeClass.getType()));//(soot.Local)getBaseLocal(field.target()));
2794
//soot.Local local = (soot.Local)getBaseLocal(field.target());
2795
//params.add(local);
2796
//}
2797
}
2798     
2799        return Util.getPrivateAccessFieldInvoke(toInvoke.makeRef(), params, body, lg);
2800    }
2801
2802
2803    /**
2804     * To get the local for the special .class literal
2805     */

2806    private soot.Local getSpecialClassLitLocal(polyglot.ast.ClassLit lit) {
2807      
2808        if (lit.typeNode().type().isPrimitive()){
2809            polyglot.types.PrimitiveType primType = (polyglot.types.PrimitiveType)lit.typeNode().type();
2810            soot.Local retLocal = lg.generateLocal(soot.RefType.v("java.lang.Class"));
2811            soot.SootFieldRef primField = null;
2812            if (primType.isBoolean()){
2813                primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Boolean"), "TYPE", soot.RefType.v("java.lang.Class"), true);
2814            }
2815            else if (primType.isByte()){
2816                primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Byte"), "TYPE", soot.RefType.v("java.lang.Class"), true);
2817            }
2818            else if (primType.isChar()){
2819                primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Character"), "TYPE", soot.RefType.v("java.lang.Class"), true);
2820            }
2821            else if (primType.isDouble()){
2822                primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Double"), "TYPE", soot.RefType.v("java.lang.Class"), true);
2823            }
2824            else if (primType.isFloat()){
2825                primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Float"), "TYPE", soot.RefType.v("java.lang.Class"), true);
2826            }
2827            else if (primType.isInt()){
2828                primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Integer"), "TYPE", soot.RefType.v("java.lang.Class"), true);
2829            }
2830            else if (primType.isLong()){
2831                primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Long"), "TYPE", soot.RefType.v("java.lang.Class"), true);
2832            }
2833            else if (primType.isShort()){
2834                primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Short"), "TYPE", soot.RefType.v("java.lang.Class"), true);
2835            }
2836            else if (primType.isVoid()){
2837                primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Void"), "TYPE", soot.RefType.v("java.lang.Class"), true);
2838            }
2839            soot.jimple.StaticFieldRef fieldRef = soot.jimple.Jimple.v().newStaticFieldRef(primField);
2840            soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, fieldRef);
2841            body.getUnits().add(assignStmt);
2842            return retLocal;
2843        }
2844        else {
2845            // this class
2846
soot.SootClass thisClass = body.getMethod().getDeclaringClass();
2847            String JavaDoc fieldName = Util.getFieldNameForClassLit(lit.typeNode().type());
2848            soot.Type fieldType = soot.RefType.v("java.lang.Class");
2849            soot.Local fieldLocal = lg.generateLocal(soot.RefType.v("java.lang.Class"));
2850            soot.SootFieldRef sootField = null;
2851            if (thisClass.isInterface()){
2852                HashMap specialAnonMap = InitialResolver.v().specialAnonMap();
2853                if ((specialAnonMap != null) && (specialAnonMap.containsKey(thisClass))){
2854                    soot.SootClass specialClass = (soot.SootClass)specialAnonMap.get(thisClass);
2855                    sootField = soot.Scene.v().makeFieldRef(specialClass, fieldName, fieldType, true);
2856                }
2857                else {
2858                    throw new RuntimeException JavaDoc("Class is interface so it must have an anon class to handle class lits but its anon class cannot be found.");
2859                }
2860            }
2861            else {
2862                sootField = soot.Scene.v().makeFieldRef(thisClass, fieldName, fieldType, true);
2863            }
2864            soot.jimple.StaticFieldRef fieldRef = soot.jimple.Jimple.v().newStaticFieldRef(sootField);
2865            soot.jimple.Stmt fieldAssign = soot.jimple.Jimple.v().newAssignStmt(fieldLocal, fieldRef);
2866            body.getUnits().add(fieldAssign);
2867
2868            soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
2869            soot.jimple.Expr neExpr = soot.jimple.Jimple.v().newNeExpr(fieldLocal, soot.jimple.NullConstant.v());
2870            soot.jimple.Stmt ifStmt = soot.jimple.Jimple.v().newIfStmt(neExpr, noop1);
2871            body.getUnits().add(ifStmt);
2872
2873            ArrayList paramTypes = new ArrayList();
2874            paramTypes.add(soot.RefType.v("java.lang.String"));
2875            soot.SootMethodRef invokeMeth = null;
2876            if (thisClass.isInterface()){
2877                HashMap specialAnonMap = InitialResolver.v().specialAnonMap();
2878                if ((specialAnonMap != null) && (specialAnonMap.containsKey(thisClass))){
2879                    soot.SootClass specialClass = (soot.SootClass)specialAnonMap.get(thisClass);
2880                    invokeMeth = soot.Scene.v().makeMethodRef(specialClass, "class$", paramTypes, soot.RefType.v("java.lang.Class"), true);
2881                }
2882                else {
2883                    throw new RuntimeException JavaDoc("Class is interface so it must have an anon class to handle class lits but its anon class cannot be found.");
2884                }
2885            }
2886            else {
2887                invokeMeth = soot.Scene.v().makeMethodRef(thisClass, "class$", paramTypes, soot.RefType.v("java.lang.Class"), true);
2888            }
2889            ArrayList params = new ArrayList();
2890            params.add(soot.jimple.StringConstant.v(Util.getParamNameForClassLit(lit.typeNode().type())));
2891            soot.jimple.Expr classInvoke = soot.jimple.Jimple.v().newStaticInvokeExpr(invokeMeth, params);
2892            soot.Local methLocal = lg.generateLocal(soot.RefType.v("java.lang.Class"));
2893            soot.jimple.Stmt invokeAssign = soot.jimple.Jimple.v().newAssignStmt(methLocal, classInvoke);
2894            body.getUnits().add(invokeAssign);
2895
2896            soot.jimple.Stmt assignField = soot.jimple.Jimple.v().newAssignStmt(fieldRef, methLocal);
2897            body.getUnits().add(assignField);
2898
2899            soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
2900            soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2);
2901            body.getUnits().add(goto1);
2902        
2903            body.getUnits().add(noop1);
2904            fieldAssign = soot.jimple.Jimple.v().newAssignStmt(methLocal, fieldRef);
2905            body.getUnits().add(fieldAssign);
2906            body.getUnits().add(noop2);
2907
2908            return methLocal;
2909        }
2910    }
2911
2912    /**
2913     * Array Length local for example a.length w/o brackets gets length
2914     * of array
2915     */

2916    private soot.Local getSpecialArrayLengthLocal(polyglot.ast.Field field) {
2917            
2918        soot.Local localField;
2919        polyglot.ast.Receiver receiver = field.target();
2920        if (receiver instanceof polyglot.ast.Local) {
2921            localField = getLocal((polyglot.ast.Local)receiver);
2922        }
2923        else if (receiver instanceof polyglot.ast.Expr){
2924            localField = (soot.Local)base().createExpr((polyglot.ast.Expr)receiver);
2925        }
2926        else {
2927            localField = generateLocal(receiver.type());
2928        }
2929        soot.jimple.LengthExpr lengthExpr = soot.jimple.Jimple.v().newLengthExpr(localField);
2930        soot.Local retLocal = lg.generateLocal(soot.IntType.v());
2931        soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(retLocal, lengthExpr);
2932        body.getUnits().add(assign);
2933        Util.addLnPosTags(assign, field.position());
2934        Util.addLnPosTags(lengthExpr.getOpBox(), field.target().position());
2935        return retLocal;
2936    }
2937   
2938    /**
2939     * Binary Expression Creation
2940     */

2941    private soot.Value getBinaryLocal(polyglot.ast.Binary binary) {
2942        //System.out.println("binary: "+binary+" class: "+binary.getClass());
2943

2944        soot.Value rhs;
2945                
2946        if (binary.operator() == polyglot.ast.Binary.COND_AND) {
2947            return createCondAnd(binary);
2948        }
2949        if (binary.operator() == polyglot.ast.Binary.COND_OR) {
2950            return createCondOr(binary);
2951        }
2952
2953        if (binary.type().toString().equals("java.lang.String")){
2954            //System.out.println("binary: "+binary);
2955
if (areAllStringLits(binary)){
2956                String JavaDoc result = createStringConstant(binary);
2957                //System.out.println("created string constant: "+result);
2958
return soot.jimple.StringConstant.v(result);
2959            }
2960            else {
2961                soot.Local sb = (soot.Local)createStringBuffer(binary);
2962                sb = generateAppends(binary.left(), sb);
2963                sb = generateAppends(binary.right(), sb);
2964                return createToString(sb, binary);
2965            }
2966        }
2967        
2968        soot.Value lVal = base().createExpr(binary.left());
2969        soot.Value rVal = base().createExpr(binary.right());
2970
2971        if (isComparisonBinary(binary.operator())) {
2972            rhs = getBinaryComparisonExpr(lVal, rVal, binary.operator());
2973        }
2974        else {
2975            rhs = getBinaryExpr(lVal, rVal, binary.operator());
2976        }
2977        
2978        if (rhs instanceof soot.jimple.BinopExpr) {
2979            Util.addLnPosTags(((soot.jimple.BinopExpr)rhs).getOp1Box(), binary.left().position());
2980            Util.addLnPosTags(((soot.jimple.BinopExpr)rhs).getOp2Box(), binary.right().position());
2981        }
2982        
2983        if (rhs instanceof soot.jimple.ConditionExpr) {
2984            return rhs;
2985        }
2986        
2987        soot.Local lhs = generateLocal(binary.type());
2988
2989
2990        soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(lhs, rhs);
2991        body.getUnits().add(assignStmt);
2992        //System.out.println("binary pos: "+binary.position());
2993

2994     
2995        Util.addLnPosTags(assignStmt.getRightOpBox(), binary.position());
2996        Util.addLnPosTags(assignStmt, binary.position());
2997        return lhs;
2998    }
2999
3000    private boolean areAllStringLits(polyglot.ast.Node node){
3001       
3002       // System.out.println("node in is string lit: "+node+" kind: "+node.getClass());
3003
if (node instanceof polyglot.ast.StringLit) return true;
3004        else if ( node instanceof polyglot.ast.Field) {
3005            if (shouldReturnConstant((polyglot.ast.Field)node)) return true;
3006            else return false;
3007        }
3008        else if (node instanceof polyglot.ast.Binary){
3009            if (areAllStringLitsBinary((polyglot.ast.Binary)node)) return true;
3010            return false;
3011        }
3012        else if (node instanceof polyglot.ast.Unary){
3013            polyglot.ast.Unary unary = (polyglot.ast.Unary)node;
3014            if (unary.isConstant()){
3015                return true;
3016            }
3017            return false;
3018        }
3019        else if (node instanceof polyglot.ast.Cast){
3020            polyglot.ast.Cast cast = (polyglot.ast.Cast)node;
3021            if (cast.isConstant()){
3022                return true;
3023            }
3024            return false;
3025        }
3026        else if (node instanceof polyglot.ast.Lit){
3027            polyglot.ast.Lit lit = (polyglot.ast.Lit)node;
3028            //System.out.println("lit: "+lit+" is constant: "+(lit.isConstant()?true:false));
3029
if (lit.isConstant()){
3030                return true;
3031            }
3032            return false;
3033        }
3034        return false;
3035    }
3036   
3037    private boolean areAllStringLitsBinary(polyglot.ast.Binary binary){
3038        if (areAllStringLits(binary.left()) && areAllStringLits(binary.right())) return true;
3039        else return false;
3040    }
3041
3042    private String JavaDoc createStringConstant(polyglot.ast.Node node){
3043        //System.out.println("creatinf string constant: "+createConstant((polyglot.ast.Expr)node));
3044
String JavaDoc s = null;
3045        if (node instanceof polyglot.ast.StringLit){
3046            s = ((polyglot.ast.StringLit)node).value();
3047        }
3048        else if (node instanceof polyglot.ast.Cast){
3049            polyglot.ast.Cast cast = (polyglot.ast.Cast)node;
3050            if (cast.type().isChar()){
3051                s = "" + (char)((Character JavaDoc)cast.constantValue()).charValue();
3052            }
3053            else {
3054                s = "" + cast.constantValue();
3055            }
3056        }
3057        else if (node instanceof polyglot.ast.Unary){
3058            polyglot.ast.Unary unary = (polyglot.ast.Unary)node;
3059            s = "" + unary.constantValue();
3060        }
3061        else if (node instanceof polyglot.ast.CharLit){
3062            s = "" + ((polyglot.ast.CharLit)node).value();
3063        }
3064        else if (node instanceof polyglot.ast.BooleanLit){
3065            s = "" + ((polyglot.ast.BooleanLit)node).value();
3066        }
3067        else if (node instanceof polyglot.ast.IntLit){
3068            s = "" + ((polyglot.ast.IntLit)node).value();
3069        }
3070        else if (node instanceof polyglot.ast.FloatLit){
3071            s = "" + ((polyglot.ast.FloatLit)node).value();
3072        }
3073        else if (node instanceof polyglot.ast.NullLit){
3074            s = "null";
3075        }
3076        else if (node instanceof polyglot.ast.Field){
3077            polyglot.ast.Field field = (polyglot.ast.Field)node;
3078            if (field.fieldInstance().constantValue() instanceof String JavaDoc){
3079                s = (String JavaDoc)field.constantValue();
3080            }
3081            else if (field.fieldInstance().constantValue() instanceof Boolean JavaDoc){
3082                boolean val = ((Boolean JavaDoc)field.constantValue()).booleanValue();
3083                int temp = val ? 1 : 0;
3084                s = "" + temp;
3085            }
3086            else if (field.type().isChar()){
3087            
3088                char val = (char)((Integer JavaDoc)field.constantValue()).intValue();
3089                s = "" + val;
3090            }
3091            else {
3092                Number JavaDoc num = (Number JavaDoc)field.fieldInstance().constantValue();
3093                num = createConstantCast(field.type(), num);
3094                if (num instanceof Long JavaDoc) {
3095                    s = "" + ((Long JavaDoc)num).longValue();
3096                }
3097                else if (num instanceof Double JavaDoc) {
3098                    s = "" + ((Double JavaDoc)num).doubleValue();
3099                }
3100                else if (num instanceof Float JavaDoc) {
3101                    s = "" + ((Float JavaDoc)num).floatValue();
3102                }
3103                else if (num instanceof Byte JavaDoc) {
3104                    s = "" + ((Byte JavaDoc)num).byteValue();
3105                }
3106                else if (num instanceof Short JavaDoc) {
3107                    s = "" + ((Short JavaDoc)num).shortValue();
3108                }
3109                else {
3110                    s = "" + ((Integer JavaDoc)num).intValue();
3111                }
3112            }
3113            
3114        }
3115        else if (node instanceof polyglot.ast.Binary){
3116            s = createStringConstantBinary((polyglot.ast.Binary)node);
3117        }
3118        else {
3119            throw new RuntimeException JavaDoc("No other string constant folding done");
3120        }
3121        return s;
3122    }
3123    
3124    private String JavaDoc createStringConstantBinary(polyglot.ast.Binary binary){
3125        //System.out.println("create string binary: type"+binary.type());
3126
String JavaDoc s = null;
3127        if (Util.getSootType(binary.type()).toString().equals("java.lang.String")){
3128            // here if type is a string return string constant
3129
s = createStringConstant(binary.left()) + createStringConstant(binary.right());
3130        }
3131        else {
3132            // else eval and return string of the eval result
3133
s = binary.constantValue().toString();
3134        }
3135        return s;
3136        
3137    }
3138    
3139    private boolean isComparisonBinary(polyglot.ast.Binary.Operator op) {
3140        if ((op == polyglot.ast.Binary.EQ) || (op == polyglot.ast.Binary.NE) ||
3141           (op == polyglot.ast.Binary.GE) || (op == polyglot.ast.Binary.GT) ||
3142           (op == polyglot.ast.Binary.LE) || (op == polyglot.ast.Binary.LT)) {
3143            
3144            return true;
3145        }
3146        else {
3147            return false;
3148        }
3149
3150        
3151    }
3152    
3153    /**
3154     * Creates a binary expression that is not a comparison
3155     */

3156    private soot.Value getBinaryExpr(soot.Value lVal, soot.Value rVal, polyglot.ast.Binary.Operator operator){
3157        
3158        soot.Value rValue = null;
3159
3160        if (lVal instanceof soot.jimple.ConditionExpr) {
3161            lVal = handleCondBinExpr((soot.jimple.ConditionExpr)lVal);
3162        }
3163        if (rVal instanceof soot.jimple.ConditionExpr) {
3164            rVal = handleCondBinExpr((soot.jimple.ConditionExpr)rVal);
3165        }
3166        if (operator == polyglot.ast.Binary.ADD){
3167           
3168                rValue = soot.jimple.Jimple.v().newAddExpr(lVal, rVal);
3169        }
3170        else if (operator == polyglot.ast.Binary.SUB){
3171            rValue = soot.jimple.Jimple.v().newSubExpr(lVal, rVal);
3172        }
3173        else if (operator == polyglot.ast.Binary.MUL){
3174            rValue = soot.jimple.Jimple.v().newMulExpr(lVal, rVal);
3175        }
3176        else if (operator == polyglot.ast.Binary.DIV){
3177            rValue = soot.jimple.Jimple.v().newDivExpr(lVal, rVal);
3178        }
3179        else if (operator == polyglot.ast.Binary.SHR){
3180            if (rVal.getType().equals(soot.LongType.v())){
3181                soot.Local intVal = lg.generateLocal(soot.IntType.v());
3182                soot.jimple.CastExpr castExpr = soot.jimple.Jimple.v().newCastExpr(rVal, soot.IntType.v());
3183                soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(intVal, castExpr);
3184                body.getUnits().add(assignStmt);
3185                rValue = soot.jimple.Jimple.v().newShrExpr(lVal, intVal);
3186            }
3187            else {
3188                rValue = soot.jimple.Jimple.v().newShrExpr(lVal, rVal);
3189            }
3190        }
3191        else if (operator == polyglot.ast.Binary.USHR){
3192            if (rVal.getType().equals(soot.LongType.v())){
3193                soot.Local intVal = lg.generateLocal(soot.IntType.v());
3194                soot.jimple.CastExpr castExpr = soot.jimple.Jimple.v().newCastExpr(rVal, soot.IntType.v());
3195                soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(intVal, castExpr);
3196                body.getUnits().add(assignStmt);
3197                rValue = soot.jimple.Jimple.v().newUshrExpr(lVal, intVal);
3198            }
3199            else {
3200                rValue = soot.jimple.Jimple.v().newUshrExpr(lVal, rVal);
3201            }
3202        }
3203        else if (operator == polyglot.ast.Binary.SHL){
3204            if (rVal.getType().equals(soot.LongType.v())){
3205                soot.Local intVal = lg.generateLocal(soot.IntType.v());
3206                soot.jimple.CastExpr castExpr = soot.jimple.Jimple.v().newCastExpr(rVal, soot.IntType.v());
3207                soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(intVal, castExpr);
3208                body.getUnits().add(assignStmt);
3209                rValue = soot.jimple.Jimple.v().newShlExpr(lVal, intVal);
3210            }
3211            else {
3212                rValue = soot.jimple.Jimple.v().newShlExpr(lVal, rVal);
3213            }
3214        }
3215        else if (operator == polyglot.ast.Binary.BIT_AND){
3216            rValue = soot.jimple.Jimple.v().newAndExpr(lVal, rVal);
3217        }
3218        else if (operator == polyglot.ast.Binary.BIT_OR){
3219            rValue = soot.jimple.Jimple.v().newOrExpr(lVal, rVal);
3220        }
3221        else if (operator == polyglot.ast.Binary.BIT_XOR){
3222            rValue = soot.jimple.Jimple.v().newXorExpr(lVal, rVal);
3223        }
3224        else if (operator == polyglot.ast.Binary.MOD){
3225            rValue = soot.jimple.Jimple.v().newRemExpr(lVal, rVal);
3226        }
3227        else {
3228            throw new RuntimeException JavaDoc("Binary not yet handled!");
3229        }
3230
3231        return rValue;
3232    }
3233 
3234    /**
3235     * Creates a binary expr that is a comparison
3236     */

3237    private soot.Value getBinaryComparisonExpr(soot.Value lVal, soot.Value rVal, polyglot.ast.Binary.Operator operator) {
3238        
3239        soot.Value rValue;
3240        
3241            if (operator == polyglot.ast.Binary.EQ){
3242                rValue = soot.jimple.Jimple.v().newEqExpr(lVal, rVal);
3243            }
3244            else if (operator == polyglot.ast.Binary.GE){
3245                rValue = soot.jimple.Jimple.v().newGeExpr(lVal, rVal);
3246            }
3247            else if (operator == polyglot.ast.Binary.GT){
3248                rValue = soot.jimple.Jimple.v().newGtExpr(lVal, rVal);
3249            }
3250            else if (operator == polyglot.ast.Binary.LE){
3251                rValue = soot.jimple.Jimple.v().newLeExpr(lVal, rVal);
3252            }
3253            else if (operator == polyglot.ast.Binary.LT){
3254                rValue = soot.jimple.Jimple.v().newLtExpr(lVal, rVal);
3255            }
3256            else if (operator == polyglot.ast.Binary.NE){
3257                rValue = soot.jimple.Jimple.v().newNeExpr(lVal, rVal);
3258            }
3259            else {
3260                throw new RuntimeException JavaDoc("Unknown Comparison Expr");
3261            }
3262       
3263            return rValue;
3264    }
3265
3266    /**
3267     * in bytecode and Jimple the conditions in conditional binary
3268     * expressions are often reversed
3269     */

3270    private soot.Value reverseCondition(soot.jimple.ConditionExpr cond) {
3271    
3272        soot.jimple.ConditionExpr newExpr;
3273        if (cond instanceof soot.jimple.EqExpr) {
3274            newExpr = soot.jimple.Jimple.v().newNeExpr(cond.getOp1(), cond.getOp2());
3275        }
3276        else if (cond instanceof soot.jimple.NeExpr) {
3277            newExpr = soot.jimple.Jimple.v().newEqExpr(cond.getOp1(), cond.getOp2());
3278        }
3279        else if (cond instanceof soot.jimple.GtExpr) {
3280            newExpr = soot.jimple.Jimple.v().newLeExpr(cond.getOp1(), cond.getOp2());
3281        }
3282        else if (cond instanceof soot.jimple.GeExpr) {
3283            newExpr = soot.jimple.Jimple.v().newLtExpr(cond.getOp1(), cond.getOp2());
3284        }
3285        else if (cond instanceof soot.jimple.LtExpr) {
3286            newExpr = soot.jimple.Jimple.v().newGeExpr(cond.getOp1(), cond.getOp2());
3287        }
3288        else if (cond instanceof soot.jimple.LeExpr) {
3289            newExpr = soot.jimple.Jimple.v().newGtExpr(cond.getOp1(), cond.getOp2());
3290        }
3291        else {
3292            throw new RuntimeException JavaDoc("Unknown Condition Expr");
3293        }
3294
3295
3296        newExpr.getOp1Box().addAllTagsOf(cond.getOp1Box());
3297        newExpr.getOp2Box().addAllTagsOf(cond.getOp2Box());
3298        return newExpr;
3299    }
3300   
3301    
3302    /**
3303     * Special conditions for doubles and floats and longs
3304     */

3305    private soot.Value handleDFLCond(soot.jimple.ConditionExpr cond){
3306        soot.Local result = lg.generateLocal(soot.ByteType.v());
3307        soot.jimple.Expr cmExpr = null;
3308        if (isDouble(cond.getOp1()) || isDouble(cond.getOp2()) || isFloat(cond.getOp1()) || isFloat(cond.getOp2())) {
3309            // use cmpg and cmpl
3310
if ((cond instanceof soot.jimple.GeExpr) || (cond instanceof soot.jimple.GtExpr)) {
3311                // use cmpg
3312
cmExpr = soot.jimple.Jimple.v().newCmpgExpr(cond.getOp1(), cond.getOp2());
3313            }
3314            else {
3315                // use cmpl
3316
cmExpr = soot.jimple.Jimple.v().newCmplExpr(cond.getOp1(), cond.getOp2());
3317            }
3318        }
3319        else if (isLong(cond.getOp1()) || isLong(cond.getOp2())) {
3320            // use cmp
3321
cmExpr = soot.jimple.Jimple.v().newCmpExpr(cond.getOp1(), cond.getOp2());
3322        }
3323        else {
3324            return cond;
3325        }
3326        soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(result, cmExpr);
3327        body.getUnits().add(assign);
3328
3329        if (cond instanceof soot.jimple.EqExpr){
3330            cond = soot.jimple.Jimple.v().newEqExpr(result, soot.jimple.IntConstant.v(0));
3331        }
3332        else if (cond instanceof soot.jimple.GeExpr){
3333            cond = soot.jimple.Jimple.v().newGeExpr(result, soot.jimple.IntConstant.v(0));
3334        }
3335        else if (cond instanceof soot.jimple.GtExpr){
3336            cond = soot.jimple.Jimple.v().newGtExpr(result, soot.jimple.IntConstant.v(0));
3337        }
3338        else if (cond instanceof soot.jimple.LeExpr){
3339            cond = soot.jimple.Jimple.v().newLeExpr(result, soot.jimple.IntConstant.v(0));
3340        }
3341        else if (cond instanceof soot.jimple.LtExpr){
3342            cond = soot.jimple.Jimple.v().newLtExpr(result, soot.jimple.IntConstant.v(0));
3343        }
3344        else if (cond instanceof soot.jimple.NeExpr){
3345            cond = soot.jimple.Jimple.v().newNeExpr(result, soot.jimple.IntConstant.v(0));
3346        }
3347        else {
3348            throw new RuntimeException JavaDoc("Unknown Comparison Expr");
3349        }
3350    
3351        return cond;
3352    }
3353
3354    private boolean isDouble(soot.Value val) {
3355        if (val.getType() instanceof soot.DoubleType) return true;
3356        return false;
3357    }
3358    
3359    private boolean isFloat(soot.Value val) {
3360        if (val.getType() instanceof soot.FloatType) return true;
3361        return false;
3362    }
3363    
3364    private boolean isLong(soot.Value val) {
3365        if (val.getType() instanceof soot.LongType) return true;
3366        return false;
3367    }
3368    
3369    /**
3370     * Creates a conitional AND expr
3371     */

3372    private soot.Value createCondAnd(polyglot.ast.Binary binary) {
3373            
3374        soot.Local retLocal = lg.generateLocal(soot.BooleanType.v());
3375            
3376        soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
3377        
3378        soot.Value lVal = base().createExpr(binary.left());
3379        boolean leftNeedIf = needSootIf(lVal);
3380        if (!(lVal instanceof soot.jimple.ConditionExpr)) {
3381            lVal = soot.jimple.Jimple.v().newEqExpr(lVal, soot.jimple.IntConstant.v(0));
3382        }
3383        else {
3384            lVal = reverseCondition((soot.jimple.ConditionExpr)lVal);
3385            lVal = handleDFLCond((soot.jimple.ConditionExpr)lVal);
3386        }
3387            
3388        if (leftNeedIf){
3389            soot.jimple.IfStmt ifLeft;
3390            /*if (!falseNoop.empty()){
3391                soot.jimple.Stmt fNoop = (soot.jimple.Stmt)falseNoop.peek();
3392                ifLeft = soot.jimple.Jimple.v().newIfStmt(lVal, fNoop);
3393            }
3394            else {*/

3395                ifLeft = soot.jimple.Jimple.v().newIfStmt(lVal, noop1);
3396            //}
3397
body.getUnits().add(ifLeft);
3398            Util.addLnPosTags(ifLeft.getConditionBox(), binary.left().position());
3399            Util.addLnPosTags(ifLeft, binary.left().position());
3400        }
3401        
3402        soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt();
3403        soot.Value rVal = base().createExpr(binary.right());
3404        boolean rightNeedIf = needSootIf(rVal);
3405        if (!(rVal instanceof soot.jimple.ConditionExpr)) {
3406            rVal = soot.jimple.Jimple.v().newEqExpr(rVal, soot.jimple.IntConstant.v(0));
3407        }
3408        else {
3409            rVal = reverseCondition((soot.jimple.ConditionExpr)rVal);
3410            rVal = handleDFLCond((soot.jimple.ConditionExpr)rVal);
3411        }
3412        if (rightNeedIf){
3413            soot.jimple.IfStmt ifRight;
3414            /*if (!falseNoop.empty()){
3415                soot.jimple.Stmt fNoop = (soot.jimple.Stmt)falseNoop.peek();
3416                ifRight = soot.jimple.Jimple.v().newIfStmt(rVal, fNoop);
3417            }
3418            else {*/

3419                ifRight = soot.jimple.Jimple.v().newIfStmt(rVal, noop1);
3420            //}
3421
body.getUnits().add(ifRight);
3422            Util.addLnPosTags(ifRight.getConditionBox(), binary.right().position());
3423            Util.addLnPosTags(ifRight, binary.right().position());
3424        }
3425
3426        // return if cond will be used in if
3427
/*if (!falseNoop.empty()){
3428            return soot.jimple.IntConstant.v(1);
3429        }*/

3430        
3431        soot.jimple.Stmt assign1 = soot.jimple.Jimple.v().newAssignStmt(retLocal, soot.jimple.IntConstant.v(1));
3432        body.getUnits().add(assign1);
3433        soot.jimple.Stmt gotoEnd1 = soot.jimple.Jimple.v().newGotoStmt(endNoop);
3434        body.getUnits().add(gotoEnd1);
3435        
3436        body.getUnits().add(noop1);
3437
3438        soot.jimple.Stmt assign2 = soot.jimple.Jimple.v().newAssignStmt(retLocal, soot.jimple.IntConstant.v(0));
3439        body.getUnits().add(assign2);
3440
3441        body.getUnits().add(endNoop);
3442        
3443        Util.addLnPosTags(assign1, binary.position());
3444        Util.addLnPosTags(assign2, binary.position());
3445        
3446        return retLocal;
3447    }
3448
3449    int inLeftOr = 0;
3450
3451    /**
3452     * Creates a conditional OR expr
3453     */

3454    private soot.Value createCondOr(polyglot.ast.Binary binary) {
3455        //System.out.println("cond or binary: "+binary);
3456
soot.Local retLocal = lg.generateLocal(soot.BooleanType.v());
3457            
3458        //end
3459
soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt();
3460         
3461        soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
3462        soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
3463        //inLeftOr++;
3464
soot.Value lVal = base().createExpr(binary.left());
3465        //inLeftOr--;
3466

3467        //System.out.println("leftval : "+lVal);
3468
boolean leftNeedIf = needSootIf(lVal);
3469        if (!(lVal instanceof soot.jimple.ConditionExpr)) {
3470            lVal = soot.jimple.Jimple.v().newNeExpr(lVal, soot.jimple.IntConstant.v(0));
3471        }
3472        else {
3473            // no reversing of condition needed for first expr in conditional
3474
// or expression
3475
lVal = handleDFLCond((soot.jimple.ConditionExpr)lVal);
3476        }
3477        
3478        if (leftNeedIf){
3479            soot.jimple.IfStmt ifLeft;
3480            /*if (!trueNoop.empty()){
3481                ifLeft = soot.jimple.Jimple.v().newIfStmt(lVal, (soot.jimple.Stmt)trueNoop.peek());
3482            }
3483            else {*/

3484                ifLeft = soot.jimple.Jimple.v().newIfStmt(lVal, noop1);
3485            //}
3486
body.getUnits().add(ifLeft);
3487            Util.addLnPosTags(ifLeft, binary.left().position());
3488            Util.addLnPosTags(ifLeft.getConditionBox(), binary.left().position());
3489        }
3490        
3491        soot.Value rVal = base().createExpr(binary.right());
3492        boolean rightNeedIf = needSootIf(rVal);
3493        if (!(rVal instanceof soot.jimple.ConditionExpr)) {
3494            rVal = soot.jimple.Jimple.v().newEqExpr(rVal, soot.jimple.IntConstant.v(0));
3495        }
3496        else {
3497            // need to reverse right part of conditional or expr
3498
if (/*!trueNoop.empty() &&*/ inLeftOr == 0){
3499                rVal = reverseCondition((soot.jimple.ConditionExpr)rVal);
3500            }
3501            rVal = handleDFLCond((soot.jimple.ConditionExpr)rVal);
3502        }
3503        if (rightNeedIf){
3504            
3505            soot.jimple.IfStmt ifRight;
3506            /*if (!trueNoop.empty()){
3507                if (inLeftOr == 0){
3508                    ifRight = soot.jimple.Jimple.v().newIfStmt(rVal, (soot.jimple.Stmt)falseNoop.peek());
3509                }
3510                else {
3511                    ifRight = soot.jimple.Jimple.v().newIfStmt(rVal, (soot.jimple.Stmt)trueNoop.peek());
3512                }
3513            }
3514            else {*/

3515                ifRight = soot.jimple.Jimple.v().newIfStmt(rVal, noop2);
3516            //}
3517
body.getUnits().add(ifRight);
3518            Util.addLnPosTags(ifRight, binary.right().position());
3519            Util.addLnPosTags(ifRight.getConditionBox(), binary.right().position());
3520        }
3521        
3522        // return if cond will be used in if
3523
/*if (!trueNoop.empty()){
3524            return soot.jimple.IntConstant.v(1);
3525        }*/

3526        
3527        body.getUnits().add(noop1);
3528        
3529        soot.jimple.Stmt assign2 = soot.jimple.Jimple.v().newAssignStmt(retLocal, soot.jimple.IntConstant.v(1));
3530        body.getUnits().add(assign2);
3531        Util.addLnPosTags(assign2, binary.position());
3532        soot.jimple.Stmt gotoEnd2 = soot.jimple.Jimple.v().newGotoStmt(endNoop);
3533        body.getUnits().add(gotoEnd2);
3534           
3535        body.getUnits().add(noop2);
3536
3537        soot.jimple.Stmt assign3 = soot.jimple.Jimple.v().newAssignStmt(retLocal, soot.jimple.IntConstant.v(0));
3538        body.getUnits().add(assign3);
3539        Util.addLnPosTags(assign3, binary.position());
3540
3541        body.getUnits().add(endNoop);
3542        Util.addLnPosTags(assign2, binary.position());
3543        Util.addLnPosTags(assign3, binary.position());
3544
3545        return retLocal;
3546    }
3547    
3548    private soot.Local handleCondBinExpr(soot.jimple.ConditionExpr condExpr) {
3549    
3550        soot.Local boolLocal = lg.generateLocal(soot.BooleanType.v());
3551
3552        soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
3553            
3554        soot.Value newVal;
3555       
3556        newVal = reverseCondition(condExpr);
3557        newVal = handleDFLCond((soot.jimple.ConditionExpr)newVal);
3558
3559        soot.jimple.Stmt ifStmt = soot.jimple.Jimple.v().newIfStmt(newVal, noop1);
3560        body.getUnits().add(ifStmt);
3561
3562        body.getUnits().add(soot.jimple.Jimple.v().newAssignStmt(boolLocal, soot.jimple.IntConstant.v(1)));
3563
3564        soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
3565        
3566        soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2);
3567
3568        body.getUnits().add(goto1);
3569
3570        body.getUnits().add(noop1);
3571        
3572        body.getUnits().add(soot.jimple.Jimple.v().newAssignStmt(boolLocal, soot.jimple.IntConstant.v(0)));
3573
3574        body.getUnits().add(noop2);
3575
3576        return boolLocal;
3577        
3578        
3579    }
3580    
3581    private soot.Local createStringBuffer(polyglot.ast.Expr expr){
3582        // create and add one string buffer
3583
soot.Local local = lg.generateLocal(soot.RefType.v("java.lang.StringBuffer"));
3584        soot.jimple.NewExpr newExpr = soot.jimple.Jimple.v().newNewExpr(soot.RefType.v("java.lang.StringBuffer"));
3585        soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(local, newExpr);
3586        
3587        body.getUnits().add(assign);
3588        Util.addLnPosTags(assign, expr.position());
3589        
3590        soot.SootClass classToInvoke1 = soot.Scene.v().getSootClass("java.lang.StringBuffer");
3591        soot.SootMethodRef methodToInvoke1 = soot.Scene.v().makeMethodRef(classToInvoke1, "<init>", new ArrayList(), soot.VoidType.v(), false);
3592        
3593        soot.jimple.SpecialInvokeExpr invoke = soot.jimple.Jimple.v().newSpecialInvokeExpr(local, methodToInvoke1);
3594            
3595        soot.jimple.Stmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(invoke);
3596        body.getUnits().add(invokeStmt);
3597        Util.addLnPosTags(invokeStmt, expr.position());
3598        
3599        return local;
3600    }
3601    
3602
3603    private soot.Local createToString(soot.Local sb, polyglot.ast.Expr expr){
3604        // invoke toString on local (type StringBuffer)
3605
soot.Local newString = lg.generateLocal(soot.RefType.v("java.lang.String"));
3606        soot.SootClass classToInvoke2 = soot.Scene.v().getSootClass("java.lang.StringBuffer");
3607        soot.SootMethodRef methodToInvoke2 = soot.Scene.v().makeMethodRef(classToInvoke2, "toString", new ArrayList(), soot.RefType.v("java.lang.String"), false);
3608                 
3609        soot.jimple.VirtualInvokeExpr toStringInvoke = soot.jimple.Jimple.v().newVirtualInvokeExpr(sb, methodToInvoke2);
3610                
3611        soot.jimple.Stmt lastAssign = soot.jimple.Jimple.v().newAssignStmt(newString, toStringInvoke);
3612
3613        body.getUnits().add(lastAssign);
3614        Util.addLnPosTags(lastAssign, expr.position());
3615        
3616        return newString;
3617    }
3618
3619    
3620
3621    private boolean isStringConcat(polyglot.ast.Expr expr){
3622        if (expr instanceof polyglot.ast.Binary) {
3623            polyglot.ast.Binary bin = (polyglot.ast.Binary)expr;
3624            if (bin.operator() == polyglot.ast.Binary.ADD){
3625                if (bin.type().toString().equals("java.lang.String")) return true;
3626                return false;
3627            }
3628            return false;
3629        }
3630        else if (expr instanceof polyglot.ast.Assign) {
3631            polyglot.ast.Assign assign = (polyglot.ast.Assign)expr;
3632            if (assign.operator() == polyglot.ast.Assign.ADD_ASSIGN){
3633                if (assign.type().toString().equals("java.lang.String")) return true;
3634                return false;
3635            }
3636            return false;
3637        }
3638        return false;
3639    }
3640    
3641    /**
3642     * Generates one part of a concatenation String
3643     */

3644    private soot.Local generateAppends(polyglot.ast.Expr expr, soot.Local sb) {
3645
3646        //System.out.println("generate appends for expr: "+expr);
3647
if (isStringConcat(expr)){
3648            if (expr instanceof polyglot.ast.Binary){
3649                sb = generateAppends(((polyglot.ast.Binary)expr).left(), sb);
3650                sb = generateAppends(((polyglot.ast.Binary)expr).right(), sb);
3651            }
3652            else {
3653                sb = generateAppends(((polyglot.ast.Assign)expr).left(), sb);
3654                sb = generateAppends(((polyglot.ast.Assign)expr).right(), sb);
3655            }
3656        }
3657        else {
3658            soot.Value toApp = base().createExpr(expr);
3659            //System.out.println("toApp: "+toApp+" type: "+toApp.getType());
3660
soot.Type appendType = null;
3661            if (toApp instanceof soot.jimple.StringConstant) {
3662                appendType = soot.RefType.v("java.lang.String");
3663            }
3664            else if (toApp instanceof soot.jimple.NullConstant){
3665                appendType = soot.RefType.v("java.lang.Object");
3666            }
3667            else if (toApp instanceof soot.jimple.Constant) {
3668                appendType = toApp.getType();
3669            }
3670            else if (toApp instanceof soot.Local) {
3671                if (((soot.Local)toApp).getType() instanceof soot.PrimType) {
3672                    appendType = ((soot.Local)toApp).getType();
3673                }
3674                else if (((soot.Local)toApp).getType() instanceof soot.RefType) {
3675                    if (((soot.Local)toApp).getType().toString().equals("java.lang.String")){
3676                        appendType = soot.RefType.v("java.lang.String");
3677                    }
3678                    else if (((soot.Local)toApp).getType().toString().equals("java.lang.StringBuffer")){
3679                        appendType = soot.RefType.v("java.lang.StringBuffer");
3680                    }
3681                    else{
3682                        appendType = soot.RefType.v("java.lang.Object");
3683                    }
3684                }
3685                else {
3686                    // this is for arrays
3687
appendType = soot.RefType.v("java.lang.Object");
3688                }
3689            }
3690            else if (toApp instanceof soot.jimple.ConditionExpr) {
3691                toApp = handleCondBinExpr((soot.jimple.ConditionExpr)toApp);
3692                appendType = soot.BooleanType.v();
3693            }
3694
3695            // handle shorts
3696
if (appendType instanceof soot.ShortType || appendType instanceof soot.ByteType) {
3697                soot.Local intLocal = lg.generateLocal(soot.IntType.v());
3698                soot.jimple.Expr cast = soot.jimple.Jimple.v().newCastExpr(toApp, soot.IntType.v());
3699                soot.jimple.Stmt castAssign = soot.jimple.Jimple.v().newAssignStmt(intLocal, cast);
3700                body.getUnits().add(castAssign);
3701                toApp = intLocal;
3702                appendType = soot.IntType.v();
3703            }
3704        
3705            ArrayList paramsTypes = new ArrayList();
3706            paramsTypes.add(appendType);
3707            ArrayList params = new ArrayList();
3708            params.add(toApp);
3709
3710            soot.SootClass classToInvoke = soot.Scene.v().getSootClass("java.lang.StringBuffer");
3711            soot.SootMethodRef methodToInvoke = soot.Scene.v().makeMethodRef(classToInvoke, "append", paramsTypes, soot.RefType.v("java.lang.StringBuffer"), false);
3712
3713            soot.jimple.VirtualInvokeExpr appendInvoke = soot.jimple.Jimple.v().newVirtualInvokeExpr(sb, methodToInvoke, params);
3714
3715            Util.addLnPosTags(appendInvoke.getArgBox(0), expr.position());
3716            
3717            soot.Local tmp = lg.generateLocal(soot.RefType.v("java.lang.StringBuffer"));
3718            soot.jimple.Stmt appendStmt = soot.jimple.Jimple.v().newAssignStmt(tmp, appendInvoke);
3719
3720            sb = tmp;
3721            
3722            body.getUnits().add(appendStmt);
3723        
3724            Util.addLnPosTags(appendStmt, expr.position());
3725        }
3726        return sb;
3727    }
3728
3729    /**
3730     * Unary Expression Creation
3731     */

3732    private soot.Value getUnaryLocal(polyglot.ast.Unary unary) {
3733       
3734        polyglot.ast.Expr expr = unary.expr();
3735        polyglot.ast.Unary.Operator op = unary.operator();
3736
3737        if (op == polyglot.ast.Unary.POST_INC || op == polyglot.ast.Unary.PRE_INC || op == polyglot.ast.Unary.POST_DEC || op == polyglot.ast.Unary.PRE_DEC) {
3738            if (base().needsAccessor(unary.expr())){
3739                return base().handlePrivateFieldUnarySet(unary);
3740            }
3741                
3742            soot.Value left = base().createLHS(unary.expr());
3743            
3744            // do necessary cloning
3745
soot.Value leftClone = soot.jimple.Jimple.v().cloneIfNecessary(left);
3746            
3747            
3748            soot.Local tmp = lg.generateLocal(left.getType());
3749            soot.jimple.AssignStmt stmt1 = soot.jimple.Jimple.v().newAssignStmt(tmp, left);
3750            body.getUnits().add(stmt1);
3751            Util.addLnPosTags(stmt1, unary.position());
3752            
3753            soot.Value incVal = base().getConstant(left.getType(), 1);
3754           
3755            soot.jimple.BinopExpr binExpr;
3756            if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.POST_INC){
3757                binExpr = soot.jimple.Jimple.v().newAddExpr(tmp, incVal);
3758            }
3759            else {
3760                binExpr = soot.jimple.Jimple.v().newSubExpr(tmp, incVal);
3761            }
3762           
3763            soot.Local tmp2 = lg.generateLocal(left.getType());
3764            soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(tmp2, binExpr);
3765            body.getUnits().add(assign);
3766                
3767            //if (base().needsAccessor(unary.expr())){
3768
// base().handlePrivateFieldSet(unary.expr(), tmp2);
3769
//}
3770
//else {
3771
soot.jimple.AssignStmt stmt3 = soot.jimple.Jimple.v().newAssignStmt(leftClone, tmp2);
3772                body.getUnits().add(stmt3);
3773            //}
3774

3775            if (unary.operator() == polyglot.ast.Unary.POST_DEC || unary.operator() == polyglot.ast.Unary.POST_INC){
3776                return tmp;
3777            }
3778            else {
3779                return tmp2;
3780            }
3781        }
3782        /*if (op == polyglot.ast.Unary.POST_INC){
3783            soot.Local retLocal = generateLocal(expr.type());
3784            soot.Value sootExpr = base().createExpr(expr);
3785            soot.jimple.AssignStmt preStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, sootExpr);
3786            body.getUnits().add(preStmt);
3787
3788            soot.jimple.AddExpr addExpr = soot.jimple.Jimple.v().newAddExpr(sootExpr, getConstant(retLocal.getType(), 1));
3789            
3790            Util.addLnPosTags(addExpr.getOp1Box(), expr.position());
3791            
3792            soot.Local local = generateLocal(expr.type());
3793            soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(local, addExpr);
3794            body.getUnits().add(stmt);
3795
3796            Util.addLnPosTags(stmt, expr.position());
3797            soot.jimple.AssignStmt aStmt = soot.jimple.Jimple.v().newAssignStmt(sootExpr, local);
3798            body.getUnits().add(aStmt);
3799
3800            Util.addLnPosTags(aStmt, expr.position());
3801            Util.addLnPosTags(aStmt, unary.position());
3802            
3803            if ((expr instanceof polyglot.ast.Field) || (expr instanceof polyglot.ast.ArrayAccess)) {
3804                //if ((expr instanceof polyglot.ast.Field) && (needsPrivateAccessor((polyglot.ast.Field)expr) || needsProtectedAccessor((polyglot.ast.Field)expr))){
3805                if (base().needsAccessor(expr)){
3806                    handlePrivateFieldSet(expr, local);
3807                }
3808                else {
3809                    soot.Value actualUnaryExpr = createLHS(expr);
3810                    soot.jimple.AssignStmt s = soot.jimple.Jimple.v().newAssignStmt(actualUnaryExpr, local);
3811                    body.getUnits().add(s);
3812                    Util.addLnPosTags(s, expr.position());
3813                    Util.addLnPosTags(s.getLeftOpBox(), expr.position());
3814                }
3815                
3816            }
3817            return retLocal;
3818            
3819        }
3820        else if (op == polyglot.ast.Unary.POST_DEC) {
3821            soot.Local retLocal = generateLocal(expr.type());
3822            
3823            soot.Value sootExpr = base().createExpr(expr);
3824
3825            soot.jimple.AssignStmt preStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, sootExpr);
3826            body.getUnits().add(preStmt);
3827            
3828            soot.jimple.SubExpr subExpr = soot.jimple.Jimple.v().newSubExpr(sootExpr, getConstant(retLocal.getType(), 1));
3829            Util.addLnPosTags(subExpr.getOp1Box(), expr.position());
3830            
3831            soot.Local local = generateLocal(expr.type());
3832            soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(local, subExpr);
3833            body.getUnits().add(stmt);
3834            Util.addLnPosTags(stmt, expr.position());
3835            
3836            soot.jimple.AssignStmt aStmt = soot.jimple.Jimple.v().newAssignStmt(sootExpr, local);
3837            body.getUnits().add(aStmt);
3838
3839            Util.addLnPosTags(aStmt, expr.position());
3840            Util.addLnPosTags(aStmt, unary.position());
3841           
3842            if ((expr instanceof polyglot.ast.Field) || (expr instanceof polyglot.ast.ArrayAccess)) {
3843                //if ((expr instanceof polyglot.ast.Field) && (needsPrivateAccessor((polyglot.ast.Field)expr) || needsProtectedAccessor((polyglot.ast.Field)expr))){
3844                if (base().needsAccessor(expr)){
3845                    handlePrivateFieldSet(expr, local);
3846                }
3847                else {
3848                    soot.Value actualUnaryExpr = createLHS(expr);
3849                    soot.jimple.AssignStmt s = soot.jimple.Jimple.v().newAssignStmt(actualUnaryExpr, local);
3850                    body.getUnits().add(s);
3851
3852                    Util.addLnPosTags(s, expr.position());
3853                    Util.addLnPosTags(s.getLeftOpBox(), expr.position());
3854                }
3855            }
3856
3857            return retLocal;
3858            
3859        }
3860        else if (op == polyglot.ast.Unary.PRE_INC) {
3861            
3862            soot.Value sootExpr = base().createExpr(expr);
3863          
3864            soot.jimple.AddExpr addExpr = soot.jimple.Jimple.v().newAddExpr(sootExpr, getConstant(sootExpr.getType(), 1));
3865            Util.addLnPosTags(addExpr.getOp1Box(), expr.position());
3866
3867            soot.Local local = generateLocal(expr.type());
3868            
3869            soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(local, addExpr);
3870
3871            body.getUnits().add(stmt);
3872            Util.addLnPosTags(stmt, expr.position());
3873            
3874            if ((expr instanceof polyglot.ast.Field) || (expr instanceof polyglot.ast.ArrayAccess) || (expr instanceof polyglot.ast.Local)) {
3875                //if ((expr instanceof polyglot.ast.Field) && (needsPrivateAccessor((polyglot.ast.Field)expr) || needsProtectedAccessor((polyglot.ast.Field)expr))){
3876                if (base().needsAccessor(expr)){
3877                    handlePrivateFieldSet(expr, local);
3878                }
3879                else {
3880                    soot.Value actualUnaryExpr = createLHS(expr);
3881                    body.getUnits().add(soot.jimple.Jimple.v().newAssignStmt(actualUnaryExpr, local));
3882                }
3883            }
3884
3885            return local;
3886            
3887        }
3888        else if (op == polyglot.ast.Unary.PRE_DEC) {
3889            
3890            soot.Value sootExpr = base().createExpr(expr);
3891          
3892            soot.jimple.SubExpr subExpr = soot.jimple.Jimple.v().newSubExpr(sootExpr, getConstant(sootExpr.getType(), 1));
3893            Util.addLnPosTags(subExpr.getOp1Box(), expr.position());
3894            
3895            soot.Local local = generateLocal(expr.type());
3896            
3897            soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(local, subExpr);
3898
3899            body.getUnits().add(stmt);
3900            Util.addLnPosTags(stmt, expr.position());
3901            
3902            if ((expr instanceof polyglot.ast.Field) || (expr instanceof polyglot.ast.ArrayAccess) || (expr instanceof polyglot.ast.Local)) {
3903                    
3904                //if ((expr instanceof polyglot.ast.Field) && (needsPrivateAccessor((polyglot.ast.Field)expr) || needsProtectedAccessor((polyglot.ast.Field)expr))){
3905                if (base().needsAccessor(expr)){
3906                    handlePrivateFieldSet(expr, local);
3907                }
3908                else {
3909                    soot.Value actualUnaryExpr = createLHS(expr);
3910                    body.getUnits().add(soot.jimple.Jimple.v().newAssignStmt(actualUnaryExpr, local));
3911                }
3912            }
3913
3914            return local;
3915            
3916        }*/

3917        else if (op == polyglot.ast.Unary.BIT_NOT) {
3918            soot.jimple.IntConstant int1 = soot.jimple.IntConstant.v(-1);
3919            
3920            soot.Local retLocal = generateLocal(expr.type());
3921            
3922            soot.Value sootExpr = base().createExpr(expr);
3923            
3924            soot.jimple.XorExpr xor = soot.jimple.Jimple.v().newXorExpr(sootExpr, base().getConstant(sootExpr.getType(), -1));
3925
3926            Util.addLnPosTags(xor.getOp1Box(), expr.position());
3927            soot.jimple.Stmt assign1 = soot.jimple.Jimple.v().newAssignStmt(retLocal, xor);
3928
3929            body.getUnits().add(assign1);
3930            
3931            Util.addLnPosTags(assign1, unary.position());
3932            
3933            return retLocal;
3934        }
3935        else if (op == polyglot.ast.Unary.NEG) {
3936            soot.Value sootExpr;
3937            if (expr instanceof polyglot.ast.IntLit) {
3938                
3939                long longVal = ((polyglot.ast.IntLit)expr).value();
3940                if (((polyglot.ast.IntLit)expr).kind() == polyglot.ast.IntLit.LONG){
3941                    sootExpr = soot.jimple.LongConstant.v(-longVal);
3942                }
3943                else {
3944                    sootExpr = soot.jimple.IntConstant.v(-(int)longVal);
3945                }
3946            }
3947            else if (expr instanceof polyglot.ast.FloatLit){
3948                double doubleVal = ((polyglot.ast.FloatLit)expr).value();
3949                if (((polyglot.ast.FloatLit)expr).kind() == polyglot.ast.FloatLit.DOUBLE){
3950                    sootExpr = soot.jimple.DoubleConstant.v(-doubleVal);
3951                }
3952                else {
3953                    sootExpr = soot.jimple.FloatConstant.v(-(float)doubleVal);
3954                }
3955            }
3956            else {
3957                soot.Value local = base().createExpr(expr);
3958
3959                soot.jimple.NegExpr negExpr = soot.jimple.Jimple.v().newNegExpr(local);
3960                sootExpr = negExpr;
3961                Util.addLnPosTags(negExpr.getOpBox(), expr.position());
3962            }
3963            
3964            soot.Local retLocal = generateLocal(expr.type());
3965
3966            soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(retLocal, sootExpr);
3967
3968            body.getUnits().add(assign);
3969            
3970            Util.addLnPosTags(assign, expr.position());
3971            
3972            return retLocal;
3973
3974        }
3975        else if (op == polyglot.ast.Unary.POS) {
3976            soot.Local retLocal = generateLocal(expr.type());
3977            soot.Value sootExpr = base().createExpr(expr);
3978            soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(retLocal, sootExpr);
3979            body.getUnits().add(assign);
3980            
3981            Util.addLnPosTags(assign, expr.position());
3982            
3983            return retLocal;
3984        }
3985        else if (op == polyglot.ast.Unary.NOT) {
3986        
3987            //pop any trueNoop and falseNoop - if its in an if and in a unary
3988
//then it needs old style generation
3989
boolean repush = false;
3990            soot.jimple.Stmt tNoop = null;
3991            soot.jimple.Stmt fNoop = null;
3992            if (!trueNoop.empty() && !falseNoop.empty()){
3993                tNoop = (soot.jimple.Stmt)trueNoop.pop();
3994                fNoop = (soot.jimple.Stmt)falseNoop.pop();
3995                repush = true;
3996            }
3997
3998            soot.Value local = base().createExpr(expr);
3999            
4000            // repush right away to optimize ! for ifs
4001
if (repush){
4002                trueNoop.push(tNoop);
4003                falseNoop.push(fNoop);
4004            }
4005           
4006            if (local instanceof soot.jimple.ConditionExpr){
4007                local = handleCondBinExpr((soot.jimple.ConditionExpr)local);
4008            }
4009            soot.jimple.NeExpr neExpr = soot.jimple.Jimple.v().newNeExpr(local, base().getConstant(local.getType(), 0));
4010
4011            soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
4012
4013            soot.jimple.IfStmt ifStmt;
4014            if (!falseNoop.empty()){
4015                ifStmt = soot.jimple.Jimple.v().newIfStmt(neExpr, (soot.jimple.Stmt)falseNoop.peek());
4016            }
4017            else {
4018               ifStmt = soot.jimple.Jimple.v().newIfStmt(neExpr, noop1);
4019            }
4020            body.getUnits().add(ifStmt);
4021            Util.addLnPosTags(ifStmt, expr.position());
4022            Util.addLnPosTags(ifStmt.getConditionBox(), expr.position());
4023
4024            if (!falseNoop.empty()){
4025                return soot.jimple.IntConstant.v(1);
4026            }
4027            soot.Local retLocal = lg.generateLocal(local.getType());
4028
4029            soot.jimple.Stmt assign1 = soot.jimple.Jimple.v().newAssignStmt(retLocal, base().getConstant(retLocal.getType(), 1));
4030
4031            body.getUnits().add(assign1);
4032            Util.addLnPosTags(assign1, expr.position());
4033
4034            soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
4035            
4036            soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2);
4037
4038            body.getUnits().add(goto1);
4039            
4040            body.getUnits().add(noop1);
4041            
4042            soot.jimple.Stmt assign2 = soot.jimple.Jimple.v().newAssignStmt(retLocal, base().getConstant(retLocal.getType(), 0));
4043
4044            body.getUnits().add(assign2);
4045            Util.addLnPosTags(assign2, expr.position());
4046
4047            body.getUnits().add(noop2);
4048            
4049            return retLocal;
4050        }
4051        else {
4052            throw new RuntimeException JavaDoc("Unhandled Unary Expr");
4053        }
4054
4055        
4056    }
4057
4058    /**
4059     * Returns a needed constant given a type and val
4060     */

4061    protected soot.jimple.Constant getConstant(soot.Type type, int val) {
4062   
4063        if (type instanceof soot.DoubleType) {
4064            return soot.jimple.DoubleConstant.v(val);
4065        }
4066        else if (type instanceof soot.FloatType) {
4067            return soot.jimple.FloatConstant.v(val);
4068        }
4069        else if (type instanceof soot.LongType) {
4070            return soot.jimple.LongConstant.v(val);
4071        }
4072        else {
4073            return soot.jimple.IntConstant.v(val);
4074        }
4075    }
4076    /**
4077     * Cast Expression Creation
4078     */

4079    private soot.Value getCastLocal(polyglot.ast.Cast castExpr){
4080 
4081        
4082        // if its already the right type
4083
if (castExpr.expr().type().equals(castExpr.type()) || (castExpr.type().isClass() && Util.getSootType(castExpr.type()).toString().equals("java.lang.Object"))) {
4084            return base().createExpr(castExpr.expr());
4085        }
4086
4087        soot.Value val;
4088            val = base().createExpr(castExpr.expr());
4089        soot.Type type = Util.getSootType(castExpr.type());
4090
4091        soot.jimple.CastExpr cast = soot.jimple.Jimple.v().newCastExpr(val, type);
4092        Util.addLnPosTags(cast.getOpBox(), castExpr.expr().position());
4093        soot.Local retLocal = lg.generateLocal(cast.getCastType());
4094        soot.jimple.Stmt castAssign = soot.jimple.Jimple.v().newAssignStmt(retLocal, cast);
4095        body.getUnits().add(castAssign);
4096        Util.addLnPosTags(castAssign, castExpr.position());
4097
4098        return retLocal;
4099    }
4100    
4101    /**
4102     * Procedure Call Helper Methods
4103     * Returns list of params
4104     */

4105    private ArrayList getSootParams(polyglot.ast.ProcedureCall call) {
4106        
4107        ArrayList sootParams = new ArrayList();
4108        Iterator it = call.arguments().iterator();
4109        while (it.hasNext()) {
4110            polyglot.ast.Expr next = (polyglot.ast.Expr)it.next();
4111            soot.Value nextExpr = base().createExpr(next);
4112            if (nextExpr instanceof soot.jimple.ConditionExpr){
4113                nextExpr = handleCondBinExpr((soot.jimple.ConditionExpr)nextExpr);
4114            }
4115            sootParams.add(nextExpr);
4116        }
4117        return sootParams;
4118    }
4119    
4120    /**
4121     * Returns list of param types
4122     */

4123    private ArrayList getSootParamsTypes(polyglot.ast.ProcedureCall call) {
4124        
4125        ArrayList sootParamsTypes = new ArrayList();
4126        Iterator it = call.procedureInstance().formalTypes().iterator();
4127        while (it.hasNext()) {
4128            Object JavaDoc next = it.next();
4129            sootParamsTypes.add(Util.getSootType((polyglot.types.Type)next));
4130        }
4131        return sootParamsTypes;
4132    }
4133
4134    /**
4135     * Gets the Soot Method form the given Soot Class
4136     */

4137    private soot.SootMethodRef getMethodFromClass(soot.SootClass sootClass, String JavaDoc name, ArrayList paramTypes, soot.Type returnType, boolean isStatic) {
4138        soot.SootMethodRef ref = soot.Scene.v().makeMethodRef(sootClass, name, paramTypes, returnType, isStatic);
4139        return ref;
4140    }
4141  
4142    /**
4143     * Adds extra params
4144     */

4145    private void handleFinalLocalParams(ArrayList sootParams, ArrayList sootParamTypes, polyglot.types.ClassType keyType){
4146        
4147        HashMap finalLocalInfo = soot.javaToJimple.InitialResolver.v().finalLocalInfo();
4148        if (finalLocalInfo != null){
4149            if (finalLocalInfo.containsKey(new polyglot.util.IdentityKey(keyType))){
4150                AnonLocalClassInfo alci = (AnonLocalClassInfo)finalLocalInfo.get(new polyglot.util.IdentityKey(keyType));
4151                
4152                ArrayList finalLocals = alci.finalLocalsUsed();
4153                if (finalLocals != null){
4154                    Iterator it = finalLocals.iterator();
4155                    while (it.hasNext()){
4156                        Object JavaDoc next = it.next();
4157                        polyglot.types.LocalInstance li = (polyglot.types.LocalInstance)((polyglot.util.IdentityKey)next).object();
4158                        sootParamTypes.add(Util.getSootType(li.type()));
4159                        sootParams.add(getLocal(li));
4160                    }
4161                }
4162            }
4163        }
4164    }
4165   
4166    protected soot.Local getThis(soot.Type sootType){
4167
4168        return Util.getThis(sootType, body, getThisMap, lg);
4169    }
4170    
4171    protected boolean needsOuterClassRef(polyglot.types.ClassType typeToInvoke){
4172        // anon and local
4173
AnonLocalClassInfo info = (AnonLocalClassInfo)InitialResolver.v().finalLocalInfo().get(new polyglot.util.IdentityKey(typeToInvoke));
4174        
4175        if (InitialResolver.v().isAnonInCCall(typeToInvoke)) return false;
4176        
4177        if ((info != null) && (!info.inStaticMethod())){
4178            return true;
4179        }
4180        
4181        // other nested
4182
else if (typeToInvoke.isNested() && !typeToInvoke.flags().isStatic() && !typeToInvoke.isAnonymous() && !typeToInvoke.isLocal()){
4183            return true;
4184        }
4185        
4186        return false;
4187    }
4188
4189    /**
4190     * adds outer class params
4191     */

4192    private void handleOuterClassParams(ArrayList sootParams, soot.Value qVal, ArrayList sootParamsTypes, polyglot.types.ClassType typeToInvoke){
4193           
4194
4195        ArrayList needsRef = soot.javaToJimple.InitialResolver.v().getHasOuterRefInInit();
4196
4197        boolean addRef = needsOuterClassRef(typeToInvoke);//(needsRef != null) && (needsRef.contains(Util.getSootType(typeToInvoke)));
4198
if (addRef){
4199            // if adding an outer type ref always add exact type
4200
soot.SootClass outerClass = ((soot.RefType)Util.getSootType(typeToInvoke.outer())).getSootClass();
4201            sootParamsTypes.add(outerClass.getType());
4202        }
4203
4204        if (addRef && !typeToInvoke.isAnonymous() && (qVal != null)){
4205            // for nested and local if qualifier use that for param
4206
sootParams.add(qVal);
4207        }
4208        else if (addRef && !typeToInvoke.isAnonymous()){
4209            soot.SootClass outerClass = ((soot.RefType)Util.getSootType(typeToInvoke.outer())).getSootClass();
4210            sootParams.add(getThis(outerClass.getType()));
4211        }
4212        else if (addRef && typeToInvoke.isAnonymous()){
4213            soot.SootClass outerClass = ((soot.RefType)Util.getSootType(typeToInvoke.outer())).getSootClass();
4214            sootParams.add(getThis(outerClass.getType()));
4215        }
4216
4217        // handle anon qualifiers
4218
if (typeToInvoke.isAnonymous() && (qVal != null)){
4219            sootParamsTypes.add(qVal.getType());
4220            sootParams.add(qVal);
4221        }
4222    }
4223    
4224    /**
4225     * Constructor Call Creation
4226     */

4227    private void createConstructorCall(polyglot.ast.ConstructorCall cCall) {
4228      
4229        ArrayList sootParams = new ArrayList();
4230        ArrayList sootParamsTypes = new ArrayList();
4231        
4232        polyglot.types.ConstructorInstance cInst = cCall.constructorInstance();
4233        String JavaDoc containerName = null;
4234        
4235        if (cInst.container() instanceof polyglot.types.ClassType) {
4236            containerName = ((polyglot.types.ClassType)cInst.container()).fullName();
4237        }
4238        
4239        soot.SootClass classToInvoke;
4240           
4241        if (cCall.kind() == polyglot.ast.ConstructorCall.SUPER) {
4242
4243            classToInvoke = ((soot.RefType)Util.getSootType(cInst.container())).getSootClass();
4244        }
4245        else if (cCall.kind() == polyglot.ast.ConstructorCall.THIS) {
4246            classToInvoke = body.getMethod().getDeclaringClass();
4247        }
4248        else {
4249            throw new RuntimeException JavaDoc("Unknown kind of Constructor Call");
4250        }
4251        soot.Local base = specialThisLocal;
4252
4253        polyglot.types.ClassType objType = (polyglot.types.ClassType)cInst.container();
4254        soot.Local qVal = null;
4255        if (cCall.qualifier() != null){// && (!(cCall.qualifier() instanceof polyglot.ast.Special && ((polyglot.ast.Special)cCall.qualifier()).kind() == polyglot.ast.Special.THIS)) ){
4256
qVal = (soot.Local)base().createExpr(cCall.qualifier());
4257        }
4258        handleOuterClassParams(sootParams, qVal, sootParamsTypes, objType);
4259        sootParams.addAll(getSootParams(cCall));
4260        sootParamsTypes.addAll(getSootParamsTypes(cCall));
4261        handleFinalLocalParams(sootParams, sootParamsTypes, (polyglot.types.ClassType)cCall.constructorInstance().container());
4262        
4263        soot.SootMethodRef methodToInvoke = getMethodFromClass(classToInvoke, "<init>", sootParamsTypes, soot.VoidType.v(), false);
4264        
4265        soot.jimple.SpecialInvokeExpr specialInvokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(base, methodToInvoke, sootParams);
4266
4267        soot.jimple.Stmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(specialInvokeExpr);
4268        
4269        body.getUnits().add(invokeStmt);
4270        Util.addLnPosTags(invokeStmt, cCall.position());
4271
4272        // this is clearly broken if an outer class this ref was added as first
4273
// param
4274
int numParams = 0;
4275        Iterator invokeParamsIt = cCall.arguments().iterator();
4276        while (invokeParamsIt.hasNext()) {
4277            Util.addLnPosTags(specialInvokeExpr.getArgBox(numParams), ((polyglot.ast.Expr)invokeParamsIt.next()).position());
4278            numParams++;
4279        }
4280       
4281        // if method is <init> handle field inits
4282
if (body.getMethod().getName().equals("<init>") && (cCall.kind() == polyglot.ast.ConstructorCall.SUPER)){
4283            
4284            handleOuterClassThisInit(body.getMethod());
4285            handleFinalLocalInits();
4286            handleFieldInits(body.getMethod());
4287            handleInitializerBlocks(body.getMethod());
4288        }
4289        
4290    }
4291
4292    private void handleFinalLocalInits(){
4293        ArrayList finalsList = ((PolyglotMethodSource)body.getMethod().getSource()).getFinalsList();
4294        if (finalsList == null) return;
4295        int paramCount = paramRefCount - finalsList.size();
4296        Iterator it = finalsList.iterator();
4297        while (it.hasNext()){
4298            soot.SootField sf = (soot.SootField)it.next();
4299
4300            soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, sf.makeRef());
4301            soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(fieldRef, body.getParameterLocal(paramCount));
4302            body.getUnits().add(stmt);
4303            paramCount++;
4304        }
4305    }
4306    
4307    /**
4308     * Local Class Decl - Local Inner Class
4309     */

4310    private void createLocalClassDecl(polyglot.ast.LocalClassDecl cDecl) {
4311        BiMap lcMap = InitialResolver.v().getLocalClassMap();
4312        String JavaDoc name = Util.getSootType(cDecl.decl().type()).toString();
4313        if (!InitialResolver.v().hasClassInnerTag(body.getMethod().getDeclaringClass(), name)){
4314            Util.addInnerClassTag(body.getMethod().getDeclaringClass(), name, null, cDecl.decl().name(), Util.getModifier(cDecl.decl().flags()));
4315        }
4316    }
4317    
4318    /**
4319     * New Expression Creation
4320     */

4321    private soot.Local getNewLocal(polyglot.ast.New newExpr) {
4322
4323        // handle parameters/args
4324
ArrayList sootParams = new ArrayList();
4325        ArrayList sootParamsTypes = new ArrayList();
4326
4327        polyglot.types.ClassType objType = (polyglot.types.ClassType)newExpr.objectType().type();
4328
4329        if (newExpr.anonType() != null){
4330            objType = newExpr.anonType();
4331            // add inner class tags for any anon classes created
4332
String JavaDoc name = Util.getSootType(objType).toString();
4333            polyglot.types.ClassType outerType = objType.outer();
4334            if (!InitialResolver.v().hasClassInnerTag(body.getMethod().getDeclaringClass(), name)){
4335                Util.addInnerClassTag(body.getMethod().getDeclaringClass(), name, null, null, outerType.flags().isInterface() ? soot.Modifier.PUBLIC | soot.Modifier.STATIC : Util.getModifier(objType.flags()));
4336            }
4337        }
4338        else {
4339            // not an anon class but actually invoking a new something
4340
if (!objType.isTopLevel()){
4341                String JavaDoc name = Util.getSootType(objType).toString();
4342                polyglot.types.ClassType outerType = objType.outer();
4343                if (!InitialResolver.v().hasClassInnerTag(body.getMethod().getDeclaringClass(), name)){
4344                    Util.addInnerClassTag(body.getMethod().getDeclaringClass(), name, Util.getSootType(outerType).toString(), objType.name(), outerType.flags().isInterface() ? soot.Modifier.PUBLIC | soot.Modifier.STATIC : Util.getModifier(objType.flags()));
4345            }
4346                
4347            }
4348        }
4349        soot.RefType sootType = (soot.RefType)Util.getSootType(objType);
4350        soot.Local retLocal = lg.generateLocal(sootType);
4351        soot.jimple.NewExpr sootNew = soot.jimple.Jimple.v().newNewExpr(sootType);
4352
4353        soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, sootNew);
4354        body.getUnits().add(stmt);
4355        Util.addLnPosTags(stmt, newExpr.position());
4356        Util.addLnPosTags(stmt.getRightOpBox(), newExpr.position());
4357        
4358        
4359        soot.SootClass classToInvoke = sootType.getSootClass();
4360        // if no qualifier --> X to invoke is static
4361
soot.Value qVal = null;
4362        //System.out.println("new qualifier: "+newExpr.qualifier());
4363
//if (newExpr.qualifier() != null) {
4364
if (newExpr.qualifier() != null){// && (!(newExpr.qualifier() instanceof polyglot.ast.Special && ((polyglot.ast.Special)newExpr.qualifier()).kind() == polyglot.ast.Special.THIS)) ){
4365
qVal = base().createExpr(newExpr.qualifier());
4366        }
4367        handleOuterClassParams(sootParams, qVal, sootParamsTypes, objType);
4368
4369        boolean repush = false;
4370        soot.jimple.Stmt tNoop = null;
4371        soot.jimple.Stmt fNoop = null;
4372        
4373        if (!trueNoop.empty() && !falseNoop.empty()){
4374            tNoop = (soot.jimple.Stmt)trueNoop.pop();
4375            fNoop = (soot.jimple.Stmt)falseNoop.pop();
4376            repush = true;
4377        }
4378        
4379        sootParams.addAll(getSootParams(newExpr));
4380
4381        if (repush){
4382            trueNoop.push(tNoop);
4383            falseNoop.push(fNoop);
4384        }
4385        
4386        sootParamsTypes.addAll(getSootParamsTypes(newExpr));
4387
4388        handleFinalLocalParams(sootParams, sootParamsTypes, (polyglot.types.ClassType)objType);
4389    
4390        soot.SootMethodRef methodToInvoke = getMethodFromClass(classToInvoke, "<init>", sootParamsTypes, soot.VoidType.v(), false);
4391        soot.jimple.SpecialInvokeExpr specialInvokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(retLocal, methodToInvoke, sootParams);
4392                
4393        soot.jimple.Stmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(specialInvokeExpr);
4394
4395        body.getUnits().add(invokeStmt);
4396        Util.addLnPosTags(invokeStmt, newExpr.position());
4397        
4398        int numParams = 0;
4399        Iterator invokeParamsIt = newExpr.arguments().iterator();
4400        while (invokeParamsIt.hasNext()) {
4401            Util.addLnPosTags(specialInvokeExpr.getArgBox(numParams), ((polyglot.ast.Expr)invokeParamsIt.next()).position());
4402            numParams++;
4403        }
4404        
4405        
4406        return retLocal;
4407    }
4408
4409    protected soot.SootMethodRef getSootMethodRef(polyglot.ast.Call call){
4410        soot.Type sootRecType;
4411        soot.SootClass receiverTypeClass;
4412        if (Util.getSootType(call.methodInstance().container()).equals(soot.RefType.v("java.lang.Object"))){
4413            sootRecType = soot.RefType.v("java.lang.Object");
4414            receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object");
4415        }
4416        else {
4417            if (call.target().type() == null){
4418                sootRecType = Util.getSootType(call.methodInstance().container());
4419            }
4420            else {
4421                sootRecType = Util.getSootType(call.target().type());
4422            }
4423            if (sootRecType instanceof soot.RefType){
4424                 receiverTypeClass = ((soot.RefType)sootRecType).getSootClass();
4425            }
4426            else if (sootRecType instanceof soot.ArrayType){
4427                receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object");
4428            }
4429            else {
4430                throw new RuntimeException JavaDoc("call target problem: "+call);
4431            }
4432        }
4433        
4434        polyglot.types.MethodInstance methodInstance = call.methodInstance();
4435        soot.Type sootRetType = Util.getSootType(methodInstance.returnType());
4436        ArrayList sootParamsTypes = getSootParamsTypes(call);
4437     
4438        soot.SootMethodRef callMethod = soot.Scene.v().makeMethodRef(receiverTypeClass, methodInstance.name(), sootParamsTypes, sootRetType, methodInstance.flags().isStatic());
4439        return callMethod;
4440    }
4441    
4442    /**
4443     * Call Expression Creation
4444     */

4445    private soot.Local getCallLocal(polyglot.ast.Call call){
4446       
4447        // handle name
4448
String JavaDoc name = call.name();
4449        // handle receiver/target
4450
polyglot.ast.Receiver receiver = call.target();
4451        //System.out.println("call: "+call+" receiver: "+receiver);
4452
soot.Local baseLocal;
4453        if ((receiver instanceof polyglot.ast.Special) && (((polyglot.ast.Special)receiver).kind() == polyglot.ast.Special.SUPER) && (((polyglot.ast.Special)receiver).qualifier() != null)){
4454            baseLocal = getSpecialSuperQualifierLocal(call);
4455            return baseLocal;
4456
4457        }
4458        baseLocal = (soot.Local)base().getBaseLocal(receiver);
4459        
4460        //System.out.println("base local: "+baseLocal);
4461

4462        boolean repush = false;
4463        soot.jimple.Stmt tNoop = null;
4464        soot.jimple.Stmt fNoop = null;
4465        if (!trueNoop.empty() && !falseNoop.empty()){
4466            tNoop = (soot.jimple.Stmt)trueNoop.pop();
4467            fNoop = (soot.jimple.Stmt)falseNoop.pop();
4468            repush = true;
4469        }
4470        ArrayList sootParams = getSootParams(call);
4471       
4472        if (repush){
4473            trueNoop.push(tNoop);
4474            falseNoop.push(fNoop);
4475        }
4476        
4477        soot.SootMethodRef callMethod = base().getSootMethodRef(call);
4478        
4479        soot.Type sootRecType;
4480        soot.SootClass receiverTypeClass;
4481        if (Util.getSootType(call.methodInstance().container()).equals(soot.RefType.v("java.lang.Object"))){
4482            sootRecType = soot.RefType.v("java.lang.Object");
4483            receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object");
4484        }
4485        else {
4486            if (call.target().type() == null){
4487                sootRecType = Util.getSootType(call.methodInstance().container());
4488            }
4489            else {
4490                sootRecType = Util.getSootType(call.target().type());
4491            }
4492            if (sootRecType instanceof soot.RefType){
4493                 receiverTypeClass = ((soot.RefType)sootRecType).getSootClass();
4494            }
4495            else if (sootRecType instanceof soot.ArrayType){
4496                receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object");
4497            }
4498            else {
4499                throw new RuntimeException JavaDoc("call target problem: "+call);
4500            }
4501        }
4502        
4503        polyglot.types.MethodInstance methodInstance = call.methodInstance();
4504        /*soot.Type sootRetType = Util.getSootType(methodInstance.returnType());
4505        ArrayList sootParamsTypes = getSootParamsTypes(call);
4506        ArrayList sootParams = getSootParams(call);
4507     
4508        soot.SootMethodRef callMethod = soot.Scene.v().makeMethodRef(receiverTypeClass, methodInstance.name(), sootParamsTypes, sootRetType, methodInstance.flags().isStatic());*/

4509
4510        boolean isPrivateAccess = false;
4511        //if (call.methodInstance().flags().isPrivate() && !Util.getSootType(call.methodInstance().container()).equals(body.getMethod().getDeclaringClass().getType())){
4512
if (needsAccessor(call)){
4513            
4514            soot.SootClass containingClass = ((soot.RefType)Util.getSootType(call.methodInstance().container())).getSootClass();
4515            soot.SootClass classToAddMethTo = containingClass;
4516            
4517            if (call.methodInstance().flags().isProtected()){
4518                
4519                if (InitialResolver.v().hierarchy() == null){
4520                    InitialResolver.v().hierarchy(new soot.FastHierarchy());
4521                }
4522                soot.SootClass addToClass;
4523                if (body.getMethod().getDeclaringClass().hasOuterClass()){
4524                    addToClass = body.getMethod().getDeclaringClass().getOuterClass();
4525            
4526                    while (!InitialResolver.v().hierarchy().canStoreType(containingClass.getType(), addToClass.getType())){
4527                        if (addToClass.hasOuterClass()){
4528                            addToClass = addToClass.getOuterClass();
4529                        }
4530                        else {
4531                            break;
4532                        }
4533                    }
4534                }
4535                else{
4536                    addToClass = containingClass;
4537                }
4538                classToAddMethTo = addToClass;
4539            }
4540            
4541            callMethod = addGetMethodAccessMeth(classToAddMethTo, call).makeRef();
4542            if (!call.methodInstance().flags().isStatic()){
4543            
4544                if (call.target() instanceof polyglot.ast.Expr){
4545                    sootParams.add(0, baseLocal);
4546                }
4547            
4548                else if (body.getMethod().getDeclaringClass().declaresFieldByName("this$0")){
4549                    sootParams.add(0, getThis(Util.getSootType(call.methodInstance().container())));//baseLocal);
4550
}
4551                else {
4552                    sootParams.add(0, baseLocal);
4553                }
4554            }
4555            isPrivateAccess = true;
4556        }
4557
4558        soot.jimple.InvokeExpr invokeExpr;
4559        if (isPrivateAccess){
4560            // for accessing private methods in outer class -> always static
4561
invokeExpr = soot.jimple.Jimple.v().newStaticInvokeExpr(callMethod, sootParams);
4562        }
4563        else if (soot.Modifier.isInterface(receiverTypeClass.getModifiers()) && methodInstance.flags().isAbstract()) {
4564            // if reciever class is interface and method is abstract -> interface
4565
invokeExpr = soot.jimple.Jimple.v().newInterfaceInvokeExpr(baseLocal, callMethod, sootParams);
4566        }
4567        else if (methodInstance.flags().isStatic()){
4568            // if flag isStatic -> static invoke
4569
invokeExpr = soot.jimple.Jimple.v().newStaticInvokeExpr(callMethod, sootParams);
4570        }
4571        else if (methodInstance.flags().isPrivate()){
4572            // if flag isPrivate -> special invoke
4573
invokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(baseLocal, callMethod, sootParams);
4574        }
4575        else if ((receiver instanceof polyglot.ast.Special) &&
4576            (((polyglot.ast.Special)receiver).kind() == polyglot.ast.Special.SUPER)){
4577            // receiver is special super -> special
4578
invokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(baseLocal, callMethod, sootParams);
4579        }
4580        else {
4581            // else virtual invoke
4582
invokeExpr = soot.jimple.Jimple.v().newVirtualInvokeExpr(baseLocal, callMethod, sootParams);
4583
4584        }
4585
4586        int numParams = 0;
4587        Iterator callParamsIt = call.arguments().iterator();
4588        while (callParamsIt.hasNext()) {
4589            Util.addLnPosTags(invokeExpr.getArgBox(numParams), ((polyglot.ast.Expr)callParamsIt.next()).position());
4590            numParams++;
4591        }
4592
4593        if (invokeExpr instanceof soot.jimple.InstanceInvokeExpr) {
4594            Util.addLnPosTags(((soot.jimple.InstanceInvokeExpr)invokeExpr).getBaseBox(), call.target().position());
4595        }
4596        
4597        // create an assign stmt so invoke can be used somewhere else
4598

4599        if (invokeExpr.getMethodRef().returnType().equals(soot.VoidType.v())) {
4600            soot.jimple.Stmt invoke = soot.jimple.Jimple.v().newInvokeStmt(invokeExpr);
4601            body.getUnits().add(invoke);
4602            Util.addLnPosTags(invoke, call.position());
4603            return null;
4604        }
4605        else {
4606            soot.Local retLocal = lg.generateLocal(invokeExpr.getMethodRef().returnType());
4607        
4608            soot.jimple.Stmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invokeExpr);
4609        
4610            // add assign stmt to body
4611
body.getUnits().add(assignStmt);
4612            
4613            Util.addLnPosTags(assignStmt, call.position());
4614            return retLocal;
4615        }
4616    }
4617   
4618
4619    protected soot.Value getBaseLocal(polyglot.ast.Receiver receiver) {
4620      
4621        if (receiver instanceof polyglot.ast.TypeNode) {
4622            return generateLocal(((polyglot.ast.TypeNode)receiver).type());
4623        }
4624        else {
4625            soot.Value val = base().createExpr((polyglot.ast.Expr)receiver);
4626            if (val instanceof soot.jimple.Constant) {
4627                soot.Local retLocal = lg.generateLocal(val.getType());
4628                soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, val);
4629                body.getUnits().add(stmt);
4630                return retLocal;
4631            }
4632            return val;
4633        }
4634    }
4635
4636    /**
4637     * NewArray Expression Creation
4638     */

4639    private soot.Local getNewArrayLocal(polyglot.ast.NewArray newArrExpr) {
4640
4641        soot.Type sootType = Util.getSootType(newArrExpr.type());
4642
4643        //System.out.println("creating new array of type: "+sootType);
4644
soot.jimple.Expr expr;
4645        if (newArrExpr.numDims() == 1) {
4646           
4647            soot.Value dimLocal;
4648            if (newArrExpr.additionalDims() == 1) {
4649                dimLocal = soot.jimple.IntConstant.v(1);
4650            }
4651            else {
4652                dimLocal = base().createExpr((polyglot.ast.Expr)newArrExpr.dims().get(0));
4653            }
4654            //System.out.println("creating new array: "+((soot.ArrayType)sootType).getElementType());
4655
soot.jimple.NewArrayExpr newArrayExpr = soot.jimple.Jimple.v().newNewArrayExpr(((soot.ArrayType)sootType).getElementType(), dimLocal);
4656            expr = newArrayExpr;
4657            if (newArrExpr.additionalDims() != 1){
4658                Util.addLnPosTags(newArrayExpr.getSizeBox(), ((polyglot.ast.Expr)newArrExpr.dims().get(0)).position());
4659            }
4660        }
4661        else {
4662        
4663            ArrayList valuesList = new ArrayList();
4664            Iterator it = newArrExpr.dims().iterator();
4665            while (it.hasNext()){
4666                valuesList.add(base().createExpr((polyglot.ast.Expr)it.next()));
4667            }
4668
4669            if (newArrExpr.additionalDims() != 0) {
4670                valuesList.add(soot.jimple.IntConstant.v(newArrExpr.additionalDims()));
4671            }
4672            soot.jimple.NewMultiArrayExpr newMultiArrayExpr = soot.jimple.Jimple.v().newNewMultiArrayExpr((soot.ArrayType)sootType, valuesList);
4673
4674            
4675            expr = newMultiArrayExpr;
4676            Iterator sizeBoxIt = newArrExpr.dims().iterator();
4677            int counter = 0;
4678            while (sizeBoxIt.hasNext()){
4679                Util.addLnPosTags(newMultiArrayExpr.getSizeBox(counter), ((polyglot.ast.Expr)sizeBoxIt.next()).position());
4680                counter++;
4681            }
4682        }
4683
4684        soot.Local retLocal = lg.generateLocal(sootType);
4685        
4686        soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, expr);
4687        
4688        body.getUnits().add(stmt);
4689            
4690        Util.addLnPosTags(stmt, newArrExpr.position());
4691        Util.addLnPosTags(stmt.getRightOpBox(), newArrExpr.position());
4692        
4693        // handle array init if one exists
4694
if (newArrExpr.init() != null) {
4695            soot.Value initVal = getArrayInitLocal(newArrExpr.init(), newArrExpr.type());
4696            soot.jimple.AssignStmt initStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, initVal);
4697        
4698            body.getUnits().add(initStmt);
4699            
4700        }
4701        
4702        return retLocal;
4703  
4704    }
4705
4706    /**
4707     * create ArrayInit given init and the array local
4708     */

4709    private soot.Local getArrayInitLocal(polyglot.ast.ArrayInit arrInit, polyglot.types.Type lhsType) {
4710  
4711        //System.out.println("lhs type: "+lhsType);
4712

4713        soot.Local local = generateLocal(lhsType);
4714
4715        //System.out.println("creating new array: "+((soot.ArrayType)local.getType()).getElementType());
4716
soot.jimple.NewArrayExpr arrExpr = soot.jimple.Jimple.v().newNewArrayExpr(((soot.ArrayType)local.getType()).getElementType(), soot.jimple.IntConstant.v(arrInit.elements().size()));
4717
4718        soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(local, arrExpr);
4719        
4720        body.getUnits().add(assign);
4721        Util.addLnPosTags(assign, arrInit.position());
4722       
4723
4724        Iterator it = arrInit.elements().iterator();
4725        int index = 0;
4726        
4727        while (it.hasNext()){
4728        
4729            polyglot.ast.Expr elemExpr = (polyglot.ast.Expr)it.next();
4730            soot.Value elem;
4731            if (elemExpr instanceof polyglot.ast.ArrayInit){
4732               
4733                if (((polyglot.ast.ArrayInit)elemExpr).type() instanceof polyglot.types.NullType) {
4734                    if (lhsType instanceof polyglot.types.ArrayType){
4735                        //System.out.println("coming from 1 in get arrayinitlocal"+((polyglot.types.ArrayType)lhsType).base());
4736
elem = getArrayInitLocal((polyglot.ast.ArrayInit)elemExpr, ((polyglot.types.ArrayType)lhsType).base());
4737                    }
4738                    else {
4739                        //System.out.println("coming from 2 in get arrayinitlocal"+((polyglot.types.ArrayType)lhsType).base());
4740
elem = getArrayInitLocal((polyglot.ast.ArrayInit)elemExpr, lhsType);
4741                        
4742                    }
4743                }
4744                else {
4745                    //System.out.println("coming from 3 in get arrayinitlocal"+((polyglot.types.ArrayType)lhsType).base());
4746
//elem = getArrayInitLocal((polyglot.ast.ArrayInit)elemExpr, ((polyglot.ast.ArrayInit)elemExpr).type());
4747
elem = getArrayInitLocal((polyglot.ast.ArrayInit)elemExpr, ((polyglot.types.ArrayType)lhsType).base());
4748                }
4749            }
4750            else {
4751                elem = base().createExpr(elemExpr);
4752            }
4753            soot.jimple.ArrayRef arrRef = soot.jimple.Jimple.v().newArrayRef(local, soot.jimple.IntConstant.v(index));
4754            
4755            soot.jimple.AssignStmt elemAssign = soot.jimple.Jimple.v().newAssignStmt(arrRef, elem);
4756            body.getUnits().add(elemAssign);
4757            Util.addLnPosTags(elemAssign, elemExpr.position());
4758            Util.addLnPosTags(elemAssign.getRightOpBox(), elemExpr.position());
4759            
4760            index++;
4761        }
4762
4763        return local;
4764    }
4765    
4766
4767    /**
4768     * create LHS expressions
4769     */

4770    protected soot.Value createLHS(polyglot.ast.Expr expr) {
4771        if (expr instanceof polyglot.ast.Local) {
4772            return getLocal((polyglot.ast.Local)expr);
4773        }
4774        else if (expr instanceof polyglot.ast.ArrayAccess) {
4775            return getArrayRefLocalLeft((polyglot.ast.ArrayAccess)expr);
4776        }
4777        else if (expr instanceof polyglot.ast.Field) {
4778            return getFieldLocalLeft((polyglot.ast.Field)expr);
4779        }
4780        else {
4781            throw new RuntimeException JavaDoc("Unhandled LHS");
4782        }
4783    }
4784
4785    /**
4786     * Array Ref Expression Creation - LHS
4787     */

4788    private soot.Value getArrayRefLocalLeft(polyglot.ast.ArrayAccess arrayRefExpr) {
4789        polyglot.ast.Expr array = arrayRefExpr.array();
4790        polyglot.ast.Expr access = arrayRefExpr.index();
4791        
4792        soot.Local arrLocal = (soot.Local)base().createExpr(array);
4793        soot.Value arrAccess = base().createExpr(access);
4794
4795        soot.Local retLocal = generateLocal(arrayRefExpr.type());
4796
4797        soot.jimple.ArrayRef ref = soot.jimple.Jimple.v().newArrayRef(arrLocal, arrAccess);
4798  
4799        Util.addLnPosTags(ref.getBaseBox(), arrayRefExpr.array().position());
4800        Util.addLnPosTags(ref.getIndexBox(), arrayRefExpr.index().position());
4801        return ref;
4802    }
4803
4804    /**
4805     * Array Ref Expression Creation
4806     */

4807    private soot.Value getArrayRefLocal(polyglot.ast.ArrayAccess arrayRefExpr) {
4808    
4809        polyglot.ast.Expr array = arrayRefExpr.array();
4810        polyglot.ast.Expr access = arrayRefExpr.index();
4811        
4812        soot.Local arrLocal = (soot.Local)base().createExpr(array);
4813        soot.Value arrAccess = base().createExpr(access);
4814
4815        soot.Local retLocal = generateLocal(arrayRefExpr.type());
4816
4817        soot.jimple.ArrayRef ref = soot.jimple.Jimple.v().newArrayRef(arrLocal, arrAccess);
4818        
4819        Util.addLnPosTags(ref.getBaseBox(), arrayRefExpr.array().position());
4820        Util.addLnPosTags(ref.getIndexBox(), arrayRefExpr.index().position());
4821
4822        soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, ref);
4823        body.getUnits().add(stmt);
4824        Util.addLnPosTags(stmt, arrayRefExpr.position());
4825        
4826
4827        return retLocal;
4828    }
4829    
4830  
4831    private soot.Local getSpecialSuperQualifierLocal(polyglot.ast.Expr expr){
4832        soot.SootClass classToInvoke;
4833        ArrayList methodParams = new ArrayList();
4834        if (expr instanceof polyglot.ast.Call){
4835            polyglot.ast.Special target = (polyglot.ast.Special)((polyglot.ast.Call)expr).target();
4836            classToInvoke = ((soot.RefType)Util.getSootType(target.qualifier().type())).getSootClass();
4837            methodParams = getSootParams((polyglot.ast.Call)expr);
4838        }
4839        else if (expr instanceof polyglot.ast.Field){
4840            polyglot.ast.Special target = (polyglot.ast.Special)((polyglot.ast.Field)expr).target();
4841            classToInvoke = ((soot.RefType)Util.getSootType(target.qualifier().type())).getSootClass();
4842        }
4843        else {
4844            throw new RuntimeException JavaDoc("Trying to create special super qualifier for: "+expr+" which is not a field or call");
4845        }
4846        // make an access method
4847
soot.SootMethod methToInvoke = makeSuperAccessMethod(classToInvoke, expr);
4848        // invoke it
4849
soot.Local classToInvokeLocal = Util.getThis(classToInvoke.getType(), body, getThisMap, lg);
4850        methodParams.add(0, classToInvokeLocal);
4851        
4852        soot.jimple.InvokeExpr invokeExpr = soot.jimple.Jimple.v().newStaticInvokeExpr(methToInvoke.makeRef(), methodParams);
4853        
4854        // return the local of return type if not void
4855
if (!methToInvoke.getReturnType().equals(soot.VoidType.v())){
4856            soot.Local retLocal = lg.generateLocal(methToInvoke.getReturnType());
4857            soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invokeExpr);
4858            body.getUnits().add(stmt);
4859        
4860            return retLocal;
4861        }
4862        else {
4863            body.getUnits().add(soot.jimple.Jimple.v().newInvokeStmt(invokeExpr));
4864            return null;
4865        }
4866    }
4867    
4868    /**
4869     * Special Expression Creation
4870     */

4871    private soot.Local getSpecialLocal(polyglot.ast.Special specialExpr) {
4872      
4873        //System.out.println(specialExpr);
4874
if (specialExpr.kind() == polyglot.ast.Special.SUPER) {
4875            if (specialExpr.qualifier() == null){
4876                return specialThisLocal;
4877            }
4878            else {
4879                // this isn't enough
4880
// need to getThis for the type which may be several levels up
4881
// add access$N method to class of the type which returns
4882
// field or method wanted
4883
// invoke it
4884
// and it needs to be called specially when getting fields
4885
// or calls because need to know field or method to access
4886
// as it access' a field or meth in the super class of the
4887
// outer class refered to by the qualifier
4888
return getThis(Util.getSootType(specialExpr.qualifier().type()));
4889            }
4890        }
4891        else if (specialExpr.kind() == polyglot.ast.Special.THIS) {
4892            //System.out.println("this is special this: "+specialExpr);
4893
if (specialExpr.qualifier() == null) {
4894                return specialThisLocal;
4895            }
4896            else {
4897                return getThis(Util.getSootType(specialExpr.qualifier().type()));
4898            }
4899        }
4900        else {
4901            throw new RuntimeException JavaDoc("Unknown Special");
4902        }
4903    }
4904    
4905
4906    private soot.SootMethod makeSuperAccessMethod(soot.SootClass classToInvoke, Object JavaDoc memberToAccess){
4907        String JavaDoc name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00";
4908        ArrayList paramTypes = new ArrayList();
4909        paramTypes.add(classToInvoke.getType());
4910        
4911        soot.SootMethod meth;
4912        soot.MethodSource src;
4913        if (memberToAccess instanceof polyglot.ast.Field){
4914            polyglot.ast.Field fieldToAccess = (polyglot.ast.Field)memberToAccess;
4915            meth = new soot.SootMethod(name, paramTypes, Util.getSootType(fieldToAccess.type()), soot.Modifier.STATIC);
4916            PrivateFieldAccMethodSource fSrc = new PrivateFieldAccMethodSource(
4917            Util.getSootType(fieldToAccess.type()),
4918            fieldToAccess.name(),
4919            fieldToAccess.flags().isStatic(),
4920                        ((soot.RefType)Util.getSootType(fieldToAccess.target().type())).getSootClass()
4921            );
4922            src = fSrc;
4923        }
4924        else if (memberToAccess instanceof polyglot.ast.Call){
4925            polyglot.ast.Call methToAccess = (polyglot.ast.Call)memberToAccess;
4926            paramTypes.addAll(getSootParamsTypes(methToAccess));
4927            meth = new soot.SootMethod(name, paramTypes, Util.getSootType(methToAccess.methodInstance().returnType()), soot.Modifier.STATIC);
4928            PrivateMethodAccMethodSource mSrc = new PrivateMethodAccMethodSource( methToAccess.methodInstance());
4929            src = mSrc;
4930        }
4931        else {
4932            throw new RuntimeException JavaDoc("trying to access unhandled member type: "+memberToAccess);
4933        }
4934        classToInvoke.addMethod(meth);
4935        meth.setActiveBody(src.getBody(meth, null));
4936        meth.addTag(new soot.tagkit.SyntheticTag());
4937        return meth;
4938    }
4939    
4940    /**
4941     * InstanceOf Expression Creation
4942     */

4943    private soot.Local getInstanceOfLocal(polyglot.ast.Instanceof instExpr) {
4944        
4945        soot.Type sootType = Util.getSootType(instExpr.compareType().type());
4946
4947        soot.Value local = base().createExpr(instExpr.expr());
4948
4949        soot.jimple.InstanceOfExpr instOfExpr = soot.jimple.Jimple.v().newInstanceOfExpr(local, sootType);
4950
4951        soot.Local lhs = lg.generateLocal(soot.BooleanType.v());
4952
4953        soot.jimple.AssignStmt instAssign = soot.jimple.Jimple.v().newAssignStmt(lhs, instOfExpr);
4954        body.getUnits().add(instAssign);
4955        Util.addLnPosTags(instAssign, instExpr.position());
4956        Util.addLnPosTags(instAssign.getRightOpBox(), instExpr.position());
4957
4958        Util.addLnPosTags(instOfExpr.getOpBox(), instExpr.expr().position());
4959        return lhs;
4960    }
4961
4962    /**
4963     * Condition Expression Creation - can maybe merge with If
4964     */

4965    private soot.Local getConditionalLocal(polyglot.ast.Conditional condExpr){
4966        
4967
4968        // handle cond
4969
soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt();
4970        polyglot.ast.Expr condition = condExpr.cond();
4971        createBranchingExpr(condition, noop1, false);
4972        
4973        soot.Local retLocal = generateLocal(condExpr.type());
4974        
4975        // handle consequence
4976
polyglot.ast.Expr consequence = condExpr.consequent();
4977        
4978        soot.Value conseqVal = base().createExpr(consequence);
4979        if (conseqVal instanceof soot.jimple.ConditionExpr) {
4980            conseqVal = handleCondBinExpr((soot.jimple.ConditionExpr)conseqVal);
4981        }
4982        soot.jimple.AssignStmt conseqAssignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, conseqVal);
4983        body.getUnits().add(conseqAssignStmt);
4984        Util.addLnPosTags(conseqAssignStmt, condExpr.position());
4985        Util.addLnPosTags(conseqAssignStmt.getRightOpBox(), consequence.position());
4986        
4987        soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt();
4988        soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2);
4989        body.getUnits().add(goto1);
4990        
4991        // handle alternative
4992

4993        body.getUnits().add(noop1);
4994        polyglot.ast.Expr alternative = condExpr.alternative();
4995        if (alternative != null){
4996            soot.Value altVal = base().createExpr(alternative);
4997            if (altVal instanceof soot.jimple.ConditionExpr) {
4998                altVal = handleCondBinExpr((soot.jimple.ConditionExpr)altVal);
4999            }
5000            soot.jimple.AssignStmt altAssignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, altVal);
5001            body.getUnits().add(altAssignStmt);
5002            Util.addLnPosTags(altAssignStmt, condExpr.position());
5003            Util.addLnPosTags(altAssignStmt, alternative.position());
5004            Util.addLnPosTags(altAssignStmt.getRightOpBox(), alternative.position());
5005        }
5006        body.getUnits().add(noop2);
5007
5008        
5009        return retLocal;
5010    }
5011    
5012    /**
5013     * Utility methods
5014     */

5015    /*private boolean isLitOrLocal(polyglot.ast.Expr exp) {
5016        if (exp instanceof polyglot.ast.Lit) return true;
5017        if (exp instanceof polyglot.ast.Local) return true;
5018        else return false;
5019    }*/

5020    
5021    /**
5022     * Extra Local Variables Generation
5023     */

5024    protected soot.Local generateLocal(polyglot.types.Type polyglotType) {
5025        soot.Type type = Util.getSootType(polyglotType);
5026        return lg.generateLocal(type);
5027    }
5028    
5029    protected soot.Local generateLocal(soot.Type sootType){
5030        return lg.generateLocal(sootType);
5031    }
5032}
5033
Popular Tags