Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

AssertionProcessor.java

00001 package edu.ksu.cis.bandera.specification.assertion;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 2000   Robby (robby@cis.ksu.edu)                    *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 import edu.ksu.cis.bandera.jjjc.symboltable.*;
00036 import edu.ksu.cis.bandera.annotation.*;
00037 import edu.ksu.cis.bandera.jjjc.analysis.*;
00038 import edu.ksu.cis.bandera.jjjc.node.*;
00039 import edu.ksu.cis.bandera.jjjc.*;
00040 import java.util.*;
00041 import edu.ksu.cis.bandera.specification.assertion.datastructure.*;
00042 public class AssertionProcessor extends DepthFirstAdapter {
00043     private static Hashtable assertionTable;
00044     private static AssertionProcessor processor = new AssertionProcessor();
00045     private static HashSet preSet;
00046     private static Hashtable locationTable;
00047     private static HashSet postSet;
00048     private static PType type;
00049     private static boolean hasRet;
00050     private static Hashtable modifiedMethodTable;
00051     private static Annotation currentAnnotation;
00052 /**
00053  * 
00054  * @return edu.ksu.cis.bandera.jjjc.node.PExp
00055  * @param a edu.ksu.cis.bandera.specification.assertion.datastructure.Assertion
00056  */
00057 private ca.mcgill.sable.util.List buildArgumentList(Assertion a) {
00058     PExp exp;
00059 
00060     if (((Collection) assertionTable.get(a)).size() == 0) {
00061         exp = (PExp) a.getConstraint().clone();
00062     } else {
00063         Iterator i = ((Collection) assertionTable.get(a)).iterator();
00064         if (a instanceof PreAssertion) {
00065             exp = new ABinaryExp((PExp) a.getConstraint().clone(), new AOrBinaryOperator(new TOr()), (PExp) i.next());
00066             while (i.hasNext()) {
00067                 exp = new ABinaryExp(exp, new AOrBinaryOperator(new TOr()), (PExp) i.next());
00068             }
00069         } else {
00070             exp = new ABinaryExp((PExp) a.getConstraint().clone(), new AAndBinaryOperator(new TAnd()), (PExp) i.next());
00071             while (i.hasNext()) {
00072                 exp = new ABinaryExp(exp, new AAndBinaryOperator(new TAnd()), (PExp) i.next());
00073             }
00074         }
00075     }
00076     
00077     ca.mcgill.sable.util.LinkedList result = new ca.mcgill.sable.util.LinkedList();
00078     result.addLast(exp);
00079     return result;
00080 }
00081 /**
00082  * 
00083  * @param node edu.ksu.cis.bandera.jjjc.node.ABlockMethodBody
00084  */
00085 public void caseABlockMethodBody(ABlockMethodBody node) {
00086     ca.mcgill.sable.util.LinkedList list = ((ABlock) node.getBlock()).getBlockedStmt();
00087 
00088     boolean isSynchronized = false;
00089     boolean isStatic = false;
00090     
00091     Method m = ((MethodDeclarationAnnotation) currentAnnotation).getMethod();
00092     isSynchronized = CompilationManager.isSynchTransformed(currentAnnotation.getNode());
00093     isStatic = java.lang.reflect.Modifier.isStatic(m.getModifiers());
00094 
00095     if (isSynchronized) {
00096         if (isStatic) {
00097             ATryStmt ts = (ATryStmt) ((AStmtBlockedStmt) list.iterator().next()).getStmt();
00098             list = ((ABlock) ts.getBlock()).getBlockedStmt();
00099             ASynchronizedStmt ss = (ASynchronizedStmt) ((AStmtBlockedStmt) list.iterator().next()).getStmt();
00100             list = ((ABlock) ss.getBlock()).getBlockedStmt();
00101         } else {
00102             ASynchronizedStmt ss = (ASynchronizedStmt) ((AStmtBlockedStmt) list.iterator().next()).getStmt();
00103             list = ((ABlock) ss.getBlock()).getBlockedStmt();
00104         }
00105     }
00106 
00107     for (Iterator i = preSet.iterator(); i.hasNext();) {
00108         PreAssertion a = (PreAssertion) i.next();
00109         PName name = new AQualifiedName(new ASimpleName(new TId("Bandera")), new TDot(), new TId("assert"));
00110         PExp exp = new ANameMethodInvocationExp(name, new TLPar(), buildArgumentList(a), new TRPar());
00111         PStmt stmt = new AExpStmt(exp, new TSemicolon());
00112         list.addFirst(new AStmtBlockedStmt(stmt));
00113     }
00114 
00115     hasRet = false;
00116 
00117     for (Iterator i = postSet.iterator(); i.hasNext();) {
00118         PostAssertion a = (PostAssertion) i.next();
00119         if (a.hasRet()) {
00120             hasRet = true;
00121             break;
00122         }
00123     }
00124 
00125     if (hasRet) {
00126         ca.mcgill.sable.util.LinkedList varList = new ca.mcgill.sable.util.LinkedList();
00127         varList.addFirst(new AIdVariableDeclarator(new AVariableDeclaratorId(new TId("$ret"), new ca.mcgill.sable.util.LinkedList())));
00128         ALocalVariableDeclaration decl = new ALocalVariableDeclaration(new ca.mcgill.sable.util.LinkedList(),
00129                 type, varList);
00130         list.addFirst(new ALocalVariableDeclarationInBlockedStmt(decl, new TSemicolon()));
00131     }
00132 
00133     if (type == null) {
00134         PStmt lastStmt = ((AStmtBlockedStmt) list.getLast()).getStmt();
00135         if (!(lastStmt instanceof AReturnStmt)) {
00136             ca.mcgill.sable.util.LinkedList list2 = new ca.mcgill.sable.util.LinkedList();
00137             for (Iterator i = postSet.iterator(); i.hasNext();) {
00138                 PostAssertion a = (PostAssertion) i.next();
00139                 PName name = new AQualifiedName(new ASimpleName(new TId("Bandera")), new TDot(), new TId("assert"));
00140                 PExp exp2 = new ANameMethodInvocationExp(name, new TLPar(), buildArgumentList(a), new TRPar());
00141                 PStmt stmt = new AExpStmt(exp2, new TSemicolon());
00142                 list2.addLast(new AStmtBlockedStmt(stmt));
00143             }
00144 
00145             ABlock block = new ABlock(new TLBrace(), list2, new TRBrace());
00146             list.addLast(new AStmtBlockedStmt(new ABlockStmt(block)));
00147         }
00148     }
00149     
00150     super.caseABlockMethodBody(node);
00151 }
00152 /**
00153  * 
00154  * @param node edu.ksu.cis.bandera.jjjc.node.ABreakStmt
00155  */
00156 public void caseABreakStmt(ABreakStmt node) {
00157     if (node.getId() != null) {
00158         String label = node.getId().toString().trim();
00159         if (locationTable.get(label) != null) {
00160             node.getId().setText("assertion$" + label);
00161         }
00162     }
00163     super.caseABreakStmt(node);
00164 }
00165 /**
00166  * 
00167  * @param node edu.ksu.cis.bandera.jjjc.node.AConstructorBody
00168  */
00169 public void caseAConstructorBody(AConstructorBody node) {
00170     ca.mcgill.sable.util.LinkedList list = node.getBlockedStmt();
00171     Method m = ((ConstructorDeclarationAnnotation) currentAnnotation).getConstructor();
00172     if (preSet.size() > 0) {
00173         ca.mcgill.sable.util.LinkedList list2 = new ca.mcgill.sable.util.LinkedList();
00174         for (Iterator i = preSet.iterator(); i.hasNext();) {
00175             PreAssertion a = (PreAssertion) i.next();
00176             PName name = new AQualifiedName(new ASimpleName(new TId("Bandera")), new TDot(), new TId("assert"));
00177             PExp exp = new ANameMethodInvocationExp(name, new TLPar(), buildArgumentList(a), new TRPar());
00178             PStmt stmt = new AExpStmt(exp, new TSemicolon());
00179             list2.addLast(new AStmtBlockedStmt(stmt));
00180         }
00181         ABlock block = new ABlock(new TLBrace(), list2, new TRBrace());
00182         list.addFirst(new AStmtBlockedStmt(new ABlockStmt(block)));
00183     }
00184     PStmt lastStmt = ((AStmtBlockedStmt) list.getLast()).getStmt();
00185     if (!(lastStmt instanceof AReturnStmt)) {
00186         if (postSet.size() > 0) {
00187             ca.mcgill.sable.util.LinkedList list2 = new ca.mcgill.sable.util.LinkedList();
00188             for (Iterator i = postSet.iterator(); i.hasNext();) {
00189                 PostAssertion a = (PostAssertion) i.next();
00190                 PName name = new AQualifiedName(new ASimpleName(new TId("Bandera")), new TDot(), new TId("assert"));
00191                 PExp exp2 = new ANameMethodInvocationExp(name, new TLPar(), buildArgumentList(a), new TRPar());
00192                 PStmt stmt = new AExpStmt(exp2, new TSemicolon());
00193                 list2.addLast(new AStmtBlockedStmt(stmt));
00194             }
00195             ABlock block = new ABlock(new TLBrace(), list2, new TRBrace());
00196             list.addLast(new AStmtBlockedStmt(new ABlockStmt(block)));
00197         }
00198     }
00199     super.caseAConstructorBody(node);
00200 }
00201 /**
00202  * 
00203  * @param node edu.ksu.cis.bandera.jjjc.node.AConstructorDeclaration
00204  */
00205 public void caseAConstructorDeclaration(AConstructorDeclaration node) {
00206     AConstructorDeclaration newNode = (AConstructorDeclaration) node.clone();
00207     modifiedMethodTable.put(node, newNode);
00208     super.caseAConstructorDeclaration(newNode);
00209 }
00210 /**
00211  * 
00212  * @param node edu.ksu.cis.bandera.jjjc.node.AContinueStmt
00213  */
00214 public void caseAContinueStmt(AContinueStmt node) {
00215     if (node.getId() != null) {
00216         String label = node.getId().toString().trim();
00217         if (locationTable.get(label) != null) {
00218             node.getId().setText("assertion$" + label);
00219         }
00220     }
00221 }
00222 /**
00223  * 
00224  * @param node edu.ksu.cis.bandera.jjjc.node.ALabelStmt
00225  */
00226 public void caseALabelStmt(ALabelStmt node) {
00227     String label = node.getId().toString().trim();
00228     if (locationTable.get(label) != null) {
00229         ca.mcgill.sable.util.LinkedList list = new ca.mcgill.sable.util.LinkedList();
00230         
00231         for (Iterator i = ((Collection) locationTable.get(label)).iterator(); i.hasNext();) {
00232             LocationAssertion a = (LocationAssertion) i.next();
00233             PName name = new AQualifiedName(new ASimpleName(new TId("Bandera")), new TDot(), new TId("assert"));
00234             PExp exp = new ANameMethodInvocationExp(name, new TLPar(), buildArgumentList(a), new TRPar());
00235             PStmt stmt = new AExpStmt(exp, new TSemicolon());
00236             list.addFirst(new AStmtBlockedStmt(stmt));
00237         }
00238 
00239         ABlock block = new ABlock(new TLBrace(), list, new TRBrace());
00240         PStmt stmt = new ABlockStmt(block);
00241 
00242         list = new ca.mcgill.sable.util.LinkedList();
00243         list.addLast(new AStmtBlockedStmt(stmt));
00244         block = new ABlock(new TLBrace(), list, new TRBrace());
00245         
00246         stmt = new ALabelStmt(new TId("assertion$" + label), new TColon(), block);
00247 
00248         block = (ABlock) node.parent().parent();
00249         list = block.getBlockedStmt();
00250         int index = list.indexOf(node.parent());
00251         list.add(index, new AStmtBlockedStmt(stmt));
00252     }
00253     super.caseALabelStmt(node);
00254 }
00255 /**
00256  * 
00257  * @param node edu.ksu.cis.bandera.jjjc.node.AMethodDeclaration
00258  */
00259 public void caseAMethodDeclaration(AMethodDeclaration node) {
00260     AMethodDeclaration newNode = (AMethodDeclaration) node.clone();
00261     modifiedMethodTable.put(node, newNode);
00262     super.caseAMethodDeclaration(newNode);
00263     //System.out.println(newNode.toString());
00264 }
00265 /**
00266  * 
00267  * @param node edu.ksu.cis.bandera.jjjc.node.AReturnStmt
00268  */
00269 public void caseAReturnStmt(AReturnStmt node) {
00270     if (postSet.size() > 0) {
00271         ca.mcgill.sable.util.LinkedList list = new ca.mcgill.sable.util.LinkedList();
00272         
00273         PExp exp = null;
00274         if (type != null) {
00275             exp = (PExp) node.getExp().clone();
00276         }
00277         
00278         if (hasRet) {
00279             exp = new AAssignmentExp(new ANameLeftHandSide(new ASimpleName(new TId("$ret"))), new AAssignAssignmentOperator(new TAssign()), exp);
00280             list.addFirst(new AStmtBlockedStmt(new AExpStmt(exp, new TSemicolon())));
00281             exp = new ANameExp(new ASimpleName(new TId("$ret")));
00282         }
00283 
00284         for (Iterator i = postSet.iterator(); i.hasNext();) {
00285             PostAssertion a = (PostAssertion) i.next();
00286             PName name = new AQualifiedName(new ASimpleName(new TId("Bandera")), new TDot(), new TId("assert"));
00287             PExp exp2 = new ANameMethodInvocationExp(name, new TLPar(), buildArgumentList(a), new TRPar());
00288             PStmt stmt = new AExpStmt(exp2, new TSemicolon());
00289             list.addLast(new AStmtBlockedStmt(stmt));
00290         }
00291 
00292         list.addLast(new AStmtBlockedStmt(new AReturnStmt(node.getReturn(), exp, node.getSemicolon())));
00293         
00294         ABlock block = new ABlock(new TLBrace(), list, new TRBrace());
00295         node.replaceBy(new ABlockStmt(block));
00296     }
00297     super.caseAReturnStmt(node);
00298 }
00299 /**
00300  * 
00301  * @param node edu.ksu.cis.bandera.jjjc.node.ATypedMethodHeader
00302  */
00303 public void caseATypedMethodHeader(ATypedMethodHeader node) {
00304     type = (PType) node.getType().clone();
00305     super.caseATypedMethodHeader(node);
00306 }
00307 /**
00308  *
00309  * @return java.util.Hashtable
00310  * @param assertionTable java.util.Hashtable
00311  */
00312 public static Hashtable process(Hashtable assertionTable) {
00313     modifiedMethodTable = new Hashtable();
00314     AssertionProcessor.assertionTable = assertionTable;
00315 
00316     HashSet methodAnnotationSet = new HashSet();
00317     
00318     for (Enumeration e = assertionTable.keys(); e.hasMoreElements();) {
00319         Annotation a = ((Assertion) e.nextElement()).getAnnotation();
00320 
00321         if (a instanceof LabeledStmtAnnotation) {
00322             a = CompilationManager.getAnnotationManager().getMethodAnnotationContainingAnnotation(a);
00323         }
00324 
00325         methodAnnotationSet.add(a);
00326     }
00327 
00328 
00329     StringBuffer sb = new StringBuffer();
00330     for (Iterator i = methodAnnotationSet.iterator(); i.hasNext();) {
00331         preSet = new HashSet();
00332         locationTable = new Hashtable();
00333         postSet = new HashSet();
00334         Annotation a = (Annotation) i.next();
00335 
00336         for (Enumeration e = assertionTable.keys(); e.hasMoreElements();) {
00337             Assertion as = (Assertion) e.nextElement();
00338             if (as.getExceptions().size() > 0) {
00339                 sb.append("In '" + as + "':\n");
00340                 for (Iterator j = as.getExceptions().iterator(); j.hasNext();) {
00341                     sb.append("* " + ((Exception) j.next()).getMessage() + "\n");
00342                 }
00343             }
00344             Annotation a2 = as.getAnnotation();
00345             if (a2 instanceof LabeledStmtAnnotation) {
00346                 a2 = CompilationManager.getAnnotationManager().getMethodAnnotationContainingAnnotation(a2);
00347             }
00348             if (a == a2) {
00349                 if (as instanceof PreAssertion) {
00350                     preSet.add(as);
00351                 } else if (as instanceof LocationAssertion) {
00352                     String label = ((LocationAssertion) as).getLabel();
00353                     if (locationTable.get(label) == null) {
00354                         locationTable.put(label, new HashSet());
00355                     }
00356                     ((HashSet) locationTable.get(label)).add(as);
00357                 } else {
00358                     postSet.add(as);
00359                 }
00360             }
00361         }
00362 
00363         String s = sb.toString();
00364         if (s.length() != 0)
00365             throw new RuntimeException(s.substring(0, s.length() - 1));
00366 
00367         type = null;
00368         currentAnnotation = a;
00369         a.getNode().apply(processor);
00370     }
00371     return modifiedMethodTable;
00372 }
00373 }

Generated at Thu Feb 7 06:39:48 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001