Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(466)

Unified Diff: third_party/WebKit/Source/devtools/front_end/sources/SourceMapNamesResolver.js

Issue 1770263002: Devtools: resolve expressions in minified scripts with sourcemaps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/devtools/front_end/sources/SourceMapNamesResolver.js
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourceMapNamesResolver.js b/third_party/WebKit/Source/devtools/front_end/sources/SourceMapNamesResolver.js
index ccbe65f70e83c27a9cfc84890617a8d06ea6bfb3..27e62065bb59b8550eb8eda6571525b1a463bcca 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourceMapNamesResolver.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourceMapNamesResolver.js
@@ -5,7 +5,7 @@
WebInspector.SourceMapNamesResolver = {};
WebInspector.SourceMapNamesResolver._cachedMapSymbol = Symbol("cache");
-WebInspector.SourceMapNamesResolver._cachedPromiseSymbol = Symbol("cache");
+WebInspector.SourceMapNamesResolver._cachedPromiseSymbol = Symbol("cachePromise");
/**
* @param {!WebInspector.DebuggerModel.Scope} scope
@@ -23,11 +23,11 @@ WebInspector.SourceMapNamesResolver._resolveScope = function(scope)
var startLocation = scope.startLocation();
var endLocation = scope.endLocation();
- var script = startLocation.script();
- if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !endLocation || !script.sourceMapURL || script !== endLocation.script())
+ if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !endLocation || !startLocation.script().sourceMapURL || (startLocation.script() !== endLocation.script()))
return Promise.resolve(new Map());
+ var script = startLocation.script();
var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(script);
if (!sourceMap)
return Promise.resolve(new Map());
@@ -117,6 +117,144 @@ WebInspector.SourceMapNamesResolver._resolveScope = function(scope)
}
/**
+ * @param {!WebInspector.DebuggerModel.CallFrame} callFrame
+ * @return {!Promise.<!Map<string, string>>}
+ */
+WebInspector.SourceMapNamesResolver._allVariablesInCallFrame = function(callFrame)
+{
+ var cached = callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol];
+ if (cached)
+ return Promise.resolve(cached);
+
+ var promises = [];
+ var scopeChain = callFrame.scopeChain();
+ for (var i = 0; i < scopeChain.length; ++i)
+ promises.push(WebInspector.SourceMapNamesResolver._resolveScope(scopeChain[i]));
+
+ return Promise.all(promises).then(mergeVariables);
+
+ /**
+ * @param {!Array<!Map<string, string>>} nameMappings
+ * @return {!Map<string, string>}
+ */
+ function mergeVariables(nameMappings)
+ {
+ var reverseMapping = new Map();
+ for (var map of nameMappings) {
+ for (var compiledName of map.keys()) {
+ var originalName = map.get(compiledName);
+ if (!reverseMapping.has(originalName))
+ reverseMapping.set(originalName, compiledName);
+ }
+ }
+ callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = reverseMapping;
+ return reverseMapping;
+ }
+}
+
+/**
+ * @param {!WebInspector.DebuggerModel.CallFrame} callFrame
+ * @param {string} originalText
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {number} lineNumber
+ * @param {number} startColumnNumber
+ * @param {number} endColumnNumber
+ * @return {!Promise<string>}
+ */
+WebInspector.SourceMapNamesResolver.resolveExpression = function(callFrame, originalText, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber)
+{
+ if (!Runtime.experiments.isEnabled("resolveVariableNames"))
+ return Promise.resolve("");
+
+ return WebInspector.SourceMapNamesResolver._allVariablesInCallFrame(callFrame).then(findCompiledName);
+
+ /**
+ * @param {!Map<string, string>} reverseMapping
+ * @return {!Promise<string>}
+ */
+ function findCompiledName(reverseMapping)
+ {
+ if (reverseMapping.has(originalText))
+ return Promise.resolve(reverseMapping.get(originalText) || "");
+
+ return WebInspector.SourceMapNamesResolver._resolveExpression(callFrame, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber)
+ }
+}
+
+/**
+ * @param {!WebInspector.DebuggerModel.CallFrame} callFrame
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {number} lineNumber
+ * @param {number} startColumnNumber
+ * @param {number} endColumnNumber
+ * @return {!Promise<string>}
+ */
+WebInspector.SourceMapNamesResolver._resolveExpression = function(callFrame, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber)
+{
+ var target = callFrame.target();
+ var rawLocation = WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocation(target, uiSourceCode, lineNumber, startColumnNumber);
+ if (!rawLocation)
+ return Promise.resolve("");
+
+ var script = rawLocation.script();
+ var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(script);
+ if (!sourceMap)
+ return Promise.resolve("");
+
+ return script.requestContent().then(onContent);
+
+ /**
+ * @param {?string} content
+ * @return {string}
+ */
+ function onContent(content)
+ {
+ if (!content)
+ return "";
+
+ var textRange = sourceMap.reverseMapTextRange(uiSourceCode.url(), new WebInspector.TextRange(lineNumber, startColumnNumber, lineNumber, endColumnNumber));
+ var originalText = textRange.extract(content);
+ if (!originalText)
+ return "";
+
+ var tokenizer = acorn.tokenizer(originalText, {ecmaVersion: 6});
+ try {
+ var token = tokenizer.getToken();
+ while (token.type !== acorn.tokTypes.eof && WebInspector.AcornTokenizer.punctuator(token))
+ token = tokenizer.getToken();
+
+ var startIndex = token.start;
+ var endIndex = token.end;
+ var openBracketsCounter = 0;
+ while (token.type !== acorn.tokTypes.eof) {
+ var isIdentifier = WebInspector.AcornTokenizer.identifier(token);
+ var isThis = WebInspector.AcornTokenizer.keyword(token, "this");
+ var isString = token.type === acorn.tokTypes.string;
+ if (!isThis && !isIdentifier && !isString)
+ break;
+
+ endIndex = token.end;
+ token = tokenizer.getToken();
+ while (WebInspector.AcornTokenizer.punctuator(token, ".[]")) {
+ if (WebInspector.AcornTokenizer.punctuator(token, "["))
+ openBracketsCounter++;
+
+ if (WebInspector.AcornTokenizer.punctuator(token, "]")) {
+ endIndex = openBracketsCounter > 0 ? token.end : endIndex;
+ openBracketsCounter--;
+ }
+
+ token = tokenizer.getToken();
+ }
+ }
+ return originalText.substring(startIndex, endIndex);
+ } catch (e) {
+ return "";
+ }
+ }
+}
+
+/**
* @param {!WebInspector.DebuggerModel.Scope} scope
* @return {!WebInspector.RemoteObject}
*/
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698