import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
+import java.util.Vector;
+import IR.AnnotationDescriptor;
import IR.ClassDescriptor;
import IR.MethodDescriptor;
import IR.Operation;
import IR.Tree.OpNode;
import IR.Tree.ReturnNode;
import IR.Tree.SubBlockNode;
+import IR.Tree.SwitchBlockNode;
+import IR.Tree.SwitchStatementNode;
import IR.Tree.TertiaryNode;
import Util.Pair;
ClassDescriptor cd = (ClassDescriptor) obj;
toanalyze.remove(cd);
- if (!cd.isInterface()) {
+ if (!ssjava.isSSJavaUtil(cd) && !cd.isInterface()) {
for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
MethodDescriptor md = (MethodDescriptor) method_it.next();
+ checkTrustworthyMethodAnnotation(md);
checkMethodBody(cd, md);
}
}
for (Iterator iterator = annotatedMDSet.iterator(); iterator.hasNext();) {
MethodDescriptor md = (MethodDescriptor) iterator.next();
- ssjava.addAnnotationRequire(md);
+ if (!ssjava.isTrustMethod(md)) {
+ ssjava.addAnnotationRequire(md);
+ }
}
Set<Pair> visited = new HashSet<Pair>();
if (!visited.contains(p)) {
visited.add(p);
- if (calleeMD.getClassDesc().isInterface()) {
- calleeMD.getClassDesc();
-
- }
-
- tovisit.add(calleeMD);
+ if (!ssjava.isTrustMethod(callerMD) && !ssjava.isTrustMethod(calleeMD)) {
+ // if method is annotated as "TRUST", do not need to check for
+ // linear type & flow-down rule
+ tovisit.add(calleeMD);
- if (calleeMD.isAbstract()) {
Set<MethodDescriptor> possibleCalleeSet =
(Set<MethodDescriptor>) ssjava.getCallGraph().getMethods(calleeMD);
for (Iterator iterator2 = possibleCalleeSet.iterator(); iterator2.hasNext();) {
MethodDescriptor possibleCallee = (MethodDescriptor) iterator2.next();
- if (!possibleCallee.isAbstract()) {
+ if (!possibleCallee.isAbstract() && !possibleCallee.getModifiers().isNative()) {
ssjava.addAnnotationRequire(possibleCallee);
tovisit.add(possibleCallee);
}
-
}
-
- } else {
- ssjava.addAnnotationRequire(calleeMD);
}
}
}
+ private void checkTrustworthyMethodAnnotation(MethodDescriptor md) {
+ // method annotation parsing
+ Vector<AnnotationDescriptor> methodAnnotations = md.getModifiers().getAnnotations();
+ if (methodAnnotations != null) {
+ for (int i = 0; i < methodAnnotations.size(); i++) {
+ AnnotationDescriptor an = methodAnnotations.elementAt(i);
+ if (an.getMarker().equals(ssjava.TRUST)) {
+ ssjava.addTrustMethod(md);
+ }
+ }
+ }
+ }
+
public void methodAnnoataionInheritanceCheck() {
// check If a method is annotated, any method that overrides it should
// be annotated.
}
}
}
+
+ // need to check super classess if the current method is inherited from
+ // them, all of ancestor method should be annotated.
+
+ ClassDescriptor curClassDesc;
+ ClassDescriptor parentClassDesc = cd;
+
+ while (!parentClassDesc.getSymbol().equals("Object")) {
+ curClassDesc = parentClassDesc;
+ parentClassDesc = tu.getSuper(curClassDesc);
+ Set possiblematches = parentClassDesc.getMethodTable().getSet(md.getSymbol());
+ for (Iterator methodit = possiblematches.iterator(); methodit.hasNext();) {
+ MethodDescriptor matchmd = (MethodDescriptor) methodit.next();
+ if (md.matches(matchmd)) {
+ ssjava.addAnnotationRequire(matchmd);
+ }
+ }
+ }
+
+ Set<ClassDescriptor> superIFSet = tu.getSuperIFs(cd);
+ for (Iterator iterator = superIFSet.iterator(); iterator.hasNext();) {
+ ClassDescriptor parentInterface = (ClassDescriptor) iterator.next();
+ Set possiblematches = parentInterface.getMethodTable().getSet(md.getSymbol());
+ for (Iterator methodit = possiblematches.iterator(); methodit.hasNext();) {
+ MethodDescriptor matchmd = (MethodDescriptor) methodit.next();
+ if (md.matches(matchmd)) {
+ ssjava.addAnnotationRequire(matchmd);
+ }
+ }
+ }
+
}
}
private void checkBlockNode(MethodDescriptor md, SymbolTable nametable, BlockNode bn, boolean flag) {
bn.getVarTable().setParent(nametable);
- String label = bn.getLabel();
- boolean isSSJavaLoop = flag;
- if (label != null && label.equals(ssjava.SSJAVA)) {
- if (isSSJavaLoop) {
- throw new Error("Only outermost loop can be the self-stabilizing loop.");
- } else {
- annotatedMDSet.add(md);
- isSSJavaLoop = true;
- }
- }
for (int i = 0; i < bn.size(); i++) {
BlockStatementNode bsn = bn.get(i);
- checkBlockStatementNode(md, bn.getVarTable(), bsn, isSSJavaLoop);
+ checkBlockStatementNode(md, bn.getVarTable(), bsn, flag);
}
}
checkReturnNode(md, nametable, (ReturnNode) bsn, flag);
break;
+ case Kind.SwitchStatementNode:
+ checkSwitchStatementNode(md, nametable, (SwitchStatementNode) bsn, flag);
+ return;
+
}
}
+ private void checkSwitchStatementNode(MethodDescriptor md, SymbolTable nametable,
+ SwitchStatementNode ssn, boolean flag) {
+
+ checkExpressionNode(md, nametable, ssn.getCondition(), flag);
+
+ BlockNode sbn = ssn.getSwitchBody();
+ for (int i = 0; i < sbn.size(); i++) {
+ checkBlockNode(md, nametable, ((SwitchBlockNode) sbn.get(i)).getSwitchBlockStatement(), flag);
+ }
+
+ }
+
private void checkDeclarationNode(MethodDescriptor md, SymbolTable nametable, DeclarationNode dn,
boolean flag) {
if (dn.getExpression() != null) {
}
private void checkLoopNode(MethodDescriptor md, SymbolTable nametable, LoopNode ln, boolean flag) {
+
+ String label = ln.getLabel();
+ boolean isSSJavaLoop = flag;
+ if (label != null && label.equals(ssjava.SSJAVA)) {
+ if (isSSJavaLoop) {
+ throw new Error("Only outermost loop can be the self-stabilizing loop.");
+ } else {
+ ssjava.setMethodContainingSSJavaLoop(md);
+ annotatedMDSet.add(md);
+ isSSJavaLoop = true;
+ }
+ }
+
if (ln.getType() == LoopNode.WHILELOOP || ln.getType() == LoopNode.DOWHILELOOP) {
- checkExpressionNode(md, nametable, ln.getCondition(), flag);
- checkBlockNode(md, nametable, ln.getBody(), flag);
+ checkExpressionNode(md, nametable, ln.getCondition(), isSSJavaLoop);
+ checkBlockNode(md, nametable, ln.getBody(), isSSJavaLoop);
} else {
// For loop case
/* Link in the initializer naming environment */
bn.getVarTable().setParent(nametable);
for (int i = 0; i < bn.size(); i++) {
BlockStatementNode bsn = bn.get(i);
- checkBlockStatementNode(md, bn.getVarTable(), bsn, flag);
+ checkBlockStatementNode(md, bn.getVarTable(), bsn, isSSJavaLoop);
}
// check the condition
- checkExpressionNode(md, bn.getVarTable(), ln.getCondition(), flag);
- checkBlockNode(md, bn.getVarTable(), ln.getBody(), flag);
- checkBlockNode(md, bn.getVarTable(), ln.getUpdate(), flag);
+ checkExpressionNode(md, bn.getVarTable(), ln.getCondition(), isSSJavaLoop);
+ checkBlockNode(md, bn.getVarTable(), ln.getBody(), isSSJavaLoop);
+ checkBlockNode(md, bn.getVarTable(), ln.getUpdate(), isSSJavaLoop);
}
}