/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.lang.java.symboltable; import java.util.Collections; import java.util.HashSet; import java.util.Set; import net.sourceforge.pmd.lang.symboltable.NameDeclaration; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; import net.sourceforge.pmd.lang.symboltable.Scope; public class Search { private static final boolean TRACE = false; private NameOccurrence occ; private Set<NameDeclaration> declarations = new HashSet<>(); public Search(JavaNameOccurrence occ) { if (TRACE) { System.out.println( "new search for " + (occ.isMethodOrConstructorInvocation() ? "method" : "variable") + " " + occ); } this.occ = occ; } public void execute() { Set<NameDeclaration> found = searchUpward(occ, occ.getLocation().getScope()); if (TRACE) { System.out.println("found " + found); } declarations.addAll(found); } public void execute(Scope startingScope) { Set<NameDeclaration> found = searchUpward(occ, startingScope); if (TRACE) { System.out.println("found " + found); } declarations.addAll(found); } public Set<NameDeclaration> getResult() { return declarations; } private Set<NameDeclaration> searchUpward(NameOccurrence nameOccurrence, Scope scope) { if (TRACE) { System.out.println(" checking scope " + scope + " for name occurrence " + nameOccurrence); } final boolean isInScope = scope.contains(nameOccurrence); if (!isInScope && scope.getParent() != null) { if (TRACE) { System.out.println(" moving up from " + scope + " to " + scope.getParent()); } return searchUpward(nameOccurrence, scope.getParent()); } if (isInScope) { if (TRACE) { System.out.println(" found it!"); } return scope.addNameOccurrence(nameOccurrence); } return Collections.emptySet(); } }