Factor out sourceroot calc
This commit is contained in:
Родитель
d038f33466
Коммит
1a8e46e0a0
|
@ -5,53 +5,96 @@
|
|||
import * as Path from 'path';
|
||||
import * as URL from 'url';
|
||||
|
||||
import * as utils from '../../webkit/utilities';
|
||||
|
||||
export function getPathRoot(p: string) {
|
||||
if (p) {
|
||||
if (p.length >= 3 && p[1] === ':' && p[2] === '\\' && ((p[0] >= 'a' && p[0] <= 'z') || (p[0] >= 'A' && p[0] <= 'Z'))) {
|
||||
return p.substr(0, 3);
|
||||
}
|
||||
if (p.length > 0 && p[0] === '/') {
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
return null;
|
||||
if (p) {
|
||||
if (p.length >= 3 && p[1] === ':' && p[2] === '\\' && ((p[0] >= 'a' && p[0] <= 'z') || (p[0] >= 'A' && p[0] <= 'Z'))) {
|
||||
return p.substr(0, 3);
|
||||
}
|
||||
if (p.length > 0 && p[0] === '/') {
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function makePathAbsolute(absPath: string, relPath: string): string {
|
||||
return Path.resolve(Path.dirname(absPath), relPath);
|
||||
return Path.resolve(Path.dirname(absPath), relPath);
|
||||
}
|
||||
|
||||
export function removeFirstSegment(path: string) {
|
||||
const segments = path.split(Path.sep);
|
||||
segments.shift();
|
||||
if (segments.length > 0) {
|
||||
return segments.join(Path.sep);
|
||||
}
|
||||
return null;
|
||||
const segments = path.split(Path.sep);
|
||||
segments.shift();
|
||||
if (segments.length > 0) {
|
||||
return segments.join(Path.sep);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function makeRelative(target: string, path: string) {
|
||||
const t = target.split(Path.sep);
|
||||
const p = path.split(Path.sep);
|
||||
const t = target.split(Path.sep);
|
||||
const p = path.split(Path.sep);
|
||||
|
||||
let i = 0;
|
||||
for (; i < Math.min(t.length, p.length) && t[i] === p[i]; i++) {
|
||||
}
|
||||
let i = 0;
|
||||
for (; i < Math.min(t.length, p.length) && t[i] === p[i]; i++) {
|
||||
}
|
||||
|
||||
let result = '';
|
||||
for (; i < p.length; i++) {
|
||||
result = Path.join(result, p[i]);
|
||||
}
|
||||
return result;
|
||||
let result = '';
|
||||
for (; i < p.length; i++) {
|
||||
result = Path.join(result, p[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function canonicalizeUrl(url: string): string {
|
||||
let u = URL.parse(url);
|
||||
let p = u.pathname;
|
||||
let u = URL.parse(url);
|
||||
let p = u.pathname;
|
||||
|
||||
if (p.length >= 4 && p[0] === '/' && p[2] === ':' && p[3] === '/' && ((p[1] >= 'a' && p[1] <= 'z') || (p[1] >= 'A' && p[1] <= 'Z'))) {
|
||||
return p.substr(1);
|
||||
}
|
||||
return p;
|
||||
if (p.length >= 4 && p[0] === '/' && p[2] === ':' && p[3] === '/' && ((p[1] >= 'a' && p[1] <= 'z') || (p[1] >= 'A' && p[1] <= 'Z'))) {
|
||||
return p.substr(1);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the absolute path to the sourceRoot.
|
||||
*/
|
||||
export function getAbsSourceRoot(sourceRoot: string, webRoot: string, generatedPath: string): string {
|
||||
let absSourceRoot: string;
|
||||
if (sourceRoot) {
|
||||
if (sourceRoot.startsWith('file:///')) {
|
||||
// sourceRoot points to a local path like "file:///c:/project/src"
|
||||
absSourceRoot = canonicalizeUrl(sourceRoot);
|
||||
} else if (Path.isAbsolute(sourceRoot)) {
|
||||
// like "/src", would be like http://localhost/src, resolve to a local path under webRoot
|
||||
// note that C:/src (or /src as an absolute local path) is not a valid sourceroot
|
||||
absSourceRoot = Path.join(webRoot, sourceRoot);
|
||||
} else {
|
||||
// like "src" or "../src", relative to the script
|
||||
if (Path.isAbsolute(generatedPath)) {
|
||||
absSourceRoot = makePathAbsolute(generatedPath, sourceRoot);
|
||||
} else {
|
||||
// runtime script is not on disk, resolve the sourceRoot location on disk
|
||||
absSourceRoot = Path.join(webRoot, URL.parse(generatedPath).pathname, sourceRoot);
|
||||
}
|
||||
}
|
||||
|
||||
utils.Logger.log(`SourceMap: resolved sourceRoot ${sourceRoot} -> ${absSourceRoot}`);
|
||||
} else {
|
||||
if (Path.isAbsolute(generatedPath)) {
|
||||
absSourceRoot = Path.dirname(generatedPath);
|
||||
utils.Logger.log(`SourceMap: no sourceRoot specified, using script dirname: ${absSourceRoot}`);
|
||||
} else {
|
||||
// runtime script is not on disk, resolve the sourceRoot location on disk
|
||||
const scriptPathDirname = Path.dirname(URL.parse(generatedPath).pathname);
|
||||
absSourceRoot = Path.join(webRoot, scriptPathDirname);
|
||||
utils.Logger.log(`SourceMap: no sourceRoot specified, using webRoot + script path dirname: ${absSourceRoot}`);
|
||||
}
|
||||
}
|
||||
|
||||
absSourceRoot = utils.stripTrailingSlash(absSourceRoot);
|
||||
absSourceRoot = utils.fixDriveLetterAndSlashes(absSourceRoot);
|
||||
|
||||
return absSourceRoot;
|
||||
}
|
|
@ -23,6 +23,7 @@ export class SourceMapTransformer implements IDebugTransformer {
|
|||
private _allRuntimeScriptPaths: Set<string>;
|
||||
private _pendingBreakpointsByPath = new Map<string, IPendingBreakpoint>();
|
||||
private _webRoot: string;
|
||||
private _authoredPathsToBreakpoints: Map<string, number[]>;
|
||||
|
||||
public launch(args: ILaunchRequestArgs): void {
|
||||
this.init(args);
|
||||
|
@ -38,6 +39,7 @@ export class SourceMapTransformer implements IDebugTransformer {
|
|||
this._sourceMaps = new SourceMaps(this._webRoot);
|
||||
this._requestSeqToSetBreakpointsArgs = new Map<number, DebugProtocol.SetBreakpointsArguments>();
|
||||
this._allRuntimeScriptPaths = new Set<string>();
|
||||
this._authoredPathsToBreakpoints = new Map<string, number[]>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ enum Bias {
|
|||
}
|
||||
|
||||
class SourceMap {
|
||||
private _generatedFile: string; // the generated file for this sourcemap
|
||||
private _generatedPath: string; // the generated file for this sourcemap
|
||||
private _sources: string[]; // the sources of generated file (relative to sourceRoot)
|
||||
private _absSourceRoot: string; // the common prefix for the source (can be a URL)
|
||||
private _smc: SourceMapConsumer; // the source map
|
||||
|
@ -252,43 +252,11 @@ class SourceMap {
|
|||
*/
|
||||
public constructor(generatedPath: string, json: string, webRoot: string) {
|
||||
Logger.log(`SourceMap: creating SM for ${generatedPath}`)
|
||||
this._generatedFile = generatedPath;
|
||||
this._generatedPath = generatedPath;
|
||||
this._webRoot = webRoot;
|
||||
|
||||
const sm = JSON.parse(json);
|
||||
let sr = <string> sm.sourceRoot;
|
||||
if (sr) {
|
||||
if (sr.startsWith('file:///')) {
|
||||
// sourceRoot points to a local path like "file:///c:/project/src"
|
||||
this._absSourceRoot = PathUtils.canonicalizeUrl(sr);
|
||||
} else if (Path.isAbsolute(sr)) {
|
||||
// like "/src", would be like http://localhost/src, resolve to a local path under webRoot
|
||||
this._absSourceRoot = Path.join(this._webRoot, sr);
|
||||
} else {
|
||||
// like "src" or "../src", relative to the script
|
||||
if (Path.isAbsolute(generatedPath)) {
|
||||
this._absSourceRoot = PathUtils.makePathAbsolute(generatedPath, sr);
|
||||
} else {
|
||||
// runtime script is not on disk, resolve the sourceRoot location on disk
|
||||
this._absSourceRoot = Path.join(this._webRoot, URL.parse(generatedPath).pathname, sr);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.log(`SourceMap: resolved sourceRoot ${sr} -> ${this._absSourceRoot}`);
|
||||
} else {
|
||||
if (Path.isAbsolute(generatedPath)) {
|
||||
this._absSourceRoot = Path.dirname(generatedPath);
|
||||
Logger.log(`SourceMap: no sourceRoot specified, using script dirname: ${this._absSourceRoot}`);
|
||||
} else {
|
||||
// runtime script is not on disk, resolve the sourceRoot location on disk
|
||||
const scriptPathDirname = Path.dirname(URL.parse(generatedPath).pathname);
|
||||
this._absSourceRoot = Path.join(this._webRoot, scriptPathDirname);
|
||||
Logger.log(`SourceMap: no sourceRoot specified, using webRoot + script path dirname: ${this._absSourceRoot}`);
|
||||
}
|
||||
}
|
||||
|
||||
this._absSourceRoot = utils.stripTrailingSlash(this._absSourceRoot);
|
||||
this._absSourceRoot = utils.fixDriveLetterAndSlashes(this._absSourceRoot);
|
||||
this._absSourceRoot = PathUtils.getAbsSourceRoot(sm.sourceRoot, this._webRoot, this._generatedPath);
|
||||
|
||||
// Overwrite the sourcemap's sourceRoot with the version that's resolved to an absolute path,
|
||||
// so the work above only has to be done once
|
||||
|
@ -327,7 +295,7 @@ class SourceMap {
|
|||
* the generated file of this source map.
|
||||
*/
|
||||
public generatedPath(): string {
|
||||
return this._generatedFile;
|
||||
return this._generatedPath;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -372,7 +340,6 @@ class SourceMap {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const needle = {
|
||||
source: src,
|
||||
line: line,
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as mockery from 'mockery';
|
||||
|
||||
import * as testUtils from '../../testUtils';
|
||||
|
||||
const MODULE_UNDER_TEST = '../../../adapter/sourceMaps/pathUtilities';
|
||||
|
||||
suite('PathUtilities', () => {
|
||||
setup(() => {
|
||||
testUtils.setupUnhandledRejectionListener();
|
||||
|
||||
// Set up mockery
|
||||
mockery.enable({ warnOnReplace: false, useCleanCache: true });
|
||||
mockery.registerAllowables([MODULE_UNDER_TEST, 'path', 'url', '../../webkit/utilities']);
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
testUtils.removeUnhandledRejectionListener();
|
||||
mockery.deregisterAll();
|
||||
mockery.disable();
|
||||
});
|
||||
|
||||
|
||||
suite('getAbsSourceRoot', () => {
|
||||
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче