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 5f0acca Add Run with configuration into code lenses. 5f0acca is described below commit 5f0acca3f6c8639d886ace996f76df1fb877dcce Author: Martin Entlicher <martin.entlic...@oracle.com> AuthorDate: Wed Jun 16 11:19:30 2021 +0200 Add Run with configuration into code lenses. --- .../server/protocol/TextDocumentServiceImpl.java | 76 +++++++++++++++++++++- java/java.lsp.server/vscode/src/extension.ts | 15 +++-- 2 files changed, 82 insertions(+), 9 deletions(-) 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 1a9d211..f0d1348 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 @@ -37,6 +37,7 @@ import java.net.URI; import java.net.URL; import java.time.Instant; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.EnumMap; import java.util.EnumSet; @@ -51,6 +52,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiConsumer; import java.util.function.IntFunction; import java.util.logging.Level; @@ -148,6 +150,7 @@ import org.netbeans.api.java.source.ui.ElementOpen; import org.netbeans.api.lexer.TokenSequence; import org.netbeans.api.lsp.Completion; import org.netbeans.api.lsp.HyperlinkLocation; +import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.SourceGroup; @@ -189,12 +192,17 @@ import org.netbeans.modules.refactoring.spi.Transaction; import org.netbeans.spi.editor.hints.ErrorDescription; import org.netbeans.spi.editor.hints.Fix; import org.netbeans.spi.lsp.ErrorProvider; +import org.netbeans.spi.project.ActionProvider; +import org.netbeans.spi.project.ProjectConfiguration; +import org.netbeans.spi.project.ProjectConfigurationProvider; import org.openide.cookies.EditorCookie; import org.openide.filesystems.FileObject; import org.openide.text.NbDocument; import org.openide.text.PositionBounds; import org.openide.util.Exceptions; import org.openide.util.Lookup; +import org.openide.util.NbBundle; +import org.openide.util.Pair; import org.openide.util.RequestProcessor; import org.openide.util.Union2; import org.openide.util.WeakSet; @@ -208,6 +216,9 @@ import org.openide.util.lookup.ServiceProvider; public class TextDocumentServiceImpl implements TextDocumentService, LanguageClientAware { private static final Logger LOG = Logger.getLogger(TextDocumentServiceImpl.class.getName()); + private static final String COMMAND_RUN_SINGLE = "java.run.single"; // NOI18N + private static final String COMMAND_DEBUG_SINGLE = "java.debug.single"; // NOI18N + private static final RequestProcessor BACKGROUND_TASKS = new RequestProcessor(TextDocumentServiceImpl.class.getName(), 1, false, false); private static final RequestProcessor WORKER = new RequestProcessor(TextDocumentServiceImpl.class.getName(), 1, false, false); @@ -884,6 +895,10 @@ public class TextDocumentServiceImpl implements TextDocumentService, LanguageCli private ConcurrentHashMap<String, Boolean> upToDateTests = new ConcurrentHashMap<>(); + @NbBundle.Messages({"# {0} - method name", "LBL_Run=Run {0}", + "# {0} - method name", "LBL_Debug=Debug {0}", + "# {0} - method name", "# {1} - configuration name", "LBL_RunWith=Run {0} with {1}", + "# {0} - method name", "# {1} - configuration name", "LBL_DebugWith=Debug {0} with {1}"}) @Override public CompletableFuture<List<? extends CodeLens>> codeLens(CodeLensParams params) { // shortcut: if the projects are not yet initialized, return empty: @@ -932,18 +947,36 @@ public class TextDocumentServiceImpl implements TextDocumentService, LanguageCli } //look for main methods: List<CodeLens> lens = new ArrayList<>(); + 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("Run main", "java.run.single", arguments), + new Command(Bundle.LBL_Run(method), COMMAND_RUN_SINGLE, arguments), null)); lens.add(new CodeLens(range, - new Command("Debug main", "java.debug.single", arguments), + 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)); + } + } } return null; } @@ -956,6 +989,45 @@ public class TextDocumentServiceImpl implements TextDocumentService, LanguageCli return result; } + private List<Pair<String, String>> getProjectConfigurations(JavaSource source) { + for (FileObject fo : source.getFileObjects()) { + Project p = FileOwnerQuery.getOwner(fo); + if (p != null) { + ProjectConfigurationProvider<ProjectConfiguration> configProvider = p.getLookup().lookup(ProjectConfigurationProvider.class); + ActionProvider actionProvider = p.getLookup().lookup(ActionProvider.class); + List<Pair<String, String>> configDispNames = new ArrayList<>(); + if (configProvider != null && actionProvider != null) { + boolean skippedFirst = false; + for (ProjectConfiguration configuration : configProvider.getConfigurations()) { + if (skippedFirst) { + String runConfig = null; + String debugConfig = null; + Lookup configLookup = Lookups.fixed(fo, configuration); + if (isConfigurationAction(configProvider, actionProvider, configLookup, ActionProvider.COMMAND_RUN_SINGLE)) { + runConfig = configuration.getDisplayName(); + } + if (isConfigurationAction(configProvider, actionProvider, configLookup, ActionProvider.COMMAND_DEBUG_SINGLE)) { + debugConfig = configuration.getDisplayName(); + } + if (runConfig != null || debugConfig != null) { + configDispNames.add(Pair.of(runConfig, debugConfig)); + } + } else { + // Ignore the default config + skippedFirst = true; + } + } + } + return configDispNames; + } + } + return Collections.emptyList(); + } + + private static boolean isConfigurationAction(ProjectConfigurationProvider<ProjectConfiguration> configProvider, ActionProvider actionProvider, Lookup configLookup, String action) { + return configProvider.configurationsAffectAction(action) && actionProvider.isActionEnabled(action, configLookup); + } + @Override public CompletableFuture<CodeLens> resolveCodeLens(CodeLens arg0) { throw new UnsupportedOperationException("Not supported yet."); diff --git a/java/java.lsp.server/vscode/src/extension.ts b/java/java.lsp.server/vscode/src/extension.ts index 84f5651..f2a5255 100644 --- a/java/java.lsp.server/vscode/src/extension.ts +++ b/java/java.lsp.server/vscode/src/extension.ts @@ -283,7 +283,7 @@ export function activate(context: ExtensionContext): VSNetBeansAPI { ]); } })); - const runDebug = async (noDebug: boolean, testRun: boolean, uri: string, methodName?: string) => { + const runDebug = async (noDebug: boolean, testRun: boolean, uri: string, methodName?: string, launchConfiguration?: string) => { const docUri = uri ? vscode.Uri.file(uri) : window.activeTextEditor?.document.uri; if (docUri) { const workspaceFolder = vscode.workspace.getWorkspaceFolder(docUri); @@ -293,6 +293,7 @@ export function activate(context: ExtensionContext): VSNetBeansAPI { request: "launch", mainClass: uri, methodName, + launchConfiguration, testRun }; const debugOptions : vscode.DebugSessionOptions = { @@ -307,14 +308,14 @@ export function activate(context: ExtensionContext): VSNetBeansAPI { }) : ret; } }; - context.subscriptions.push(commands.registerCommand('java.run.test', async (uri, methodName?) => { - await runDebug(true, true, uri, methodName); + context.subscriptions.push(commands.registerCommand('java.run.test', async (uri, methodName?, launchConfiguration?) => { + await runDebug(true, true, uri, methodName, launchConfiguration); })); - context.subscriptions.push(commands.registerCommand('java.run.single', async (uri, methodName?) => { - await runDebug(true, false, uri, methodName); + context.subscriptions.push(commands.registerCommand('java.run.single', async (uri, methodName?, launchConfiguration?) => { + await runDebug(true, false, uri, methodName, launchConfiguration); })); - context.subscriptions.push(commands.registerCommand('java.debug.single', async (uri, methodName?) => { - await runDebug(false, false, uri, methodName); + context.subscriptions.push(commands.registerCommand('java.debug.single', async (uri, methodName?, launchConfiguration?) => { + await runDebug(false, false, uri, methodName, launchConfiguration); })); // get the Test Explorer extension and register TestAdapter --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists