diff --git a/vscode-wpilib/i18n/zh-CN/package.i18n.json b/vscode-wpilib/i18n/zh-CN/package.i18n.json index d0541150..326bfd8f 100644 --- a/vscode-wpilib/i18n/zh-CN/package.i18n.json +++ b/vscode-wpilib/i18n/zh-CN/package.i18n.json @@ -31,5 +31,6 @@ "wpilibcore.setDeployOffline.title": "在离线模式中 更改 部署/调试命令 设置", "wpilibcore.setOffline.title": "在离线模式中 更改 部署/调试命令 外的设置", "wpilibcore.selectCppBinaryTypes.title": "Select Enabled C++ Intellisense Binary Types", - "wpilibcore.openApiDocumentation.title": "Open API Documentation" + "wpilibcore.openApiDocumentation.title": "Open API Documentation", + "wpilibjava.setupRunDebugButtons.title": "Setup Java Run and Debug Buttons" } diff --git a/vscode-wpilib/package.json b/vscode-wpilib/package.json index 38a017ae..d8ba9188 100644 --- a/vscode-wpilib/package.json +++ b/vscode-wpilib/package.json @@ -310,6 +310,11 @@ "command": "wpilibcore.openApiDocumentation", "title": "%wpilibcore.openApiDocumentation.title%", "category": "WPILib" + }, + { + "command": "wpilibjava.setupRunDebugButtons", + "title": "%wpilibjava.setupRunDebugButtons.title%", + "category": "WPILib" } ], "views": { diff --git a/vscode-wpilib/package.nls.json b/vscode-wpilib/package.nls.json index 71821bb6..89222305 100644 --- a/vscode-wpilib/package.nls.json +++ b/vscode-wpilib/package.nls.json @@ -31,5 +31,6 @@ "wpilibcore.resetAutoUpdate.title": "Reset Ask for WPILib Updates Flag", "wpilibcore.changeDesktop.title": "Change Desktop Support Enabled Setting", "wpilibcore.selectCppBinaryTypes.title": "Select Enabled C++ Intellisense Binary Types", - "wpilibcore.openApiDocumentation.title": "Open API Documentation" + "wpilibcore.openApiDocumentation.title": "Open API Documentation", + "wpilibjava.setupRunDebugButtons.title": "Setup Java Run and Debug Buttons" } diff --git a/vscode-wpilib/src/java/deploydebug.ts b/vscode-wpilib/src/java/deploydebug.ts index fd95a9ea..a643add1 100644 --- a/vscode-wpilib/src/java/deploydebug.ts +++ b/vscode-wpilib/src/java/deploydebug.ts @@ -167,13 +167,14 @@ class SimulateCodeDeployer implements ICodeDeployer { const currentLanguage = prefs.getCurrentLanguage(); return currentLanguage === 'none' || currentLanguage === 'java'; } - public async runDeployer(_: number, workspace: vscode.WorkspaceFolder, - __: vscode.Uri | undefined, ...args: string[]): Promise { + + public async getSimulationInformation(_: number, workspace: vscode.WorkspaceFolder, + __: vscode.Uri | undefined, ...args: string[]): Promise { const command = 'simulateExternalJava ' + args.join(' '); const prefs = this.preferences.getPreferences(workspace); const result = await gradleRun(command, workspace.uri.fsPath, workspace, 'Java Simulate', this.executeApi, prefs); if (result !== 0) { - return false; + return undefined; } const simulateInfo = await readFileAsync(path.join(workspace.uri.fsPath, 'build', 'debug', 'desktopinfo.json'), 'utf8'); @@ -189,7 +190,7 @@ class SimulateCodeDeployer implements ICodeDeployer { }); if (picked === undefined) { vscode.window.showInformationMessage('Artifact cancelled'); - return false; + return undefined; } targetSimulateInfo = picked.debugInfo; } @@ -224,6 +225,19 @@ class SimulateCodeDeployer implements ICodeDeployer { workspace, }; + return config; + + } + + public async runDeployer(_: number, workspace: vscode.WorkspaceFolder, + __: vscode.Uri | undefined, ...args: string[]): Promise { + + const config = await this.getSimulationInformation(_, workspace, __, ...args); + + if (config === undefined) { + return false; + } + await startSimulation(config); return true; @@ -257,6 +271,10 @@ export class DeployDebug { } } + public getSimulator(): SimulateCodeDeployer { + return this.simulator; + } + public dispose() { // } diff --git a/vscode-wpilib/src/java/java.ts b/vscode-wpilib/src/java/java.ts index 7e70045b..5f0e599d 100644 --- a/vscode-wpilib/src/java/java.ts +++ b/vscode-wpilib/src/java/java.ts @@ -12,10 +12,11 @@ import { onVendorDepsChanged } from '../vendorlibraries'; import { BuildTest } from './buildtest'; import { Commands } from './commands'; import { DeployDebug } from './deploydebug'; +import { getCodeLensRunCommand, getCodeLensTestCommand } from './simulate'; // this method is called when your extension is activated // your extension is activated the very first time the command is executed -export async function activateJava(context: vscode.ExtensionContext, coreExports: IExternalAPI) { +export async function activateJava(context: vscode.ExtensionContext, coreExports: IExternalAPI): Promise { const extensionResourceLocation = path.join(context.extensionPath, 'resources', 'java'); @@ -33,9 +34,7 @@ export async function activateJava(context: vscode.ExtensionContext, coreExports } // Setup build and test - const buildTest = new BuildTest(coreExports); - context.subscriptions.push(buildTest); // Setup debug and deploy @@ -52,6 +51,59 @@ export async function activateJava(context: vscode.ExtensionContext, coreExports const templates: Templates = new Templates(extensionResourceLocation, true, exampleTemplate); context.subscriptions.push(templates); + // Setup java run debug configuration + context.subscriptions.push(vscode.commands.registerCommand('wpilibjava.setupRunDebugButtons', async () => { + const preferencesApi = coreExports.getPreferencesAPI(); + const workspace = await preferencesApi.getFirstOrSelectedWorkspace(); + if (workspace === undefined) { + vscode.window.showInformationMessage('Cannot enable simulation with an empty workspace'); + return; + } + const teamNumber = await preferencesApi.getPreferences(workspace).getTeamNumber(); + const simInfo = await deployDebug.getSimulator().getSimulationInformation(teamNumber, workspace, undefined); + + if (simInfo === undefined) { + return; + } + + const config = vscode.workspace.getConfiguration('launch', workspace.uri); + const testConfig = vscode.workspace.getConfiguration('java.test', workspace.uri); + + // tslint:disable-next-line:no-any + const testValues: any[] | undefined = testConfig.get('config', undefined); + const has = testConfig.has('config'); + + // This is broken, getting proxy objects. Need to figure out what is going on. + if (testValues === undefined || !has) { + testConfig.update('config', [await getCodeLensTestCommand(simInfo)]); + } else { + let found = false; + for (let i = 0; i < testValues.length; i++) { + // tslint:disable-next-line: no-unsafe-any + if (testValues[i].name === 'WPILib Configuration') { + testValues[i] = await getCodeLensTestCommand(simInfo); + testConfig.update('config', testValues); + found = true; + break; + } + } + if (!found) { + testValues.push(await getCodeLensTestCommand(simInfo)); + testConfig.update('config', testValues); + } + } + + // tslint:disable-next-line:no-any + const values: any[] | undefined = config.get('configurations'); + + if (values === undefined) { + config.update('configurations', [await getCodeLensRunCommand(simInfo)]); + } else { + values.push(await getCodeLensRunCommand(simInfo)); + config.update('configurations', values); + } +})); + if (vscode.extensions.getExtension('redhat.java') !== undefined) { // Add handlers for each workspace if java is installed const wp = vscode.workspace.workspaceFolders; diff --git a/vscode-wpilib/src/java/simulate.ts b/vscode-wpilib/src/java/simulate.ts index 2a42ff79..9124848f 100644 --- a/vscode-wpilib/src/java/simulate.ts +++ b/vscode-wpilib/src/java/simulate.ts @@ -11,6 +11,59 @@ export interface ISimulateCommands { workspace: vscode.WorkspaceFolder; } +export interface ICodeLensCommand { + console: string; + cwd: string; + env: { [key: string]: string }; + mainClass: string; + name: string; + request: string; + stopOnEntry: boolean; + type: string; + vmArgs: string; +} + +export interface ITestCodeLensCommand { + env: { [key: string]: string }; + name: string; + vmargs: string[]; + workingDirectory: string; +} + +export async function getCodeLensRunCommand(commands: ISimulateCommands): Promise { + let mainClassName = commands.mainclass; + const lastDot = mainClassName.lastIndexOf('.'); + if (lastDot > 0) { + mainClassName = mainClassName.substring(lastDot + 1); + } + return { + console: 'integratedTerminal', + cwd: commands.workspace.uri.fsPath, + env: { + DYLD_LIBRARY_PATH: commands.librarydir, + HALSIM_EXTENSIONS: commands.extensions, + LD_LIBRARY_PATH: commands.librarydir, + PATH: commands.librarydir, + }, + mainClass: commands.mainclass, + name: `CodeLens (Launch) - ${mainClassName}`, + request: 'launch', + stopOnEntry: commands.stopOnEntry, + type: 'java', + vmArgs: `-Djava.library.path="${commands.librarydir}"`, + }; +} + +export async function getCodeLensTestCommand(commands: ISimulateCommands): Promise { + const runData = await getCodeLensRunCommand(commands); + return { + env: runData.env, + name: 'WPILib Configuration', + vmargs: [runData.vmArgs], + workingDirectory: commands.workspace.uri.fsPath, + }; +} + export async function startSimulation(commands: ISimulateCommands): Promise { const config: vscode.DebugConfiguration = { args: commands.robotclass, diff --git a/vscode-wpilib/tslint.json b/vscode-wpilib/tslint.json index 0530cd77..39add249 100644 --- a/vscode-wpilib/tslint.json +++ b/vscode-wpilib/tslint.json @@ -11,7 +11,8 @@ "allow-leading-underscore" ], "max-classes-per-file": [ - false + false, + 1 ], "max-line-length": [ true, @@ -57,5 +58,10 @@ "no-var-keyword": true, "eofline": true }, + "linterOptions": { + "exclude": [ + "node_modules/**" + ] + }, "defaultSeverity": "error" }