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

jlahoda 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 2a7063a196 Adding ability to run OpenJDK's jtreg tests in VSCode using 
LSP's code lens
2a7063a196 is described below

commit 2a7063a196168bf578f5c78b2abd6ae516d8f9d5
Author: Jan Lahoda <[email protected]>
AuthorDate: Mon Jul 11 07:19:08 2022 +0200

    Adding ability to run OpenJDK's jtreg tests in VSCode using LSP's code lens
---
 ide/api.lsp/apichanges.xml                         |  13 ++
 .../api/lsp/{Command.java => CodeLens.java}        |  48 +++---
 ide/api.lsp/src/org/netbeans/api/lsp/Command.java  |  24 +++
 .../src/org/netbeans/spi/lsp/CodeLensProvider.java |  42 ++++++
 .../modules/java/lsp/server/protocol/Server.java   |  18 +++
 .../server/protocol/TextDocumentServiceImpl.java   | 161 +++++++++++++--------
 java/java.openjdk.project/nbproject/project.xml    |   9 ++
 .../release/scripts/build-generic.xml              |   1 +
 .../modules/java/openjdk/common/BuildUtils.java    |   4 +
 .../java/openjdk/jtreg/ActionProviderImpl.java     |  34 ++++-
 .../java/openjdk/jtreg/CodeLensProviderImpl.java   |  72 +++++++++
 .../java/openjdk/project/ActionProviderImpl.java   |   7 +
 .../modules/java/openjdk/project/Settings.java     |   2 +-
 13 files changed, 355 insertions(+), 80 deletions(-)

diff --git a/ide/api.lsp/apichanges.xml b/ide/api.lsp/apichanges.xml
index 323d4c53d3..967bc85ad4 100644
--- a/ide/api.lsp/apichanges.xml
+++ b/ide/api.lsp/apichanges.xml
@@ -51,6 +51,19 @@
 <!-- ACTUAL CHANGES BEGIN HERE: -->
 
 <changes>
+    <change id="CodeLensProvider">
+        <api name="LSP_API"/>
+        <summary>Added CodeLensProvider and relevant elements</summary>
+        <version major="1" minor="12"/>
+        <date day="2" month="7" year="2022"/>
+        <author login="jlahoda"/>
+        <compatibility binary="compatible" source="compatible" addition="yes" 
deletion="no"/>
+        <description>
+            <a 
href="@TOP@/org/netbeans/spi/lsp/CodeLensProvider.html">CodeLensProvider</a> 
SPI allows to provide code lens for a given document.
+        </description>
+        <class package="org.netbeans.api.lsp" name="CodeLens"/>
+        <class package="org.netbeans.spi.lsp" name="CodeLensProvider"/>
+    </change>
     <change id="diagnosticReporter">
         <api name="LSP_API"/>
         <summary>Added DiagnosticReporter to trigger diagnostic 
collection</summary>
diff --git a/ide/api.lsp/src/org/netbeans/api/lsp/Command.java 
b/ide/api.lsp/src/org/netbeans/api/lsp/CodeLens.java
similarity index 50%
copy from ide/api.lsp/src/org/netbeans/api/lsp/Command.java
copy to ide/api.lsp/src/org/netbeans/api/lsp/CodeLens.java
index f93a5bdb99..3765c6bc2a 100644
--- a/ide/api.lsp/src/org/netbeans/api/lsp/Command.java
+++ b/ide/api.lsp/src/org/netbeans/api/lsp/CodeLens.java
@@ -19,43 +19,53 @@
 package org.netbeans.api.lsp;
 
 /**
- * A command. The exact list of known commands depends on
- * the implementation of the server.
+ * Description of code lens from the LSP.
  *
- * @since 1.3
+ * @since 1.12
  */
-public class Command {
-
-    private final String title;
-    private final String command;
+public class CodeLens {
+    private final Range range;
+    private final Command command;
+    private final Object data;
 
     /**
-     * Construct a new {@code Command}.
+     * Create a new instance of CodeLens.
      *
-     * @param title the title of the command
-     * @param command the code of the command that should be invoked
+     * @param range the range of the code lens
+     * @param command the command associated with the lens
+     * @param data additional data
      */
-    public Command(String title, String command) {
-        this.title = title;
+    public CodeLens(Range range, Command command, Object data) {
+        this.range = range;
         this.command = command;
+        this.data = data;
     }
 
     /**
-     * The title of the command.
+     * Returns the range of the code lens.
      *
-     * @return the title of the command
+     * @return the range of the code lens
      */
-    public String getTitle() {
-        return title;
+    public Range getRange() {
+        return range;
     }
 
     /**
-     * The code of the command that should be invoked.
+     * Returns the command associated with the code lens.
      *
-     * @return the code of the command that should be invoked
+     * @return the command associated with the code lens
      */
-    public String getCommand() {
+    public Command getCommand() {
         return command;
     }
 
+    /**
+     * Returns additional data associated with the lens, if any.
+     *
+     * @return additional data associated with the lens
+     */
+    public Object getData() {
+        return data;
+    }
+
 }
diff --git a/ide/api.lsp/src/org/netbeans/api/lsp/Command.java 
b/ide/api.lsp/src/org/netbeans/api/lsp/Command.java
index f93a5bdb99..dfaff25166 100644
--- a/ide/api.lsp/src/org/netbeans/api/lsp/Command.java
+++ b/ide/api.lsp/src/org/netbeans/api/lsp/Command.java
@@ -18,6 +18,8 @@
  */
 package org.netbeans.api.lsp;
 
+import java.util.List;
+
 /**
  * A command. The exact list of known commands depends on
  * the implementation of the server.
@@ -28,6 +30,7 @@ public class Command {
 
     private final String title;
     private final String command;
+    private final List<Object> arguments;
 
     /**
      * Construct a new {@code Command}.
@@ -36,8 +39,20 @@ public class Command {
      * @param command the code of the command that should be invoked
      */
     public Command(String title, String command) {
+        this(title, command, null);
+    }
+
+    /**
+     * Construct a new {@code Command}.
+     *
+     * @param title the title of the command
+     * @param command the code of the command that should be invoked
+     * @param arguments command arguments
+     */
+    public Command(String title, String command, List<Object> arguments) {
         this.title = title;
         this.command = command;
+        this.arguments = arguments;
     }
 
     /**
@@ -58,4 +73,13 @@ public class Command {
         return command;
     }
 
+    /**
+     * The arguments of the command that should be invoked.
+     *
+     * @return the arguments of the command that should be invoked
+     */
+    public List<Object> getArguments() {
+        return arguments;
+    }
+
 }
diff --git a/ide/api.lsp/src/org/netbeans/spi/lsp/CodeLensProvider.java 
b/ide/api.lsp/src/org/netbeans/spi/lsp/CodeLensProvider.java
new file mode 100644
index 0000000000..c7d0954c5f
--- /dev/null
+++ b/ide/api.lsp/src/org/netbeans/spi/lsp/CodeLensProvider.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.spi.lsp;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import javax.swing.text.Document;
+import org.netbeans.api.annotations.common.NonNull;
+import org.netbeans.api.lsp.CodeLens;
+import org.netbeans.spi.editor.mimelookup.MimeLocation;
+
+/**
+ * A provider for code lens for a given document.
+ *
+ * @since 1.12
+ */
+@MimeLocation(subfolderName = "CodeLensProvider")
+public interface CodeLensProvider {
+    /**
+     * Provide {@code CodeLens} for the given document.
+     *
+     * @param doc the document
+     * @return the (future) code lens.
+     */
+    public CompletableFuture<List<? extends CodeLens>> codeLens(@NonNull 
Document doc);
+}
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 80ee440887..8c7143cf58 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
@@ -45,6 +45,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 import com.google.gson.InstanceCreator;
 import com.google.gson.JsonObject;
+import java.util.prefs.Preferences;
 import java.util.LinkedHashSet;
 import org.eclipse.lsp4j.CallHierarchyRegistrationOptions;
 import org.eclipse.lsp4j.CodeActionKind;
@@ -120,6 +121,7 @@ import org.openide.filesystems.FileObject;
 import org.openide.filesystems.FileUtil;
 import org.openide.util.Lookup;
 import org.openide.util.NbBundle;
+import org.openide.util.NbPreferences;
 import org.openide.util.Pair;
 import org.openide.util.RequestProcessor;
 import org.openide.util.lookup.AbstractLookup;
@@ -769,6 +771,7 @@ public final class Server {
             NbCodeClientCapabilities capa = NbCodeClientCapabilities.get(init);
             client.setClientCaps(capa);
             hackConfigureGroovySupport(capa);
+            hackNoReuseOfOutputsForAntProjects();
             List<FileObject> projectCandidates = new ArrayList<>();
             List<WorkspaceFolder> folders = init.getWorkspaceFolders();
             if (folders != null) {
@@ -1073,4 +1076,19 @@ public final class Server {
             }
         }
     }
+
+    private static boolean antClassWarningLogged;
+    private static void hackNoReuseOfOutputsForAntProjects() {
+        final String PROP_AUTO_CLOSE_TABS = "autoCloseTabs"; // NOI18N
+        try {
+            Class antSettings = 
Lookup.getDefault().lookup(ClassLoader.class).loadClass("org.apache.tools.ant.module.AntSettings");
+            Preferences prefs = NbPreferences.forModule(antSettings);
+            prefs.putBoolean(PROP_AUTO_CLOSE_TABS, false);
+        } catch (ReflectiveOperationException ex) {
+            if (!antClassWarningLogged) {
+                antClassWarningLogged = true;
+                LOG.log(Level.WARNING, "Unable to configure Ant support", ex);
+            }
+        }
+    }
 }
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 7b28f43907..232e940fe9 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
@@ -167,6 +167,7 @@ import org.netbeans.api.editor.document.AtomicLockListener;
 import org.netbeans.api.editor.document.LineDocument;
 import org.netbeans.api.editor.document.LineDocumentUtils;
 import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
 import org.netbeans.api.java.lexer.JavaTokenId;
 import org.netbeans.api.java.project.JavaProjectConstants;
 import org.netbeans.api.java.source.CodeStyle;
@@ -240,6 +241,7 @@ import org.netbeans.modules.java.lsp.server.URITranslator;
 import org.netbeans.spi.editor.hints.ErrorDescription;
 import org.netbeans.spi.editor.hints.Fix;
 import org.netbeans.spi.lsp.CallHierarchyProvider;
+import org.netbeans.spi.lsp.CodeLensProvider;
 import org.netbeans.spi.lsp.ErrorProvider;
 import org.netbeans.spi.lsp.StructureProvider;
 import org.netbeans.spi.project.ActionProvider;
@@ -1085,72 +1087,115 @@ public class TextDocumentServiceImpl implements 
TextDocumentService, LanguageCli
         if (server.openedProjects().getNow(null) == null) {
             return CompletableFuture.completedFuture(Collections.emptyList());
         }
-        String uri = params.getTextDocument().getUri();
-        Source source = getSource(uri);
-        if (source == null) {
-            return CompletableFuture.completedFuture(Collections.emptyList());
-        }
-        CompletableFuture<List<? extends CodeLens>> result = new 
CompletableFuture<>();
+        CompletableFuture<List<? extends CodeLens>> result = 
CompletableFuture.completedFuture(Collections.emptyList());
         try {
-            ParserManager.parseWhenScanFinished(Collections.singleton(source), 
new UserTask() {
-                @Override
-                public void run(ResultIterator resultIterator) throws 
Exception {
-                    Parser.Result parserResult = 
resultIterator.getParserResult();
-                    //look for main methods:
-                    List<CodeLens> lens = new ArrayList<>();
-                    if (parserResult == null) {
-                        // no parser for the sourec type
-                        result.complete(lens);
-                        return;
-                    }
-                    CompilationController cc = 
CompilationController.get(parserResult);
-                    if (cc != null) {
-                        cc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
-                        AtomicReference<List<Pair<String, String>>> 
projectConfigurations = new AtomicReference<>();
-                        new TreePathScanner<Void, Void>() {
-                            public Void visitMethod(MethodTree tree, Void p) {
-                                Element el = 
cc.getTrees().getElement(getCurrentPath());
-                                if (el != null && el.getKind() == 
ElementKind.METHOD && SourceUtils.isMainMethod((ExecutableElement) el)) {
-                                    Range range = Utils.treeRange(cc, tree);
-                                    List<Object> arguments = 
Collections.singletonList(params.getTextDocument().getUri());
-                                    String method = 
el.getSimpleName().toString();
-                                    lens.add(new CodeLens(range,
-                                                          new 
Command(Bundle.LBL_Run(method), COMMAND_RUN_SINGLE, arguments),
-                                                          null));
-                                    lens.add(new CodeLens(range,
-                                                          new 
Command(Bundle.LBL_Debug(method), COMMAND_DEBUG_SINGLE, arguments),
-                                                          null));
-                                    // Run and Debug configurations:
-                                    List<Pair<String, String>> configs = 
projectConfigurations.accumulateAndGet(null, (l, nul) -> l == null ? 
getProjectConfigurations(source) : l);
-                                    for (Pair<String, String> config : 
configs) {
-                                        String runConfig = config.first();
-                                        if (runConfig != null) {
-                                            lens.add(new CodeLens(range,
-                                                                  new 
Command(Bundle.LBL_RunWith(method, runConfig), COMMAND_RUN_SINGLE, 
Arrays.asList(params.getTextDocument().getUri(), null, runConfig)),
-                                                                  null));
-                                        }
-                                        String debugConfig = config.second();
-                                        if (debugConfig != null) {
-                                            lens.add(new CodeLens(range,
-                                                                  new 
Command(Bundle.LBL_DebugWith(method, debugConfig), COMMAND_DEBUG_SINGLE, 
Arrays.asList(params.getTextDocument().getUri(), null, debugConfig)),
-                                                                  null));
+            String uri = params.getTextDocument().getUri();
+            FileObject file = Utils.fromUri(uri);
+            Document doc = server.getOpenedDocuments().getDocument(uri);
+            if (file == null || doc == null) {
+                return 
CompletableFuture.completedFuture(Collections.emptyList());
+            }
+            for (CodeLensProvider provider : 
MimeLookup.getLookup(DocumentUtilities.getMimeType(doc)).lookupAll(CodeLensProvider.class))
 {
+                result = result.thenCombine(provider.codeLens(doc), (leftList, 
rightList) -> mergeLists(leftList, convertCodeLens(doc, rightList)));
+            }
+        } catch (MalformedURLException ex) {
+            client.logMessage(new MessageParams(MessageType.Error, 
ex.getMessage()));
+        }
+        return result;
+    }
+
+    private List<CodeLens> convertCodeLens(Document doc, List<? extends 
org.netbeans.api.lsp.CodeLens> origin) {
+        List<CodeLens> result = new ArrayList<>();
+        for (org.netbeans.api.lsp.CodeLens len : origin) {
+            Command cmd = null;
+            if (len.getCommand() != null) {
+                cmd = new Command(len.getCommand().getTitle(), 
len.getCommand().getCommand(), len.getCommand().getArguments());
+            }
+            result.add(new CodeLens(callRange2Range(len.getRange(), doc), cmd, 
len.getData()));
+        }
+        return result;
+    }
+    private List<? extends CodeLens> mergeLists(List<? extends CodeLens> left, 
List<? extends CodeLens> right) {
+        List<CodeLens> result = new ArrayList<>();
+        result.addAll(left);
+        result.addAll(right);
+        return result;
+    }
+
+    @MimeRegistration(mimeType="text/x-java", service=CodeLensProvider.class) 
//TODO: other mime types?
+    public static final class MainLens implements CodeLensProvider {
+
+        @Override
+        public CompletableFuture<List<? extends 
org.netbeans.api.lsp.CodeLens>> codeLens(Document doc) {
+            Source source = Source.create(doc);
+            if (source == null) {
+                return 
CompletableFuture.completedFuture(Collections.emptyList());
+            }
+            String uri = Utils.toUri(source.getFileObject());
+            CompletableFuture<List<? extends org.netbeans.api.lsp.CodeLens>> 
result = new CompletableFuture<>();
+            try {
+                
ParserManager.parseWhenScanFinished(Collections.singleton(source), new 
UserTask() {
+                    @Override
+                    public void run(ResultIterator resultIterator) throws 
Exception {
+                        Parser.Result parserResult = 
resultIterator.getParserResult();
+                        //look for main methods:
+                        List<org.netbeans.api.lsp.CodeLens> lens = new 
ArrayList<>();
+                        if (parserResult == null) {
+                            // no parser for the sourec type
+                            result.complete(lens);
+                            return;
+                        }
+                        CompilationController cc = 
CompilationController.get(parserResult);
+                        if (cc != null) {
+                            cc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
+                            AtomicReference<List<Pair<String, String>>> 
projectConfigurations = new AtomicReference<>();
+                            new TreePathScanner<Void, Void>() {
+                                public Void visitMethod(MethodTree tree, Void 
p) {
+                                    Element el = 
cc.getTrees().getElement(getCurrentPath());
+                                    if (el != null && el.getKind() == 
ElementKind.METHOD && SourceUtils.isMainMethod((ExecutableElement) el)) {
+                                        int start = (int) 
cc.getTrees().getSourcePositions().getStartPosition(cc.getCompilationUnit(), 
tree);
+                                        int end = (int) 
cc.getTrees().getSourcePositions().getEndPosition(cc.getCompilationUnit(), 
tree);
+                                        org.netbeans.api.lsp.Range range = new 
org.netbeans.api.lsp.Range(start, end);
+                                        List<Object> arguments = 
Collections.singletonList(uri);
+                                        String method = 
el.getSimpleName().toString();
+                                        lens.add(new 
org.netbeans.api.lsp.CodeLens(range,
+                                                              new 
org.netbeans.api.lsp.Command(Bundle.LBL_Run(method), COMMAND_RUN_SINGLE, 
arguments),
+                                                              null));
+                                        lens.add(new 
org.netbeans.api.lsp.CodeLens(range,
+                                                              new 
org.netbeans.api.lsp.Command(Bundle.LBL_Debug(method), COMMAND_DEBUG_SINGLE, 
arguments),
+                                                              null));
+                                        // Run and Debug configurations:
+                                        List<Pair<String, String>> configs = 
projectConfigurations.accumulateAndGet(null, (l, nul) -> l == null ? 
getProjectConfigurations(source) : l);
+                                        for (Pair<String, String> config : 
configs) {
+                                            String runConfig = config.first();
+                                            if (runConfig != null) {
+                                                lens.add(new 
org.netbeans.api.lsp.CodeLens(range,
+                                                                      new 
org.netbeans.api.lsp.Command(Bundle.LBL_RunWith(method, runConfig), 
COMMAND_RUN_SINGLE, Arrays.asList(uri, null, runConfig)),
+                                                                      null));
+                                            }
+                                            String debugConfig = 
config.second();
+                                            if (debugConfig != null) {
+                                                lens.add(new 
org.netbeans.api.lsp.CodeLens(range,
+                                                                      new 
org.netbeans.api.lsp.Command(Bundle.LBL_DebugWith(method, debugConfig), 
COMMAND_DEBUG_SINGLE, Arrays.asList(uri, null, debugConfig)),
+                                                                      null));
+                                            }
                                         }
                                     }
+                                    return null;
                                 }
-                                return null;
-                            }
-                        }.scan(cc.getCompilationUnit(), null);
+                            }.scan(cc.getCompilationUnit(), null);
+                        }
+                        result.complete(lens);
                     }
-                    result.complete(lens);
-                }
-            });
-        } catch (ParseException ex) {
-            result.completeExceptionally(ex);
+                });
+            } catch (ParseException ex) {
+                result.completeExceptionally(ex);
+            }
+            return result;
         }
-        return result;
     }
 
-    private List<Pair<String, String>> getProjectConfigurations(Source source) 
{
+    private static List<Pair<String, String>> getProjectConfigurations(Source 
source) {
         FileObject fo = source.getFileObject();
         Project p = FileOwnerQuery.getOwner(fo);
         if (p != null) {
diff --git a/java/java.openjdk.project/nbproject/project.xml 
b/java/java.openjdk.project/nbproject/project.xml
index d7bc364fe6..dcbf9178d0 100644
--- a/java/java.openjdk.project/nbproject/project.xml
+++ b/java/java.openjdk.project/nbproject/project.xml
@@ -83,6 +83,15 @@
                         <specification-version>1.56</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.api.lsp</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.9</specification-version>
+                    </run-dependency>
+                </dependency>
                 <dependency>
                     <code-name-base>org.netbeans.libs.javacapi</code-name-base>
                     <build-prerequisite/>
diff --git a/java/java.openjdk.project/release/scripts/build-generic.xml 
b/java/java.openjdk.project/release/scripts/build-generic.xml
index b58d7a9296..0150050f60 100644
--- a/java/java.openjdk.project/release/scripts/build-generic.xml
+++ b/java/java.openjdk.project/release/scripts/build-generic.xml
@@ -30,6 +30,7 @@ SUPPORTED_ACTIONS: build,build-fast,clean,rebuild
     <target name="build-fast">
         <exec executable="make" dir="${basedir}" failonerror="true">
             <arg value="default" />
+            <arg line="${nb.extra.make.targets}" />
             <env key="CONF" value="${CONF}" />
         </exec>
     </target>
diff --git 
a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/common/BuildUtils.java
 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/common/BuildUtils.java
index e6efb4fbac..78918fd3e7 100644
--- 
a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/common/BuildUtils.java
+++ 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/common/BuildUtils.java
@@ -99,4 +99,8 @@ public class BuildUtils {
 
         return pos < relpath.length() ? 
dir.getFileObject(relpath.substring(pos)) : dir;
     }
+
+    public interface ExtraMakeTargets {
+        public String[] getExtraMakeTargets();
+    }
 }
diff --git 
a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImpl.java
 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImpl.java
index 9edd57c43f..e80d2eae7d 100644
--- 
a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImpl.java
+++ 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImpl.java
@@ -53,6 +53,7 @@ import org.netbeans.api.java.classpath.ClassPath;
 import org.netbeans.api.project.FileOwnerQuery;
 import org.netbeans.api.project.Project;
 import org.netbeans.modules.java.openjdk.common.BuildUtils;
+import org.netbeans.modules.java.openjdk.common.BuildUtils.ExtraMakeTargets;
 import org.netbeans.modules.java.openjdk.common.ShortcutUtils;
 import org.netbeans.modules.java.openjdk.project.Settings;
 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
@@ -170,9 +171,17 @@ public class ActionProviderImpl implements ActionProvider {
                         }
 
                         if (toRun != null) {
+                            String[] extraMakeTarget;
+                            switch (inferTestType(prj)) {
+                                case JDK:
+                                    extraMakeTarget = new String[] 
{"build-test-jdk-jtreg-native"};
+                                    break;
+                                default:
+                                    extraMakeTarget = new String[0];
+                            }
                             final CountDownLatch wait = new CountDownLatch(1);
                             final boolean[] state = new boolean[1];
-                            targetContext = Lookups.singleton(new 
ActionProgress() {
+                            targetContext = Lookups.fixed(new ActionProgress() 
{
                                 @Override
                                 protected void started() {
                                     state[0] = true;
@@ -182,6 +191,12 @@ public class ActionProviderImpl implements ActionProvider {
                                     state[0] = success;
                                     wait.countDown();
                                 }
+                            },
+                            new ExtraMakeTargets() {
+                                @Override
+                                public String[] getExtraMakeTargets() {
+                                    return extraMakeTarget;
+                                }
                             });
                             prjAP.invokeAction(toRun, targetContext);
 
@@ -224,9 +239,10 @@ public class ActionProviderImpl implements ActionProvider {
                     options.add(jtregReport.getAbsolutePath());
                     options.add("-xml:verify");
                     options.add("-javacoptions:-g");
+                    File buildDir = BuildUtils.getBuildTargetDir(file);
+                    options.add("-vmoption:-Djava.library.path=" + 
buildDir.getAbsolutePath() + "/support/test/jdk/jtreg/native/lib/");
                     Set<File> toRefresh = new HashSet<>();
                     if (hasXPatch(targetJavaHome)) {
-                        File buildDir = BuildUtils.getBuildTargetDir(file);
                         CoverageSupport covSupp = 
Lookup.getDefault().lookup(CoverageSupport.class);
                         CoverageSupport.Result covResult = covSupp != null ? 
covSupp.coverage(jtregOutput, buildDir, io.getOut()) : null;
                         if (covResult != null) {
@@ -664,6 +680,20 @@ public class ActionProviderImpl implements ActionProvider {
         return false;
     }
 
+    private static TestType inferTestType(Project prj) {
+        switch (prj.getProjectDirectory().getNameExt()) {
+            case "java.base": return TestType.JDK;
+            case "java.compiler": return TestType.LANGTOOLS;
+            default: return TestType.OTHER;
+        }
+    }
+
+    static enum TestType {
+        JDK,
+        LANGTOOLS,
+        OTHER;
+    }
+
     private static final class StopAction extends AbstractAction {
 
         private static final long serialVersionUID = 1L;
diff --git 
a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/CodeLensProviderImpl.java
 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/CodeLensProviderImpl.java
new file mode 100644
index 0000000000..4d9db1f375
--- /dev/null
+++ 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/CodeLensProviderImpl.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.openjdk.jtreg;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import javax.swing.text.Document;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
+import org.netbeans.api.lsp.CodeLens;
+import org.netbeans.api.lsp.Command;
+import org.netbeans.api.lsp.Range;
+import org.netbeans.modules.editor.NbEditorUtilities;
+import org.netbeans.modules.java.openjdk.jtreg.TagParser.Result;
+import org.netbeans.spi.lsp.CodeLensProvider;
+import org.netbeans.spi.project.ActionProvider;
+import org.openide.filesystems.FileObject;
+import org.openide.util.NbBundle.Messages;
+
+/**
+ *
+ */
+@MimeRegistration(mimeType="text/x-java", service=CodeLensProvider.class)
+public class CodeLensProviderImpl implements CodeLensProvider {
+
+    @Override
+    public CompletableFuture<List<? extends CodeLens>> codeLens(Document doc) {
+        CompletableFuture<List<? extends CodeLens>> result = new 
CompletableFuture<>();
+        result.complete(doComputeCodeLens(doc));
+        return result;
+    }
+
+    @Messages({
+        "DN_RunTest=Run test",
+        "DN_DebugTest=Debug test"
+    })
+    private List<? extends CodeLens> doComputeCodeLens(Document doc) {
+        FileObject file = NbEditorUtilities.getFileObject(doc);
+        TestRootDescription rootDesc = file != null ? 
TestRootDescription.findRootDescriptionFor(file) : null;
+
+        if (rootDesc == null) return Collections.emptyList();
+
+        Result tags = TagParser.parseTags(doc);
+        List<Tag> testTags = tags.getName2Tag().getOrDefault("test", 
Collections.emptyList());
+
+        if (testTags.isEmpty()) return Collections.emptyList();
+
+        Tag testTag = testTags.get(0);
+        Range lenSpan = new Range(testTag.getTagStart(), testTag.getTagEnd());
+        List<Object> params = 
Collections.singletonList(file.toURI().toString());
+        return Collections.unmodifiableList(Arrays.asList(new 
CodeLens(lenSpan, new Command(Bundle.DN_RunTest(), "java.run.test", params), 
null),
+                                                          new 
CodeLens(lenSpan, new Command(Bundle.DN_DebugTest(), "java.debug.test", 
params), null)));
+    }
+
+}
diff --git 
a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/ActionProviderImpl.java
 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/ActionProviderImpl.java
index 8671561f1d..b39c5683b8 100644
--- 
a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/ActionProviderImpl.java
+++ 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/ActionProviderImpl.java
@@ -26,12 +26,14 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.swing.Action;
 
 import org.apache.tools.ant.module.api.support.ActionUtils;
 import org.netbeans.api.java.classpath.ClassPath;
 import org.netbeans.modules.java.openjdk.common.BuildUtils;
+import org.netbeans.modules.java.openjdk.common.BuildUtils.ExtraMakeTargets;
 import org.netbeans.modules.java.openjdk.common.ShortcutUtils;
 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 import org.netbeans.spi.project.ActionProgress;
@@ -199,12 +201,17 @@ public class ActionProviderImpl implements ActionProvider 
{
             scriptFO = genericScript;
             command = COMMAND_BUILD_FAST; //XXX: should only do this if 
genericScript supports it
         }
+        String extraTargets = context.lookupAll(ExtraMakeTargets.class)
+                                     .stream()
+                                     .flatMap(emt -> 
Arrays.stream(emt.getExtraMakeTargets()))
+                                     .collect(Collectors.joining(" "));
         FileObject basedirFO = project.currentModule != null ? scriptFO == 
genericScript ? project.moduleRepository.getJDKRoot()
                                                                                
          : repository
                                                              : 
repository.getParent();
         props.put("basedir", FileUtil.toFile(basedirFO).getAbsolutePath());
         props.put("CONF", 
project.configurations.getActiveConfiguration().getLocation().getName());
         props.put("nb.jdk.project.target.java.home", 
BuildUtils.findTargetJavaHome(project.getProjectDirectory()).getAbsolutePath());
+        props.put("nb.extra.make.targets", extraTargets);
         RootKind kind = getKind(context);
         RunSingleConfig singleFileProperty = 
command2Properties.get(Pair.of(command, kind));
         if (singleFileProperty != null) {
diff --git 
a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/Settings.java
 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/Settings.java
index d993f44e1e..01cf8b1722 100644
--- 
a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/Settings.java
+++ 
b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/Settings.java
@@ -36,7 +36,7 @@ public class Settings {
     private static final String KEY_USE_ANT_BUILD = "use-langtools-ant-build";
     private static final String KEY_ANT_BUILD_LOCATION = 
"langtools-ant-build-location";
 
-    private static final String DEF_ANT_BUILD_LOCATION = 
"make/langtools/netbeans/langtools/build.xml";
+    private static final String DEF_ANT_BUILD_LOCATION = 
"make/ide/netbeans/langtools/build.xml";
 
     private final Project prj;
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

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

Reply via email to