1 19 20 package org.netbeans.api.java.source.query; 21 22 import org.netbeans.modules.java.source.engine.EngineEnvironment; 23 import org.netbeans.api.java.source.ElementUtilities; 24 import org.netbeans.api.java.source.query.ElementReferenceList; 25 import com.sun.source.tree.AssignmentTree; 26 import com.sun.source.tree.CompoundAssignmentTree; 27 import com.sun.source.tree.ExpressionTree; 28 import com.sun.source.tree.IdentifierTree; 29 import com.sun.source.tree.ImportTree; 30 import com.sun.source.tree.MemberSelectTree; 31 import com.sun.source.tree.MethodInvocationTree; 32 import com.sun.source.tree.MethodTree; 33 import com.sun.source.tree.NewArrayTree; 34 import com.sun.source.tree.NewClassTree; 35 import com.sun.source.tree.Tree; 36 import com.sun.source.tree.UnaryTree; 37 import com.sun.source.tree.VariableTree; 38 import com.sun.source.util.TreeScanner; 39 import java.util.HashMap ; 40 import java.util.Map ; 41 import java.util.Set ; 42 import javax.lang.model.element.Element; 43 import javax.lang.model.element.ExecutableElement; 44 import javax.lang.model.element.PackageElement; 45 import javax.lang.model.element.TypeElement; 46 import org.netbeans.modules.java.source.engine.EngineEnvironment; 47 import org.netbeans.modules.java.source.engine.ASTModel; 48 49 import static org.netbeans.api.java.source.query.UseFinder.*; 50 51 56 public class ReferenceFinder extends TreeScanner<Void ,Object > { 57 private ASTModel model; 58 private ElementUtilities elements; 59 private Element currentSym; 60 Map <Element, ElementReferenceList<Element>> elementReferences; 61 62 71 public static ReferenceFinder findReferences(QueryEnvironment env, Set <Element> elementSet, Tree root) { 72 ReferenceFinder finder = new ReferenceFinder(env, elementSet); 73 finder.scan(root, null); 74 return finder; 75 } 76 77 84 protected ReferenceFinder(QueryEnvironment env, Set <Element> elementSet) { 85 this.model = ((EngineEnvironment)env).getModel(); 86 elements = env.getElementUtilities(); 87 elementReferences = new HashMap <Element,ElementReferenceList<Element>>(); 88 for (Element e : elementSet) 89 elementReferences.put(e, new ElementReferenceList<Element>(e)); 90 } 91 92 103 public ElementReferenceList<Element> get(Element var) { 104 return elementReferences.get(var); 105 } 106 107 112 public boolean hasReferences(Element var) { 113 return elementReferences.containsKey(var); 114 } 115 116 120 @Override 121 public Void scan(Tree tree, Object p) { 122 if(tree != null) { 123 Tree.Kind kind = tree.getKind(); 124 boolean saveSymbol = 125 kind == Tree.Kind.CLASS || 126 kind == Tree.Kind.METHOD || 127 kind == Tree.Kind.VARIABLE; 128 Element sym = model.getElement(tree); 129 if (sym != null && saveSymbol) { 130 Element oldSym = currentSym; 131 currentSym = sym; 132 tree.accept(this, p); 133 currentSym = oldSym; 134 } 135 else 136 tree.accept(this, p); 137 } 138 return null; 139 } 140 141 142 private void add(Tree var, int usage) { 143 Element sym = model.getElement(var); 144 ElementReferenceList<Element> varRef = elementReferences.get(sym); 145 if (varRef == null) return; 147 if (currentSym == null) 148 149 throw new AssertionError ("no currentSym"); 150 TypeElement here = elements.enclosingTypeElement(currentSym); 151 PackageElement phere = elements.packageElement(here); 152 int flags = usage << 153 (here == varRef.varClass ? CLASSSHIFT 154 : phere == varRef.varPackage ? PACKAGESHIFT 155 : WORLDSHIFT); 156 varRef.addReference(currentSym, flags); 157 } 158 159 163 @Override 164 public Void visitAssignment(AssignmentTree tree, Object p) { 165 if (tree.getVariable() instanceof MemberSelectTree) { 166 MemberSelectTree t = (MemberSelectTree)tree.getVariable(); 167 add(t, SETUSE); 168 scan(t.getExpression(), p); 169 } else if (tree.getVariable() instanceof IdentifierTree) { 170 add(tree, SETUSE); 171 } else 172 scan(tree.getVariable(), p); 173 scan(tree.getExpression(), p); 174 return null; 175 } 176 177 181 @Override 182 public Void visitCompoundAssignment(CompoundAssignmentTree tree, Object p) { 183 if (tree.getVariable() instanceof MemberSelectTree) { 184 MemberSelectTree t = (MemberSelectTree)tree.getVariable(); 185 scan(t.getExpression(), p); 186 add(t, SETUSE | GETUSE); 187 } else if (tree.getVariable() instanceof IdentifierTree) { 188 add(tree, SETUSE | GETUSE); 189 } else 190 scan(tree.getVariable(), p); 191 scan(tree.getExpression(), p); 192 return null; 193 } 194 195 199 @Override 200 public Void visitUnary(UnaryTree tree, Object p) { 201 switch (tree.getKind()) { 202 case PREFIX_INCREMENT: 203 case PREFIX_DECREMENT: 204 case POSTFIX_INCREMENT: 205 case POSTFIX_DECREMENT: { 206 ExpressionTree expr = tree.getExpression(); 207 if (expr instanceof MemberSelectTree) { 208 scan(((MemberSelectTree)expr).getExpression(), p); 209 add(expr, SETUSE | GETUSE); 210 } else if (tree.getExpression() instanceof IdentifierTree) { 211 add(expr, SETUSE | GETUSE); 212 } else 213 scan(tree.getExpression(), p); 214 break; 215 } 216 default: 217 scan(tree.getExpression(), p); 218 } 219 return null; 220 } 221 222 226 @Override 227 public Void visitIdentifier(IdentifierTree tree, Object p) { 228 add(tree, GETUSE); 229 return super.visitIdentifier(tree, p); 230 } 231 232 236 @Override 237 public Void visitVariable(VariableTree tree, Object p) { 238 ElementReferenceList<Element> varRef = elementReferences.get(model.getElement(tree)); 239 if (varRef != null) { 240 int flags = DECLARATION; 241 if (tree.getInitializer() != null) 242 flags |= SETUSE << CLASSSHIFT; 243 varRef.addReference(currentSym, flags); 244 } 245 return super.visitVariable(tree, p); 246 } 247 248 252 @Override 253 public Void visitMethod(MethodTree tree, Object p) { 254 ExecutableElement e = (ExecutableElement)model.getElement(tree); 255 ElementReferenceList<Element> methodRefs = elementReferences.get(e); 256 if (methodRefs != null) 257 methodRefs.addReference(e, DECLARATION); 258 ExecutableElement superMethod = elements.getOverriddenMethod(e); 259 if (superMethod != null) { 260 methodRefs = elementReferences.get(superMethod); 261 if (methodRefs != null) 262 methodRefs.addReference(superMethod, GETUSE); 263 } 264 return super.visitMethod(tree, p); 265 } 266 267 271 @Override 272 public Void visitMethodInvocation(MethodInvocationTree tree, Object p) { 273 Tree method = tree.getMethodSelect(); 274 ElementReferenceList<Element> methodRef = elementReferences.get(model.getElement(method)); 275 if (methodRef != null) 276 methodRef.addReference(currentSym, GETUSE); 277 return super.visitMethodInvocation(tree, p); 278 } 279 280 284 @Override 285 public Void visitNewClass(NewClassTree tree, Object p) { 286 ElementReferenceList<Element> constructorRef = elementReferences.get(model.getElement(tree)); 287 if (constructorRef != null) 288 constructorRef.addReference(currentSym, GETUSE); 289 return super.visitNewClass(tree, p); 290 } 291 292 296 @Override 297 public Void visitNewArray(NewArrayTree tree, Object p) { 298 Tree type = tree.getType(); 299 if (type != null) { ElementReferenceList<Element> typeRef = elementReferences.get(model.getElement(type)); 301 if (typeRef != null) 302 typeRef.addReference(currentSym, GETUSE); 303 } 304 return super.visitNewArray(tree, p); 305 } 306 307 311 @Override 312 public Void visitMemberSelect(MemberSelectTree tree, Object p) { 313 add(tree, GETUSE); 314 return super.visitMemberSelect(tree, p); 315 } 316 317 321 @Override 322 public Void visitImport(ImportTree tree, Object p) { 323 return null; } 325 } 326 | Popular Tags |