in remoting/ide/usages/src/org/netbeans/modules/jackpot30/ide/usages/Nodes.java [370:501]
static boolean computeOccurrences(FileObject file, final ElementHandle<?> eh, final Set<RemoteUsages.SearchOptions> options, final List<Node> toPopulate) {
final boolean[] success = new boolean[] {true};
try {
JavaSource.forFileObject(file).runUserActionTask(new Task<CompilationController>() {
@Override public void run(final CompilationController parameter) throws Exception {
parameter.toPhase(Phase.RESOLVED);
final Element toFind = eh.resolve(parameter);
if (toFind == null) {
return;
}
final AtomicBoolean stop = new AtomicBoolean();
new CancellableTreePathScanner<Void, Void>(stop) {
@Override public Void visitIdentifier(IdentifierTree node, Void p) {
handleNode(node.getName(), getCurrentPath().getLeaf());
return super.visitIdentifier(node, p);
}
@Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
handleNode(node.getIdentifier(), getCurrentPath().getLeaf());
return super.visitMemberSelect(node, p);
}
@Override public Void visitNewClass(NewClassTree node, Void p) {
Name simpleName = null;
Tree name = node.getIdentifier();
OUTER: while (true) {
switch (name.getKind()) {
case PARAMETERIZED_TYPE: name = ((ParameterizedTypeTree) name).getType(); break;
case MEMBER_SELECT: simpleName = ((MemberSelectTree) name).getIdentifier(); break OUTER;
case IDENTIFIER: simpleName = ((IdentifierTree) name).getName(); break OUTER;
default: name = node; break OUTER;
}
}
handleNode(simpleName, name);
return super.visitNewClass(node, p);
}
private void handleNode(Name simpleName, Tree toHighlight) {
if (!options.contains(RemoteUsages.SearchOptions.USAGES)) return;
Element el = parameter.getTrees().getElement(getCurrentPath());
if (el == null || el.asType().getKind() == TypeKind.ERROR) {
if (toFind.getSimpleName().equals(simpleName)) {
success[0] = false;
stop.set(true);
return; //TODO: correct? what about the second pass?
}
}
if (Nodes.equals(parameter, toFind, el)) {
toPopulate.add(new OccurrenceNode(parameter, toHighlight));
}
}
@Override
public Void visitMethod(MethodTree node, Void p) {
if (options.contains(RemoteUsages.SearchOptions.SUB) && toFind.getKind() == ElementKind.METHOD) {
boolean found = false;
Element el = parameter.getTrees().getElement(getCurrentPath());
if (el != null && el.getKind() == ElementKind.METHOD) {
if (parameter.getElements().overrides((ExecutableElement) el, (ExecutableElement) toFind, (TypeElement) el.getEnclosingElement())) {
toPopulate.add(new OccurrenceNode(parameter, node));
found = true;
}
}
if (!found && el != null && el.getSimpleName().contentEquals(toFind.getSimpleName())) {
for (TypeMirror sup : superTypes((TypeElement) el.getEnclosingElement())) {
if (sup.getKind() == TypeKind.ERROR) {
success[0] = false;
stop.set(true);
return null; //TODO: correct? what about the second pass?
}
}
}
}
return super.visitMethod(node, p);
}
@Override
public Void visitClass(ClassTree node, Void p) {
if (options.contains(RemoteUsages.SearchOptions.SUB) && (toFind.getKind().isClass() || toFind.getKind().isInterface())) {
Element el = parameter.getTrees().getElement(getCurrentPath());
boolean wasError = false;
for (TypeMirror sup : superTypes((TypeElement) el)) {
if (sup.getKind() == TypeKind.ERROR) {
wasError = true;
} else {
if (toFind.equals(parameter.getTypes().asElement(sup))) {
wasError = false;
toPopulate.add(new OccurrenceNode(parameter, node));
break;
}
}
}
if (wasError) {
success[0] = false;
stop.set(true);
return null; //TODO: correct? what about the second pass?
}
}
return super.visitClass(node, p);
}
private Set<TypeMirror> superTypes(TypeElement type) {
Set<TypeMirror> result = new HashSet<TypeMirror>();
List<TypeMirror> todo = new LinkedList<TypeMirror>();
todo.add(type.asType());
while (!todo.isEmpty()) {
List<? extends TypeMirror> directSupertypes = parameter.getTypes().directSupertypes(todo.remove(0));
todo.addAll(directSupertypes);
result.addAll(directSupertypes);
}
return result;
}
}.scan(parameter.getCompilationUnit(), null);
}
}, true);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return success[0];
}