OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 WebInspector.SourceMapNamesResolver = {}; | 5 WebInspector.SourceMapNamesResolver = {}; |
6 | 6 |
7 WebInspector.SourceMapNamesResolver._cachedMapSymbol = Symbol("cache"); | 7 WebInspector.SourceMapNamesResolver._cachedMapSymbol = Symbol("cache"); |
8 WebInspector.SourceMapNamesResolver._cachedPromiseSymbol = Symbol("cache"); | 8 WebInspector.SourceMapNamesResolver._cachedPromiseSymbol = Symbol("cachePromise"
); |
9 | 9 |
10 /** | 10 /** |
11 * @param {!WebInspector.DebuggerModel.Scope} scope | 11 * @param {!WebInspector.DebuggerModel.Scope} scope |
12 * @return {!Promise.<!Map<string, string>>} | 12 * @return {!Promise.<!Map<string, string>>} |
13 */ | 13 */ |
14 WebInspector.SourceMapNamesResolver._resolveScope = function(scope) | 14 WebInspector.SourceMapNamesResolver._resolveScope = function(scope) |
15 { | 15 { |
16 var cachedMap = scope[WebInspector.SourceMapNamesResolver._cachedMapSymbol]; | 16 var cachedMap = scope[WebInspector.SourceMapNamesResolver._cachedMapSymbol]; |
17 if (cachedMap) | 17 if (cachedMap) |
18 return Promise.resolve(cachedMap); | 18 return Promise.resolve(cachedMap); |
19 | 19 |
20 var cachedPromise = scope[WebInspector.SourceMapNamesResolver._cachedPromise
Symbol]; | 20 var cachedPromise = scope[WebInspector.SourceMapNamesResolver._cachedPromise
Symbol]; |
21 if (cachedPromise) | 21 if (cachedPromise) |
22 return cachedPromise; | 22 return cachedPromise; |
23 | 23 |
24 var startLocation = scope.startLocation(); | 24 var startLocation = scope.startLocation(); |
25 var endLocation = scope.endLocation(); | 25 var endLocation = scope.endLocation(); |
26 var script = startLocation.script(); | |
27 | 26 |
28 if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !en
dLocation || !script.sourceMapURL || script !== endLocation.script()) | 27 if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !en
dLocation || !startLocation.script().sourceMapURL || (startLocation.script() !==
endLocation.script())) |
29 return Promise.resolve(new Map()); | 28 return Promise.resolve(new Map()); |
30 | 29 |
| 30 var script = startLocation.script(); |
31 var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(scr
ipt); | 31 var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(scr
ipt); |
32 if (!sourceMap) | 32 if (!sourceMap) |
33 return Promise.resolve(new Map()); | 33 return Promise.resolve(new Map()); |
34 | 34 |
35 var promise = script.requestContent().then(onContent); | 35 var promise = script.requestContent().then(onContent); |
36 scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol] = promise; | 36 scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol] = promise; |
37 return promise; | 37 return promise; |
38 | 38 |
39 /** | 39 /** |
40 * @param {?string} content | 40 * @param {?string} content |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 namesMapping.set(id.name, entry.name); | 110 namesMapping.set(id.name, entry.name); |
111 } | 111 } |
112 | 112 |
113 scope[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = namesMappi
ng; | 113 scope[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = namesMappi
ng; |
114 delete scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol]; | 114 delete scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol]; |
115 return namesMapping; | 115 return namesMapping; |
116 } | 116 } |
117 } | 117 } |
118 | 118 |
119 /** | 119 /** |
| 120 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame |
| 121 * @return {!Promise.<!Map<string, string>>} |
| 122 */ |
| 123 WebInspector.SourceMapNamesResolver._allVariablesInCallFrame = function(callFram
e) |
| 124 { |
| 125 var cached = callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol]
; |
| 126 if (cached) |
| 127 return Promise.resolve(cached); |
| 128 |
| 129 var promises = []; |
| 130 var scopeChain = callFrame.scopeChain(); |
| 131 for (var i = 0; i < scopeChain.length; ++i) |
| 132 promises.push(WebInspector.SourceMapNamesResolver._resolveScope(scopeCha
in[i])); |
| 133 |
| 134 return Promise.all(promises).then(mergeVariables); |
| 135 |
| 136 /** |
| 137 * @param {!Array<!Map<string, string>>} nameMappings |
| 138 * @return {!Map<string, string>} |
| 139 */ |
| 140 function mergeVariables(nameMappings) |
| 141 { |
| 142 var reverseMapping = new Map(); |
| 143 for (var map of nameMappings) { |
| 144 for (var compiledName of map.keys()) { |
| 145 var originalName = map.get(compiledName); |
| 146 if (!reverseMapping.has(originalName)) |
| 147 reverseMapping.set(originalName, compiledName); |
| 148 } |
| 149 } |
| 150 callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = revers
eMapping; |
| 151 return reverseMapping; |
| 152 } |
| 153 } |
| 154 |
| 155 /** |
| 156 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame |
| 157 * @param {string} originalText |
| 158 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 159 * @param {number} lineNumber |
| 160 * @param {number} startColumnNumber |
| 161 * @param {number} endColumnNumber |
| 162 * @return {!Promise<string>} |
| 163 */ |
| 164 WebInspector.SourceMapNamesResolver.resolveExpression = function(callFrame, orig
inalText, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) |
| 165 { |
| 166 if (!Runtime.experiments.isEnabled("resolveVariableNames")) |
| 167 return Promise.resolve(""); |
| 168 |
| 169 return WebInspector.SourceMapNamesResolver._allVariablesInCallFrame(callFram
e).then(findCompiledName); |
| 170 |
| 171 /** |
| 172 * @param {!Map<string, string>} reverseMapping |
| 173 * @return {!Promise<string>} |
| 174 */ |
| 175 function findCompiledName(reverseMapping) |
| 176 { |
| 177 if (reverseMapping.has(originalText)) |
| 178 return Promise.resolve(reverseMapping.get(originalText) || ""); |
| 179 |
| 180 return WebInspector.SourceMapNamesResolver._resolveExpression(callFrame,
uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) |
| 181 } |
| 182 } |
| 183 |
| 184 /** |
| 185 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame |
| 186 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 187 * @param {number} lineNumber |
| 188 * @param {number} startColumnNumber |
| 189 * @param {number} endColumnNumber |
| 190 * @return {!Promise<string>} |
| 191 */ |
| 192 WebInspector.SourceMapNamesResolver._resolveExpression = function(callFrame, uiS
ourceCode, lineNumber, startColumnNumber, endColumnNumber) |
| 193 { |
| 194 var target = callFrame.target(); |
| 195 var rawLocation = WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocat
ion(target, uiSourceCode, lineNumber, startColumnNumber); |
| 196 if (!rawLocation) |
| 197 return Promise.resolve(""); |
| 198 |
| 199 var script = rawLocation.script(); |
| 200 var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(scr
ipt); |
| 201 if (!sourceMap) |
| 202 return Promise.resolve(""); |
| 203 |
| 204 return script.requestContent().then(onContent); |
| 205 |
| 206 /** |
| 207 * @param {?string} content |
| 208 * @return {string} |
| 209 */ |
| 210 function onContent(content) |
| 211 { |
| 212 if (!content) |
| 213 return ""; |
| 214 |
| 215 var textRange = sourceMap.reverseMapTextRange(uiSourceCode.url(), new We
bInspector.TextRange(lineNumber, startColumnNumber, lineNumber, endColumnNumber)
); |
| 216 var originalText = textRange.extract(content); |
| 217 if (!originalText) |
| 218 return ""; |
| 219 |
| 220 var tokenizer = acorn.tokenizer(originalText, {ecmaVersion: 6}); |
| 221 try { |
| 222 var token = tokenizer.getToken(); |
| 223 while (token.type !== acorn.tokTypes.eof && WebInspector.AcornTokeni
zer.punctuator(token)) |
| 224 token = tokenizer.getToken(); |
| 225 |
| 226 var startIndex = token.start; |
| 227 var endIndex = token.end; |
| 228 var openBracketsCounter = 0; |
| 229 while (token.type !== acorn.tokTypes.eof) { |
| 230 var isIdentifier = WebInspector.AcornTokenizer.identifier(token)
; |
| 231 var isThis = WebInspector.AcornTokenizer.keyword(token, "this"); |
| 232 var isString = token.type === acorn.tokTypes.string; |
| 233 if (!isThis && !isIdentifier && !isString) |
| 234 break; |
| 235 |
| 236 endIndex = token.end; |
| 237 token = tokenizer.getToken(); |
| 238 while (WebInspector.AcornTokenizer.punctuator(token, ".[]")) { |
| 239 if (WebInspector.AcornTokenizer.punctuator(token, "[")) |
| 240 openBracketsCounter++; |
| 241 |
| 242 if (WebInspector.AcornTokenizer.punctuator(token, "]")) { |
| 243 endIndex = openBracketsCounter > 0 ? token.end : endInde
x; |
| 244 openBracketsCounter--; |
| 245 } |
| 246 |
| 247 token = tokenizer.getToken(); |
| 248 } |
| 249 } |
| 250 return originalText.substring(startIndex, endIndex); |
| 251 } catch (e) { |
| 252 return ""; |
| 253 } |
| 254 } |
| 255 } |
| 256 |
| 257 /** |
120 * @param {!WebInspector.DebuggerModel.Scope} scope | 258 * @param {!WebInspector.DebuggerModel.Scope} scope |
121 * @return {!WebInspector.RemoteObject} | 259 * @return {!WebInspector.RemoteObject} |
122 */ | 260 */ |
123 WebInspector.SourceMapNamesResolver.resolveScopeInObject = function(scope) | 261 WebInspector.SourceMapNamesResolver.resolveScopeInObject = function(scope) |
124 { | 262 { |
125 if (!Runtime.experiments.isEnabled("resolveVariableNames")) | 263 if (!Runtime.experiments.isEnabled("resolveVariableNames")) |
126 return scope.object(); | 264 return scope.object(); |
127 | 265 |
128 var startLocation = scope.startLocation(); | 266 var startLocation = scope.startLocation(); |
129 var endLocation = scope.endLocation(); | 267 var endLocation = scope.endLocation(); |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 * @override | 510 * @override |
373 * @param {function(?Array<!DebuggerAgent.CollectionEntry>)} callback | 511 * @param {function(?Array<!DebuggerAgent.CollectionEntry>)} callback |
374 */ | 512 */ |
375 collectionEntries: function(callback) | 513 collectionEntries: function(callback) |
376 { | 514 { |
377 this._object.collectionEntries(callback); | 515 this._object.collectionEntries(callback); |
378 }, | 516 }, |
379 | 517 |
380 __proto__: WebInspector.RemoteObject.prototype | 518 __proto__: WebInspector.RemoteObject.prototype |
381 } | 519 } |
OLD | NEW |