Skip to content

Commit

Permalink
Merge pull request #1885 from captainsafia/safia/debug-adapter
Browse files Browse the repository at this point in the history
Add support for one-step debugging for Blazor
  • Loading branch information
captainsafia authored May 14, 2020
2 parents d88c258 + ea7b144 commit 2d31bd0
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"activationEvents": [
"onWebviewPanel:razorReportIssue",
"onDebugInitialConfigurations",
"onDebugResolve:blazorwasm",
"onDebugResolve:coreclr",
"onDebugResolve:clr",
"onLanguage:csharp",
Expand Down Expand Up @@ -46,6 +47,65 @@
],
"main": "./dist/extension",
"contributes": {
"breakpoints": [
{
"language": "aspnetcorerazor"
},
{
"language": "csharp"
}
],
"debuggers": [
{
"type": "blazorwasm",
"label": "Blazor WebAssembly Debug",
"initialConfigurations": [
{
"type": "blazorwasm",
"name": "Launch and Debug Blazor WebAssembly Application",
"request": "launch"
}
],
"configurationAttributes": {
"launch": {
"properties": {
"cwd": {
"type": "string",
"description": "The directory of the Blazor WebAssembly app, defaults to the workspace folder.",
"default": "${workspaceFolder}"
},
"url": {
"type": "string",
"description": "The URL of the application",
"default": "https://localhost:5001"
},
"browser": {
"type": "string",
"description": "The debugging browser to launch (Edge or Chrome)",
"default": "chrome",
"enum": ["chrome", "edge"]
},
"trace": {
"type": ["boolean", "string"],
"default": "true",
"enum": ["verbose", true],
"description": "If true, verbose logs from JS debugger are sent to log file. If 'verbose', send logs to console."
},
"webRoot": {
"type": "string",
"default": "${workspaceFolder}",
"description": "Specifies the absolute path to the webserver root."
},
"timeout": {
"type": "number",
"default": 30000,
"description": "Retry for this number of milliseconds to connect to browser."
}
}
}
}
}
],
"semanticTokenTypes": [
{
"id": "razorTagHelperElement",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ path-parse@^1.0.6:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==

ps-list@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-7.0.0.tgz#fd740a839786605d257117b899031db9b34b8b4b"
integrity sha512-ZDhdxqb+kE895BAvqIdGnWwfvB43h7KHMIcJC0hw7xLbbiJoprS+bqZxuGZ0jWdDxZEvB3jpnfgJyOn3lmsH+Q==

resolve@^1.3.2:
version "1.12.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"typescript": "3.3.4000"
},
"dependencies": {
"ps-list": "^7.0.0",
"vscode-html-languageservice": "2.1.7",
"vscode-languageclient": "5.2.1"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import * as vscode from 'vscode';

import { RazorLogger } from '../RazorLogger';
import { onDidTerminateDebugSession } from './TerminateDebugHandler';

export class BlazorDebugConfigurationProvider implements vscode.DebugConfigurationProvider {

constructor(private readonly logger: RazorLogger, private readonly vscodeType: typeof vscode) { }

public async resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, configuration: vscode.DebugConfiguration): Promise<vscode.DebugConfiguration | undefined> {
const shellPath = process.platform === 'win32' ? 'cmd.exe' : 'dotnet';
const shellArgs = process.platform === 'win32' ? ['/c', 'chcp 65001 >NUL & dotnet run'] : ['run'];
const spawnOptions = {
cwd: configuration.cwd || (folder && folder.uri && folder.uri.fsPath),
};

const output = this.vscodeType.window.createTerminal({
name: 'Blazor WebAssembly App',
shellPath,
shellArgs,
...spawnOptions,
});

/**
* On non-Windows platforms, we need to terminate the Blazor
* dev server and its child processes.
*/
const terminate = this.vscodeType.debug.onDidTerminateDebugSession(async event => {
await onDidTerminateDebugSession(event, this.logger, await output.processId);
terminate.dispose();
});

output.show(/*preserveFocus*/true);

const browser = {
name: '.NET Core Debug Blazor Web Assembly in Browser',
type: configuration.browser === 'edge' ? 'pwa-msedge' : 'pwa-chrome',
request: 'launch',
timeout: configuration.timeout || 30000,
url: configuration.url || 'https://localhost:5001',
webRoot: configuration.webRoot || '${workspaceFolder}',
inspectUri: '{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}',
trace: configuration.trace || false,
noDebug: configuration.noDebug || false,
};

try {
/**
* The browser debugger will immediately launch after the
* application process is started. It waits a `timeout`
* interval before crashing after being unable to find the launched
* process.
*
* We do this to provide immediate visual feedback to the user
* that their debugger session has started.
*/
await this.vscodeType.debug.startDebugging(folder, browser);
this.logger.logVerbose('[DEBUGGER] Launching browser debugger...');
} catch (error) {
this.logger.logError(
'[DEBUGGER] Error when launching browser debugger: ',
error,
);
const message = `There was an unexpected error while launching your debugging session. Check the console for helpful logs and visit the debugging docs for more info.`;
this.vscodeType.window.showErrorMessage(message, `View Debug Docs`, `Ignore`).then(async result => {
if (result === 'View Debug Docs') {
const debugDocsUri = 'https://aka.ms/blazorwasmcodedebug';
await this.vscodeType.commands.executeCommand(`vcode.open`, debugDocsUri);
}
});
}

/**
* If `resolveDebugConfiguration` returns undefined, then the debugger
* launch is canceled. Here, we opt to manually launch the browser
* configruation using `startDebugging` above instead of returning
* the configuration to avoid a bug where VS Code is unable to resolve
* the debug adapter for the browser debugger.
*/
return undefined;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import * as psList from 'ps-list';
import { DebugSession } from 'vscode';

import { RazorLogger } from '../RazorLogger';

export async function onDidTerminateDebugSession(
event: DebugSession,
logger: RazorLogger,
targetPid: number | undefined,
) {
if (event.type !== 'pwa-chrome' && event.type !== 'pwa-msedge') {
return;
}
if (!targetPid) {
return;
}

logger.logVerbose(`[DEBUGGER] Terminating debugging session with PID ${targetPid}...`);

let processes: psList.ProcessDescriptor[] = [];
try {
processes = await psList();
} catch (error) {
logger.logError(`Error retrieving processes under PID ${targetPid} to clean-up: `, error);
}

try {
process.kill(targetPid);
processes.map((proc) => {
if (proc.ppid === targetPid) {
process.kill(proc.pid);
}
});
logger.logVerbose(`[DEBUGGER] Debug process clean-up of PID ${targetPid} complete.`);
} catch (error) {
logger.logError(`[DEBUGGER] Error terminating debug processes with PID ${targetPid}: `, error);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import * as vscode from 'vscode';
import * as vscodeapi from 'vscode';
import { ExtensionContext } from 'vscode';
import { BlazorDebugConfigurationProvider } from './BlazorDebug/BlazorDebugConfigurationProvider';
import { CompositeCodeActionTranslator } from './CodeActions/CompositeRazorCodeActionTranslator';
import { RazorCodeActionProvider } from './CodeActions/RazorCodeActionProvider';
import { RazorFullyQualifiedCodeActionTranslator } from './CodeActions/RazorFullyQualifiedCodeActionTranslator';
Expand Down Expand Up @@ -182,6 +183,9 @@ export async function activate(vscodeType: typeof vscodeapi, context: ExtensionC
localRegistrations.length = 0;
});

const provider = new BlazorDebugConfigurationProvider(logger, vscodeType);
context.subscriptions.push(vscodeType.debug.registerDebugConfigurationProvider('blazorwasm', provider));

languageServerClient.onStarted(async () => {
await documentManager.initialize();
});
Expand Down
5 changes: 5 additions & 0 deletions src/Razor/src/Microsoft.AspNetCore.Razor.VSCode/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ path-parse@^1.0.6:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==

ps-list@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-7.0.0.tgz#fd740a839786605d257117b899031db9b34b8b4b"
integrity sha512-ZDhdxqb+kE895BAvqIdGnWwfvB43h7KHMIcJC0hw7xLbbiJoprS+bqZxuGZ0jWdDxZEvB3jpnfgJyOn3lmsH+Q==

resolve@^1.3.2:
version "1.12.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2606,6 +2606,11 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.3"

ps-list@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-7.0.0.tgz#fd740a839786605d257117b899031db9b34b8b4b"
integrity sha512-ZDhdxqb+kE895BAvqIdGnWwfvB43h7KHMIcJC0hw7xLbbiJoprS+bqZxuGZ0jWdDxZEvB3jpnfgJyOn3lmsH+Q==

psl@^1.1.24, psl@^1.1.28:
version "1.7.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c"
Expand Down

0 comments on commit 2d31bd0

Please sign in to comment.