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

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

Issue 1653053002: Devtools: parse variables scopes and sourcemap them (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 WebInspector.SourceMapNamesResolver = {};
6
7 WebInspector.SourceMapNamesResolver._cachedMapSymbol = Symbol("cache");
8 WebInspector.SourceMapNamesResolver._cachedPromiseSymbol = Symbol("cache");
9
10 /**
11 * @param {!WebInspector.DebuggerModel.Scope} scope
12 * @return {!Promise.<!Map<string, string>>}
13 */
14 WebInspector.SourceMapNamesResolver._resolveScope = function(scope)
15 {
16 var cachedMap = scope[WebInspector.SourceMapNamesResolver._cachedMapSymbol];
17 if (cachedMap)
18 return Promise.resolve(cachedMap);
19
20 var cachedPromise = scope[WebInspector.SourceMapNamesResolver._cachedPromise Symbol];
21 if (cachedPromise)
22 return cachedPromise;
23
24 var startLocation = scope.startLocation();
25 var endLocation = scope.endLocation();
26 var script = startLocation.script();
27
28 if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !en dLocation || !script.sourceMapURL || script !== endLocation.script())
29 return Promise.resolve(new Map());
30
31 var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(scr ipt);
32 if (!sourceMap)
33 return Promise.resolve(new Map());
34
35 var promise = script.requestContent().then(onContent);
36 scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol] = promise;
37 return promise;
38
39 /**
40 * @param {?string} content
41 * @return {!Map<string, string>}
42 */
43 function onContent(content)
44 {
45 if (!content)
46 return new Map();
47
48 var startLocation = scope.startLocation();
49 var endLocation = scope.endLocation();
50 var textRange = new WebInspector.TextRange(startLocation.lineNumber, sta rtLocation.columnNumber, endLocation.lineNumber, endLocation.columnNumber);
51
52 var scopeText = textRange.extract(content);
53 var scopeStart = textRange.toSourceRange(content).offset;
54 var prefix = "function fui";
55 var root = acorn.parse(prefix + scopeText, {});
56 var declarators = [];
57 var functionDeclarationCounter = 0;
58 var walker = new WebInspector.ESTreeWalker(beforeVisit, afterVisit);
59
60 /**
61 * @param {!ESTree.Node} node
62 */
63 function beforeVisit(node)
64 {
65 if (node.type === "FunctionDeclaration" || node.type === "FunctionEx pression")
66 functionDeclarationCounter++;
67
68 if (node.type === "VariableDeclarator" && functionDeclarationCounter === 1)
69 declarators.push(node);
70 }
71
72 /**
73 * @param {!ESTree.Node} node
74 */
75 function afterVisit(node)
76 {
77 if (node.type === "FunctionDeclaration" || node.type === "FunctionEx pression")
78 functionDeclarationCounter--;
79 }
80
81 walker.walk(root);
82
83 var namesMapping = new Map();
84 var lineEndings = content.lineEndings();
85
86 for (var i = 0; i < declarators.length; ++i) {
87 var id = declarators[i].id;
88 var start = scopeStart + id.start - prefix.length;
89
90 var lineNumber = lineEndings.lowerBound(start);
91 var columnNumber = start - (lineNumber === 0 ? 0 : (lineEndings[line Number - 1] + 1));
92 var entry = sourceMap.findEntry(lineNumber, columnNumber);
93 if (entry)
94 namesMapping.set(id.name, entry.name);
95 }
96
97 scope[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = namesMappi ng;
98 delete scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol];
99 return namesMapping;
100 }
101 }
102
103 /**
104 * @param {!WebInspector.DebuggerModel.Scope} scope
105 * @return {!WebInspector.RemoteObject}
106 */
107 WebInspector.SourceMapNamesResolver.resolveScopeInObject = function(scope)
108 {
109 if (!Runtime.experiments.isEnabled("resolveVariableNames"))
110 return scope.object();
111
112 var startLocation = scope.startLocation();
113 var endLocation = scope.endLocation();
114
115 if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !en dLocation || !startLocation.script().sourceMapURL || startLocation.script() !== endLocation.script())
116 return scope.object();
117
118 return new WebInspector.SourceMapNamesResolver.RemoteObject(scope);
119 }
120
121 /**
122 * @constructor
123 * @extends {WebInspector.RemoteObject}
124 * @param {!WebInspector.DebuggerModel.Scope} scope
125 */
126 WebInspector.SourceMapNamesResolver.RemoteObject = function(scope)
127 {
128 WebInspector.RemoteObject.call(this);
129 this._scope = scope;
130 this._object = scope.object();
131 };
132
133 WebInspector.SourceMapNamesResolver.RemoteObject.prototype = {
134 /**
135 * @override
136 * @return {?RuntimeAgent.CustomPreview}
137 */
138 customPreview: function()
139 {
140 return this._object.customPreview();
141 },
142
143 /**
144 * @override
145 * @return {string}
146 */
147 get type()
148 {
149 return this._object.type;
150 },
151
152 /**
153 * @override
154 * @return {string|undefined}
155 */
156 get subtype()
157 {
158 return this._object.subtype;
159 },
160
161 /**
162 * @override
163 * @return {string|undefined}
164 */
165 get description()
166 {
167 return this._object.description;
168 },
169
170 /**
171 * @override
172 * @return {boolean}
173 */
174 get hasChildren()
175 {
176 return this._object.hasChildren;
177 },
178
179 /**
180 * @override
181 * @return {number}
182 */
183 arrayLength: function()
184 {
185 return this._object.arrayLength();
186 },
187
188 /**
189 * @override
190 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!We bInspector.RemoteObjectProperty>)} callback
191 */
192 getOwnProperties: function(callback)
193 {
194 this._object.getOwnProperties(callback);
195 },
196
197 /**
198 * @override
199 * @param {boolean} accessorPropertiesOnly
200 * @param {function(?Array<!WebInspector.RemoteObjectProperty>, ?Array<!WebI nspector.RemoteObjectProperty>)} callback
201 */
202 getAllProperties: function(accessorPropertiesOnly, callback)
203 {
204 /**
205 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
206 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperti es
207 * @this {WebInspector.SourceMapNamesResolver.RemoteObject}
208 */
209 function wrappedCallback(properties, internalProperties)
210 {
211 WebInspector.SourceMapNamesResolver._resolveScope(this._scope).then( resolveNames.bind(null, properties, internalProperties))
212 }
213
214 /**
215 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
216 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperti es
217 * @param {!Map<string, string>} namesMapping
218 */
219 function resolveNames(properties, internalProperties, namesMapping)
220 {
221 var newProperties = [];
222 if (properties) {
223 for (var i = 0; i < properties.length; ++i) {
224 var property = properties[i];
225 var name = namesMapping.get(property.name) || properties[i]. name;
226 newProperties.push(new WebInspector.RemoteObjectProperty(nam e, property.value, property.enumerable, property.writable, property.isOwn, prope rty.wasThrown, property.symbol, property.synthetic));
227 }
228 }
229
230 callback(newProperties, internalProperties);
231 }
232
233 this._object.getAllProperties(accessorPropertiesOnly, wrappedCallback.bi nd(this));
234 },
235
236 /**
237 * @override
238 * @param {string|!RuntimeAgent.CallArgument} argumentName
239 * @param {string} value
240 * @param {function(string=)} callback
241 */
242 setPropertyValue: function(argumentName, value, callback)
243 {
244 WebInspector.SourceMapNamesResolver._resolveScope(this._scope).then(reso lveName.bind(this));
245
246 /**
247 * @param {!Map<string, string>} namesMapping
248 * @this {WebInspector.SourceMapNamesResolver.RemoteObject}
249 */
250 function resolveName(namesMapping)
251 {
252 var name;
253 if (typeof argumentName === "string")
254 name = argumentName;
255 else
256 name = /** @type {string} */ (argumentName.value);
257
258 var actualName = name;
259 for (var compiledName of namesMapping.keys()) {
260 if (namesMapping.get(compiledName) === name) {
261 actualName = compiledName;
262 break;
263 }
264 }
265 this._object.setPropertyValue(actualName, value, callback);
266 }
267 },
268
269 /**
270 * @override
271 * @return {!Promise<?Array<!WebInspector.EventListener>>}
272 */
273 eventListeners: function()
274 {
275 return this._object.eventListeners();
276 },
277
278 /**
279 * @override
280 * @param {!RuntimeAgent.CallArgument} name
281 * @param {function(string=)} callback
282 */
283 deleteProperty: function(name, callback)
284 {
285 this._object.deleteProperty(name, callback);
286 },
287
288 /**
289 * @override
290 * @param {function(this:Object, ...)} functionDeclaration
291 * @param {!Array<!RuntimeAgent.CallArgument>=} args
292 * @param {function(?WebInspector.RemoteObject, boolean=)=} callback
293 */
294 callFunction: function(functionDeclaration, args, callback)
295 {
296 this._object.callFunction(functionDeclaration, args, callback);
297 },
298
299 /**
300 * @override
301 * @param {function(this:Object, ...)} functionDeclaration
302 * @param {!Array<!RuntimeAgent.CallArgument>|undefined} args
303 * @param {function(*)} callback
304 */
305 callFunctionJSON: function(functionDeclaration, args, callback)
306 {
307 this._object.callFunctionJSON(functionDeclaration, args, callback);
308 },
309
310 /**
311 * @override
312 * @return {!WebInspector.Target}
313 */
314 target: function()
315 {
316 return this._object.target();
317 },
318
319 /**
320 * @override
321 * @return {?WebInspector.DebuggerModel}
322 */
323 debuggerModel: function()
324 {
325 return this._object.debuggerModel();
326 },
327
328 /**
329 * @override
330 * @return {boolean}
331 */
332 isNode: function()
333 {
334 return this._object.isNode();
335 },
336
337 /**
338 * @override
339 * @param {function(?WebInspector.DebuggerModel.FunctionDetails)} callback
340 */
341 functionDetails: function(callback)
342 {
343 this._object.functionDetails(callback);
344 },
345
346 /**
347 * @override
348 * @param {function(?WebInspector.DebuggerModel.GeneratorObjectDetails)} cal lback
349 */
350 generatorObjectDetails: function(callback)
351 {
352 this._object.generatorObjectDetails(callback);
353 },
354
355 /**
356 * @override
357 * @param {function(?Array<!DebuggerAgent.CollectionEntry>)} callback
358 */
359 collectionEntries: function(callback)
360 {
361 this._object.collectionEntries(callback);
362 },
363
364 __proto__: WebInspector.RemoteObject.prototype
365 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698