OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 WebInspector.SourceMap = function(sourceMappingURL, payload) | 69 WebInspector.SourceMap = function(sourceMappingURL, payload) |
70 { | 70 { |
71 if (!WebInspector.SourceMap.prototype._base64Map) { | 71 if (!WebInspector.SourceMap.prototype._base64Map) { |
72 const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx
yz0123456789+/"; | 72 const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx
yz0123456789+/"; |
73 WebInspector.SourceMap.prototype._base64Map = {}; | 73 WebInspector.SourceMap.prototype._base64Map = {}; |
74 for (var i = 0; i < base64Digits.length; ++i) | 74 for (var i = 0; i < base64Digits.length; ++i) |
75 WebInspector.SourceMap.prototype._base64Map[base64Digits.charAt(i)]
= i; | 75 WebInspector.SourceMap.prototype._base64Map[base64Digits.charAt(i)]
= i; |
76 } | 76 } |
77 | 77 |
78 this._sourceMappingURL = sourceMappingURL; | 78 this._sourceMappingURL = sourceMappingURL; |
79 this._reverseMappingsBySourceURL = {}; | 79 this._reverseMappingsBySourceURL = new Map(); |
80 this._mappings = []; | 80 this._mappings = []; |
81 this._sources = {}; | 81 this._sources = {}; |
82 this._sourceContentByURL = {}; | 82 this._sourceContentByURL = {}; |
83 this._parseMappingPayload(payload); | 83 this._parseMappingPayload(payload); |
84 } | 84 } |
85 | 85 |
86 /** | 86 /** |
87 * @param {string} sourceMapURL | 87 * @param {string} sourceMapURL |
88 * @param {string} compiledURL | 88 * @param {string} compiledURL |
89 * @param {function(?WebInspector.SourceMap)} callback | 89 * @param {function(?WebInspector.SourceMap)} callback |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 { | 184 { |
185 for (var i = 0; i < sections.length; ++i) { | 185 for (var i = 0; i < sections.length; ++i) { |
186 var section = sections[i]; | 186 var section = sections[i]; |
187 this._parseMap(section.map, section.offset.line, section.offset.colu
mn); | 187 this._parseMap(section.map, section.offset.line, section.offset.colu
mn); |
188 } | 188 } |
189 }, | 189 }, |
190 | 190 |
191 /** | 191 /** |
192 * @param {number} lineNumber in compiled resource | 192 * @param {number} lineNumber in compiled resource |
193 * @param {number} columnNumber in compiled resource | 193 * @param {number} columnNumber in compiled resource |
194 * @return {?Array.<number|string>} | 194 * @return {?WebInspector.SourceMap.Entry} |
195 */ | 195 */ |
196 findEntry: function(lineNumber, columnNumber) | 196 findEntry: function(lineNumber, columnNumber) |
197 { | 197 { |
198 var first = 0; | 198 var first = 0; |
199 var count = this._mappings.length; | 199 var count = this._mappings.length; |
200 while (count > 1) { | 200 while (count > 1) { |
201 var step = count >> 1; | 201 var step = count >> 1; |
202 var middle = first + step; | 202 var middle = first + step; |
203 var mapping = this._mappings[middle]; | 203 var mapping = this._mappings[middle]; |
204 if (lineNumber < mapping[0] || (lineNumber === mapping[0] && columnNum
ber < mapping[1])) | 204 if (lineNumber < mapping.lineNumber || (lineNumber === mapping.lineNum
ber && columnNumber < mapping.columnNumber)) |
205 count = step; | 205 count = step; |
206 else { | 206 else { |
207 first = middle; | 207 first = middle; |
208 count -= step; | 208 count -= step; |
209 } | 209 } |
210 } | 210 } |
211 var entry = this._mappings[first]; | 211 var entry = this._mappings[first]; |
212 if (!first && entry && (lineNumber < entry[0] || (lineNumber === entry[0
] && columnNumber < entry[1]))) | 212 if (!first && entry && (lineNumber < entry.lineNumber || (lineNumber ===
entry.lineNumber && columnNumber < entry.columnNumber))) |
213 return null; | 213 return null; |
214 return entry; | 214 return entry; |
215 }, | 215 }, |
216 | 216 |
217 /** | 217 /** |
218 * @param {string} sourceURL of the originating resource | 218 * @param {string} sourceURL |
219 * @param {number} lineNumber in the originating resource | 219 * @param {number} lineNumber |
220 * @param {number=} span | 220 * @return {?WebInspector.SourceMap.Entry} |
221 * @return {?Array.<*>} | |
222 */ | 221 */ |
223 findEntryReversed: function(sourceURL, lineNumber, span) | 222 firstSourceLineMapping: function(sourceURL, lineNumber) |
224 { | 223 { |
225 var mappings = this._reverseMappingsBySourceURL[sourceURL]; | 224 var mappings = this._reversedMappings(sourceURL); |
226 if (!mappings) | 225 var index = mappings.lowerBound(lineNumber, lineComparator); |
| 226 if (index >= mappings.length || mappings[index].sourceLineNumber !== lin
eNumber) |
227 return null; | 227 return null; |
228 var maxLineNumber = typeof span === "number" ? Math.min(lineNumber + spa
n + 1, mappings.length) : mappings.length; | 228 var minColumn = mappings[index]; |
229 for ( ; lineNumber < maxLineNumber; ++lineNumber) { | 229 for (var i = index + 1; i < mappings.length && mappings[i].sourceLineNum
ber === lineNumber; ++i) { |
230 var mapping = mappings[lineNumber]; | 230 if (minColumn.sourceColumnNumber > mappings[i].sourceColumnNumber) |
231 if (mapping) | 231 minColumn = mappings[i]; |
232 return mapping; | |
233 } | 232 } |
234 return null; | 233 return minColumn; |
| 234 |
| 235 /** |
| 236 * @param {number} lineNumber |
| 237 * @param {!WebInspector.SourceMap.Entry} mapping |
| 238 * @return {number} |
| 239 */ |
| 240 function lineComparator(lineNumber, mapping) |
| 241 { |
| 242 return lineNumber - mapping.sourceLineNumber; |
| 243 } |
235 }, | 244 }, |
236 | 245 |
237 /** | 246 /** |
| 247 * @param {string} sourceURL |
| 248 * @return {!Array.<!WebInspector.SourceMap.Entry>} |
| 249 */ |
| 250 _reversedMappings: function(sourceURL) |
| 251 { |
| 252 var mappings = this._reverseMappingsBySourceURL.get(sourceURL); |
| 253 if (!mappings) |
| 254 return []; |
| 255 if (!mappings._sorted) { |
| 256 mappings.sort(sourceMappingComparator); |
| 257 mappings._sorted = true; |
| 258 } |
| 259 return mappings; |
| 260 |
| 261 /** |
| 262 * @param {!WebInspector.SourceMap.Entry} a |
| 263 * @param {!WebInspector.SourceMap.Entry} b |
| 264 * @return {number} |
| 265 */ |
| 266 function sourceMappingComparator(a, b) |
| 267 { |
| 268 if (a.sourceLineNumber !== b.sourceLineNumber) |
| 269 return a.sourceLineNumber - b.sourceLineNumber; |
| 270 return a.sourceColumnNumber - b.sourceColumnNumber; |
| 271 } |
| 272 }, |
| 273 |
| 274 /** |
238 * @param {!SourceMapV3} map | 275 * @param {!SourceMapV3} map |
239 * @param {number} lineNumber | 276 * @param {number} lineNumber |
240 * @param {number} columnNumber | 277 * @param {number} columnNumber |
241 */ | 278 */ |
242 _parseMap: function(map, lineNumber, columnNumber) | 279 _parseMap: function(map, lineNumber, columnNumber) |
243 { | 280 { |
244 var sourceIndex = 0; | 281 var sourceIndex = 0; |
245 var sourceLineNumber = 0; | 282 var sourceLineNumber = 0; |
246 var sourceColumnNumber = 0; | 283 var sourceColumnNumber = 0; |
247 var nameIndex = 0; | 284 var nameIndex = 0; |
(...skipping 26 matching lines...) Expand all Loading... |
274 lineNumber += 1; | 311 lineNumber += 1; |
275 columnNumber = 0; | 312 columnNumber = 0; |
276 stringCharIterator.next(); | 313 stringCharIterator.next(); |
277 } | 314 } |
278 if (!stringCharIterator.hasNext()) | 315 if (!stringCharIterator.hasNext()) |
279 break; | 316 break; |
280 } | 317 } |
281 | 318 |
282 columnNumber += this._decodeVLQ(stringCharIterator); | 319 columnNumber += this._decodeVLQ(stringCharIterator); |
283 if (!stringCharIterator.hasNext() || this._isSeparator(stringCharIte
rator.peek())) { | 320 if (!stringCharIterator.hasNext() || this._isSeparator(stringCharIte
rator.peek())) { |
284 this._mappings.push([lineNumber, columnNumber]); | 321 this._mappings.push(new WebInspector.SourceMap.Entry(lineNumber,
columnNumber)); |
285 continue; | 322 continue; |
286 } | 323 } |
287 | 324 |
288 var sourceIndexDelta = this._decodeVLQ(stringCharIterator); | 325 var sourceIndexDelta = this._decodeVLQ(stringCharIterator); |
289 if (sourceIndexDelta) { | 326 if (sourceIndexDelta) { |
290 sourceIndex += sourceIndexDelta; | 327 sourceIndex += sourceIndexDelta; |
291 sourceURL = sources[sourceIndex]; | 328 sourceURL = sources[sourceIndex]; |
292 } | 329 } |
293 sourceLineNumber += this._decodeVLQ(stringCharIterator); | 330 sourceLineNumber += this._decodeVLQ(stringCharIterator); |
294 sourceColumnNumber += this._decodeVLQ(stringCharIterator); | 331 sourceColumnNumber += this._decodeVLQ(stringCharIterator); |
295 if (!this._isSeparator(stringCharIterator.peek())) | 332 if (!this._isSeparator(stringCharIterator.peek())) |
296 nameIndex += this._decodeVLQ(stringCharIterator); | 333 nameIndex += this._decodeVLQ(stringCharIterator); |
297 | 334 |
298 this._mappings.push([lineNumber, columnNumber, sourceURL, sourceLine
Number, sourceColumnNumber]); | 335 this._mappings.push(new WebInspector.SourceMap.Entry(lineNumber, col
umnNumber, sourceURL, sourceLineNumber, sourceColumnNumber)); |
299 } | 336 } |
300 | 337 |
301 for (var i = 0; i < this._mappings.length; ++i) { | 338 for (var i = 0; i < this._mappings.length; ++i) { |
302 var mapping = this._mappings[i]; | 339 var mapping = this._mappings[i]; |
303 var url = mapping[2]; | 340 var url = mapping.sourceURL; |
304 if (!url) | 341 if (!url) |
305 continue; | 342 continue; |
306 if (!this._reverseMappingsBySourceURL[url]) | 343 if (!this._reverseMappingsBySourceURL.has(url)) |
307 this._reverseMappingsBySourceURL[url] = []; | 344 this._reverseMappingsBySourceURL.set(url, []); |
308 var reverseMappings = this._reverseMappingsBySourceURL[url]; | 345 var reverseMappings = this._reverseMappingsBySourceURL.get(url); |
309 var sourceLine = mapping[3]; | 346 reverseMappings.push(mapping); |
310 if (!reverseMappings[sourceLine]) | |
311 reverseMappings[sourceLine] = [mapping[0], mapping[1]]; | |
312 } | 347 } |
313 }, | 348 }, |
314 | 349 |
315 /** | 350 /** |
316 * @param {string} char | 351 * @param {string} char |
317 * @return {boolean} | 352 * @return {boolean} |
318 */ | 353 */ |
319 _isSeparator: function(char) | 354 _isSeparator: function(char) |
320 { | 355 { |
321 return char === "," || char === ";"; | 356 return char === "," || char === ";"; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 }, | 410 }, |
376 | 411 |
377 /** | 412 /** |
378 * @return {boolean} | 413 * @return {boolean} |
379 */ | 414 */ |
380 hasNext: function() | 415 hasNext: function() |
381 { | 416 { |
382 return this._position < this._string.length; | 417 return this._position < this._string.length; |
383 } | 418 } |
384 } | 419 } |
| 420 |
| 421 /** |
| 422 * @constructor |
| 423 * @param {number} lineNumber |
| 424 * @param {number} columnNumber |
| 425 * @param {string=} sourceURL |
| 426 * @param {number=} sourceLineNumber |
| 427 * @param {number=} sourceColumnNumber |
| 428 */ |
| 429 WebInspector.SourceMap.Entry = function(lineNumber, columnNumber, sourceURL, sou
rceLineNumber, sourceColumnNumber) |
| 430 { |
| 431 this.lineNumber = lineNumber; |
| 432 this.columnNumber = columnNumber; |
| 433 this.sourceURL = sourceURL; |
| 434 this.sourceLineNumber = sourceLineNumber; |
| 435 this.sourceColumnNumber = sourceColumnNumber; |
| 436 } |
OLD | NEW |