Chromium Code Reviews| 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 /** | |
| 205 * @param {!{lineNumber: number, columnNumber: number}} position | |
| 206 * @param {!WebInspector.SourceMap.Entry} mapping | |
| 207 * @return {number} | |
| 208 */ | |
| 209 function comparator(position, mapping) | |
| 210 { | |
| 211 if (position.lineNumber !== mapping.sourceLineNumber) | |
| 212 return position.lineNumber - mapping.sourceLineNumber; | |
| 213 | |
| 214 return position.columnNumber - mapping.sourceColumnNumber; | |
| 215 } | |
| 216 | |
| 217 var mappings = sourceMap.reversedMappings(uiSourceCode.url()); | |
| 218 var startIndex = mappings.lowerBound({lineNumber: lineNumber, columnNumber: startColumnNumber}, comparator); | |
|
dgozman
2016/03/08 18:26:42
Let's move this to SourceMap.reverseMapTextRange.
sergeyv
2016/03/08 22:53:04
Done.
| |
| 219 var endIndex = mappings.upperBound({lineNumber: lineNumber, columnNumber: en dColumnNumber}, comparator); | |
| 220 | |
| 221 var startMapping = mappings[startIndex]; | |
| 222 var endMapping = mappings[endIndex]; | |
| 223 | |
| 224 if (startMapping === endMapping) | |
| 225 return Promise.resolve(""); | |
| 226 | |
| 227 return script.requestContent().then(onContent); | |
| 228 | |
| 229 /** | |
| 230 * @param {?string} content | |
| 231 * @return {string} | |
| 232 */ | |
| 233 function onContent(content) | |
| 234 { | |
| 235 if (!content) | |
| 236 return ""; | |
| 237 | |
| 238 var textRange = new WebInspector.TextRange(startMapping.lineNumber, star tMapping.columnNumber, endMapping.lineNumber, endMapping.columnNumber); | |
| 239 var originalText = textRange.extract(content); | |
| 240 var tokenizer = acorn.tokenizer(originalText, {ecmaVersion: 6}); | |
| 241 try { | |
| 242 var token = tokenizer.getToken(); | |
| 243 while (token.type !== acorn.tokTypes.eof && WebInspector.AcornTokeni zer.punctuator(token)) | |
| 244 token = tokenizer.getToken(); | |
| 245 | |
| 246 var startIndex = token.start; | |
| 247 var endIndex = token.end; | |
| 248 while (token.type !== acorn.tokTypes.eof) { | |
| 249 var isIdentifier = WebInspector.AcornTokenizer.identifier(token) ; | |
| 250 var isThis = WebInspector.AcornTokenizer.keyword(token, "this"); | |
| 251 var isString = token.type === acorn.tokTypes.string; | |
| 252 if (!isThis && !isIdentifier && !isString) | |
| 253 break; | |
| 254 | |
| 255 endIndex = token.end; | |
| 256 token = tokenizer.getToken(); | |
| 257 while (WebInspector.AcornTokenizer.punctuator(token, ".[]")) { | |
| 258 if (WebInspector.AcornTokenizer.punctuator(token, "]")) | |
| 259 endIndex = token.end; | |
|
dgozman
2016/03/08 18:26:42
Let's not do this if current balance of [] is zero
sergeyv
2016/03/08 22:53:04
Done.
| |
| 260 | |
| 261 token = tokenizer.getToken(); | |
| 262 } | |
| 263 } | |
| 264 return originalText.substring(startIndex, endIndex); | |
| 265 } catch (e) { | |
| 266 return ""; | |
| 267 } | |
| 268 } | |
| 269 } | |
| 270 | |
| 271 /** | |
| 120 * @param {!WebInspector.DebuggerModel.Scope} scope | 272 * @param {!WebInspector.DebuggerModel.Scope} scope |
| 121 * @return {!WebInspector.RemoteObject} | 273 * @return {!WebInspector.RemoteObject} |
| 122 */ | 274 */ |
| 123 WebInspector.SourceMapNamesResolver.resolveScopeInObject = function(scope) | 275 WebInspector.SourceMapNamesResolver.resolveScopeInObject = function(scope) |
| 124 { | 276 { |
| 125 if (!Runtime.experiments.isEnabled("resolveVariableNames")) | 277 if (!Runtime.experiments.isEnabled("resolveVariableNames")) |
| 126 return scope.object(); | 278 return scope.object(); |
| 127 | 279 |
| 128 var startLocation = scope.startLocation(); | 280 var startLocation = scope.startLocation(); |
| 129 var endLocation = scope.endLocation(); | 281 var endLocation = scope.endLocation(); |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 * @override | 524 * @override |
| 373 * @param {function(?Array<!DebuggerAgent.CollectionEntry>)} callback | 525 * @param {function(?Array<!DebuggerAgent.CollectionEntry>)} callback |
| 374 */ | 526 */ |
| 375 collectionEntries: function(callback) | 527 collectionEntries: function(callback) |
| 376 { | 528 { |
| 377 this._object.collectionEntries(callback); | 529 this._object.collectionEntries(callback); |
| 378 }, | 530 }, |
| 379 | 531 |
| 380 __proto__: WebInspector.RemoteObject.prototype | 532 __proto__: WebInspector.RemoteObject.prototype |
| 381 } | 533 } |
| OLD | NEW |