Add a terminal provider to detect the Java stacktrace printed in terminal (#890)
This commit is contained in:
parent
0755aa2172
commit
5f1a6edc5a
|
@ -49,9 +49,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@types/vscode": {
|
||||
"version": "1.47.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.47.0.tgz",
|
||||
"integrity": "sha512-nJA37ykkz9FYA0ZOQUSc3OZnhuzEW2vUhUEo4MiduUo82jGwwcLfyvmgd/Q7b0WrZAAceojGhZybg319L24bTA==",
|
||||
"version": "1.49.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.49.0.tgz",
|
||||
"integrity": "sha512-wfNQmLmm1VdMBr6iuNdprWmC1YdrgZ9dQzadv+l2eSjJlElOdJw8OTm4RU4oGTBcfvG6RZI2jOcppkdSS18mZw==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"debugger"
|
||||
],
|
||||
"engines": {
|
||||
"vscode": "^1.47.3"
|
||||
"vscode": "^1.49.0"
|
||||
},
|
||||
"license": "SEE LICENSE IN LICENSE.txt",
|
||||
"repository": {
|
||||
|
@ -745,7 +745,7 @@
|
|||
"@types/lodash": "^4.14.137",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^8.10.51",
|
||||
"@types/vscode": "1.47.0",
|
||||
"@types/vscode": "1.49.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-tslint": "^8.1.4",
|
||||
|
|
|
@ -42,6 +42,8 @@ export const JAVA_FETCH_PLATFORM_SETTINGS = "vscode.java.fetchPlatformSettings";
|
|||
|
||||
export const JAVA_RESOLVE_CLASSFILTERS = "vscode.java.resolveClassFilters";
|
||||
|
||||
export const JAVA_RESOLVE_SOURCE_URI = "vscode.java.resolveSourceUri";
|
||||
|
||||
export function executeJavaLanguageServerCommand(...rest) {
|
||||
return executeJavaExtensionCommand(JAVA_EXECUTE_WORKSPACE_COMMAND, ...rest);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import { IMainClassOption, IMainMethod, resolveMainClass, resolveMainMethod } fr
|
|||
import { logger, Type } from "./logger";
|
||||
import { mainClassPicker } from "./mainClassPicker";
|
||||
import { pickJavaProcess } from "./processPicker";
|
||||
import { JavaTerminalLinkProvder } from "./terminalLinkProvider";
|
||||
import { initializeThreadOperations } from "./threadOperations";
|
||||
import * as utility from "./utility";
|
||||
|
||||
|
@ -34,6 +35,7 @@ function initializeExtension(operationId: string, context: vscode.ExtensionConte
|
|||
|
||||
registerDebugEventListener(context);
|
||||
context.subscriptions.push(logger);
|
||||
context.subscriptions.push(vscode.window.registerTerminalLinkProvider(new JavaTerminalLinkProvder()));
|
||||
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider("java", new JavaDebugConfigurationProvider()));
|
||||
context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory("java", new JavaDebugAdapterDescriptorFactory()));
|
||||
context.subscriptions.push(instrumentOperationAsVsCodeCommand("JavaDebug.SpecifyProgramArgs", async () => {
|
||||
|
|
|
@ -112,3 +112,7 @@ export function fetchPlatformSettings(): any {
|
|||
export async function resolveClassFilters(patterns: string[]): Promise<string[]> {
|
||||
return <string[]> await commands.executeJavaLanguageServerCommand(commands.JAVA_RESOLVE_CLASSFILTERS, ...patterns);
|
||||
}
|
||||
|
||||
export async function resolveSourceUri(line: string): Promise<string> {
|
||||
return <string> await commands.executeJavaLanguageServerCommand(commands.JAVA_RESOLVE_SOURCE_URI, line);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { CancellationToken, commands, Position, ProviderResult, Range, TerminalLink, TerminalLinkContext,
|
||||
TerminalLinkProvider, Uri, window } from "vscode";
|
||||
import { resolveSourceUri } from "./languageServerPlugin";
|
||||
|
||||
export class JavaTerminalLinkProvder implements TerminalLinkProvider<IJavaTerminalLink> {
|
||||
/**
|
||||
* Provide terminal links for the given context. Note that this can be called multiple times
|
||||
* even before previous calls resolve, make sure to not share global objects (eg. `RegExp`)
|
||||
* that could have problems when asynchronous usage may overlap.
|
||||
* @param context Information about what links are being provided for.
|
||||
* @param token A cancellation token.
|
||||
* @return A list of terminal links for the given line.
|
||||
*/
|
||||
public provideTerminalLinks(context: TerminalLinkContext, token: CancellationToken): ProviderResult<IJavaTerminalLink[]> {
|
||||
if (context.terminal.name !== "Java Debug Console" && context.terminal.name !== "Java Process Console") {
|
||||
return [];
|
||||
}
|
||||
|
||||
const regex = new RegExp("(\\sat\\s+)([\\w$\\.]+\\/)?(([\\w$]+\\.)+[<\\w$>]+)\\(([\\w-$]+\\.java:\\d+)\\)");
|
||||
const result: RegExpExecArray = regex.exec(context.line);
|
||||
if (result && result.length) {
|
||||
const stackTrace = `${result[2] || ""}${result[3]}(${result[5]})`;
|
||||
const sourceLineNumber = Number(result[5].split(":")[1]);
|
||||
return [{
|
||||
startIndex: result.index + result[1].length,
|
||||
length: stackTrace.length,
|
||||
methodName: result[3],
|
||||
stackTrace,
|
||||
lineNumber: sourceLineNumber,
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an activated terminal link.
|
||||
*/
|
||||
public async handleTerminalLink(link: IJavaTerminalLink): Promise<void> {
|
||||
const uri = await resolveSourceUri(link.stackTrace);
|
||||
if (uri) {
|
||||
const lineNumber = Math.max(link.lineNumber - 1, 0);
|
||||
window.showTextDocument(Uri.parse(uri), {
|
||||
preserveFocus: true,
|
||||
selection: new Range(new Position(lineNumber, 0), new Position(lineNumber, 0)),
|
||||
});
|
||||
} else {
|
||||
// If no source is found, then open the searching symbols quickpick box.
|
||||
const fullyQualifiedName = link.methodName.substring(0, link.methodName.lastIndexOf("."));
|
||||
const className = fullyQualifiedName.substring(fullyQualifiedName.lastIndexOf(".") + 1);
|
||||
commands.executeCommand("workbench.action.quickOpen", "#" + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IJavaTerminalLink extends TerminalLink {
|
||||
methodName: string;
|
||||
stackTrace: string;
|
||||
lineNumber: number;
|
||||
}
|
Loading…
Reference in New Issue