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 3354718cab VSCode: Stacktraces in test exceptions should be clickable. (#5938) 3354718cab is described below commit 3354718cabd4707241c498c7302ff27d3e3b3f3c Author: Dusan Balek <dusan.ba...@oracle.com> AuthorDate: Mon May 15 08:52:58 2023 +0200 VSCode: Stacktraces in test exceptions should be clickable. (#5938) --- .../modules/java/lsp/server/protocol/Server.java | 2 + .../lsp/server/protocol/WorkspaceServiceImpl.java | 44 ++++++++++++++++++++++ java/java.lsp.server/vscode/src/extension.ts | 12 ++++++ java/java.lsp.server/vscode/src/testAdapter.ts | 25 ++++++++++-- 4 files changed, 80 insertions(+), 3 deletions(-) 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 d11e33b21c..67c2fbbe32 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 @@ -789,6 +789,7 @@ public final class Server { JAVA_GET_PROJECT_PACKAGES, JAVA_GET_PROJECT_SOURCE_ROOTS, JAVA_LOAD_WORKSPACE_TESTS, + JAVA_RESOLVE_STACKTRACE_LOCATION, JAVA_NEW_FROM_TEMPLATE, JAVA_NEW_PROJECT, JAVA_PROJECT_CONFIGURATION_COMPLETION, @@ -967,6 +968,7 @@ public final class Server { 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_RESOLVE_STACKTRACE_LOCATION = "java.resolve.stacktrace.location"; public static final String JAVA_SUPER_IMPLEMENTATION = "java.super.implementation"; public static final String GRAALVM_PAUSE_SCRIPT = "graalvm.pause.script"; public static final String JAVA_RUN_PROJECT_ACTION = "java.project.run.action"; 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 d595c1a6c8..b009ab7c3b 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 @@ -124,6 +124,7 @@ import org.netbeans.modules.java.source.ui.JavaSymbolProvider; import org.netbeans.modules.java.source.ui.JavaTypeProvider; import org.netbeans.modules.java.source.usages.ClassIndexImpl; import org.netbeans.modules.parsing.lucene.support.Queries; +import org.netbeans.spi.java.classpath.support.ClassPathSupport; import org.netbeans.spi.jumpto.type.SearchType; import org.netbeans.spi.project.ActionProgress; import org.netbeans.spi.project.ActionProvider; @@ -397,6 +398,49 @@ public final class WorkspaceServiceImpl implements WorkspaceService, LanguageCli return future; }); } + case Server.JAVA_RESOLVE_STACKTRACE_LOCATION: { + CompletableFuture<Object> future = new CompletableFuture<>(); + try { + if (params.getArguments().size() >= 3) { + String uri = ((JsonPrimitive) params.getArguments().get(0)).getAsString(); + String methodName = ((JsonPrimitive) params.getArguments().get(1)).getAsString(); + String fileName = ((JsonPrimitive) params.getArguments().get(2)).getAsString(); + FileObject fo = Utils.fromUri(uri); + if (fo != null) { + ClassPath classPath = ClassPathSupport.createProxyClassPath(new ClassPath[] { + ClassPath.getClassPath(fo, ClassPath.EXECUTE), + ClassPath.getClassPath(fo, ClassPath.BOOT) + }); + String name = fileName.substring(0, fileName.lastIndexOf('.')); + String packageName = methodName.substring(0, methodName.indexOf(name)).replace('.', '/'); + String resourceName = packageName + name + ".class"; + List<FileObject> resources = classPath.findAllResources(resourceName); + if (resources != null) { + for (FileObject resource : resources) { + FileObject root = classPath.findOwnerRoot(resource); + if (root != null) { + URL url = URLMapper.findURL(root, URLMapper.INTERNAL); + SourceForBinaryQuery.Result res = SourceForBinaryQuery.findSourceRoots(url); + FileObject[] rootz = res.getRoots(); + for (int i = 0; i < rootz.length; i++) { + String path = packageName + fileName; + FileObject sourceFo = rootz[i].getFileObject(path); + if (sourceFo != null) { + future.complete(Utils.toUri(sourceFo)); + return future; + } + } + } + } + } + } + } + future.complete(null); + } catch (IOException ex) { + future.completeExceptionally(ex); + } + return future; + } case Server.JAVA_SUPER_IMPLEMENTATION: String uri = ((JsonPrimitive) params.getArguments().get(0)).getAsString(); Position pos = gson.fromJson(gson.toJson(params.getArguments().get(1)), Position.class); diff --git a/java/java.lsp.server/vscode/src/extension.ts b/java/java.lsp.server/vscode/src/extension.ts index 8a05ba4dbc..b4c1fa7f39 100644 --- a/java/java.lsp.server/vscode/src/extension.ts +++ b/java/java.lsp.server/vscode/src/extension.ts @@ -598,6 +598,18 @@ export function activate(context: ExtensionContext): VSNetBeansAPI { context.subscriptions.push(commands.registerCommand('java.package.test', async (uri, launchConfiguration?) => { await runDebug(true, true, uri, undefined, launchConfiguration); })); + context.subscriptions.push(commands.registerCommand('java.open.stacktrace', async (uri, methodName, fileName, line) => { + const location: string | undefined = uri ? await commands.executeCommand('java.resolve.stacktrace.location', uri, methodName, fileName) : undefined; + if (location) { + const lNum = line - 1; + window.showTextDocument(vscode.Uri.parse(location), { selection: new vscode.Range(new vscode.Position(lNum, 0), new vscode.Position(lNum, 0)) }); + } else { + if (methodName) { + const fqn: string = methodName.substring(0, methodName.lastIndexOf('.')); + commands.executeCommand('workbench.action.quickOpen', '#' + fqn.substring(fqn.lastIndexOf('.') + 1)); + } + } + })); context.subscriptions.push(commands.registerCommand('nbls.startup.condition', async () => { return client; })); diff --git a/java/java.lsp.server/vscode/src/testAdapter.ts b/java/java.lsp.server/vscode/src/testAdapter.ts index e1c3ac5e29..2141996ccc 100644 --- a/java/java.lsp.server/vscode/src/testAdapter.ts +++ b/java/java.lsp.server/vscode/src/testAdapter.ts @@ -18,7 +18,7 @@ */ 'use strict'; -import { commands, debug, tests, workspace, CancellationToken, TestController, TestItem, TestRunProfileKind, TestRunRequest, Uri, TestRun, TestMessage, Location, Position } from "vscode"; +import { commands, debug, tests, workspace, CancellationToken, TestController, TestItem, TestRunProfileKind, TestRunRequest, Uri, TestRun, TestMessage, Location, Position, MarkdownString } from "vscode"; import * as path from 'path'; import { asRange, TestCase, TestSuite } from "./protocol"; @@ -163,7 +163,7 @@ export class NbTestAdapter { } let message: TestMessage | undefined; if (test.stackTrace) { - message = new TestMessage(test.stackTrace.join('\n')); + message = new TestMessage(this.stacktrace2Message(currentTest?.uri?.toString(), test.stackTrace)); if (currentTest) { const testUri = currentTest.uri || currentTest.parent?.uri; if (testUri) { @@ -220,7 +220,7 @@ export class NbTestAdapter { let currentTest = currentSuite?.children.get(test.id); const testUri = test.file ? Uri.parse(test.file) : undefined; if (currentTest) { - if (currentTest.uri?.toString() !== testUri?.toString()) { + if (testUri && currentTest.uri?.toString() !== testUri?.toString()) { currentTest = this.testController.createTestItem(test.id, test.name, testUri); currentSuite?.children.add(currentTest); } @@ -296,4 +296,23 @@ export class NbTestAdapter { }); return ret; } + + stacktrace2Message(currentTestUri: string | undefined, stacktrace: string[]): MarkdownString { + const regExp: RegExp = /(\s*at\s+(?:[\w$\\.]+\/)?((?:[\w$]+\.)+[\w\s$<>]+))\(((.*):(\d+))\)/; + const message = new MarkdownString(); + message.isTrusted = true; + message.supportHtml = true; + for (const line of stacktrace) { + if (message.value.length) { + message.appendMarkdown('<br/>'); + } + const result = regExp.exec(line); + if (result) { + message.appendText(result[1]).appendText('(').appendMarkdown(`[${result[3]}](command:java.open.stacktrace?${encodeURIComponent(JSON.stringify([currentTestUri, result[2], result[4], +result[5]]))})`).appendText(')'); + } else { + message.appendText(line); + } + } + return message; + } } --------------------------------------------------------------------- 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