00001 package edu.ksu.cis.bandera.jjjc.ast;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import ca.mcgill.sable.util.*;
00036 import edu.ksu.cis.bandera.jjjc.analysis.*;
00037 import edu.ksu.cis.bandera.jjjc.node.*;
00038 import edu.ksu.cis.bandera.jjjc.doc.*;
00039 import edu.ksu.cis.bandera.jjjc.symboltable.*;
00040 import java.util.Vector;
00041 import java.util.Hashtable;
00042 public class SynchronizedMethodTransformer extends DepthFirstAdapter {
00043 private String packageName = null;
00044 private String className;
00045 private Vector v;
00046 private Hashtable docComments;
00047
00048
00049
00050
00051 public SynchronizedMethodTransformer(Vector synchTransformed, Hashtable docComments) {
00052 v = synchTransformed;
00053 this.docComments = docComments;
00054 }
00055
00056
00057
00058
00059 public void caseAClassDeclaration(AClassDeclaration node) {
00060 className = node.getId().toString().trim();
00061 if (packageName != null) {
00062 className = packageName + "." + className;
00063 }
00064 super.caseAClassDeclaration(node);
00065 }
00066
00067
00068
00069
00070 public void caseAMethodDeclaration(AMethodDeclaration node) {
00071 PMethodHeader methodHeader = node.getMethodHeader();
00072 List modifiers;
00073 boolean isStatic = false;
00074 boolean isSynchronized = false;
00075 boolean isNative = false;
00076 boolean isAbstract = false;
00077 Object synchronizedModifier = null;
00078 if (methodHeader instanceof ATypedMethodHeader) {
00079 modifiers = ((ATypedMethodHeader) methodHeader).getModifier();
00080 } else {
00081 modifiers = ((AVoidMethodHeader) methodHeader).getModifier();
00082 }
00083 for (Iterator i = modifiers.iterator(); i.hasNext();) {
00084 Object o = i.next();
00085 String mod = o.toString().trim();
00086 if ("static".equals(mod)) {
00087 isStatic = true;
00088 } else
00089 if ("synchronized".equals(mod)) {
00090 isSynchronized = true;
00091 synchronizedModifier = o;
00092 } else
00093 if ("native".equals(mod)) {
00094 isNative = true;
00095 } else
00096 if ("abstract".equals(mod)) {
00097 isAbstract = true;
00098 }
00099 }
00100 if (!isSynchronized)
00101 return;
00102 else
00103 if (isNative || isAbstract)
00104 return;
00105 PMethodBody methodBody = node.getMethodBody();
00106 if (methodBody instanceof AEmptyMethodBody)
00107 return;
00108 PBlock methodBlock = ((ABlockMethodBody) methodBody).getBlock();
00109 PExp lock;
00110 if (isStatic) {
00111 LinkedList args = new LinkedList();
00112 args.addLast(new ALiteralExp(new AStringLiteralLiteral(new TStringLiteral("\"" + className + "\""))));
00113 lock = new ANameMethodInvocationExp(new AQualifiedName(new ASimpleName(new TId("Class")), new TDot(), new TId("forName")), new TLPar(), args, new TRPar());
00114 } else {
00115 lock = new AThisExp(new TThis());
00116 }
00117 ASynchronizedStmt synchStmt = new ASynchronizedStmt(new TSynchronized(), new TLPar(), lock, new TRPar(), null);
00118 LinkedList blockedStmts = new LinkedList();
00119 blockedStmts.addLast(new AStmtBlockedStmt(synchStmt));
00120 if (isStatic) {
00121 LinkedList catchClauses = new LinkedList();
00122 AFormalParameter formal = new AFormalParameter(new LinkedList(), new AReferenceType(new ANameReferenceType(new ASimpleName(new TId("ClassNotFoundException")))), new AVariableDeclaratorId(new TId("JJJCTEMP$E"), new LinkedList()));
00123
00124 PExp expNewRuntime = new ASimpleClassInstanceCreationExp(new TNew(), new AQualifiedName(new AQualifiedName(new ASimpleName(new TId("java")), new TDot(), new TId("lang")), new TDot() ,new TId("RuntimeException")), new TLPar(), new LinkedList(), new TRPar(), null);
00125 AThrowStmt throwStmt = new AThrowStmt(new TThrow(), expNewRuntime,new TSemicolon());
00126 LinkedList throwBlockedStmt = new LinkedList();
00127 throwBlockedStmt.addLast(new AStmtBlockedStmt(throwStmt));
00128 catchClauses.addLast(new ACatchClause(new TCatch(), new TLPar(), formal, new TRPar(), new ABlock(new TLBrace(), throwBlockedStmt, new TRBrace())));
00129 ATryStmt tryStmt = new ATryStmt(new TTry(), new ABlock(new TLBrace(), blockedStmts, new TRBrace()), catchClauses);
00130 blockedStmts = new LinkedList();
00131 blockedStmts.addLast(new AStmtBlockedStmt(tryStmt));
00132 }
00133 ABlock block = new ABlock(new TLBrace(), blockedStmts, new TRBrace());
00134 methodBlock.replaceBy(block);
00135 synchStmt.setBlock(methodBlock);
00136 if (DocProcessor.getKey(node) == synchronizedModifier) {
00137 modifiers.remove(synchronizedModifier);
00138 Object value = docComments.get(synchronizedModifier);
00139 docComments.remove(synchronizedModifier);
00140 docComments.put(DocProcessor.getKey(node), value);
00141 } else {
00142 modifiers.remove(synchronizedModifier);
00143 }
00144 v.add(node);
00145 }
00146
00147
00148
00149
00150 public void caseAPackageDeclaration(APackageDeclaration node) {
00151 packageName = (new Name(node.getName().toString())).toString();
00152 }
00153 }