Clover coverage report - PMD - 3.3
Coverage timestamp: Thu Sep 15 2005 17:59:57 EDT
file stats: LOC: 216   Methods: 20
NCLOC: 137   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ScopeAndDeclarationFinder.java 100% 100% 100% 100%
coverage
 1    /**
 2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 3    */
 4    package net.sourceforge.pmd.symboltable;
 5   
 6    import net.sourceforge.pmd.ast.ASTBlock;
 7    import net.sourceforge.pmd.ast.ASTCatchStatement;
 8    import net.sourceforge.pmd.ast.ASTClassOrInterfaceBodyDeclaration;
 9    import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
 10    import net.sourceforge.pmd.ast.ASTCompilationUnit;
 11    import net.sourceforge.pmd.ast.ASTConstructorDeclaration;
 12    import net.sourceforge.pmd.ast.ASTEnumDeclaration;
 13    import net.sourceforge.pmd.ast.ASTFinallyStatement;
 14    import net.sourceforge.pmd.ast.ASTForStatement;
 15    import net.sourceforge.pmd.ast.ASTIfStatement;
 16    import net.sourceforge.pmd.ast.ASTMethodDeclaration;
 17    import net.sourceforge.pmd.ast.ASTMethodDeclarator;
 18    import net.sourceforge.pmd.ast.ASTPackageDeclaration;
 19    import net.sourceforge.pmd.ast.ASTSwitchStatement;
 20    import net.sourceforge.pmd.ast.ASTTryStatement;
 21    import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
 22    import net.sourceforge.pmd.ast.JavaParserVisitorAdapter;
 23    import net.sourceforge.pmd.ast.Node;
 24    import net.sourceforge.pmd.ast.SimpleNode;
 25   
 26    import java.util.List;
 27    import java.util.Stack;
 28   
 29    /**
 30    * Visitor for scope creation.
 31    * Visits all nodes of an AST and creates scope objects for nodes representing
 32    * syntactic entities which may contain declarations. For example, a block
 33    * may contain variable definitions (which are declarations) and
 34    * therefore needs a scope object where these declarations can be associated,
 35    * whereas an expression can't contain declarations and therefore doesn't need
 36    * a scope object.
 37    * With the exception of global scopes, each scope object is linked to its
 38    * parent scope, which is the scope object of the next embedding syntactic
 39    * entity that has a scope.
 40    */
 41    public class ScopeAndDeclarationFinder extends JavaParserVisitorAdapter {
 42   
 43    /**
 44    * A stack of scopes reflecting the scope hierarchy when a node is visited.
 45    * This is used to set the parents of the created scopes correctly.
 46    */
 47    private Stack scopes = new Stack();
 48   
 49    /**
 50    * Sets the scope of a node and adjustes the scope stack accordingly.
 51    * The scope on top of the stack is set as the parent of the given scope,
 52    * which is then also stored on the scope stack.
 53    * @param newScope the scope for the node.
 54    * @param node the AST node for which the scope is to be set.
 55    * @throws java.util.EmptyStackException if the scope stack is empty.
 56    */
 57  2956 private void addScope(Scope newScope, SimpleNode node) {
 58  2956 newScope.setParent((Scope)scopes.peek());
 59  2956 scopes.push(newScope);
 60  2956 node.setScope(newScope);
 61    }
 62   
 63    /**
 64    * Creates a new local scope for an AST node.
 65    * The scope on top of the stack is set as the parent of the new scope,
 66    * which is then also stored on the scope stack.
 67    * @param node the AST node for which the scope has to be created.
 68    * @throws java.util.EmptyStackException if the scope stack is empty.
 69    */
 70  1290 private void createLocalScope(SimpleNode node) {
 71  1290 addScope(new LocalScope(), node);
 72    }
 73   
 74    /**
 75    * Creates a new method scope for an AST node.
 76    * The scope on top of the stack is set as the parent of the new scope,
 77    * which is then also stored on the scope stack.
 78    * @param node the AST node for which the scope has to be created.
 79    * @throws java.util.EmptyStackException if the scope stack is empty.
 80    */
 81  772 private void createMethodScope(SimpleNode node) {
 82  772 addScope(new MethodScope(node), node);
 83    }
 84   
 85    /**
 86    * Creates a new class scope for an AST node.
 87    * The scope on top of the stack is set as the parent of the new scope,
 88    * which is then also stored on the scope stack.
 89    * @param node the AST node for which the scope has to be created.
 90    * @throws java.util.EmptyStackException if the scope stack is empty.
 91    */
 92  894 private void createClassScope(SimpleNode node) {
 93  894 if (node instanceof ASTClassOrInterfaceBodyDeclaration){
 94  9 addScope(new ClassScope(), node);
 95    }
 96    else {
 97  885 addScope(new ClassScope(node.getImage()), node);
 98    }
 99    }
 100   
 101    /**
 102    * Creates a new global scope for an AST node.
 103    * The new scope is stored on the scope stack.
 104    * @param node the AST node for which the scope has to be created.
 105    */
 106  831 private void createSourceFileScope(SimpleNode node) {
 107    // When we do full symbol resolution, we'll need to add a truly top-level GlobalScope.
 108  831 Scope scope;
 109  831 List packages = node.findChildrenOfType(ASTPackageDeclaration.class);
 110  831 if (!packages.isEmpty()) {
 111  12 Node n = (Node)packages.get(0);
 112  12 scope = new SourceFileScope(((SimpleNode)n.jjtGetChild(0)).getImage());
 113    } else {
 114  819 scope = new SourceFileScope();
 115    }
 116  831 scopes.push(scope);
 117  831 node.setScope(scope);
 118    }
 119   
 120  831 public Object visit(ASTCompilationUnit node, Object data) {
 121  831 createSourceFileScope(node);
 122  831 cont(node);
 123  831 return data;
 124    }
 125   
 126  883 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
 127  883 createClassScope(node);
 128  883 Scope s = ((SimpleNode)node.jjtGetParent()).getScope();
 129  883 s.addDeclaration(new ClassNameDeclaration(node));
 130  883 cont(node);
 131  883 return data;
 132    }
 133   
 134  2 public Object visit(ASTEnumDeclaration node, Object data) {
 135  2 createClassScope(node);
 136  2 cont(node);
 137  2 return data;
 138    }
 139   
 140  1131 public Object visit(ASTClassOrInterfaceBodyDeclaration node, Object data) {
 141  1131 if (node.isAnonymousInnerClass()) {
 142  9 createClassScope(node);
 143  9 cont(node);
 144    } else {
 145  1122 super.visit(node, data);
 146    }
 147  1131 return data;
 148    }
 149   
 150  975 public Object visit(ASTBlock node, Object data) {
 151  975 createLocalScope(node);
 152  975 cont(node);
 153  975 return data;
 154    }
 155   
 156  62 public Object visit(ASTCatchStatement node, Object data) {
 157  62 createLocalScope(node);
 158  62 cont(node);
 159  62 return data;
 160    }
 161   
 162  15 public Object visit(ASTFinallyStatement node, Object data) {
 163  15 createLocalScope(node);
 164  15 cont(node);
 165  15 return data;
 166    }
 167   
 168  85 public Object visit(ASTConstructorDeclaration node, Object data) {
 169  85 createMethodScope(node);
 170  85 cont(node);
 171  85 return data;
 172    }
 173   
 174  687 public Object visit(ASTMethodDeclaration node, Object data) {
 175  687 createMethodScope(node);
 176  687 ASTMethodDeclarator md = (ASTMethodDeclarator)node.getFirstChildOfType(ASTMethodDeclarator.class);
 177  687 node.getScope().getEnclosingClassScope().addDeclaration(new MethodNameDeclaration(md));
 178  687 cont(node);
 179  687 return data;
 180    }
 181   
 182  67 public Object visit(ASTTryStatement node, Object data) {
 183  67 createLocalScope(node);
 184  67 cont(node);
 185  67 return data;
 186    }
 187   
 188    // TODO - what about while loops and do loops?
 189  57 public Object visit(ASTForStatement node, Object data) {
 190  57 createLocalScope(node);
 191  57 cont(node);
 192  57 return data;
 193    }
 194   
 195  94 public Object visit(ASTIfStatement node, Object data) {
 196  94 createLocalScope(node);
 197  94 cont(node);
 198  94 return data;
 199    }
 200   
 201  842 public Object visit(ASTVariableDeclaratorId node, Object data) {
 202  842 node.getScope().addDeclaration(new VariableNameDeclaration(node));
 203  842 return super.visit(node, data);
 204    }
 205   
 206  20 public Object visit(ASTSwitchStatement node, Object data) {
 207  20 createLocalScope(node);
 208  20 cont(node);
 209  20 return data;
 210    }
 211   
 212  3787 private void cont(SimpleNode node) {
 213  3787 super.visit(node, null);
 214  3787 scopes.pop();
 215    }
 216    }