From d5d67e7ee9813239f79d4528d35fefac22ca530c Mon Sep 17 00:00:00 2001 From: xuzho Date: Tue, 8 Aug 2017 17:28:57 +0800 Subject: [PATCH 1/4] support single file debug Signed-off-by: xuzho --- src/extension.ts | 21 +++++++++++++++++++- src/javaServerStarter.ts | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index 438e1b696b..cd8693b375 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,7 +6,7 @@ import * as vscode from 'vscode'; import { workspace, ExtensionContext, window, StatusBarAlignment, commands, ViewColumn, Uri, CancellationToken, TextDocumentContentProvider, TextEditor, WorkspaceConfiguration, languages, IndentAction, ProgressLocation, Progress } from 'vscode'; import { LanguageClient, LanguageClientOptions, Position as LSPosition, Location as LSLocation } from 'vscode-languageclient'; -import { runServer, awaitServerConnection } from './javaServerStarter'; +import { runServer, awaitServerConnection, runJavaC } from './javaServerStarter'; import { Commands } from './commands'; import { StatusNotification, ClassFileContentsRequest, ProjectConfigurationUpdateRequest, MessageType, ActionableNotification, FeatureStatus, ActionableMessage, DebugSessionRequest, ClasspathResolveRequest, ClasspathResolveRequestParams } from './protocol'; @@ -105,6 +105,25 @@ export function activate(context: ExtensionContext) { lastStatus = item.text; resolve(); commands.registerCommand(Commands.START_DEBUG_SESSION, async (config) => { + if (!config.request) { // if 'request' is missing interpret this as a missing launch.json + config.type = 'java'; + config.name = 'Java Debug'; + config.request = 'launch'; + const editor = vscode.window.activeTextEditor; + if (editor && editor.document.languageId === 'java') { + const fullpath = editor.document.fileName; + const cur = path.parse(fullpath).dir; + config.startupClass = path.parse(fullpath).base.slice(0, -5); + config.sourcePath = [cur]; + config.cwd = cur; + config.stopOnEntry = true; + await runJavaC(fullpath, cur).then(function () { + config.classpath = cur; + }, function (error) { + vscode.window.showErrorMessage('Compile file failed. error: ' + error); + }); + } + } if (!config.startupClass) { vscode.window.showErrorMessage('Please specify startupClass on launch.json firstly.'); } else { diff --git a/src/javaServerStarter.ts b/src/javaServerStarter.ts index a3a43c3f7a..9079bee695 100644 --- a/src/javaServerStarter.ts +++ b/src/javaServerStarter.ts @@ -12,6 +12,7 @@ const glob = require('glob'); declare let v8debug; const DEBUG = (typeof v8debug === 'object') || startedInDebugMode(); let electron = require('./electron_j'); +let cp = require('child_process'); export function awaitServerConnection(port): Thenable { let addr = parseInt(port); @@ -59,6 +60,48 @@ export function runServer(workspacePath, javaConfig): Thenable { }); } +export function runJavaC(sourcePath, outputPath) { + return requirements.resolveRequirements().catch(error => { + //show error + window.showErrorMessage(error.message, error.label).then((selection) => { + if (error.label && error.label === selection && error.openUrl) { + commands.executeCommand(Commands.OPEN_BROWSER, error.openUrl); + } + }); + // rethrow to disrupt the chain. + throw error; + }).then(requirements => { + return new Promise(function(resolve, reject) { + let child = path.resolve(requirements.java_home + '/bin/javac'); + let params = [sourcePath, '-d', path.resolve(outputPath)]; + + console.log('Executing ' + child + ' ' + params.join(' ')); + + let childProcess = cp.spawn(child, params, { + silent: true, + }); + childProcess.stdout.on('data', function (data) { + console.log('stdout: ' + data); + }); + childProcess.stderr.on('data', function (data) { + console.log('stderr: ' + data); + }); + childProcess.once('error', function (err) { + reject(err); + }); + childProcess.on('exit', function (code) { + if (code === 0) { + resolve(); + } + else { + reject(code); + } + }); + + }); + }) +} + function prepareParams(requirements, javaConfiguration, workspacePath) { let params = []; if (DEBUG) { From 39612c3204f7a0136ddf6b17af6ab2e44b709eaa Mon Sep 17 00:00:00 2001 From: xuzho Date: Wed, 9 Aug 2017 16:34:44 +0800 Subject: [PATCH 2/4] resolve comments Signed-off-by: xuzho --- src/extension.ts | 4 ++-- src/javaServerStarter.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index cd8693b375..0613fd3c77 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -117,9 +117,9 @@ export function activate(context: ExtensionContext) { config.sourcePath = [cur]; config.cwd = cur; config.stopOnEntry = true; - await runJavaC(fullpath, cur).then(function () { + await runJavaC(fullpath, cur).then(() => { config.classpath = cur; - }, function (error) { + }, error => { vscode.window.showErrorMessage('Compile file failed. error: ' + error); }); } diff --git a/src/javaServerStarter.ts b/src/javaServerStarter.ts index 9079bee695..edee9e8a8a 100644 --- a/src/javaServerStarter.ts +++ b/src/javaServerStarter.ts @@ -12,7 +12,7 @@ const glob = require('glob'); declare let v8debug; const DEBUG = (typeof v8debug === 'object') || startedInDebugMode(); let electron = require('./electron_j'); -let cp = require('child_process'); +const cp = require('child_process'); export function awaitServerConnection(port): Thenable { let addr = parseInt(port); @@ -87,7 +87,7 @@ export function runJavaC(sourcePath, outputPath) { console.log('stderr: ' + data); }); childProcess.once('error', function (err) { - reject(err); + reject(err); }); childProcess.on('exit', function (code) { if (code === 0) { From 65d025c0b5562496958215f3b0d3619843c1813e Mon Sep 17 00:00:00 2001 From: xuzho Date: Fri, 11 Aug 2017 14:52:27 +0800 Subject: [PATCH 3/4] use default java project to build instead of javac --- src/extension.ts | 10 +++------- src/javaServerStarter.ts | 43 ---------------------------------------- src/protocol.ts | 4 ++++ 3 files changed, 7 insertions(+), 50 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 0613fd3c77..6118d6f71a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,9 +6,9 @@ import * as vscode from 'vscode'; import { workspace, ExtensionContext, window, StatusBarAlignment, commands, ViewColumn, Uri, CancellationToken, TextDocumentContentProvider, TextEditor, WorkspaceConfiguration, languages, IndentAction, ProgressLocation, Progress } from 'vscode'; import { LanguageClient, LanguageClientOptions, Position as LSPosition, Location as LSLocation } from 'vscode-languageclient'; -import { runServer, awaitServerConnection, runJavaC } from './javaServerStarter'; +import { runServer, awaitServerConnection } from './javaServerStarter'; import { Commands } from './commands'; -import { StatusNotification, ClassFileContentsRequest, ProjectConfigurationUpdateRequest, MessageType, ActionableNotification, FeatureStatus, ActionableMessage, DebugSessionRequest, ClasspathResolveRequest, ClasspathResolveRequestParams } from './protocol'; +import { StatusNotification, ClassFileContentsRequest, ProjectConfigurationUpdateRequest, MessageType, ActionableNotification, FeatureStatus, ActionableMessage, DebugSessionRequest, ClasspathResolveRequest, ClasspathResolveRequestParams, BuildWorkspaceRequest } from './protocol'; let os = require('os'); let oldConfig; @@ -117,11 +117,7 @@ export function activate(context: ExtensionContext) { config.sourcePath = [cur]; config.cwd = cur; config.stopOnEntry = true; - await runJavaC(fullpath, cur).then(() => { - config.classpath = cur; - }, error => { - vscode.window.showErrorMessage('Compile file failed. error: ' + error); - }); + await languageClient.sendRequest(BuildWorkspaceRequest.type, ''); } } if (!config.startupClass) { diff --git a/src/javaServerStarter.ts b/src/javaServerStarter.ts index edee9e8a8a..a3a43c3f7a 100644 --- a/src/javaServerStarter.ts +++ b/src/javaServerStarter.ts @@ -12,7 +12,6 @@ const glob = require('glob'); declare let v8debug; const DEBUG = (typeof v8debug === 'object') || startedInDebugMode(); let electron = require('./electron_j'); -const cp = require('child_process'); export function awaitServerConnection(port): Thenable { let addr = parseInt(port); @@ -60,48 +59,6 @@ export function runServer(workspacePath, javaConfig): Thenable { }); } -export function runJavaC(sourcePath, outputPath) { - return requirements.resolveRequirements().catch(error => { - //show error - window.showErrorMessage(error.message, error.label).then((selection) => { - if (error.label && error.label === selection && error.openUrl) { - commands.executeCommand(Commands.OPEN_BROWSER, error.openUrl); - } - }); - // rethrow to disrupt the chain. - throw error; - }).then(requirements => { - return new Promise(function(resolve, reject) { - let child = path.resolve(requirements.java_home + '/bin/javac'); - let params = [sourcePath, '-d', path.resolve(outputPath)]; - - console.log('Executing ' + child + ' ' + params.join(' ')); - - let childProcess = cp.spawn(child, params, { - silent: true, - }); - childProcess.stdout.on('data', function (data) { - console.log('stdout: ' + data); - }); - childProcess.stderr.on('data', function (data) { - console.log('stderr: ' + data); - }); - childProcess.once('error', function (err) { - reject(err); - }); - childProcess.on('exit', function (code) { - if (code === 0) { - resolve(); - } - else { - reject(code); - } - }); - - }); - }) -} - function prepareParams(requirements, javaConfiguration, workspacePath) { let params = []; if (DEBUG) { diff --git a/src/protocol.ts b/src/protocol.ts index 0ef8de02ab..65fed56011 100644 --- a/src/protocol.ts +++ b/src/protocol.ts @@ -82,4 +82,8 @@ export namespace DebugSessionRequest { export namespace ClasspathResolveRequest { export const type = new RequestType('java/resolveClasspaths'); +} + +export namespace BuildWorkspaceRequest { + export const type = new RequestType('java/buildWorkspace'); } \ No newline at end of file From be281151d618b53f38c0457ac94f8340cee4b24c Mon Sep 17 00:00:00 2001 From: xuzho Date: Fri, 11 Aug 2017 18:18:49 +0800 Subject: [PATCH 4/4] if build has errors, not trigger debug and give user notification Signed-off-by: xuzho --- src/extension.ts | 12 ++++++++---- src/protocol.ts | 11 ++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 6118d6f71a..f0605b0dc5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -8,7 +8,7 @@ import { workspace, ExtensionContext, window, StatusBarAlignment, commands, View import { LanguageClient, LanguageClientOptions, Position as LSPosition, Location as LSLocation } from 'vscode-languageclient'; import { runServer, awaitServerConnection } from './javaServerStarter'; import { Commands } from './commands'; -import { StatusNotification, ClassFileContentsRequest, ProjectConfigurationUpdateRequest, MessageType, ActionableNotification, FeatureStatus, ActionableMessage, DebugSessionRequest, ClasspathResolveRequest, ClasspathResolveRequestParams, BuildWorkspaceRequest } from './protocol'; +import { StatusNotification, ClassFileContentsRequest, ProjectConfigurationUpdateRequest, MessageType, ActionableNotification, FeatureStatus, ActionableMessage, DebugSessionRequest, ClasspathResolveRequest, ClasspathResolveRequestParams, BuildWorkspaceRequest, BuildWorkspaceResult, BuildWorkspaceStatus } from './protocol'; let os = require('os'); let oldConfig; @@ -112,12 +112,16 @@ export function activate(context: ExtensionContext) { const editor = vscode.window.activeTextEditor; if (editor && editor.document.languageId === 'java') { const fullpath = editor.document.fileName; - const cur = path.parse(fullpath).dir; - config.startupClass = path.parse(fullpath).base.slice(0, -5); + const cur = path.dirname(fullpath); + config.startupClass = path.basename(fullpath, '.java'); config.sourcePath = [cur]; config.cwd = cur; config.stopOnEntry = true; - await languageClient.sendRequest(BuildWorkspaceRequest.type, ''); + const buildResult = await languageClient.sendRequest(BuildWorkspaceRequest.type, ''); + if (buildResult.status === BuildWorkspaceStatus.FAILURE) { + vscode.window.showErrorMessage('Build failed, please fix build error first.'); + return; + } } } if (!config.startupClass) { diff --git a/src/protocol.ts b/src/protocol.ts index 65fed56011..764718a8e6 100644 --- a/src/protocol.ts +++ b/src/protocol.ts @@ -60,6 +60,15 @@ export interface ClasspathResolveRequestParams { projectName?: string; } +export enum BuildWorkspaceStatus { + FAILURE = 0, + SUCCESS = 1, +} + +export interface BuildWorkspaceResult { + status: BuildWorkspaceStatus; +} + export namespace StatusNotification { export const type = new NotificationType('language/status'); } @@ -85,5 +94,5 @@ export namespace ClasspathResolveRequest { } export namespace BuildWorkspaceRequest { - export const type = new RequestType('java/buildWorkspace'); + export const type = new RequestType('java/buildWorkspace'); } \ No newline at end of file