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

Reply via email to