| 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}
|
| */
|
|
|