Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

Commit

Permalink
Implement remote debugging with localRoot/remoteRoot
Browse files Browse the repository at this point in the history
  • Loading branch information
roblourens committed Sep 13, 2016
1 parent 7c9784d commit db803e5
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 42 deletions.
8 changes: 6 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@
"cwd": "${workspaceRoot}/../../.vscode/extensions/vscode-chrome-debug",
"program": "${workspaceRoot}/../../.vscode/extensions/vscode-chrome-debug/out/src/chromeDebug.js"
},
// "osx": {
// "cwd": "${workspaceRoot}/../vscode-chrome-debug",
// "program": "${workspaceRoot}/../vscode-chrome-debug/out/src/chromeDebug.js"
// },
"osx": {
"cwd": "${workspaceRoot}/../vscode-chrome-debug",
"program": "${workspaceRoot}/../vscode-chrome-debug/out/src/chromeDebug.js"
"cwd": "${workspaceRoot}/../vscode-node-cdp-debug",
"program": "${workspaceRoot}/../vscode-node-cdp-debug/out/src/nodeDebug.js"
},
"stopOnEntry": false,
"args": [ "--server=4712" ],
Expand Down
2 changes: 1 addition & 1 deletion src/chrome/chromeConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export class ChromeConnection {
}

public runtime_getProperties(objectId: string, ownProperties: boolean, accessorPropertiesOnly: boolean): Promise<Chrome.Runtime.GetPropertiesResponse> {
return this.sendMessage('Runtime.getProperties', <Chrome.Runtime.GetPropertiesParams>{ objectId, ownProperties, accessorPropertiesOnly });
return this.sendMessage('Runtime.getProperties', <Chrome.Runtime.GetPropertiesParams>{ objectId, ownProperties, accessorPropertiesOnly, generatePreview: true });
}

public runtime_evaluate(expression: string, objectGroup = 'dummyObjectGroup', contextId = 1, returnByValue = false): Promise<Chrome.Runtime.EvaluateResponse> {
Expand Down
3 changes: 2 additions & 1 deletion src/chrome/chromeDebugAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {BaseDebugAdapter} from '../baseDebugAdapter';

import {LineNumberTransformer} from '../transformers/lineNumberTransformer';
import {BasePathTransformer} from '../transformers/basePathTransformer';
import {RemotePathTransformer} from '../transformers/remotePathTransformer';
import {LazySourceMapTransformer} from '../transformers/lazySourceMapTransformer';

import * as path from 'path';
Expand Down Expand Up @@ -65,7 +66,7 @@ export abstract class ChromeDebugAdapter extends BaseDebugAdapter {

this._lineNumberTransformer = lineNumberTransformer || new LineNumberTransformer(/*targetLinesStartAt1=*/false);
this._sourceMapTransformer = sourceMapTransformer || new LazySourceMapTransformer();
this._pathTransformer = pathTransformer || new BasePathTransformer();
this._pathTransformer = pathTransformer || new RemotePathTransformer();

this.clearEverything();
}
Expand Down
2 changes: 2 additions & 0 deletions src/debugAdapterInterfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export interface IAttachRequestArgs extends DebugProtocol.AttachRequestArguments
port: number;
url?: string;
address?: string;
remoteRoot?: string;
localRoot?: string;
}

export interface ISetBreakpointsArgs extends DebugProtocol.SetBreakpointsArguments {
Expand Down
41 changes: 41 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/

import {DebugProtocol} from 'vscode-debugprotocol';

import {localize} from './utils';

export function attributePathNotExist(attribute: string, path: string): DebugProtocol.Message {
return {
id: 2007,
format: localize('attribute.path.not.exist', "Attribute '{0}' does not exist ('{1}').", attribute, '{path}'),
variables: { path }
};
}

/**
* Error stating that a relative path should be absolute
*/
export function attributePathRelative(attribute: string, path: string): DebugProtocol.Message {
return withInfoLink(
2008,
localize('attribute.path.not.absolute', "Attribute '{0}' is not absolute ('{1}'); consider adding '{2}' as a prefix to make it absolute.", attribute, '{path}', '${workspaceRoot}/'),
{ path },
20003
);
}

/**
* Get error with 'More Information' link.
*/
export function withInfoLink(id: number, format: string, variables: any, infoId: number): DebugProtocol.Message {
return {
id,
format,
variables,
showUser: true,
url: 'http://go.microsoft.com/fwlink/?linkID=534832#_' + infoId.toString(),
urlLabel: localize('more.information', "More Information")
};
}
10 changes: 6 additions & 4 deletions src/transformers/basePathTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import {ISetBreakpointsArgs, ILaunchRequestArgs, IAttachRequestArgs, IStackTrace
* Converts a local path from Code to a path on the target.
*/
export class BasePathTransformer {
public launch(args: ILaunchRequestArgs): void {
public launch(args: ILaunchRequestArgs): Promise<void> {
return Promise.resolve<void>();
}

public attach(args: IAttachRequestArgs): void {
public attach(args: IAttachRequestArgs): Promise<void> {
return Promise.resolve<void>();
}

public setBreakpoints(args: ISetBreakpointsArgs): Promise<void> {
Expand All @@ -24,8 +26,8 @@ export class BasePathTransformer {
public clearTargetContext(): void {
}

public scriptParsed(scriptUrl: string): string {
return scriptUrl;
public scriptParsed(scriptPath: string): string {
return scriptPath;
}

public stackTraceResponse(response: IStackTraceResponseBody): void {
Expand Down
88 changes: 73 additions & 15 deletions src/transformers/remotePathTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,96 @@
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/

import {ISetBreakpointsArgs, ILaunchRequestArgs, IAttachRequestArgs, IStackTraceResponseBody} from '../debugAdapterInterfaces';
import * as path from 'path';
import * as fs from 'fs';

import {BasePathTransformer} from './basePathTransformer';

import * as utils from '../utils';
import * as errors from '../errors';
import {ISetBreakpointsArgs, IAttachRequestArgs, IStackTraceResponseBody} from '../debugAdapterInterfaces';

/**
* Converts a local path from Code to a path on the target.
*/
export class BasePathTransformer {
public launch(args: ILaunchRequestArgs): void {
}
export class RemotePathTransformer extends BasePathTransformer {
private _localRoot: string;
private _remoteRoot: string;

public attach(args: IAttachRequestArgs): void {
private get shouldMapPaths(): boolean {
return !!this._localRoot && !!this._remoteRoot;
}

public setBreakpoints(args: ISetBreakpointsArgs): Promise<void> {
return Promise.resolve<void>();
}
public attach(args: IAttachRequestArgs): Promise<void> {
// Validate that localRoot is absolute and exists
let localRootP = Promise.resolve<void>();
if (args.localRoot) {
const localRoot = args.localRoot;
if (!path.isAbsolute(localRoot)) {
return Promise.reject(errors.attributePathRelative('localRoot', localRoot));
}

public clearClientContext(): void {
localRootP = new Promise<void>((resolve, reject) => {
fs.exists(localRoot, exists => {
if (!exists) {
reject(errors.attributePathNotExist('localRoot', localRoot));
}

this._localRoot = localRoot;
resolve();
});
});
}

// Maybe validate that it's absolute, for either windows or unix
this._remoteRoot = args.remoteRoot;

return localRootP;
}

public clearTargetContext(): void {
public setBreakpoints(args: ISetBreakpointsArgs): Promise<void> {
if (!args.source.path) {
return Promise.resolve<void>();
}

args.source.path = this.localToRemote(args.source.path);
return super.setBreakpoints(args);
}

public scriptParsed(scriptUrl: string): string {
return scriptUrl;
public scriptParsed(scriptPath: string): string {
scriptPath = this.remoteToLocal(scriptPath);
return super.scriptParsed(scriptPath);
}

public stackTraceResponse(response: IStackTraceResponseBody): void {
// Have a responsibility to clean up the sourceReference here when it's not needed... See #93
response.stackFrames.forEach(frame => {
if (frame.source.path) {
frame.source.sourceReference = 0;
const remotePath = frame.source.path;
if (remotePath) {
frame.source.path = this.remoteToLocal(remotePath);
}
});

return super.stackTraceResponse(response);
}

private remoteToLocal(remotePath: string): string {
if (!this.shouldMapPaths) return remotePath;

// need / paths for path.relative, if this platform is posix
remotePath = utils.forceForwardSlashes(remotePath);

const relPath = path.relative(this._remoteRoot, remotePath);
const localPath = path.join(this._localRoot, relPath);

return utils.fixDriveLetterAndSlashes(localPath);
}

private localToRemote(localPath: string): string {
if (!this.shouldMapPaths) return localPath;

const relPath = path.relative(this._localRoot, localPath);
const remotePath = path.join(this._remoteRoot, relPath);

return utils.fixDriveLetterAndSlashes(remotePath);
}
}
6 changes: 4 additions & 2 deletions src/transformers/urlPathTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ export class UrlPathTransformer extends BasePathTransformer {
private _targetUrlToClientPath = new Map<string, string>();
private _pendingBreakpointsByPath = new Map<string, IPendingBreakpoint>();

public launch(args: ILaunchRequestArgs): void {
public launch(args: ILaunchRequestArgs): Promise<void> {
this._webRoot = args.webRoot;
return super.launch(args);
}

public attach(args: IAttachRequestArgs): void {
public attach(args: IAttachRequestArgs): Promise<void> {
this._webRoot = args.webRoot;
return super.attach(args);
}

public setBreakpoints(args: ISetBreakpointsArgs): Promise<void> {
Expand Down
33 changes: 21 additions & 12 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,16 @@ export function forceForwardSlashes(aUrl: string): string {
* Ensure lower case drive letter and \ on Windows
*/
export function fixDriveLetterAndSlashes(aPath: string): string {
if (getPlatform() === Platform.Windows) {
if (aPath.match(/file:\/\/\/[A-Za-z]:/)) {
const prefixLen = 'file:///'.length;
aPath =
'file:///' +
aPath[prefixLen].toLowerCase() +
aPath.substr(prefixLen + 1).replace(/\//g, path.sep);
} else if (aPath.match(/^[A-Za-z]:/)) {
// If this is Windows and the path starts with a drive letter, ensure lowercase. VS Code uses a lowercase drive letter
aPath = aPath[0].toLowerCase() + aPath.substr(1);
aPath = aPath.replace(/\//g, path.sep);
}
if (aPath.match(/file:\/\/\/[A-Za-z]:/)) {
const prefixLen = 'file:///'.length;
aPath =
'file:///' +
aPath[prefixLen].toLowerCase() +
aPath.substr(prefixLen + 1).replace(/\//g, path.sep);
} else if (aPath.match(/^[A-Za-z]:/)) {
// If this is Windows and the path starts with a drive letter, ensure lowercase. VS Code uses a lowercase drive letter
aPath = aPath[0].toLowerCase() + aPath.substr(1);
aPath = aPath.replace(/\//g, path.sep);
}

return aPath;
Expand Down Expand Up @@ -264,3 +262,14 @@ export function pathToFileURL(absPath: string): string {
absPath;
return encodeURI(absPath);
}

/**
* Placeholder localize function
*/
export function localize(id: string, msg: string, ...args: any[]): string {
args.forEach((arg, i) => {
msg = msg.replace(new RegExp(`\\{${i}\\}`, 'g'), arg);
});

return msg;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function createTransformer(): _UrlPathTransformer {
return new (require(MODULE_UNDER_TEST).UrlPathTransformer)();
}

suite('PathTransformer', () => {
suite('UrlPathTransformer', () => {
const TARGET_URL = 'http://mysite.com/scripts/script1.js';
const CLIENT_PATH = testUtils.pathResolve('/projects/mysite/scripts/script1.js');

Expand Down
4 changes: 0 additions & 4 deletions tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@
"check-else",
"check-whitespace"
],
"quotemark": [
true,
"single"
],
"radix": true,
"semicolon": true,
"switch-default": true,
Expand Down

0 comments on commit db803e5

Please sign in to comment.