KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > toolkits > astmetrics > StmtSumWeightedByDepth


1 package soot.toolkits.astmetrics;
2
3 import java.util.*;
4 import polyglot.ast.*;
5 import polyglot.visit.NodeVisitor;
6
7 public class StmtSumWeightedByDepth extends ASTMetric {
8   
9   int currentDepth;
10   int sum;
11   int maxDepth;
12   int numNodes;
13   //int returnSum;
14

15   Stack labelNodesSoFar = new Stack();
16   ArrayList blocksWithAbruptFlow = new ArrayList();
17   
18   public static boolean tmpAbruptChecker = false;
19   
20   public StmtSumWeightedByDepth(Node node){
21     super(node);
22   }
23   
24   
25   public void reset() {
26     currentDepth = 1; //inside a class
27
maxDepth = 1;
28     sum = 0;
29     numNodes = 0;
30     //returnSum =0;
31
}
32   
33   public void addMetrics(ClassData data) {
34     data.addMetric(new MetricData("MaxDepth",new Integer JavaDoc(maxDepth)));
35     data.addMetric(new MetricData("D-W-Complexity",new Integer JavaDoc(sum)));
36     data.addMetric(new MetricData("AST-Node-Count",new Integer JavaDoc(numNodes)));
37     //data.addMetric(new MetricData("Return-Depth-Sum",new Integer(returnSum)));
38
}
39   
40   private void increaseDepth(){
41     currentDepth++;
42     if(currentDepth > maxDepth)
43       maxDepth = currentDepth;
44   }
45   
46   private void decreaseDepth(){
47     currentDepth--;
48   }
49   
50   
51   /*
52    * List of Node types which increase depth of traversal!!!
53    * Any construct where one can have a { } increases the depth
54    * hence even though if(cond) stmt doesnt expicitly use a block
55    * its depth is still +1 when executing the stmt
56    *
57    * If the "if" stmt has code if(cond) { stmt } OR if(cond) stmt this will only increase the depth by 1 (ignores compound stmt blocks)
58    *
59    * If, Loop, Try, Synch, ProcDecl, Init, Switch, LocalClassDecl .... add currentDepth to sum and then increase depth by one
60    * irrespective of how many stmts there are in the body
61    *
62    * Block ... if it is a block within a block, add currentDepth plus increment depth ONLY if it has abrupt flow out of it.
63    */

64   public NodeVisitor enter(Node parent, Node n){
65     numNodes++;
66     if (n instanceof CodeDecl) {
67       // maintain stack of label arrays (can't have label from inside method to outside)
68
labelNodesSoFar.push(new ArrayList());
69     }
70     else if (n instanceof Labeled) {
71       // add any labels we find to the array
72
((ArrayList)labelNodesSoFar.peek()).add(((Labeled)n).label());
73     }
74     
75     if(n instanceof If || n instanceof Loop || n instanceof Try || n instanceof Switch
76         || n instanceof LocalClassDecl || n instanceof Synchronized
77         || n instanceof ProcedureDecl || n instanceof Initializer ){
78       sum += currentDepth*2;
79       increaseDepth();
80     } else if (parent instanceof Block && n instanceof Block) {
81       StmtSumWeightedByDepth.tmpAbruptChecker = false;
82       n.visit(new NodeVisitor() {
83         // extended NodeVisitor that checks for branching out of a block
84
public NodeVisitor enter(Node parent, Node node){
85           if(node instanceof Branch) {
86             Branch b = (Branch)node;
87             // null branching out of a plain block is NOT ALLOWED!
88
if (b.label() != null && ((ArrayList)labelNodesSoFar.peek()).contains(b.label()))
89             {
90               StmtSumWeightedByDepth.tmpAbruptChecker = true;
91             }
92           }
93           return enter(node);
94         }
95         // this method simply stops further node visiting if we found our info
96
public Node override(Node parent, Node node) {
97           if (StmtSumWeightedByDepth.tmpAbruptChecker)
98             return node;
99           return null;
100         }
101       });
102       
103       if (StmtSumWeightedByDepth.tmpAbruptChecker)
104       {
105         blocksWithAbruptFlow.add(n);
106         sum += currentDepth*2;
107         increaseDepth();
108       }
109     } else {
110       //if(n instanceof Return){
111
// returnSum += currentDepth;
112
// System.out.println("RETURN111111111111111111111111111111111"+currentDepth);
113
//}
114
sum+= currentDepth;
115     }
116     
117     return enter(n);
118   }
119   
120   
121   public Node leave(Node old, Node n, NodeVisitor v){
122     
123     // stack maintenance, if leaving a method
124
if (n instanceof CodeDecl)
125       labelNodesSoFar.pop();
126     
127     if(n instanceof If || n instanceof Loop || n instanceof Try || n instanceof Switch
128         || n instanceof LocalClassDecl || n instanceof Synchronized
129         || n instanceof ProcedureDecl || n instanceof Initializer ) {
130       decreaseDepth();
131     } else if (n instanceof Block && blocksWithAbruptFlow.contains(n)) {
132       decreaseDepth();
133     }
134     return n;
135   }
136 }
137
Popular Tags