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 | |
5 WebInspector.SourceMapNamesResolver = {}; | 4 WebInspector.SourceMapNamesResolver = {}; |
6 | 5 |
7 WebInspector.SourceMapNamesResolver._cachedMapSymbol = Symbol("cache"); | 6 WebInspector.SourceMapNamesResolver._cachedMapSymbol = Symbol('cache'); |
8 WebInspector.SourceMapNamesResolver._cachedIdentifiersSymbol = Symbol("cachedIde
ntifiers"); | 7 WebInspector.SourceMapNamesResolver._cachedIdentifiersSymbol = Symbol('cachedIde
ntifiers'); |
9 | 8 |
10 /** | 9 /** |
11 * @constructor | 10 * @unrestricted |
12 * @param {string} name | 11 */ |
13 * @param {number} lineNumber | 12 WebInspector.SourceMapNamesResolver.Identifier = class { |
14 * @param {number} columnNumber | 13 /** |
15 */ | 14 * @param {string} name |
16 WebInspector.SourceMapNamesResolver.Identifier = function(name, lineNumber, colu
mnNumber) | 15 * @param {number} lineNumber |
17 { | 16 * @param {number} columnNumber |
| 17 */ |
| 18 constructor(name, lineNumber, columnNumber) { |
18 this.name = name; | 19 this.name = name; |
19 this.lineNumber = lineNumber; | 20 this.lineNumber = lineNumber; |
20 this.columnNumber = columnNumber; | 21 this.columnNumber = columnNumber; |
| 22 } |
21 }; | 23 }; |
22 | 24 |
23 /** | 25 /** |
24 * @param {!WebInspector.DebuggerModel.Scope} scope | 26 * @param {!WebInspector.DebuggerModel.Scope} scope |
25 * @return {!Promise<!Array<!WebInspector.SourceMapNamesResolver.Identifier>>} | 27 * @return {!Promise<!Array<!WebInspector.SourceMapNamesResolver.Identifier>>} |
26 */ | 28 */ |
27 WebInspector.SourceMapNamesResolver._scopeIdentifiers = function(scope) | 29 WebInspector.SourceMapNamesResolver._scopeIdentifiers = function(scope) { |
28 { | 30 var startLocation = scope.startLocation(); |
29 var startLocation = scope.startLocation(); | 31 var endLocation = scope.endLocation(); |
30 var endLocation = scope.endLocation(); | 32 |
31 | 33 if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !endL
ocation || |
32 if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !en
dLocation || !startLocation.script().sourceMapURL || (startLocation.script() !==
endLocation.script())) | 34 !startLocation.script().sourceMapURL || (startLocation.script() !== endLoc
ation.script())) |
33 return Promise.resolve(/** @type {!Array<!WebInspector.SourceMapNamesRes
olver.Identifier>}*/([])); | 35 return Promise.resolve(/** @type {!Array<!WebInspector.SourceMapNamesResolve
r.Identifier>}*/ ([])); |
34 | 36 |
35 var script = startLocation.script(); | 37 var script = startLocation.script(); |
36 return script.requestContent().then(onContent); | 38 return script.requestContent().then(onContent); |
37 | 39 |
38 /** | 40 /** |
39 * @param {?string} content | 41 * @param {?string} content |
40 * @return {!Promise<!Array<!WebInspector.SourceMapNamesResolver.Identifier>
>} | 42 * @return {!Promise<!Array<!WebInspector.SourceMapNamesResolver.Identifier>>} |
41 */ | 43 */ |
42 function onContent(content) | 44 function onContent(content) { |
43 { | 45 if (!content) |
44 if (!content) | 46 return Promise.resolve(/** @type {!Array<!WebInspector.SourceMapNamesResol
ver.Identifier>}*/ ([])); |
45 return Promise.resolve(/** @type {!Array<!WebInspector.SourceMapName
sResolver.Identifier>}*/([])); | 47 |
46 | 48 var text = new WebInspector.Text(content); |
47 var text = new WebInspector.Text(content); | 49 var scopeRange = new WebInspector.TextRange( |
48 var scopeRange = new WebInspector.TextRange(startLocation.lineNumber, st
artLocation.columnNumber, endLocation.lineNumber, endLocation.columnNumber); | 50 startLocation.lineNumber, startLocation.columnNumber, endLocation.lineNu
mber, endLocation.columnNumber); |
49 var scopeText = text.extract(scopeRange); | 51 var scopeText = text.extract(scopeRange); |
50 var scopeStart = text.toSourceRange(scopeRange).offset; | 52 var scopeStart = text.toSourceRange(scopeRange).offset; |
51 var prefix = "function fui"; | 53 var prefix = 'function fui'; |
52 return WebInspector.formatterWorkerPool.runTask("javaScriptIdentifiers",
{content: prefix + scopeText}) | 54 return WebInspector.formatterWorkerPool.runTask('javaScriptIdentifiers', {co
ntent: prefix + scopeText}) |
53 .then(onIdentifiers.bind(null, text, scopeStart, prefix)); | 55 .then(onIdentifiers.bind(null, text, scopeStart, prefix)); |
54 } | 56 } |
55 | 57 |
56 /** | 58 /** |
57 * @param {!WebInspector.Text} text | 59 * @param {!WebInspector.Text} text |
58 * @param {number} scopeStart | 60 * @param {number} scopeStart |
59 * @param {string} prefix | 61 * @param {string} prefix |
60 * @param {?MessageEvent} event | 62 * @param {?MessageEvent} event |
61 * @return {!Array<!WebInspector.SourceMapNamesResolver.Identifier>} | 63 * @return {!Array<!WebInspector.SourceMapNamesResolver.Identifier>} |
62 */ | 64 */ |
63 function onIdentifiers(text, scopeStart, prefix, event) | 65 function onIdentifiers(text, scopeStart, prefix, event) { |
64 { | 66 var identifiers = event ? /** @type {!Array<!{name: string, offset: number}>
} */ (event.data) : []; |
65 var identifiers = event ? /** @type {!Array<!{name: string, offset: numb
er}>} */(event.data) : []; | 67 var result = []; |
66 var result = []; | 68 var cursor = new WebInspector.TextCursor(text.lineEndings()); |
67 var cursor = new WebInspector.TextCursor(text.lineEndings()); | 69 var promises = []; |
68 var promises = []; | 70 for (var i = 0; i < identifiers.length; ++i) { |
69 for (var i = 0; i < identifiers.length; ++i) { | 71 var id = identifiers[i]; |
70 var id = identifiers[i]; | 72 if (id.offset < prefix.length) |
71 if (id.offset < prefix.length) | 73 continue; |
72 continue; | 74 var start = scopeStart + id.offset - prefix.length; |
73 var start = scopeStart + id.offset - prefix.length; | 75 cursor.resetTo(start); |
74 cursor.resetTo(start); | 76 result.push( |
75 result.push(new WebInspector.SourceMapNamesResolver.Identifier(id.na
me, cursor.lineNumber(), cursor.columnNumber())); | 77 new WebInspector.SourceMapNamesResolver.Identifier(id.name, cursor.lin
eNumber(), cursor.columnNumber())); |
76 } | 78 } |
77 return result; | 79 return result; |
78 } | 80 } |
79 }; | 81 }; |
80 | 82 |
81 /** | 83 /** |
82 * @param {!WebInspector.DebuggerModel.Scope} scope | 84 * @param {!WebInspector.DebuggerModel.Scope} scope |
83 * @return {!Promise.<!Map<string, string>>} | 85 * @return {!Promise.<!Map<string, string>>} |
84 */ | 86 */ |
85 WebInspector.SourceMapNamesResolver._resolveScope = function(scope) | 87 WebInspector.SourceMapNamesResolver._resolveScope = function(scope) { |
86 { | 88 var identifiersPromise = scope[WebInspector.SourceMapNamesResolver._cachedIden
tifiersSymbol]; |
87 var identifiersPromise = scope[WebInspector.SourceMapNamesResolver._cachedId
entifiersSymbol]; | 89 if (identifiersPromise) |
88 if (identifiersPromise) | |
89 return identifiersPromise; | |
90 | |
91 var script = scope.callFrame().script; | |
92 var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(scr
ipt); | |
93 if (!sourceMap) | |
94 return Promise.resolve(new Map()); | |
95 | |
96 /** @type {!Map<string, !WebInspector.Text>} */ | |
97 var textCache = new Map(); | |
98 identifiersPromise = WebInspector.SourceMapNamesResolver._scopeIdentifiers(s
cope).then(onIdentifiers); | |
99 scope[WebInspector.SourceMapNamesResolver._cachedIdentifiersSymbol] = identi
fiersPromise; | |
100 return identifiersPromise; | 90 return identifiersPromise; |
101 | 91 |
102 /** | 92 var script = scope.callFrame().script; |
103 * @param {!Array<!WebInspector.SourceMapNamesResolver.Identifier>} identifi
ers | 93 var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(scrip
t); |
104 * @return {!Promise<!Map<string, string>>} | 94 if (!sourceMap) |
105 */ | 95 return Promise.resolve(new Map()); |
106 function onIdentifiers(identifiers) | 96 |
107 { | 97 /** @type {!Map<string, !WebInspector.Text>} */ |
108 var namesMapping = new Map(); | 98 var textCache = new Map(); |
109 // Extract as much as possible from SourceMap. | 99 identifiersPromise = WebInspector.SourceMapNamesResolver._scopeIdentifiers(sco
pe).then(onIdentifiers); |
110 for (var i = 0; i < identifiers.length; ++i) { | 100 scope[WebInspector.SourceMapNamesResolver._cachedIdentifiersSymbol] = identifi
ersPromise; |
111 var id = identifiers[i]; | 101 return identifiersPromise; |
112 var entry = sourceMap.findEntry(id.lineNumber, id.columnNumber); | 102 |
113 if (entry && entry.name) | 103 /** |
114 namesMapping.set(id.name, entry.name); | 104 * @param {!Array<!WebInspector.SourceMapNamesResolver.Identifier>} identifier
s |
115 } | 105 * @return {!Promise<!Map<string, string>>} |
116 | 106 */ |
117 // Resolve missing identifier names from sourcemap ranges. | 107 function onIdentifiers(identifiers) { |
118 var promises = []; | 108 var namesMapping = new Map(); |
119 for (var i = 0; i < identifiers.length; ++i) { | 109 // Extract as much as possible from SourceMap. |
120 var id = identifiers[i]; | 110 for (var i = 0; i < identifiers.length; ++i) { |
121 if (namesMapping.has(id.name)) | 111 var id = identifiers[i]; |
122 continue; | 112 var entry = sourceMap.findEntry(id.lineNumber, id.columnNumber); |
123 var promise = resolveSourceName(id).then(onSourceNameResolved.bind(n
ull, namesMapping, id)); | 113 if (entry && entry.name) |
124 promises.push(promise); | 114 namesMapping.set(id.name, entry.name); |
125 } | 115 } |
126 return Promise.all(promises) | 116 |
127 .then(() => WebInspector.SourceMapNamesResolver._scopeResolvedForTes
t()) | 117 // Resolve missing identifier names from sourcemap ranges. |
128 .then(() => namesMapping); | 118 var promises = []; |
129 } | 119 for (var i = 0; i < identifiers.length; ++i) { |
130 | 120 var id = identifiers[i]; |
131 /** | 121 if (namesMapping.has(id.name)) |
132 * @param {!Map<string, string>} namesMapping | 122 continue; |
133 * @param {!WebInspector.SourceMapNamesResolver.Identifier} id | 123 var promise = resolveSourceName(id).then(onSourceNameResolved.bind(null, n
amesMapping, id)); |
134 * @param {?string} sourceName | 124 promises.push(promise); |
135 */ | 125 } |
136 function onSourceNameResolved(namesMapping, id, sourceName) | 126 return Promise.all(promises) |
137 { | 127 .then(() => WebInspector.SourceMapNamesResolver._scopeResolvedForTest()) |
138 if (!sourceName) | 128 .then(() => namesMapping); |
139 return; | 129 } |
140 namesMapping.set(id.name, sourceName); | 130 |
141 } | 131 /** |
142 | 132 * @param {!Map<string, string>} namesMapping |
143 /** | 133 * @param {!WebInspector.SourceMapNamesResolver.Identifier} id |
144 * @param {!WebInspector.SourceMapNamesResolver.Identifier} id | 134 * @param {?string} sourceName |
145 * @return {!Promise<?string>} | 135 */ |
146 */ | 136 function onSourceNameResolved(namesMapping, id, sourceName) { |
147 function resolveSourceName(id) | 137 if (!sourceName) |
148 { | 138 return; |
149 var startEntry = sourceMap.findEntry(id.lineNumber, id.columnNumber); | 139 namesMapping.set(id.name, sourceName); |
150 var endEntry = sourceMap.findEntry(id.lineNumber, id.columnNumber + id.n
ame.length); | 140 } |
151 if (!startEntry || !endEntry || !startEntry.sourceURL || startEntry.sour
ceURL !== endEntry.sourceURL | 141 |
152 || !startEntry.sourceLineNumber || !startEntry.sourceColumnNumber | 142 /** |
153 || !endEntry.sourceLineNumber || !endEntry.sourceColumnNumber) | 143 * @param {!WebInspector.SourceMapNamesResolver.Identifier} id |
154 return Promise.resolve(/** @type {?string} */(null)); | 144 * @return {!Promise<?string>} |
155 var sourceTextRange = new WebInspector.TextRange(startEntry.sourceLineNu
mber, startEntry.sourceColumnNumber, endEntry.sourceLineNumber, endEntry.sourceC
olumnNumber); | 145 */ |
156 var uiSourceCode = WebInspector.networkMapping.uiSourceCodeForScriptURL(
startEntry.sourceURL, script); | 146 function resolveSourceName(id) { |
157 if (!uiSourceCode) | 147 var startEntry = sourceMap.findEntry(id.lineNumber, id.columnNumber); |
158 return Promise.resolve(/** @type {?string} */(null)); | 148 var endEntry = sourceMap.findEntry(id.lineNumber, id.columnNumber + id.name.
length); |
159 | 149 if (!startEntry || !endEntry || !startEntry.sourceURL || startEntry.sourceUR
L !== endEntry.sourceURL || |
160 return uiSourceCode.requestContent() | 150 !startEntry.sourceLineNumber || !startEntry.sourceColumnNumber || !endEn
try.sourceLineNumber || |
161 .then(onSourceContent.bind(null, sourceTextRange)); | 151 !endEntry.sourceColumnNumber) |
162 } | 152 return Promise.resolve(/** @type {?string} */ (null)); |
163 | 153 var sourceTextRange = new WebInspector.TextRange( |
164 /** | 154 startEntry.sourceLineNumber, startEntry.sourceColumnNumber, endEntry.sou
rceLineNumber, |
165 * @param {!WebInspector.TextRange} sourceTextRange | 155 endEntry.sourceColumnNumber); |
166 * @param {?string} content | 156 var uiSourceCode = WebInspector.networkMapping.uiSourceCodeForScriptURL(star
tEntry.sourceURL, script); |
167 * @return {?string} | 157 if (!uiSourceCode) |
168 */ | 158 return Promise.resolve(/** @type {?string} */ (null)); |
169 function onSourceContent(sourceTextRange, content) | 159 |
170 { | 160 return uiSourceCode.requestContent().then(onSourceContent.bind(null, sourceT
extRange)); |
171 if (!content) | 161 } |
172 return null; | 162 |
173 var text = textCache.get(content); | 163 /** |
174 if (!text) { | 164 * @param {!WebInspector.TextRange} sourceTextRange |
175 text = new WebInspector.Text(content); | 165 * @param {?string} content |
176 textCache.set(content, text); | 166 * @return {?string} |
177 } | 167 */ |
178 var originalIdentifier = text.extract(sourceTextRange).trim(); | 168 function onSourceContent(sourceTextRange, content) { |
179 return /[a-zA-Z0-9_$]+/.test(originalIdentifier) ? originalIdentifier :
null; | 169 if (!content) |
180 } | 170 return null; |
181 }; | 171 var text = textCache.get(content); |
182 | 172 if (!text) { |
183 WebInspector.SourceMapNamesResolver._scopeResolvedForTest = function() { }; | 173 text = new WebInspector.Text(content); |
| 174 textCache.set(content, text); |
| 175 } |
| 176 var originalIdentifier = text.extract(sourceTextRange).trim(); |
| 177 return /[a-zA-Z0-9_$]+/.test(originalIdentifier) ? originalIdentifier : null
; |
| 178 } |
| 179 }; |
| 180 |
| 181 WebInspector.SourceMapNamesResolver._scopeResolvedForTest = function() {}; |
184 | 182 |
185 /** | 183 /** |
186 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame | 184 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame |
187 * @return {!Promise.<!Map<string, string>>} | 185 * @return {!Promise.<!Map<string, string>>} |
188 */ | 186 */ |
189 WebInspector.SourceMapNamesResolver._allVariablesInCallFrame = function(callFram
e) | 187 WebInspector.SourceMapNamesResolver._allVariablesInCallFrame = function(callFram
e) { |
190 { | 188 var cached = callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol]; |
191 var cached = callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol]
; | 189 if (cached) |
192 if (cached) | 190 return Promise.resolve(cached); |
193 return Promise.resolve(cached); | 191 |
194 | 192 var promises = []; |
195 var promises = []; | 193 var scopeChain = callFrame.scopeChain(); |
196 var scopeChain = callFrame.scopeChain(); | 194 for (var i = 0; i < scopeChain.length; ++i) |
197 for (var i = 0; i < scopeChain.length; ++i) | 195 promises.push(WebInspector.SourceMapNamesResolver._resolveScope(scopeChain[i
])); |
198 promises.push(WebInspector.SourceMapNamesResolver._resolveScope(scopeCha
in[i])); | 196 |
199 | 197 return Promise.all(promises).then(mergeVariables); |
200 return Promise.all(promises).then(mergeVariables); | 198 |
201 | 199 /** |
202 /** | 200 * @param {!Array<!Map<string, string>>} nameMappings |
203 * @param {!Array<!Map<string, string>>} nameMappings | 201 * @return {!Map<string, string>} |
204 * @return {!Map<string, string>} | 202 */ |
205 */ | 203 function mergeVariables(nameMappings) { |
206 function mergeVariables(nameMappings) | 204 var reverseMapping = new Map(); |
207 { | 205 for (var map of nameMappings) { |
208 var reverseMapping = new Map(); | 206 for (var compiledName of map.keys()) { |
209 for (var map of nameMappings) { | 207 var originalName = map.get(compiledName); |
210 for (var compiledName of map.keys()) { | 208 if (!reverseMapping.has(originalName)) |
211 var originalName = map.get(compiledName); | 209 reverseMapping.set(originalName, compiledName); |
212 if (!reverseMapping.has(originalName)) | 210 } |
213 reverseMapping.set(originalName, compiledName); | 211 } |
214 } | 212 callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = reverseMap
ping; |
215 } | 213 return reverseMapping; |
216 callFrame[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = revers
eMapping; | 214 } |
217 return reverseMapping; | 215 }; |
218 } | 216 |
219 }; | 217 /** |
220 | |
221 /** | |
222 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame | 218 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame |
223 * @param {string} originalText | 219 * @param {string} originalText |
224 * @param {!WebInspector.UISourceCode} uiSourceCode | 220 * @param {!WebInspector.UISourceCode} uiSourceCode |
225 * @param {number} lineNumber | 221 * @param {number} lineNumber |
226 * @param {number} startColumnNumber | 222 * @param {number} startColumnNumber |
227 * @param {number} endColumnNumber | 223 * @param {number} endColumnNumber |
228 * @return {!Promise<string>} | 224 * @return {!Promise<string>} |
229 */ | 225 */ |
230 WebInspector.SourceMapNamesResolver.resolveExpression = function(callFrame, orig
inalText, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) | 226 WebInspector.SourceMapNamesResolver.resolveExpression = function( |
231 { | 227 callFrame, originalText, uiSourceCode, lineNumber, startColumnNumber, endCol
umnNumber) { |
232 if (!Runtime.experiments.isEnabled("resolveVariableNames") || !uiSourceCode.
contentType().isFromSourceMap()) | 228 if (!Runtime.experiments.isEnabled('resolveVariableNames') || !uiSourceCode.co
ntentType().isFromSourceMap()) |
233 return Promise.resolve(""); | 229 return Promise.resolve(''); |
234 | 230 |
235 return WebInspector.SourceMapNamesResolver._allVariablesInCallFrame(callFram
e).then(findCompiledName); | 231 return WebInspector.SourceMapNamesResolver._allVariablesInCallFrame(callFrame)
.then(findCompiledName); |
236 | 232 |
237 /** | 233 /** |
238 * @param {!Map<string, string>} reverseMapping | 234 * @param {!Map<string, string>} reverseMapping |
239 * @return {!Promise<string>} | 235 * @return {!Promise<string>} |
240 */ | 236 */ |
241 function findCompiledName(reverseMapping) | 237 function findCompiledName(reverseMapping) { |
242 { | 238 if (reverseMapping.has(originalText)) |
243 if (reverseMapping.has(originalText)) | 239 return Promise.resolve(reverseMapping.get(originalText) || ''); |
244 return Promise.resolve(reverseMapping.get(originalText) || ""); | |
245 | 240 |
246 return WebInspector.SourceMapNamesResolver._resolveExpression(callFrame,
uiSourceCode, lineNumber, startColumnNumber, endColumnNumber); | 241 return WebInspector.SourceMapNamesResolver._resolveExpression( |
247 } | 242 callFrame, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber)
; |
| 243 } |
248 }; | 244 }; |
249 | 245 |
250 /** | 246 /** |
251 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame | 247 * @param {!WebInspector.DebuggerModel.CallFrame} callFrame |
252 * @param {!WebInspector.UISourceCode} uiSourceCode | 248 * @param {!WebInspector.UISourceCode} uiSourceCode |
253 * @param {number} lineNumber | 249 * @param {number} lineNumber |
254 * @param {number} startColumnNumber | 250 * @param {number} startColumnNumber |
255 * @param {number} endColumnNumber | 251 * @param {number} endColumnNumber |
256 * @return {!Promise<string>} | 252 * @return {!Promise<string>} |
257 */ | 253 */ |
258 WebInspector.SourceMapNamesResolver._resolveExpression = function(callFrame, uiS
ourceCode, lineNumber, startColumnNumber, endColumnNumber) | 254 WebInspector.SourceMapNamesResolver._resolveExpression = function( |
259 { | 255 callFrame, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) { |
260 var target = callFrame.target(); | 256 var target = callFrame.target(); |
261 var rawLocation = WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocat
ion(target, uiSourceCode, lineNumber, startColumnNumber); | 257 var rawLocation = WebInspector.debuggerWorkspaceBinding.uiLocationToRawLocatio
n( |
262 if (!rawLocation) | 258 target, uiSourceCode, lineNumber, startColumnNumber); |
263 return Promise.resolve(""); | 259 if (!rawLocation) |
264 | 260 return Promise.resolve(''); |
265 var script = rawLocation.script(); | 261 |
266 if (!script) | 262 var script = rawLocation.script(); |
267 return Promise.resolve(""); | 263 if (!script) |
268 var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(scr
ipt); | 264 return Promise.resolve(''); |
269 if (!sourceMap) | 265 var sourceMap = WebInspector.debuggerWorkspaceBinding.sourceMapForScript(scrip
t); |
270 return Promise.resolve(""); | 266 if (!sourceMap) |
271 | 267 return Promise.resolve(''); |
272 return script.requestContent().then(onContent); | 268 |
273 | 269 return script.requestContent().then(onContent); |
274 /** | 270 |
275 * @param {?string} content | 271 /** |
276 * @return {!Promise<string>} | 272 * @param {?string} content |
277 */ | 273 * @return {!Promise<string>} |
278 function onContent(content) | 274 */ |
279 { | 275 function onContent(content) { |
280 if (!content) | 276 if (!content) |
281 return Promise.resolve(""); | 277 return Promise.resolve(''); |
282 | 278 |
283 var text = new WebInspector.Text(content); | 279 var text = new WebInspector.Text(content); |
284 var textRange = sourceMap.reverseMapTextRange(uiSourceCode.url(), new We
bInspector.TextRange(lineNumber, startColumnNumber, lineNumber, endColumnNumber)
); | 280 var textRange = sourceMap.reverseMapTextRange( |
285 var originalText = text.extract(textRange); | 281 uiSourceCode.url(), new WebInspector.TextRange(lineNumber, startColumnNu
mber, lineNumber, endColumnNumber)); |
286 if (!originalText) | 282 var originalText = text.extract(textRange); |
287 return Promise.resolve(""); | 283 if (!originalText) |
288 return WebInspector.formatterWorkerPool.runTask("evaluatableJavaScriptSu
bstring", {content: originalText}) | 284 return Promise.resolve(''); |
289 .then(onResult); | 285 return WebInspector.formatterWorkerPool.runTask('evaluatableJavaScriptSubstr
ing', {content: originalText}) |
290 } | 286 .then(onResult); |
291 | 287 } |
292 /** | 288 |
293 * @param {?MessageEvent} event | 289 /** |
294 * @return {string} | 290 * @param {?MessageEvent} event |
295 */ | 291 * @return {string} |
296 function onResult(event) | 292 */ |
297 { | 293 function onResult(event) { |
298 return event ? /** @type {string} */(event.data) : ""; | 294 return event ? /** @type {string} */ (event.data) : ''; |
299 } | 295 } |
300 }; | 296 }; |
301 | 297 |
302 /** | 298 /** |
303 * @param {?WebInspector.DebuggerModel.CallFrame} callFrame | 299 * @param {?WebInspector.DebuggerModel.CallFrame} callFrame |
304 * @return {!Promise<?WebInspector.RemoteObject>} | 300 * @return {!Promise<?WebInspector.RemoteObject>} |
305 */ | 301 */ |
306 WebInspector.SourceMapNamesResolver.resolveThisObject = function(callFrame) | 302 WebInspector.SourceMapNamesResolver.resolveThisObject = function(callFrame) { |
307 { | 303 if (!callFrame) |
308 if (!callFrame) | 304 return Promise.resolve(/** @type {?WebInspector.RemoteObject} */ (null)); |
309 return Promise.resolve(/** @type {?WebInspector.RemoteObject} */(null)); | 305 if (!Runtime.experiments.isEnabled('resolveVariableNames') || !callFrame.scope
Chain().length) |
310 if (!Runtime.experiments.isEnabled("resolveVariableNames") || !callFrame.sco
peChain().length) | 306 return Promise.resolve(callFrame.thisObject()); |
311 return Promise.resolve(callFrame.thisObject()); | 307 |
312 | 308 return WebInspector.SourceMapNamesResolver._resolveScope(callFrame.scopeChain(
)[0]).then(onScopeResolved); |
313 return WebInspector.SourceMapNamesResolver._resolveScope(callFrame.scopeChai
n()[0]) | 309 |
314 .then(onScopeResolved); | 310 /** |
315 | 311 * @param {!Map<string, string>} namesMapping |
316 /** | 312 * @return {!Promise<?WebInspector.RemoteObject>} |
317 * @param {!Map<string, string>} namesMapping | 313 */ |
318 * @return {!Promise<?WebInspector.RemoteObject>} | 314 function onScopeResolved(namesMapping) { |
319 */ | 315 var thisMappings = namesMapping.inverse().get('this'); |
320 function onScopeResolved(namesMapping) | 316 if (!thisMappings || thisMappings.size !== 1) |
321 { | 317 return Promise.resolve(callFrame.thisObject()); |
322 var thisMappings = namesMapping.inverse().get("this"); | 318 |
323 if (!thisMappings || thisMappings.size !== 1) | 319 var thisMapping = thisMappings.valuesArray()[0]; |
324 return Promise.resolve(callFrame.thisObject()); | 320 var callback; |
325 | 321 var promise = new Promise(fulfill => callback = fulfill); |
326 var thisMapping = thisMappings.valuesArray()[0]; | 322 callFrame.evaluate(thisMapping, 'backtrace', false, true, false, true, onEva
luated.bind(null, callback)); |
327 var callback; | 323 return promise; |
328 var promise = new Promise(fulfill => callback = fulfill); | 324 } |
329 callFrame.evaluate(thisMapping, "backtrace", false, true, false, true, o
nEvaluated.bind(null, callback)); | 325 |
330 return promise; | 326 /** |
331 } | 327 * @param {function(!WebInspector.RemoteObject)} callback |
332 | 328 * @param {?RuntimeAgent.RemoteObject} evaluateResult |
333 /** | 329 */ |
334 * @param {function(!WebInspector.RemoteObject)} callback | 330 function onEvaluated(callback, evaluateResult) { |
335 * @param {?RuntimeAgent.RemoteObject} evaluateResult | 331 var remoteObject = |
336 */ | 332 evaluateResult ? callFrame.target().runtimeModel.createRemoteObject(eval
uateResult) : callFrame.thisObject(); |
337 function onEvaluated(callback, evaluateResult) | 333 callback(remoteObject); |
338 { | 334 } |
339 var remoteObject = evaluateResult ? callFrame.target().runtimeModel.crea
teRemoteObject(evaluateResult) : callFrame.thisObject(); | |
340 callback(remoteObject); | |
341 } | |
342 }; | 335 }; |
343 | 336 |
344 /** | 337 /** |
345 * @param {!WebInspector.DebuggerModel.Scope} scope | 338 * @param {!WebInspector.DebuggerModel.Scope} scope |
346 * @return {!WebInspector.RemoteObject} | 339 * @return {!WebInspector.RemoteObject} |
347 */ | 340 */ |
348 WebInspector.SourceMapNamesResolver.resolveScopeInObject = function(scope) | 341 WebInspector.SourceMapNamesResolver.resolveScopeInObject = function(scope) { |
349 { | 342 if (!Runtime.experiments.isEnabled('resolveVariableNames')) |
350 if (!Runtime.experiments.isEnabled("resolveVariableNames")) | 343 return scope.object(); |
351 return scope.object(); | 344 |
352 | 345 var startLocation = scope.startLocation(); |
353 var startLocation = scope.startLocation(); | 346 var endLocation = scope.endLocation(); |
354 var endLocation = scope.endLocation(); | 347 |
355 | 348 if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !endL
ocation || |
356 if (scope.type() === DebuggerAgent.ScopeType.Global || !startLocation || !en
dLocation || !startLocation.script().sourceMapURL || startLocation.script() !==
endLocation.script()) | 349 !startLocation.script().sourceMapURL || startLocation.script() !== endLoca
tion.script()) |
357 return scope.object(); | 350 return scope.object(); |
358 | 351 |
359 return new WebInspector.SourceMapNamesResolver.RemoteObject(scope); | 352 return new WebInspector.SourceMapNamesResolver.RemoteObject(scope); |
360 }; | 353 }; |
361 | 354 |
362 /** | 355 /** |
363 * @constructor | 356 * @unrestricted |
364 * @extends {WebInspector.RemoteObject} | |
365 * @param {!WebInspector.DebuggerModel.Scope} scope | |
366 */ | 357 */ |
367 WebInspector.SourceMapNamesResolver.RemoteObject = function(scope) | 358 WebInspector.SourceMapNamesResolver.RemoteObject = class extends WebInspector.Re
moteObject { |
368 { | 359 /** |
369 WebInspector.RemoteObject.call(this); | 360 * @param {!WebInspector.DebuggerModel.Scope} scope |
| 361 */ |
| 362 constructor(scope) { |
| 363 super(); |
370 this._scope = scope; | 364 this._scope = scope; |
371 this._object = scope.object(); | 365 this._object = scope.object(); |
| 366 } |
| 367 |
| 368 /** |
| 369 * @override |
| 370 * @return {?RuntimeAgent.CustomPreview} |
| 371 */ |
| 372 customPreview() { |
| 373 return this._object.customPreview(); |
| 374 } |
| 375 |
| 376 /** |
| 377 * @override |
| 378 * @return {string} |
| 379 */ |
| 380 get type() { |
| 381 return this._object.type; |
| 382 } |
| 383 |
| 384 /** |
| 385 * @override |
| 386 * @return {string|undefined} |
| 387 */ |
| 388 get subtype() { |
| 389 return this._object.subtype; |
| 390 } |
| 391 |
| 392 /** |
| 393 * @override |
| 394 * @return {string|undefined} |
| 395 */ |
| 396 get description() { |
| 397 return this._object.description; |
| 398 } |
| 399 |
| 400 /** |
| 401 * @override |
| 402 * @return {boolean} |
| 403 */ |
| 404 get hasChildren() { |
| 405 return this._object.hasChildren; |
| 406 } |
| 407 |
| 408 /** |
| 409 * @override |
| 410 * @return {number} |
| 411 */ |
| 412 arrayLength() { |
| 413 return this._object.arrayLength(); |
| 414 } |
| 415 |
| 416 /** |
| 417 * @override |
| 418 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebI
nspector.RemoteObjectProperty>)} callback |
| 419 */ |
| 420 getOwnProperties(callback) { |
| 421 this._object.getOwnProperties(callback); |
| 422 } |
| 423 |
| 424 /** |
| 425 * @override |
| 426 * @param {boolean} accessorPropertiesOnly |
| 427 * @param {function(?Array<!WebInspector.RemoteObjectProperty>, ?Array<!WebIns
pector.RemoteObjectProperty>)} callback |
| 428 */ |
| 429 getAllProperties(accessorPropertiesOnly, callback) { |
| 430 /** |
| 431 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties |
| 432 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties |
| 433 * @this {WebInspector.SourceMapNamesResolver.RemoteObject} |
| 434 */ |
| 435 function wrappedCallback(properties, internalProperties) { |
| 436 WebInspector.SourceMapNamesResolver._resolveScope(this._scope) |
| 437 .then(resolveNames.bind(null, properties, internalProperties)); |
| 438 } |
| 439 |
| 440 /** |
| 441 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties |
| 442 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties |
| 443 * @param {!Map<string, string>} namesMapping |
| 444 */ |
| 445 function resolveNames(properties, internalProperties, namesMapping) { |
| 446 var newProperties = []; |
| 447 if (properties) { |
| 448 for (var i = 0; i < properties.length; ++i) { |
| 449 var property = properties[i]; |
| 450 var name = namesMapping.get(property.name) || properties[i].name; |
| 451 newProperties.push(new WebInspector.RemoteObjectProperty( |
| 452 name, property.value, property.enumerable, property.writable, prop
erty.isOwn, property.wasThrown, |
| 453 property.symbol, property.synthetic)); |
| 454 } |
| 455 } |
| 456 |
| 457 callback(newProperties, internalProperties); |
| 458 } |
| 459 |
| 460 this._object.getAllProperties(accessorPropertiesOnly, wrappedCallback.bind(t
his)); |
| 461 } |
| 462 |
| 463 /** |
| 464 * @override |
| 465 * @param {string|!RuntimeAgent.CallArgument} argumentName |
| 466 * @param {string} value |
| 467 * @param {function(string=)} callback |
| 468 */ |
| 469 setPropertyValue(argumentName, value, callback) { |
| 470 WebInspector.SourceMapNamesResolver._resolveScope(this._scope).then(resolveN
ame.bind(this)); |
| 471 |
| 472 /** |
| 473 * @param {!Map<string, string>} namesMapping |
| 474 * @this {WebInspector.SourceMapNamesResolver.RemoteObject} |
| 475 */ |
| 476 function resolveName(namesMapping) { |
| 477 var name; |
| 478 if (typeof argumentName === 'string') |
| 479 name = argumentName; |
| 480 else |
| 481 name = /** @type {string} */ (argumentName.value); |
| 482 |
| 483 var actualName = name; |
| 484 for (var compiledName of namesMapping.keys()) { |
| 485 if (namesMapping.get(compiledName) === name) { |
| 486 actualName = compiledName; |
| 487 break; |
| 488 } |
| 489 } |
| 490 this._object.setPropertyValue(actualName, value, callback); |
| 491 } |
| 492 } |
| 493 |
| 494 /** |
| 495 * @override |
| 496 * @return {!Promise<?Array<!WebInspector.EventListener>>} |
| 497 */ |
| 498 eventListeners() { |
| 499 return this._object.eventListeners(); |
| 500 } |
| 501 |
| 502 /** |
| 503 * @override |
| 504 * @param {!RuntimeAgent.CallArgument} name |
| 505 * @param {function(string=)} callback |
| 506 */ |
| 507 deleteProperty(name, callback) { |
| 508 this._object.deleteProperty(name, callback); |
| 509 } |
| 510 |
| 511 /** |
| 512 * @override |
| 513 * @param {function(this:Object, ...)} functionDeclaration |
| 514 * @param {!Array<!RuntimeAgent.CallArgument>=} args |
| 515 * @param {function(?WebInspector.RemoteObject, boolean=)=} callback |
| 516 */ |
| 517 callFunction(functionDeclaration, args, callback) { |
| 518 this._object.callFunction(functionDeclaration, args, callback); |
| 519 } |
| 520 |
| 521 /** |
| 522 * @override |
| 523 * @param {function(this:Object, ...)} functionDeclaration |
| 524 * @param {!Array<!RuntimeAgent.CallArgument>|undefined} args |
| 525 * @param {function(*)} callback |
| 526 */ |
| 527 callFunctionJSON(functionDeclaration, args, callback) { |
| 528 this._object.callFunctionJSON(functionDeclaration, args, callback); |
| 529 } |
| 530 |
| 531 /** |
| 532 * @override |
| 533 * @return {!WebInspector.Target} |
| 534 */ |
| 535 target() { |
| 536 return this._object.target(); |
| 537 } |
| 538 |
| 539 /** |
| 540 * @override |
| 541 * @return {?WebInspector.DebuggerModel} |
| 542 */ |
| 543 debuggerModel() { |
| 544 return this._object.debuggerModel(); |
| 545 } |
| 546 |
| 547 /** |
| 548 * @override |
| 549 * @return {boolean} |
| 550 */ |
| 551 isNode() { |
| 552 return this._object.isNode(); |
| 553 } |
372 }; | 554 }; |
373 | |
374 WebInspector.SourceMapNamesResolver.RemoteObject.prototype = { | |
375 /** | |
376 * @override | |
377 * @return {?RuntimeAgent.CustomPreview} | |
378 */ | |
379 customPreview: function() | |
380 { | |
381 return this._object.customPreview(); | |
382 }, | |
383 | |
384 /** | |
385 * @override | |
386 * @return {string} | |
387 */ | |
388 get type() | |
389 { | |
390 return this._object.type; | |
391 }, | |
392 | |
393 /** | |
394 * @override | |
395 * @return {string|undefined} | |
396 */ | |
397 get subtype() | |
398 { | |
399 return this._object.subtype; | |
400 }, | |
401 | |
402 /** | |
403 * @override | |
404 * @return {string|undefined} | |
405 */ | |
406 get description() | |
407 { | |
408 return this._object.description; | |
409 }, | |
410 | |
411 /** | |
412 * @override | |
413 * @return {boolean} | |
414 */ | |
415 get hasChildren() | |
416 { | |
417 return this._object.hasChildren; | |
418 }, | |
419 | |
420 /** | |
421 * @override | |
422 * @return {number} | |
423 */ | |
424 arrayLength: function() | |
425 { | |
426 return this._object.arrayLength(); | |
427 }, | |
428 | |
429 /** | |
430 * @override | |
431 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!We
bInspector.RemoteObjectProperty>)} callback | |
432 */ | |
433 getOwnProperties: function(callback) | |
434 { | |
435 this._object.getOwnProperties(callback); | |
436 }, | |
437 | |
438 /** | |
439 * @override | |
440 * @param {boolean} accessorPropertiesOnly | |
441 * @param {function(?Array<!WebInspector.RemoteObjectProperty>, ?Array<!WebI
nspector.RemoteObjectProperty>)} callback | |
442 */ | |
443 getAllProperties: function(accessorPropertiesOnly, callback) | |
444 { | |
445 /** | |
446 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties | |
447 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperti
es | |
448 * @this {WebInspector.SourceMapNamesResolver.RemoteObject} | |
449 */ | |
450 function wrappedCallback(properties, internalProperties) | |
451 { | |
452 WebInspector.SourceMapNamesResolver._resolveScope(this._scope).then(
resolveNames.bind(null, properties, internalProperties)); | |
453 } | |
454 | |
455 /** | |
456 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties | |
457 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperti
es | |
458 * @param {!Map<string, string>} namesMapping | |
459 */ | |
460 function resolveNames(properties, internalProperties, namesMapping) | |
461 { | |
462 var newProperties = []; | |
463 if (properties) { | |
464 for (var i = 0; i < properties.length; ++i) { | |
465 var property = properties[i]; | |
466 var name = namesMapping.get(property.name) || properties[i].
name; | |
467 newProperties.push(new WebInspector.RemoteObjectProperty(nam
e, property.value, property.enumerable, property.writable, property.isOwn, prope
rty.wasThrown, property.symbol, property.synthetic)); | |
468 } | |
469 } | |
470 | |
471 callback(newProperties, internalProperties); | |
472 } | |
473 | |
474 this._object.getAllProperties(accessorPropertiesOnly, wrappedCallback.bi
nd(this)); | |
475 }, | |
476 | |
477 /** | |
478 * @override | |
479 * @param {string|!RuntimeAgent.CallArgument} argumentName | |
480 * @param {string} value | |
481 * @param {function(string=)} callback | |
482 */ | |
483 setPropertyValue: function(argumentName, value, callback) | |
484 { | |
485 WebInspector.SourceMapNamesResolver._resolveScope(this._scope).then(reso
lveName.bind(this)); | |
486 | |
487 /** | |
488 * @param {!Map<string, string>} namesMapping | |
489 * @this {WebInspector.SourceMapNamesResolver.RemoteObject} | |
490 */ | |
491 function resolveName(namesMapping) | |
492 { | |
493 var name; | |
494 if (typeof argumentName === "string") | |
495 name = argumentName; | |
496 else | |
497 name = /** @type {string} */ (argumentName.value); | |
498 | |
499 var actualName = name; | |
500 for (var compiledName of namesMapping.keys()) { | |
501 if (namesMapping.get(compiledName) === name) { | |
502 actualName = compiledName; | |
503 break; | |
504 } | |
505 } | |
506 this._object.setPropertyValue(actualName, value, callback); | |
507 } | |
508 }, | |
509 | |
510 /** | |
511 * @override | |
512 * @return {!Promise<?Array<!WebInspector.EventListener>>} | |
513 */ | |
514 eventListeners: function() | |
515 { | |
516 return this._object.eventListeners(); | |
517 }, | |
518 | |
519 /** | |
520 * @override | |
521 * @param {!RuntimeAgent.CallArgument} name | |
522 * @param {function(string=)} callback | |
523 */ | |
524 deleteProperty: function(name, callback) | |
525 { | |
526 this._object.deleteProperty(name, callback); | |
527 }, | |
528 | |
529 /** | |
530 * @override | |
531 * @param {function(this:Object, ...)} functionDeclaration | |
532 * @param {!Array<!RuntimeAgent.CallArgument>=} args | |
533 * @param {function(?WebInspector.RemoteObject, boolean=)=} callback | |
534 */ | |
535 callFunction: function(functionDeclaration, args, callback) | |
536 { | |
537 this._object.callFunction(functionDeclaration, args, callback); | |
538 }, | |
539 | |
540 /** | |
541 * @override | |
542 * @param {function(this:Object, ...)} functionDeclaration | |
543 * @param {!Array<!RuntimeAgent.CallArgument>|undefined} args | |
544 * @param {function(*)} callback | |
545 */ | |
546 callFunctionJSON: function(functionDeclaration, args, callback) | |
547 { | |
548 this._object.callFunctionJSON(functionDeclaration, args, callback); | |
549 }, | |
550 | |
551 /** | |
552 * @override | |
553 * @return {!WebInspector.Target} | |
554 */ | |
555 target: function() | |
556 { | |
557 return this._object.target(); | |
558 }, | |
559 | |
560 /** | |
561 * @override | |
562 * @return {?WebInspector.DebuggerModel} | |
563 */ | |
564 debuggerModel: function() | |
565 { | |
566 return this._object.debuggerModel(); | |
567 }, | |
568 | |
569 /** | |
570 * @override | |
571 * @return {boolean} | |
572 */ | |
573 isNode: function() | |
574 { | |
575 return this._object.isNode(); | |
576 }, | |
577 | |
578 __proto__: WebInspector.RemoteObject.prototype | |
579 }; | |
580 | |
OLD | NEW |