Skip to content

Commit

Permalink
fix(frontend): added file system based source mapping (GoogleChromeLa…
Browse files Browse the repository at this point in the history
…bs#98)

fix(frontend): added file system based source mapping

If we can not map generated file to compiled one we use source maps
that we fetched from file system.

Fixes GoogleChromeLabs#34
  • Loading branch information
alexkozy authored Aug 4, 2018
1 parent 1cbace7 commit 348a78c
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 82 deletions.
83 changes: 83 additions & 0 deletions front_end/ndb/FileSystemMapping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* @license Copyright 2018 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/

Ndb._FakeDebuggerLocation = class {
constructor(sourceURL, lineNumber, columnNumber) {
this.debuggerModel = {getPossibleBreakpoints: _ => []};
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
this.script = _ => ({sourceURL});
}
};

Ndb.FileSystemMapping = class {
constructor() {
this._sourceMapManager = new SDK.SourceMapManager({
inspectedURL: _ => Common.ParsedURL.platformPathToURL(NdbProcessInfo.cwd)
});
this._sourceMapManager.addEventListener(
SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this);

this._sourceUrlToSourceMap = new Map();
this._compiledUrlToSourceMap = new Map();
}

sourceMapDetected(fileName, sourceMappingUrl) {
const fileUrl = Common.ParsedURL.platformPathToURL(fileName);
this._sourceMapManager.attachSourceMap({}, fileUrl, sourceMappingUrl);
}

_sourceMapAttached(event) {
const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap);
for (const sourceUrl of sourceMap.sourceURLs())
this._sourceUrlToSourceMap.set(sourceUrl, sourceMap);
this._compiledUrlToSourceMap.set(sourceMap.compiledURL(), sourceMap);
}

/**
* @param {!SDK.DebuggerModel.Location} rawLocation
* @return {?Workspace.UILocation}
*/
rawLocationToUILocation(rawLocation) {
const sourceMap = this._compiledUrlToSourceMap.get(rawLocation.script().sourceURL);
if (sourceMap) {
const entry = sourceMap.findEntry(rawLocation.lineNumber, rawLocation.columnNumber);
if (entry) {
const fileSystemProjects = Workspace.workspace.projectsForType('filesystem');
for (const fileSystemProject of fileSystemProjects) {
const uiSourceCode = fileSystemProject.uiSourceCodeForURL(entry.sourceURL);
if (uiSourceCode) {
const networkUISourceCode = Persistence.persistence.network(uiSourceCode);
if (networkUISourceCode)
return null;
return uiSourceCode.uiLocation(entry.sourceLineNumber, entry.sourceColumnNumber);
}
}
}
}
return null;
}

/**
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?SDK.DebuggerModel.Location}
*/
uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
const url = uiSourceCode.url();
const sourceMap = this._sourceUrlToSourceMap.get(url);
if (sourceMap) {
const entry = sourceMap.sourceLineMapping(url, lineNumber, columnNumber);
if (entry)
return new Ndb._FakeDebuggerLocation(sourceMap.compiledURL(), entry.lineNumber, entry.columnNumber);
}
return null;
}
};

/** @type {!Ndb.FileSystemMapping} */
Ndb.fileSystemMapping;
84 changes: 4 additions & 80 deletions front_end/ndb/NdbMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ Ndb.NdbMain = class extends Common.Object {
Common.moduleSetting('whitelistedModules').addChangeListener(Ndb.NdbMain._calculateBlackboxState);
Ndb.NdbMain._calculateBlackboxState();
this._startRepl();
Ndb.sourceMapManager = new Ndb.SourceMapManager();

Ndb.fileSystemMapping = new Ndb.FileSystemMapping();
Bindings.debuggerWorkspaceBinding.addSourceMapping(Ndb.fileSystemMapping);

registerFileSystem('cwd', NdbProcessInfo.cwd).then(_ => {
InspectorFrontendAPI.fileSystemAdded(undefined, {
fileSystemName: 'cwd',
Expand Down Expand Up @@ -141,85 +144,6 @@ Ndb.mainConfiguration = () => {
};
};

class SourceMappableState extends Bindings.BreakpointManager.Breakpoint.State {
constructor(url, scriptId, scriptHash, lineNumber, columnNumber, condition) {
super(url, scriptId, scriptHash, lineNumber, columnNumber, condition);
if (!scriptId && !scriptHash && url) {
const sourceMap = Ndb.sourceMapManager.sourceMap(url);
if (sourceMap) {
const entry = sourceMap.sourceLineMapping(url, lineNumber, columnNumber);
if (entry) {
this.url = sourceMap.compiledURL();
this.lineNumber = entry.lineNumber;
this.columnNumber = entry.columnNumber;
}
}
}
}
}

Bindings.BreakpointManager.Breakpoint.State = SourceMappableState;

Ndb.SourceMapManager = class {
constructor() {
this._manager = new SDK.SourceMapManager({
inspectedURL: _ => Common.ParsedURL.platformPathToURL(NdbProcessInfo.cwd)
});
this._manager.addEventListener(
SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this);
Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);

this._bindings = new Map();
this._fileUrlToSourceMap = new Map();
}

_sourceMapDetected(fsPath, fileName, sourceMappingUrl) {
const fsPathUrl = Common.ParsedURL.platformPathToURL(fsPath);
const fileUrl = Common.ParsedURL.platformPathToURL(fileName);
this._manager.attachSourceMap({fsPathUrl, fileUrl}, fileUrl, sourceMappingUrl);
}

/**
* @param {!Common.Event} event
*/
_sourceMapAttached(event) {
const {fsPathUrl, fileUrl} = event.data.client;
const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap);
for (const sourceUrl of sourceMap.sourceURLs()) {
this._bindings.set(`${fsPathUrl}|${sourceUrl}`, sourceMap);
this._fileUrlToSourceMap.set(sourceUrl, sourceMap);
}
const fileSystemProjects = Workspace.workspace.projectsForType('filesystem');
for (const fileSystemProject of fileSystemProjects) {
if (fileSystemProject.fileSystemPath() === fsPathUrl) {
const uiSourceCode = fileSystemProject.uiSourceCodeForURL(fileUrl);
if (uiSourceCode) {
uiSourceCode[Bindings.CompilerScriptMapping._sourceMapSymbol] = sourceMap;
break;
}
}
}
}

sourceMap(fileUrl) {
return this._fileUrlToSourceMap.get(fileUrl) || null;
}

/**
* @param {!Common.Event} event
*/
_uiSourceCodeAdded(event) {
const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
const project = uiSourceCode.project();
if (project.type() !== 'filesystem')
return;
const key = `${project.fileSystemPath()}|${uiSourceCode.url()}`;
const sourceMap = this._bindings.get(key);
if (sourceMap)
uiSourceCode[Bindings.CompilerScriptMapping._sourceMapSymbol] = sourceMap;
}
};

/**
* @implements {UI.ContextMenu.Provider}
* @unrestricted
Expand Down
1 change: 1 addition & 0 deletions front_end/ndb/module.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
],
"dependencies": ["common", "sdk", "bindings"],
"scripts": [
"FileSystemMapping.js",
"NdbMain.js"
]
}
2 changes: 1 addition & 1 deletion front_end/ndb_ui/NodeProcesses.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Ndb.NodeProcesses = class extends UI.VBox {
const ui = this._targetToUI.get(target);
if (ui) {
const parentTreeElement = ui.treeElement.parent;
for (const child of ui.treeElement.children()) {
for (const child of ui.treeElement.children().slice()) {
ui.treeElement.removeChild(child);
parentTreeElement.appendChild(child);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/file_system_backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class FileSystem {
static async create(frontend) {
const backend = new FileSystem((fsPath, fileName, sourceMappingUrl) => {
frontend.safeEvaluate((fsPath, fileName, sourceMappingUrl) => {
callFrontend(_ => Ndb.sourceMapManager._sourceMapDetected(fsPath, fileName, sourceMappingUrl));
callFrontend(_ => Ndb.fileSystemMapping.sourceMapDetected(fileName, sourceMappingUrl));
}, fsPath, fileName, sourceMappingUrl);
});
await backend._expose(frontend);
Expand Down

0 comments on commit 348a78c

Please sign in to comment.