You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by en...@apache.org on 2022/01/04 21:09:58 UTC

[netbeans] branch master updated: Be able to resolve project problems in VSCode extension. (#3400)

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

entl 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 8b9e822  Be able to resolve project problems in VSCode extension. (#3400)
8b9e822 is described below

commit 8b9e822e3aee7ea3d8c47cc0f271d80f86eaad65
Author: Martin Entlicher <Ma...@oracle.com>
AuthorDate: Tue Jan 4 22:09:38 2022 +0100

    Be able to resolve project problems in VSCode extension. (#3400)
---
 .../org/netbeans/modules/gradle/GradleProject.java | 10 ++--
 .../gradle/GradleProjectProblemProvider.java       | 17 ++++--
 .../hints/infrastructure/JavaErrorProvider.java    | 11 +++-
 .../modules/java/lsp/server/protocol/Server.java   |  5 ++
 .../server/protocol/TextDocumentServiceImpl.java   |  2 +-
 .../lsp/server/protocol/WorkspaceServiceImpl.java  | 62 ++++++++++++++++++++++
 java/java.lsp.server/vscode/package.json           | 18 +++----
 7 files changed, 105 insertions(+), 20 deletions(-)

diff --git a/extide/gradle/src/org/netbeans/modules/gradle/GradleProject.java b/extide/gradle/src/org/netbeans/modules/gradle/GradleProject.java
index b0c4276..ed731a0 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/GradleProject.java
+++ b/extide/gradle/src/org/netbeans/modules/gradle/GradleProject.java
@@ -101,11 +101,15 @@ public final class GradleProject implements Serializable, Lookup.Provider {
     }
 
     public final GradleProject invalidate(String... reasons) {
+        Set<String> problems = reasons.length > 0 ? new LinkedHashSet<>(Arrays.asList(reasons)) : Collections.emptySet();
         if (getQuality().worseThan(Quality.EVALUATED)) {
-            return this;
+            if (!problems.isEmpty()) {
+                return new GradleProject(getQuality(), problems, this);
+            } else {
+                return this;
+            }
         } else {
-            Set<String> p = new LinkedHashSet<>(Arrays.asList(reasons));
-            return new GradleProject(Quality.EVALUATED, p, this);
+            return new GradleProject(Quality.EVALUATED, problems, this);
         }
     }
 
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/GradleProjectProblemProvider.java b/extide/gradle/src/org/netbeans/modules/gradle/GradleProjectProblemProvider.java
index b6b7b24..2b53729 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/GradleProjectProblemProvider.java
+++ b/extide/gradle/src/org/netbeans/modules/gradle/GradleProjectProblemProvider.java
@@ -26,6 +26,7 @@ import java.beans.PropertyChangeSupport;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Future;
 import org.netbeans.api.project.Project;
 import org.netbeans.spi.project.ProjectServiceProvider;
@@ -81,10 +82,11 @@ public class GradleProjectProblemProvider implements ProjectProblemsProvider {
         GradleProject gp = project.getLookup().lookup(NbGradleProjectImpl.class).getGradleProject();
         if (gp.getQuality().notBetterThan(EVALUATED)) {
             ret.add(ProjectProblem.createError(Bundle.LBL_PrimingRequired(), Bundle.TXT_PrimingRequired(), resolver));
-        }
-        for (String problem : gp.getProblems()) {
-            String[] lines = problem.split("\\n"); //NOI18N
-            ret.add(ProjectProblem.createWarning(lines[0], problem.replaceAll("\\n", "<br/>"), resolver)); //NOI18N
+        } else {
+            for (String problem : gp.getProblems()) {
+                String[] lines = problem.split("\\n"); //NOI18N
+                ret.add(ProjectProblem.createWarning(lines[0], problem.replaceAll("\\n", "<br/>"), resolver)); //NOI18N
+            }
         }
         return ret;
     }
@@ -98,7 +100,12 @@ public class GradleProjectProblemProvider implements ProjectProblemsProvider {
                 Quality q = gradleProject.getQuality();
                 Status st = q.worseThan(SIMPLE) ? Status.UNRESOLVED
                         : q.worseThan(FULL) ? Status.RESOLVED_WITH_WARNING : Status.RESOLVED;
-                return Result.create(st);
+                Set<String> problems = gradleProject.getProblems();
+                if (problems.isEmpty()) {
+                    return Result.create(st);
+                } else {
+                    return Result.create(st, problems.iterator().next());
+                }
             });
        }
     }
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/infrastructure/JavaErrorProvider.java b/java/java.hints/src/org/netbeans/modules/java/hints/infrastructure/JavaErrorProvider.java
index 2b6c246..d882cb4 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/infrastructure/JavaErrorProvider.java
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/infrastructure/JavaErrorProvider.java
@@ -147,7 +147,13 @@ public class JavaErrorProvider implements ErrorProvider {
                 default: diagBuilder.setSeverity(Diagnostic.Severity.Information); break;
             }
 
-            String id = key(errorKind) + ":" + idx++ + "-" + err.getId();
+            String rangeString;
+            try {
+                rangeString = (range.getBegin().getLine()+1) + ":" + (range.getBegin().getColumn()+1) + "-" + (range.getEnd().getLine()+1) + ":" + (range.getEnd().getColumn()+1);
+            } catch (IOException ex) {
+                rangeString = null;
+            }
+            String id = key(errorKind) + "(" + ++idx + "): " + (rangeString != null ? rangeString : "");
 
             diagBuilder.setCode(id);
             diagBuilder.addActions(errorReporter -> convertFixes(err, errorReporter));
@@ -185,7 +191,8 @@ public class JavaErrorProvider implements ErrorProvider {
 
         for (Fix f : fixes) {
             if (f instanceof IncompleteClassPath.ResolveFix) {
-                CodeAction action = new CodeAction(f.getText(), new Command(f.getText(), "XXX"/*Server.JAVA_BUILD_WORKSPACE*/));
+                // We know that this is a project problem and that the problems reported by ProjectProblemsProvider should be resolved
+                CodeAction action = new CodeAction(f.getText(), new Command(f.getText(), "java.project.resolveProjectProblems"));
                 result.add(action);
             }
             if (f instanceof ImportClass.FixImport) {
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 3694598..b6c1e05 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
@@ -709,6 +709,7 @@ public final class Server {
                         JAVA_NEW_FROM_TEMPLATE,
                         JAVA_NEW_PROJECT,
                         JAVA_PROJECT_CONFIGURATION_COMPLETION,
+                        JAVA_PROJECT_RESOLVE_PROJECT_PROBLEMS,
                         JAVA_SUPER_IMPLEMENTATION,
                         JAVA_SOURCE_FOR,
                         JAVA_CLEAR_PROJECT_CACHES,
@@ -882,6 +883,10 @@ public final class Server {
      * Provides code-completion of configurations.
      */
     public static final String JAVA_PROJECT_CONFIGURATION_COMPLETION = "java.project.configuration.completion";
+    /**
+     * Provides resolution of project problems.
+     */
+    public static final String JAVA_PROJECT_RESOLVE_PROJECT_PROBLEMS = "java.project.resolveProjectProblems";
 
 
     /**
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
index 6d23041..cccd478 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
@@ -895,7 +895,7 @@ public class TextDocumentServiceImpl implements TextDocumentService, LanguageCli
                             }
                             action.setKind(kind(err.getSeverity()));
                             if (inputAction.getCommand() != null) {
-                                action.setCommand(new Command(inputAction.getCommand().getTitle(), inputAction.getCommand().getCommand()));
+                                action.setCommand(new Command(inputAction.getCommand().getTitle(), inputAction.getCommand().getCommand(), Arrays.asList(params.getTextDocument().getUri())));
                             }
                             if (inputAction.getEdit() != null) {
                                 org.netbeans.api.lsp.WorkspaceEdit edit = inputAction.getEdit();
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 f30099a..103fc47 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
@@ -40,12 +40,15 @@ import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.BiConsumer;
@@ -111,6 +114,9 @@ import org.netbeans.spi.project.ActionProgress;
 import org.netbeans.spi.project.ActionProvider;
 import org.netbeans.spi.project.ProjectConfiguration;
 import org.netbeans.spi.project.ProjectConfigurationProvider;
+import org.netbeans.spi.project.ui.ProjectProblemsProvider;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
 import org.openide.filesystems.FileObject;
 import org.openide.filesystems.URLMapper;
 import org.openide.util.Exceptions;
@@ -485,6 +491,62 @@ public final class WorkspaceServiceImpl implements WorkspaceService, LanguageCli
                         .thenApply(avoid -> completionFutures.stream().flatMap(c -> c.join().stream()).collect(Collectors.toList()));
                 return (CompletableFuture<Object>) (CompletableFuture<?>) joinedFuture;
             }
+            case Server.JAVA_PROJECT_RESOLVE_PROJECT_PROBLEMS: {
+                final CompletableFuture<Object> result = new CompletableFuture<>();
+                List<Object> arguments = params.getArguments();
+                if (!arguments.isEmpty()) {
+                    String fileStr = ((JsonPrimitive) arguments.get(0)).getAsString();
+                    FileObject file;
+                    try {
+                        file = URLMapper.findFileObject(URI.create(fileStr).toURL());
+                    } catch (MalformedURLException ex) {
+                        result.completeExceptionally(ex);
+                        return result;
+                    }
+                    Project project = FileOwnerQuery.getOwner(file);
+                    if (project != null) {
+                        ProjectProblemsProvider ppp = project.getLookup().lookup(ProjectProblemsProvider.class);
+                        if (ppp != null) {
+                            Collection<? extends ProjectProblemsProvider.ProjectProblem> problems = ppp.getProblems();
+                            if (!problems.isEmpty()) {
+                                WORKER.post(() -> {
+                                    List<Pair<ProjectProblemsProvider.ProjectProblem, Future<ProjectProblemsProvider.Result>>> resolvers = new LinkedList<>();
+                                    for (ProjectProblemsProvider.ProjectProblem problem : ppp.getProblems()) {
+                                        if (problem.isResolvable()) {
+                                            resolvers.add(Pair.of(problem, problem.resolve()));
+                                        } else {
+                                            DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(problem.getDescription(), NotifyDescriptor.Message.ERROR_MESSAGE));
+                                        }
+                                    }
+                                    if (!resolvers.isEmpty()) {
+                                        for (Pair<ProjectProblemsProvider.ProjectProblem, Future<ProjectProblemsProvider.Result>> resolver : resolvers) {
+                                            try {
+                                                if (!resolver.second().get().isResolved()) {
+                                                    String message = resolver.second().get().getMessage();
+                                                    if (message != null) {
+                                                        DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(message, NotifyDescriptor.Message.ERROR_MESSAGE));
+                                                    }
+                                                }
+                                            } catch (ExecutionException ex) {
+                                                result.completeExceptionally(ex.getCause());
+                                            } catch (InterruptedException ex) {
+                                                result.complete(false);
+                                                break;
+                                            }
+                                        }
+                                    }
+                                    if (!result.isDone()) {
+                                        result.complete(true);
+                                    }
+                                });
+                            }
+                        }
+                    }
+                } else {
+                    result.completeExceptionally(new IllegalStateException("Expecting file URL as an argument to " + command));
+                }
+                return result;
+            }
             case Server.JAVA_CLEAR_PROJECT_CACHES: {
                 // politely clear project manager's cache of "no project" answers
                 ProjectManager.getDefault().clearNonProjectCache();
diff --git a/java/java.lsp.server/vscode/package.json b/java/java.lsp.server/vscode/package.json
index 6bb6c22..b786ba9 100644
--- a/java/java.lsp.server/vscode/package.json
+++ b/java/java.lsp.server/vscode/package.json
@@ -415,7 +415,7 @@
 				"command": "java.workspace.newproject",
 				"title": "New Project...",
 				"category": "Java",
-				"icon" : "$(new-folder)"
+				"icon": "$(new-folder)"
 			},
 			{
 				"command": "java.goto.super.implementation",
@@ -431,11 +431,11 @@
 				"command": "foundProjects.deleteEntry",
 				"title": "Delete"
 			},
-                        {
-                                "command": "db.add.connection",
-                                "title": "Add Database Connection",
- 				"category": "Database"
-                        },
+			{
+				"command": "db.add.connection",
+				"title": "Add Database Connection",
+				"category": "Database"
+			},
 			{
 				"command": "nbls:Database:netbeans.db.explorer.action.Connect",
 				"title": "Connect to Database"
@@ -494,8 +494,8 @@
 				"command": "java.workspace.configureRunSettings",
 				"title": "Edit",
 				"icon": "$(edit)"
-            },
-            {
+			},
+			{
 				"command": "testing.runAll",
 				"title": "Run All Tests",
 				"category": "Test"
@@ -606,7 +606,7 @@
 					"command": "workbench.action.debug.start",
 					"when": "nbJavaLSReady && view == foundProjects"
 				}
-				],
+			],
 			"view/item/context": [
 				{
 					"command": "foundProjects.deleteEntry",

---------------------------------------------------------------------
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