00001 package edu.ksu.cis.bandera.specification.assertion.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 edu.ksu.cis.bandera.specification.assertion.datastructure.*;
00036 import edu.ksu.cis.bandera.annotation.*;
00037 import edu.ksu.cis.bandera.jjjc.symboltable.*;
00038 import edu.ksu.cis.bandera.specification.assertion.analysis.*;
00039 import edu.ksu.cis.bandera.specification.assertion.exception.*;
00040 import edu.ksu.cis.bandera.specification.assertion.node.*;
00041 import java.lang.reflect.*;
00042 import java.util.*;
00043 public class AssertionBuilder extends DepthFirstAdapter {
00044 private Node node;
00045 private SymbolTable symbolTable;
00046 private Annotation annotation;
00047 private ClassOrInterfaceType type;
00048 private boolean isStatic;
00049 private Vector labeledStmtAnnotations;
00050 private String name;
00051 private StringBuffer buffer;
00052 private boolean hasRet;
00053 public boolean isVoid;
00054 private int modifiers;
00055
00056
00057
00058
00059
00060
00061 public AssertionBuilder(Node node, SymbolTable symbolTable, ClassOrInterfaceType type, Annotation annotation) {
00062 this.node = node;
00063 this.symbolTable = symbolTable;
00064 this.annotation = annotation;
00065 this.type = type;
00066 Vector v = annotation.getAllAnnotations(false);
00067 labeledStmtAnnotations = new Vector();
00068 for (Enumeration e = v.elements(); e.hasMoreElements();) {
00069 Object o = e.nextElement();
00070 if (o instanceof LabeledStmtAnnotation) labeledStmtAnnotations.add(o);
00071 }
00072 if (annotation instanceof MethodDeclarationAnnotation) {
00073 isStatic = java.lang.reflect.Modifier.isStatic(((MethodDeclarationAnnotation) annotation).getMethod().getModifiers());
00074 } else {
00075 isStatic = false;
00076 }
00077 }
00078
00079
00080
00081 public void build() {
00082 node.apply(this);
00083 }
00084
00085
00086
00087
00088 public void caseAEndOfLineComment(AEndOfLineComment node) {
00089 buffer.append(node.toString().trim().substring(2));
00090 }
00091
00092
00093
00094
00095 public void caseALocationAssertion(ALocationAssertion node) {
00096 buffer = new StringBuffer();
00097 Object temp[] = node.getComment().toArray();
00098 for (int i = 0; i < temp.length; i++) {
00099 ((PComment) temp[i]).apply(this);
00100 }
00101 Vector v = new Vector();
00102
00103 if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
00104 v.add(new BadAssertionDefinitionException("Cannot have location assertion for an abstract/native method"));
00105 }
00106
00107 String label = node.getLabel().toString().trim();
00108 boolean found = false;
00109 Annotation currentAnnotation = annotation;
00110 for (Enumeration e = labeledStmtAnnotations.elements(); e.hasMoreElements();) {
00111 LabeledStmtAnnotation lsa = (LabeledStmtAnnotation) e.nextElement();
00112 if (lsa.getId().equals(label)) {
00113 currentAnnotation = lsa;
00114 found = true;
00115 break;
00116 }
00117 }
00118 if (!found) {
00119 v.add(new BadAssertionDefinitionException("Invalid label '" + label + "'"));
00120 }
00121 try {
00122 Assertion assertion = new LocationAssertion(currentAnnotation, new Name(name + "." + node.getId()), node.getExp(), v, label);
00123 assertion.setDescription(buffer.toString());
00124 v.addAll(new TypeChecker(symbolTable, type, currentAnnotation, isStatic).check(node.getExp()));
00125 } catch (Exception e) {
00126 v.add(e);
00127 }
00128 }
00129
00130
00131
00132
00133 public void caseAPostAssertion(APostAssertion node) {
00134 buffer = new StringBuffer();
00135 Object temp[] = node.getComment().toArray();
00136 for (int i = 0; i < temp.length; i++) {
00137 ((PComment) temp[i]).apply(this);
00138 }
00139 hasRet = false;
00140 node.getExp().apply(new edu.ksu.cis.bandera.jjjc.analysis.DepthFirstAdapter() {
00141 public void caseANameExp(edu.ksu.cis.bandera.jjjc.node.ANameExp node) {
00142 String s = node.toString().trim();
00143 if ("$ret".equals(s)) {
00144 hasRet = true;
00145 }
00146 }
00147 });
00148 Vector v = new Vector();
00149 if (isVoid && hasRet) {
00150 v.add(new BadAssertionDefinitionException("Cannot have $ret in void method or constructor"));
00151 }
00152 try {
00153 Assertion assertion = new PostAssertion(annotation, new Name(name + "." + node.getId()), node.getExp(), v, hasRet);
00154 assertion.setDescription(buffer.toString());
00155 v.addAll(new TypeChecker(symbolTable, type, annotation, isStatic).check(node.getExp()));
00156 } catch (Exception e) {
00157 v.add(e);
00158 }
00159 }
00160
00161
00162
00163
00164 public void caseAPreAssertion(APreAssertion node) {
00165 buffer = new StringBuffer();
00166 Object temp[] = node.getComment().toArray();
00167 for (int i = 0; i < temp.length; i++) {
00168 ((PComment) temp[i]).apply(this);
00169 }
00170 Vector v = new Vector();
00171 try {
00172 Assertion assertion = new PreAssertion(annotation, new Name(name + "." + node.getId()), node.getExp(), v);
00173 assertion.setDescription(buffer.toString());
00174 v.addAll(new TypeChecker(symbolTable, type, annotation, isStatic).check(node.getExp()));
00175 } catch (Exception e) {
00176 v.add(e);
00177 }
00178 }
00179
00180
00181
00182
00183 public void caseAUnit(AUnit node) {
00184 if(node.getName() != null) {
00185 name = new Name(node.getName().toString()).toString().trim();
00186 } else {
00187 if (annotation instanceof MethodDeclarationAnnotation) {
00188 MethodDeclarationAnnotation mda = (MethodDeclarationAnnotation) annotation;
00189 isVoid = "void".equals(mda.getMethod().getReturnType().toString().trim());
00190 modifiers = mda.getMethod().getModifiers();
00191 try {
00192 name = mda.getMethod().getDeclaringClassOrInterface().getFullyQualifiedName()
00193 + "." + mda.getMethod().getName().toString();
00194 } catch (Exception e) {
00195 throw new RuntimeException("Fatal Error");
00196 }
00197 } else {
00198 isVoid = true;
00199 ConstructorDeclarationAnnotation cda = (ConstructorDeclarationAnnotation) annotation;
00200 modifiers = cda.getConstructor().getModifiers();
00201 try {
00202 name = cda.getConstructor().getDeclaringClassOrInterface().getFullyQualifiedName()
00203 + "." + cda.getConstructor().getDeclaringClassOrInterface().getName().getLastIdentifier();
00204 } catch (Exception e) {
00205 throw new RuntimeException("Fatal Error");
00206 }
00207 }
00208 }
00209 super.caseAUnit(node);
00210 }
00211 }