diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/symbols/BootJavaWorkspaceSymbolHandler.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/symbols/BootJavaWorkspaceSymbolHandler.java index 1ee07e364..7504c0564 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/symbols/BootJavaWorkspaceSymbolHandler.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/symbols/BootJavaWorkspaceSymbolHandler.java @@ -3,6 +3,7 @@ package org.springframework.ide.vscode.boot.java.symbols; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Stream; @@ -12,39 +13,47 @@ import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.MarkerAnnotation; import org.eclipse.jdt.core.dom.NormalAnnotation; import org.eclipse.jdt.core.dom.SingleMemberAnnotation; +import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.SymbolInformation; +import org.eclipse.lsp4j.SymbolKind; import org.eclipse.lsp4j.WorkspaceSymbolParams; import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; -import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.languageserver.util.WorkspaceSymbolHandler; +import org.springframework.ide.vscode.commons.util.text.LanguageId; +import org.springframework.ide.vscode.commons.util.text.TextDocument; public class BootJavaWorkspaceSymbolHandler implements WorkspaceSymbolHandler { private SimpleLanguageServer server; private JavaProjectFinder projectFinder; + private List symbols; + public BootJavaWorkspaceSymbolHandler(BootJavaLanguageServer server, JavaProjectFinder projectFinder) { this.server = server; this.projectFinder = projectFinder; + this.symbols = new ArrayList<>(); } @Override public List handle(WorkspaceSymbolParams params) { Path root = this.server.getWorkspaceRoot(); + symbols.clear(); scanFiles(root.toFile()); return collectSymbols(); } private List collectSymbols() { - return SimpleTextDocumentService.NO_SYMBOLS; + return symbols; } private void scanFiles(File directory) { @@ -65,75 +74,125 @@ public class BootJavaWorkspaceSymbolHandler implements WorkspaceSymbolHandler { private void scanProject(IJavaProject project, File directory) { try { ASTParser parser = ASTParser.newParser(AST.JLS8); - Map options = JavaCore.getOptions(); - JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options); - parser.setCompilerOptions(options); - parser.setKind(ASTParser.K_COMPILATION_UNIT); - parser.setStatementsRecovery(true); - parser.setBindingsRecovery(true); - parser.setResolveBindings(true); - String[] classpathEntries = getClasspathEntries(project); - String[] sourceEntries = new String[] {}; - parser.setEnvironment(classpathEntries, sourceEntries, null, true); - - scanFiles(parser, directory); - + scanFiles(parser, directory, classpathEntries); } catch (Exception e) { e.printStackTrace(); } } - private void scanFiles(ASTParser parser, File directory) throws Exception { + private void scanFiles(ASTParser parser, File directory, String[] classpathEntries) throws Exception { File[] javaFiles = directory.listFiles((file) -> file.getName().endsWith(".java")); for (File javaFile : javaFiles) { if (javaFile.isFile() && javaFile.exists()) { - scanFile(parser, javaFile); + scanFile(parser, javaFile, classpathEntries); } } File[] directories = directory.listFiles((file) -> file.isDirectory() && file.exists()); for (File dir : directories) { - scanFiles(parser, dir); + scanFiles(parser, dir, classpathEntries); } } - private void scanFile(ASTParser parser, File javaFile) throws Exception { - + private void scanFile(ASTParser parser, File javaFile, String[] classpathEntries) throws Exception { Path path = javaFile.toPath(); - String unitName = path.getFileName().toString(); + String unitName = "/" + path.getFileName().toString(); parser.setUnitName(unitName); String content = new String(Files.readAllBytes(path)); parser.setSource(content.toCharArray()); + Map options = JavaCore.getOptions(); + JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options); + parser.setCompilerOptions(options); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setStatementsRecovery(true); + parser.setBindingsRecovery(true); + parser.setResolveBindings(true); + + String[] sourceEntries = new String[] {}; + parser.setEnvironment(classpathEntries, sourceEntries, null, true); + CompilationUnit cu = (CompilationUnit) parser.createAST(null); if (cu != null) { System.out.println("AST node found: " + cu.getClass().getName()); - scanAST(cu); + + String docURI = "file://" + javaFile.getAbsolutePath(); + TextDocument doc = new TextDocument(docURI, LanguageId.PLAINTEXT, 0, content); + + scanAST(cu, doc); } } - private void scanAST(CompilationUnit cu) { + private void scanAST(CompilationUnit cu, TextDocument doc) { cu.accept(new ASTVisitor() { @Override public boolean visit(SingleMemberAnnotation node) { - System.out.println("annotation found: " + node.toString()); + try { + System.out.println("annotation found: " + node.toString()); + ITypeBinding typeBinding = node.resolveTypeBinding(); + + if (typeBinding != null) { + String qualifiedTypeName = typeBinding.getQualifiedName(); + if (qualifiedTypeName.startsWith("org.springframework.")) { + SymbolInformation symbol = new SymbolInformation(node.toString(), SymbolKind.Interface, + new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()))); + symbols.add(symbol); + } + } + } + catch (Exception e) { + e.printStackTrace(); + } + return super.visit(node); } @Override public boolean visit(NormalAnnotation node) { - System.out.println("annotation found: " + node.toString()); + try { + System.out.println("annotation found: " + node.toString()); + ITypeBinding typeBinding = node.resolveTypeBinding(); + + if (typeBinding != null) { + String qualifiedTypeName = typeBinding.getQualifiedName(); + if (qualifiedTypeName.startsWith("org.springframework.")) { + SymbolInformation symbol = new SymbolInformation(node.toString(), SymbolKind.Interface, + new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()))); + symbols.add(symbol); + } + } + } + catch (Exception e) { + e.printStackTrace(); + } + return super.visit(node); } @Override public boolean visit(MarkerAnnotation node) { - System.out.println("annotation found: " + node.toString()); + try { + System.out.println("annotation found: " + node.toString()); + ITypeBinding typeBinding = node.resolveTypeBinding(); + + if (typeBinding != null) { + String qualifiedTypeName = typeBinding.getQualifiedName(); + if (qualifiedTypeName.startsWith("org.springframework.")) { + SymbolInformation symbol = new SymbolInformation(node.toString(), SymbolKind.Interface, + new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()))); + symbols.add(symbol); + } + } + } + catch (Exception e) { + e.printStackTrace(); + } + return super.visit(node); } });