static boolean computeOccurrences()

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];
    }