Fix sourcemaps for merged files
This commit is contained in:
Родитель
23e38e0aec
Коммит
6c64a7d131
|
@ -126,20 +126,21 @@ export class SourceMapTransformer implements IDebugTransformer {
|
|||
if (this._sourceMaps) {
|
||||
this._allRuntimeScriptPaths.add(event.body.scriptUrl);
|
||||
|
||||
const mapped = this._sourceMaps.MapToSource(event.body.scriptUrl, 0, 0);
|
||||
if (mapped) {
|
||||
event.body.scriptUrl = mapped.path;
|
||||
}
|
||||
|
||||
const sources = this._sourceMaps.AllMappedSources(event.body.scriptUrl);
|
||||
if (sources) {
|
||||
utils.Logger.log(`SourceMaps.scriptParsed: ${event.body.scriptUrl} was just loaded and has mapped sources: ${JSON.stringify(sources)}`);
|
||||
sources.forEach(sourcePath => {
|
||||
// If there's a setBreakpoints request waiting on this script, go through setBreakpoints again
|
||||
if (this._pendingBreakpointsByPath.has(event.body.scriptUrl)) {
|
||||
utils.Logger.log(`SourceMaps.scriptParsed: ${event.body.scriptUrl} was just loaded and has pending breakpoints`);
|
||||
const pendingBreakpoint = this._pendingBreakpointsByPath.get(event.body.scriptUrl);
|
||||
this._pendingBreakpointsByPath.delete(event.body.scriptUrl);
|
||||
if (this._pendingBreakpointsByPath.has(sourcePath)) {
|
||||
utils.Logger.log(`SourceMaps.scriptParsed: Resolving pending breakpoints for ${sourcePath}`);
|
||||
const pendingBreakpoint = this._pendingBreakpointsByPath.get(sourcePath);
|
||||
this._pendingBreakpointsByPath.delete(sourcePath);
|
||||
|
||||
this.setBreakpoints(pendingBreakpoint.args, pendingBreakpoint.requestSeq)
|
||||
.then(pendingBreakpoint.resolve, pendingBreakpoint.reject);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,11 @@ export interface ISourceMaps {
|
|||
* line and column are 0 based.
|
||||
*/
|
||||
MapToSource(path: string, line: number, column: number): MappingResult;
|
||||
|
||||
/*
|
||||
* Get all the sources that map to this generated file
|
||||
*/
|
||||
AllMappedSources(path: string): string[];
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,6 +86,11 @@ export class SourceMaps implements ISourceMaps {
|
|||
return null;
|
||||
}
|
||||
|
||||
public AllMappedSources(pathToGenerated: string): string[] {
|
||||
const map = this._findGeneratedToSourceMapping(pathToGenerated);
|
||||
return map ? map.sources : null;
|
||||
}
|
||||
|
||||
//---- private -----------------------------------------------------------------------
|
||||
|
||||
private _findSourceToGeneratedMapping(pathToSource: string): SourceMap {
|
||||
|
@ -227,6 +237,13 @@ class SourceMap {
|
|||
this._smc = new SourceMapConsumer(sm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return all mapped sources as absolute paths
|
||||
*/
|
||||
public get sources(): string[] {
|
||||
return this._sources.map(sourcePath => Path.join(this._sourceRoot, sourcePath));
|
||||
}
|
||||
|
||||
/*
|
||||
* the generated file of this source map.
|
||||
*/
|
||||
|
@ -250,7 +267,7 @@ class SourceMap {
|
|||
/*
|
||||
* finds the nearest source location for the given location in the generated file.
|
||||
*/
|
||||
public originalPositionFor(line: number, column: number, bias: Bias = Bias.LEAST_UPPER_BOUND): SourceMap.MappedPosition {
|
||||
public originalPositionFor(line: number, column: number, bias: Bias = Bias.GREATEST_LOWER_BOUND): SourceMap.MappedPosition {
|
||||
|
||||
const mp = this._smc.originalPositionFor(<any>{
|
||||
line: line,
|
||||
|
@ -269,7 +286,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.LEAST_UPPER_BOUND): SourceMap.Position {
|
||||
public generatedPositionFor(src: string, line: number, column: number, bias = Bias.GREATEST_LOWER_BOUND): SourceMap.Position {
|
||||
|
||||
// make input path relative to sourceRoot
|
||||
if (this._sourceRoot) {
|
||||
|
|
|
@ -78,21 +78,22 @@ suite('SourceMapTransformer', () => {
|
|||
const args = createArgs(AUTHORED_PATH, AUTHORED_LINES);
|
||||
const expected = createArgs(RUNTIME_PATH, RUNTIME_LINES, RUNTIME_COLS);
|
||||
|
||||
const mock = testUtils.getRegisteredSinonMock('./sourceMaps', undefined, 'SourceMaps');
|
||||
const mock = testUtils.createRegisteredSinonMock('./sourceMaps', undefined, 'SourceMaps');
|
||||
mock.expects('MapPathFromSource')
|
||||
.once()
|
||||
.withArgs(AUTHORED_PATH).returns(null);
|
||||
mock.expects('MapPathFromSource')
|
||||
.once()
|
||||
.withArgs(AUTHORED_PATH).returns(RUNTIME_PATH);
|
||||
mock.expects('AllMappedSources')
|
||||
.once()
|
||||
.withArgs(RUNTIME_PATH).returns([AUTHORED_PATH]);
|
||||
args.lines.forEach((line, i) => {
|
||||
mock.expects('MapFromSource')
|
||||
.once()
|
||||
.withArgs(AUTHORED_PATH, line, 0)
|
||||
.returns({ path: RUNTIME_PATH, line: RUNTIME_LINES[i], column: RUNTIME_COLS[i] });
|
||||
});
|
||||
mock.expects('MapToSource')
|
||||
.withArgs(RUNTIME_PATH, 0, 0).returns({ path: AUTHORED_PATH });
|
||||
|
||||
const transformer = getTransformer(true, true);
|
||||
const setBreakpointsP = transformer.setBreakpoints(args, 0).then(() => {
|
||||
|
@ -175,12 +176,6 @@ suite('SourceMapTransformer', () => {
|
|||
assert.deepEqual(response, expected);
|
||||
});
|
||||
});
|
||||
|
||||
suite('scriptParsed()', () => {
|
||||
test('calls MapToSource', () => {
|
||||
getTransformer().scriptParsed(new testUtils.MockEvent('scriptParsed', { scriptUrl: RUNTIME_PATH }));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
class MockSourceMaps implements ISourceMaps {
|
||||
|
@ -216,4 +211,8 @@ class MockSourceMaps implements ISourceMaps {
|
|||
const mappedLine = AUTHORED_LINES[RUNTIME_LINES.indexOf(line)];
|
||||
return { path: AUTHORED_PATH, line: mappedLine, column: 0 };
|
||||
}
|
||||
|
||||
public AllMappedSources(pathToGenerated: string): string[] {
|
||||
return [AUTHORED_PATH];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ export function getSinonMock(mockBase = {}): Sinon.SinonMock {
|
|||
return m;
|
||||
}
|
||||
|
||||
export function getRegisteredSinonMock(requireName: string, mockInstance = {}, name?: string, asConstructor = true): Sinon.SinonMock {
|
||||
export function createRegisteredSinonMock(requireName: string, mockInstance = {}, name?: string, asConstructor = true): Sinon.SinonMock {
|
||||
const mock = getSinonMock(mockInstance);
|
||||
const mockContainer = {};
|
||||
if (asConstructor) {
|
||||
|
|
|
@ -39,7 +39,7 @@ suite('WebKitDebugAdapter', () => {
|
|||
mockery.registerMock('net', {});
|
||||
mockery.registerMock('fs', {});
|
||||
|
||||
mockWebKitConnection = testUtils.getRegisteredSinonMock('./webKitConnection', new DefaultMockWebKitConnection(), 'WebKitConnection');
|
||||
mockWebKitConnection = testUtils.createRegisteredSinonMock('./webKitConnection', new DefaultMockWebKitConnection(), 'WebKitConnection');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче