1 4 package net.sourceforge.pmd.symboltable; 5 6 import net.sourceforge.pmd.ast.ASTName; 7 import net.sourceforge.pmd.ast.SimpleNode; 8 import net.sourceforge.pmd.util.Applier; 9 10 import java.util.ArrayList ; 11 import java.util.HashMap ; 12 import java.util.Iterator ; 13 import java.util.List ; 14 import java.util.Map ; 15 16 public class ClassScope extends AbstractScope { 17 18 protected Map classNames = new HashMap (); 19 protected Map methodNames = new HashMap (); 20 protected Map variableNames = new HashMap (); 21 22 private static int anonymousInnerClassCounter = 1; 24 private String className; 25 26 public ClassScope(String className) { 27 this.className = className; 28 anonymousInnerClassCounter = 1; 29 } 30 31 38 public ClassScope() { 39 this.className = "Anonymous$" + anonymousInnerClassCounter; 41 anonymousInnerClassCounter++; 42 } 43 44 public void addDeclaration(VariableNameDeclaration variableDecl) { 45 if (variableNames.containsKey(variableDecl)) { 46 throw new RuntimeException (variableDecl + " is already in the symbol table"); 47 } 48 variableNames.put(variableDecl, new ArrayList ()); 49 } 50 51 public NameDeclaration addVariableNameOccurrence(NameOccurrence occurrence) { 52 NameDeclaration decl = findVariableHere(occurrence); 53 if (decl != null && occurrence.isMethodOrConstructorInvocation()) { 54 List nameOccurrences = (List ) methodNames.get(decl); 55 if (nameOccurrences == null) { 56 } else { 58 nameOccurrences.add(occurrence); 59 SimpleNode n = occurrence.getLocation(); 60 if (n instanceof ASTName) { 61 ((ASTName) n).setNameDeclaration(decl); 62 } } 64 65 } else if (decl != null && !occurrence.isThisOrSuper()) { 66 List nameOccurrences = (List ) variableNames.get(decl); 67 if (nameOccurrences == null) { 68 } else { 70 nameOccurrences.add(occurrence); 71 SimpleNode n = occurrence.getLocation(); 72 if (n instanceof ASTName) { 73 ((ASTName) n).setNameDeclaration(decl); 74 } } 76 } 77 return decl; 78 } 79 80 public Map getVariableDeclarations() { 81 VariableUsageFinderFunction f = new VariableUsageFinderFunction(variableNames); 82 Applier.apply(f, variableNames.keySet().iterator()); 83 return f.getUsed(); 84 } 85 86 public Map getMethodDeclarations() { 87 return methodNames; 88 } 89 90 public Map getClassDeclarations() { 91 return classNames; 92 } 93 94 public ClassScope getEnclosingClassScope() { 95 return this; 96 } 97 98 public String getClassName() { 99 return this.className; 100 } 101 102 public void addDeclaration(MethodNameDeclaration decl) { 103 methodNames.put(decl, new ArrayList ()); 104 } 105 106 public void addDeclaration(ClassNameDeclaration decl) { 107 classNames.put(decl, new ArrayList ()); 108 } 109 110 protected NameDeclaration findVariableHere(NameOccurrence occurrence) { 111 if (occurrence.isThisOrSuper() || occurrence.getImage().equals(className)) { 112 if (variableNames.isEmpty() && methodNames.isEmpty()) { 113 return null; 118 } 119 if (!variableNames.isEmpty()) { 128 return (NameDeclaration) variableNames.keySet().iterator().next(); 129 } 130 return (NameDeclaration) methodNames.keySet().iterator().next(); 131 } 132 133 if (occurrence.isMethodOrConstructorInvocation()) { 134 for (Iterator i = methodNames.keySet().iterator(); i.hasNext();) { 135 MethodNameDeclaration mnd = (MethodNameDeclaration) i.next(); 136 if (mnd.getImage().equals(occurrence.getImage())) { 137 int args = occurrence.getArgumentCount(); 138 if (args == mnd.getParameterCount()) { 139 return mnd; 144 } 145 } 146 } 147 return null; 148 } 149 150 List images = new ArrayList (); 151 images.add(occurrence.getImage()); 152 if (occurrence.getImage().startsWith(className)) { 153 images.add(clipClassName(occurrence.getImage())); 154 } 155 ImageFinderFunction finder = new ImageFinderFunction(images); 156 Applier.apply(finder, variableNames.keySet().iterator()); 157 return finder.getDecl(); 158 } 159 160 public String toString() { 161 String res = "ClassScope (" + className + "): "; 162 if (!classNames.isEmpty()) res += "(" + glomNames(classNames.keySet().iterator()) + ")"; 163 if (!methodNames.isEmpty()) { 164 Iterator i = methodNames.keySet().iterator(); 165 while (i.hasNext()) { 166 MethodNameDeclaration mnd = (MethodNameDeclaration) i.next(); 167 res += mnd.toString(); 168 int usages = ((List ) methodNames.get(mnd)).size(); 169 res += "(begins at line " + mnd.getNode().getBeginLine() + ", " + usages + " usages)"; 170 res += ","; 171 } 172 } 173 if (!variableNames.isEmpty()) res += "(" + glomNames(variableNames.keySet().iterator()) + ")"; 174 return res; 175 } 176 177 private String clipClassName(String in) { 178 return in.substring(in.indexOf('.') + 1); 179 } 180 } 181 | Popular Tags |