You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by db...@apache.org on 2021/05/25 11:03:14 UTC

[netbeans] branch master updated: LSP: Get project source roots, classpath, and packages commands added. (#2971)

This is an automated email from the ASF dual-hosted git repository.

dbalek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 6cd1a36  LSP: Get project source roots, classpath, and packages commands added. (#2971)
6cd1a36 is described below

commit 6cd1a36fcdbed041817b17080fb5c78819b807d4
Author: Dusan Balek <du...@oracle.com>
AuthorDate: Tue May 25 13:02:41 2021 +0200

    LSP: Get project source roots, classpath, and packages commands added. (#2971)
---
 .../modules/java/lsp/server/protocol/Server.java   |  7 +-
 .../lsp/server/protocol/WorkspaceServiceImpl.java  | 68 +++++++++++++++
 .../vscode/src/test/suite/extension.test.ts        | 96 ++++++++++++++++++++++
 3 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
index dc73b10..cb184b2 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
@@ -606,7 +606,9 @@ public final class Server {
                 capabilities.setImplementationProvider(true);
                 capabilities.setDocumentHighlightProvider(true);
                 capabilities.setReferencesProvider(true);
-                List<String> commands = new ArrayList<>(Arrays.asList(JAVA_NEW_FROM_TEMPLATE, JAVA_BUILD_WORKSPACE, JAVA_LOAD_WORKSPACE_TESTS, GRAALVM_PAUSE_SCRIPT, JAVA_SUPER_IMPLEMENTATION, JAVA_FIND_CONFIGURATIONS));
+                List<String> commands = new ArrayList<>(Arrays.asList(JAVA_NEW_FROM_TEMPLATE, JAVA_BUILD_WORKSPACE, JAVA_GET_PROJECT_SOURCE_ROOTS,
+                        JAVA_GET_PROJECT_CLASSPATH, JAVA_GET_PROJECT_PACKAGES,JAVA_LOAD_WORKSPACE_TESTS, GRAALVM_PAUSE_SCRIPT, JAVA_SUPER_IMPLEMENTATION,
+                        JAVA_FIND_CONFIGURATIONS));
                 for (CodeGenerator codeGenerator : Lookup.getDefault().lookupAll(CodeGenerator.class)) {
                     commands.addAll(codeGenerator.getCommands());
                 }
@@ -719,6 +721,9 @@ public final class Server {
     
     public static final String JAVA_BUILD_WORKSPACE =  "java.build.workspace";
     public static final String JAVA_NEW_FROM_TEMPLATE =  "java.new.from.template";
+    public static final String JAVA_GET_PROJECT_SOURCE_ROOTS = "java.get.project.source.roots";
+    public static final String JAVA_GET_PROJECT_CLASSPATH = "java.get.project.classpath";
+    public static final String JAVA_GET_PROJECT_PACKAGES = "java.get.project.packages";
     public static final String JAVA_LOAD_WORKSPACE_TESTS =  "java.load.workspace.tests";
     public static final String JAVA_SUPER_IMPLEMENTATION =  "java.super.implementation";
     public static final String GRAALVM_PAUSE_SCRIPT =  "graalvm.pause.script";
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
index 642ad4e..8fe666d 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
@@ -30,6 +30,7 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -59,7 +60,9 @@ import org.netbeans.api.annotations.common.NullAllowed;
 import org.netbeans.api.debugger.ActionsManager;
 import org.netbeans.api.debugger.DebuggerManager;
 import org.netbeans.api.java.project.JavaProjectConstants;
+import org.netbeans.api.java.queries.SourceForBinaryQuery;
 import org.netbeans.api.java.queries.UnitTestForSourceQuery;
+import org.netbeans.api.java.source.ClassIndex;
 import org.netbeans.api.java.source.ClasspathInfo;
 import org.netbeans.api.java.source.CompilationController;
 import org.netbeans.api.java.source.CompilationInfo;
@@ -136,6 +139,48 @@ public final class WorkspaceServiceImpl implements WorkspaceService, LanguageCli
                 progressOfCompilation.checkStatus();
                 return progressOfCompilation.getFinishFuture();
             }
+            case Server.JAVA_GET_PROJECT_SOURCE_ROOTS: {
+                String uri = ((JsonPrimitive) params.getArguments().get(0)).getAsString();
+                String type = params.getArguments().size() > 1 ? ((JsonPrimitive) params.getArguments().get(1)).getAsString() : JavaProjectConstants.SOURCES_TYPE_JAVA;
+                return getSourceRoots(uri, type).thenApply(roots -> {
+                    return roots.stream().map(root -> Utils.toUri(root)).collect(Collectors.toList());
+                });
+            }
+            case Server.JAVA_GET_PROJECT_CLASSPATH: {
+                String uri = ((JsonPrimitive) params.getArguments().get(0)).getAsString();
+                ClasspathInfo.PathKind kind = params.getArguments().size() > 1 ? ClasspathInfo.PathKind.valueOf(((JsonPrimitive) params.getArguments().get(1)).getAsString()) : ClasspathInfo.PathKind.COMPILE;
+                boolean preferSources = params.getArguments().size() > 2 ? ((JsonPrimitive) params.getArguments().get(2)).getAsBoolean() : false;
+                return getSourceRoots(uri, JavaProjectConstants.SOURCES_TYPE_JAVA).thenApply(roots -> {
+                    HashSet<FileObject> cpRoots = new HashSet<>();
+                    for(FileObject root : roots) {
+                        for (FileObject cpRoot : ClasspathInfo.create(root).getClassPath(kind).getRoots()) {
+                            FileObject[] srcRoots = preferSources ? SourceForBinaryQuery.findSourceRoots(cpRoot.toURL()).getRoots() : null;
+                            if (srcRoots != null && srcRoots.length > 0) {
+                                for (FileObject srcRoot : srcRoots) {
+                                    cpRoots.add(srcRoot);
+                                }
+                            } else {
+                                cpRoots.add(cpRoot);
+                            }
+                        }
+                    }
+                    return cpRoots.stream().map(fo -> Utils.toUri(fo)).collect(Collectors.toList());
+                });
+            }
+            case Server.JAVA_GET_PROJECT_PACKAGES: {
+                String uri = ((JsonPrimitive) params.getArguments().get(0)).getAsString();
+                boolean srcOnly = params.getArguments().size() > 1 ? ((JsonPrimitive) params.getArguments().get(1)).getAsBoolean() : false;
+                return getSourceRoots(uri, JavaProjectConstants.SOURCES_TYPE_JAVA).thenApply(roots -> {
+                    HashSet<String> packages = new HashSet<>();
+                    EnumSet<ClassIndex.SearchScope> scope = srcOnly ? EnumSet.of(ClassIndex.SearchScope.SOURCE) : EnumSet.allOf(ClassIndex.SearchScope.class);
+                    for(FileObject root : roots) {
+                        packages.addAll(ClasspathInfo.create(root).getClassIndex().getPackageNames("", false, scope));
+                    }
+                    ArrayList<String> ret = new ArrayList<>(packages);
+                    Collections.sort(ret);
+                    return ret;
+                });
+            }
             case Server.JAVA_LOAD_WORKSPACE_TESTS: {
                 String uri = ((JsonPrimitive) params.getArguments().get(0)).getAsString();
                 FileObject file;
@@ -211,6 +256,29 @@ public final class WorkspaceServiceImpl implements WorkspaceService, LanguageCli
         });
     }
 
+    private CompletableFuture<List<FileObject>> getSourceRoots(String uri, String type) {
+        FileObject file;
+        try {
+            file = URLMapper.findFileObject(new URL(uri));
+        } catch (MalformedURLException ex) {
+            Exceptions.printStackTrace(ex);
+            return CompletableFuture.completedFuture(Collections.emptyList());
+        }
+        if (file == null) {
+            return CompletableFuture.completedFuture(Collections.emptyList());
+        }
+        return server.asyncOpenFileOwner(file).thenApply(project -> {
+            if (project != null) {
+                List<FileObject> roots = new ArrayList<>();
+                for(SourceGroup sourceGroup : ProjectUtils.getSources(project).getSourceGroups(type)) {
+                    roots.add(sourceGroup.getRootFolder());
+                }
+                return roots;
+            }
+            return Collections.emptyList();
+        });
+    }
+
     private CompletableFuture<Set<URL>> getTestRootURLs(Project prj) {
         final Set<URL> testRootURLs = new HashSet<>();
         List<FileObject> contained = null;
diff --git a/java/java.lsp.server/vscode/src/test/suite/extension.test.ts b/java/java.lsp.server/vscode/src/test/suite/extension.test.ts
index 5f4e7ec..9a54548 100644
--- a/java/java.lsp.server/vscode/src/test/suite/extension.test.ts
+++ b/java/java.lsp.server/vscode/src/test/suite/extension.test.ts
@@ -206,6 +206,102 @@ class Main {
     }
 
     test("Maven run termination", async() => mavenTerminateWithoutDebugger());
+
+    async function getProjectInfo() {
+        let folder: string = assertWorkspace();
+
+        await fs.promises.writeFile(path.join(folder, 'pom.xml'), `
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.netbeans.demo.vscode.t1</groupId>
+    <artifactId>basicapp</artifactId>
+    <version>1.0</version>
+    <properties>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+    </properties>
+</project>
+		`);
+
+        let pkg = path.join(folder, 'src', 'main', 'java', 'pkg');
+        let resources = path.join(folder, 'src', 'main', 'resources');
+        let mainJava = path.join(pkg, 'Main.java');
+
+        await fs.promises.mkdir(pkg, { recursive: true });
+        await fs.promises.mkdir(resources, { recursive: true });
+
+        await fs.promises.writeFile(mainJava, `
+package pkg;
+class Main {
+	public static void main(String... args) {
+		System.out.println("Hello World!");
+	}
+}
+		`);
+
+        vscode.workspace.saveAll();
+
+        try {
+            console.log("Test: get project java source roots");
+            let res: any = await vscode.commands.executeCommand("java.get.project.source.roots", Uri.file(folder).toString());
+            console.log(`Test: get project java source roots finished with ${res}`);
+            assert.ok(res, "No java source root rertuned");
+            assert.strictEqual(res.length, 1, `Invalid number of java roots returned`);
+            assert.strictEqual(res[0], path.join('file:', folder, 'src', 'main', 'java') + path.sep, `Invalid java source root returned`);
+
+            console.log("Test: get project resource roots");
+            res = await vscode.commands.executeCommand("java.get.project.source.roots", Uri.file(folder).toString(), 'resources');
+            console.log(`Test: get project resource roots finished with ${res}`);
+            assert.ok(res, "No resource root returned");
+            assert.strictEqual(res.length, 1, `Invalid number of resource roots returned`);
+            assert.strictEqual(res[0], path.join('file:', resources) + path.sep, `Invalid resource root returned`);
+
+            console.log("Test: get project compile classpath");
+            res = await vscode.commands.executeCommand("java.get.project.classpath", Uri.file(folder).toString());
+            console.log(`Test: get project compile classpath finished with ${res}`);
+            assert.ok(res, "No compile classpath returned");
+            assert.strictEqual(res.length, 1, `Invalid number of compile classpath roots returned`);
+            assert.strictEqual(res[0], path.join('file:', folder, 'target', 'classes') + path.sep, `Invalid compile classpath root returned`);
+
+            console.log("Test: get project source classpath");
+            res = await vscode.commands.executeCommand("java.get.project.classpath", Uri.file(folder).toString(), 'SOURCE');
+            console.log(`Test: get project source classpath finished with ${res}`);
+            assert.ok(res, "No source classpath returned");
+            assert.strictEqual(res.length, 1, `Invalid number of source classpath roots returned`);
+            assert.strictEqual(res[0], path.join('file:', folder, 'src', 'main', 'java') + path.sep, `Invalid source classpath root returned`);
+
+            console.log("Test: get project boot classpath");
+            res = await vscode.commands.executeCommand("java.get.project.classpath", Uri.file(folder).toString(), 'BOOT');
+            console.log(`Test: get project boot classpath finished with ${res}`);
+            assert.ok(res, "No boot classpath returned");
+            assert.ok(res.length > 0, `Invalid number of boot classpath roots returned`);
+
+            console.log("Test: get project boot source classpath");
+            res = await vscode.commands.executeCommand("java.get.project.classpath", Uri.file(folder).toString(), 'BOOT', true);
+            console.log(`Test: get project boot source classpath finished with ${res}`);
+            assert.ok(res, "No boot source classpath returned");
+            assert.ok(res.length > 0, `Invalid number of boot source classpath roots returned`);
+
+            console.log("Test: get all project packages");
+            res = await vscode.commands.executeCommand("java.get.project.packages", Uri.file(folder).toString());
+            console.log(`Test: get all project packages finished with ${res}`);
+            assert.ok(res, "No packages returned");
+            assert.ok(res.length > 0, `Invalid number of packages returned`);
+
+            console.log("Test: get project source packages");
+            res = await vscode.commands.executeCommand("java.get.project.packages", Uri.file(folder).toString(), true);
+            console.log(`Test: get project source packages finished with ${res}`);
+            assert.ok(res, "No packages returned");
+            assert.strictEqual(res.length, 1, `Invalid number of packages returned`);
+            assert.strictEqual(res[0], 'pkg', `Invalid package returned`);
+        } catch (error) {
+            dumpJava();
+            throw error;
+        }
+    }
+
+    test("Get project sources, classpath, and packages", async() => getProjectInfo());
+
 });
 
 function assertWorkspace(): string {

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists