Sourcemaps for setBreakpointsRequest (for source.path) and testapp with TS
This commit is contained in:
Родитель
323b0fccac
Коммит
955942fc75
|
@ -8,7 +8,7 @@
|
|||
"runtimeArgs": ["--harmony"],
|
||||
"stopOnEntry": false,
|
||||
"args": [ "--server=4712" ],
|
||||
"sourceMaps": true,
|
||||
"sourceMaps": false,
|
||||
"outDir": "out"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
},
|
||||
"license": "",
|
||||
"dependencies": {
|
||||
"ws": "^0.7.2"
|
||||
"ws": "^0.7.2",
|
||||
"source-map": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.0",
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
{
|
||||
"name": "test webkit",
|
||||
"type": "webkit",
|
||||
"runtimeArgs": ["http://localhost:8080/index.html"],
|
||||
"program": "out/client/index.html",
|
||||
//"runtimeArgs": ["http://localhost:8080/index.html"],
|
||||
"cwd": "./client",
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": false
|
||||
"sourceMaps": true,
|
||||
"outDir": "out"
|
||||
},
|
||||
{
|
||||
"name": "attach to webkit",
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
function callLocalhost() {
|
||||
fetch('http://localhost:8080').then(function(r) {
|
||||
return r.text();
|
||||
}).then(function(t) {
|
||||
document.getElementById('result').textContent = t;
|
||||
});
|
||||
}
|
||||
|
||||
function printHello() {
|
||||
var arr1 = [1, 2, 3];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var arr2 = new Array();
|
||||
arr2.push('array element');
|
||||
var buffer = new ArrayBuffer(8);
|
||||
var buffView = new Int32Array(buffer);
|
||||
buffView[0] = 234;
|
||||
|
||||
var s = Symbol('hi');
|
||||
var bool = true;
|
||||
var fn = function() {
|
||||
// Some fn
|
||||
|
@ -25,8 +22,7 @@ function printHello() {
|
|||
var str = 'hello';
|
||||
var xyz = 1;
|
||||
var obj = { a: 2, get thing() { throw 'xyz'; }, set thing(x) { } };
|
||||
xyz++;
|
||||
xyz++;
|
||||
xyz++; xyz++;
|
||||
console.log(str + obj.a);
|
||||
anotherFn();
|
||||
fn();
|
|
@ -0,0 +1,40 @@
|
|||
/*---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
var gulp = require('gulp');
|
||||
var path = require('path');
|
||||
var ts = require('gulp-typescript');
|
||||
var log = require('gulp-util').log;
|
||||
var typescript = require('typescript');
|
||||
var sourcemaps = require('gulp-sourcemaps');
|
||||
|
||||
var sources = [
|
||||
'client'
|
||||
].map(function(tsFolder) { return tsFolder + '/**/*.ts'; });
|
||||
|
||||
var projectConfig = {
|
||||
noImplicitAny: false,
|
||||
target: 'ES5',
|
||||
module: 'commonjs',
|
||||
declarationFiles: true,
|
||||
typescript: typescript
|
||||
};
|
||||
|
||||
gulp.task('build', function () {
|
||||
gulp.src(sources, { base: '.' })
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(ts(projectConfig))
|
||||
.pipe(sourcemaps.write('.', { includeContent: false, sourceRoot: '../../' }))
|
||||
.pipe(gulp.dest('out'));
|
||||
|
||||
gulp.src('client/index.html', { base: '.' })
|
||||
.pipe(gulp.dest('out'));
|
||||
});
|
||||
|
||||
gulp.task('ts-watch', ['build'], function(cb) {
|
||||
log('Watching build sources...');
|
||||
gulp.watch(sources, ['build']);
|
||||
});
|
||||
|
||||
gulp.task('default', ['build']);
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "opendebug-webkit",
|
||||
"version": "0.0.0",
|
||||
"description": "OpenDebug adapters for the WebKit protocol",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation, Visual Studio Code Team"
|
||||
},
|
||||
"license": "",
|
||||
"dependencies": {
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-sourcemaps": "^1.5.2",
|
||||
"gulp-typescript": "^2.8.0",
|
||||
"gulp-util": "^3.0.5",
|
||||
"typescript": "^1.6.2"
|
||||
}
|
||||
}
|
3
tsd.json
3
tsd.json
|
@ -16,6 +16,9 @@
|
|||
},
|
||||
"es6-collections/es6-collections.d.ts": {
|
||||
"commit": "5109e1269d6ab8e8e73b1a5e85d8ceb836d3099f"
|
||||
},
|
||||
"source-map/source-map.d.ts": {
|
||||
"commit": "bb45306d0fd8ce0852a8d24c023fd787f4151e65"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/// <reference path="es6-collections/es6-collections.d.ts" />
|
||||
/// <reference path="es6-promise/es6-promise.d.ts" />
|
||||
/// <reference path="node/node.d.ts" />
|
||||
/// <reference path="source-map/source-map.d.ts" />
|
||||
/// <reference path="ws/ws.d.ts" />
|
||||
|
|
|
@ -313,7 +313,7 @@ class SourceMap {
|
|||
/*
|
||||
* finds the nearest location in the generated file for the given source location.
|
||||
*/
|
||||
public generatedPositionFor(src: string, line: number, column: number, bias = Bias.GREATEST_LOWER_BOUND): SourceMap.Position {
|
||||
public generatedPositionFor(src: string, line: number, column: number, bias = Bias.LEAST_UPPER_BOUND): SourceMap.Position {
|
||||
|
||||
// make input path relative to sourceRoot
|
||||
if (this._sourceRoot) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import {DebugSession, StoppedEvent, InitializedEvent, TerminatedEvent} from '../
|
|||
import {Handles} from '../common/handles';
|
||||
import {WebKitConnection} from './webKitConnection';
|
||||
import Utilities = require('./utilities');
|
||||
import {ISourceMaps, SourceMaps} from './sourceMaps';
|
||||
|
||||
import {Socket, createServer} from 'net';
|
||||
import {spawn, ChildProcess} from 'child_process';
|
||||
|
@ -28,6 +29,7 @@ export class WebKitDebugSession extends DebugSession {
|
|||
private _currentStack: WebKitProtocol.Debugger.CallFrame[];
|
||||
private _pendingBreakpointsByUrl: Map<string, IPendingBreakpoint>;
|
||||
private _committedBreakpointsByScriptId: Map<WebKitProtocol.Debugger.ScriptId, WebKitProtocol.Debugger.BreakpointId[]>;
|
||||
private _sourceMaps: ISourceMaps;
|
||||
|
||||
private _chromeProc: ChildProcess;
|
||||
private _webKitConnection: WebKitConnection;
|
||||
|
@ -77,7 +79,10 @@ export class WebKitDebugSession extends DebugSession {
|
|||
}
|
||||
|
||||
protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void {
|
||||
// Nothing really to do here.
|
||||
if (args.sourceMaps) {
|
||||
this._sourceMaps = new SourceMaps(args.generatedCodeDirectory);
|
||||
}
|
||||
|
||||
this.sendResponse(response);
|
||||
}
|
||||
|
||||
|
@ -91,7 +96,15 @@ export class WebKitDebugSession extends DebugSession {
|
|||
chromeArgs.push(...args.runtimeArguments);
|
||||
}
|
||||
|
||||
// Can html files be sourcemapped? May as well try.
|
||||
if (args.program) {
|
||||
if (this._sourceMaps) {
|
||||
const generatedPath = this._sourceMaps.MapPathFromSource(args.program);
|
||||
if (generatedPath) {
|
||||
args.program = generatedPath;
|
||||
}
|
||||
}
|
||||
|
||||
chromeArgs.push(args.program);
|
||||
}
|
||||
|
||||
|
@ -232,20 +245,40 @@ export class WebKitDebugSession extends DebugSession {
|
|||
}
|
||||
|
||||
private _setBreakpoints(response: DebugProtocol.SetBreakpointsResponse, args: DebugProtocol.SetBreakpointsArguments): Promise<void> {
|
||||
let sourceUrl = canonicalizeUrl(args.source.path);
|
||||
let script =
|
||||
args.source.path ? this._scriptsByUrl.get(sourceUrl) :
|
||||
args.source.sourceReference ? this._scriptsById.get(sourceReferenceToScriptId(args.source.sourceReference)) : null;
|
||||
let targetScript: WebKitProtocol.Debugger.Script;
|
||||
let path: string;
|
||||
if (args.source.path) {
|
||||
path = args.source.path;
|
||||
if (this._sourceMaps) {
|
||||
path = this._sourceMaps.MapPathFromSource(args.source.path) || args.source.path;
|
||||
}
|
||||
|
||||
let debuggerLines = args.lines
|
||||
.map(clientLine => this.convertClientLineToDebugger(clientLine));
|
||||
targetScript = this._scriptsByUrl.get(canonicalizeUrl(path));
|
||||
} else if (args.source.sourceReference) {
|
||||
// TODO de-sourcemap
|
||||
targetScript = this._scriptsById.get(sourceReferenceToScriptId(args.source.sourceReference));
|
||||
} else if (args.source.name) {
|
||||
// ??
|
||||
}
|
||||
|
||||
if (script) {
|
||||
if (targetScript) {
|
||||
// ODP sends all current breakpoints for the script. Clear all scripts for the breakpoint then add all of them
|
||||
return this.clearAllBreakpoints(script.scriptId).then(() => {
|
||||
return this.clearAllBreakpoints(targetScript.scriptId).then(() => {
|
||||
const debuggerLines = args.lines
|
||||
.map(clientLine => this.convertClientLineToDebugger(clientLine))
|
||||
.map(debuggerLine => {
|
||||
// Sourcemap lines
|
||||
if (this._sourceMaps) {
|
||||
const mapped = this._sourceMaps.MapFromSource(args.source.path, debuggerLine, /*column=*/0);
|
||||
return mapped ? mapped.line : debuggerLine;
|
||||
} else {
|
||||
return debuggerLine;
|
||||
}
|
||||
});
|
||||
|
||||
// Call setBreakpoint for all breakpoints in the script simultaneously, join to a single promise
|
||||
return Promise.all(debuggerLines
|
||||
.map(lineNumber => this._webKitConnection.debugger_setBreakpoint({ scriptId: script.scriptId, lineNumber })));
|
||||
.map(lineNumber => this._webKitConnection.debugger_setBreakpoint({ scriptId: targetScript.scriptId, lineNumber })));
|
||||
}).then(responses => {
|
||||
// Ignore errors
|
||||
let successfulResponses = responses
|
||||
|
@ -254,21 +287,33 @@ export class WebKitDebugSession extends DebugSession {
|
|||
// Process responses and cache in committedBreakpoints set
|
||||
let addedBreakpointIds = successfulResponses
|
||||
.map(response => response.result.breakpointId);
|
||||
this._committedBreakpointsByScriptId.set(script.scriptId, addedBreakpointIds);
|
||||
this._committedBreakpointsByScriptId.set(targetScript.scriptId, addedBreakpointIds);
|
||||
|
||||
// Map committed breakpoints to ODP response objects and send response
|
||||
let odpBreakpoints = successfulResponses
|
||||
.map(response => <DebugProtocol.Breakpoint>{
|
||||
verified: true,
|
||||
line: this.convertDebuggerLineToClient(response.result.actualLocation.lineNumber)
|
||||
.map(response => {
|
||||
let line = response.result.actualLocation.lineNumber;
|
||||
if (this._sourceMaps) {
|
||||
let mapped = this._sourceMaps.MapToSource(path, response.result.actualLocation.lineNumber, response.result.actualLocation.columnNumber);
|
||||
if (mapped) {
|
||||
line = mapped.line;
|
||||
}
|
||||
}
|
||||
|
||||
return <DebugProtocol.Breakpoint>{
|
||||
verified: true,
|
||||
line: this.convertDebuggerLineToClient(line)
|
||||
}
|
||||
});
|
||||
|
||||
response.body = { breakpoints: odpBreakpoints };
|
||||
this.sendResponse(response);
|
||||
});
|
||||
} else {
|
||||
// We could set breakpoints by URL here. But ODP doesn't give any way to set the position of that breakpoint when it does resolve later.
|
||||
// This seems easier
|
||||
this._pendingBreakpointsByUrl.set(sourceUrl, { response, args });
|
||||
// TODO caching by source.path seems wrong because it may not exist? But this implies that we haven't told ODP about this script so it may have to be set. Assert non-null?
|
||||
this._pendingBreakpointsByUrl.set(canonicalizeUrl(args.source.path), { response, args });
|
||||
return Promise.resolve<void>();
|
||||
}
|
||||
}
|
||||
|
@ -383,7 +428,7 @@ export class WebKitDebugSession extends DebugSession {
|
|||
let evalPromise: Promise<any>;
|
||||
if (this.paused) {
|
||||
let callFrameId = this._currentStack[args.frameId].callFrameId;
|
||||
evalPromise = this._webKitConnection.debugger_evaluateOnCallFrame(callFrameId, args.expression)
|
||||
evalPromise = this._webKitConnection.debugger_evaluateOnCallFrame(callFrameId, args.expression);
|
||||
} else {
|
||||
evalPromise = this._webKitConnection.runtime_evaluate(args.expression);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче