summaryrefslogtreecommitdiff
path: root/chromium/v8/tools/SourceMap.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/tools/SourceMap.js')
-rw-r--r--chromium/v8/tools/SourceMap.js371
1 files changed, 371 insertions, 0 deletions
diff --git a/chromium/v8/tools/SourceMap.js b/chromium/v8/tools/SourceMap.js
new file mode 100644
index 00000000000..9cbd37a7355
--- /dev/null
+++ b/chromium/v8/tools/SourceMap.js
@@ -0,0 +1,371 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This is a copy from blink dev tools, see:
+// http://src.chromium.org/viewvc/blink/trunk/Source/devtools/front_end/SourceMap.js
+// revision: 153407
+
+// Added to make the file work without dev tools
+WebInspector = {};
+WebInspector.ParsedURL = {};
+WebInspector.ParsedURL.completeURL = function(){};
+// start of original file content
+
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Implements Source Map V3 model. See http://code.google.com/p/closure-compiler/wiki/SourceMaps
+ * for format description.
+ * @constructor
+ * @param {string} sourceMappingURL
+ * @param {SourceMapV3} payload
+ */
+WebInspector.SourceMap = function(sourceMappingURL, payload)
+{
+ if (!WebInspector.SourceMap.prototype._base64Map) {
+ const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ WebInspector.SourceMap.prototype._base64Map = {};
+ for (var i = 0; i < base64Digits.length; ++i)
+ WebInspector.SourceMap.prototype._base64Map[base64Digits.charAt(i)] = i;
+ }
+
+ this._sourceMappingURL = sourceMappingURL;
+ this._reverseMappingsBySourceURL = {};
+ this._mappings = [];
+ this._sources = {};
+ this._sourceContentByURL = {};
+ this._parseMappingPayload(payload);
+}
+
+/**
+ * @param {string} sourceMapURL
+ * @param {string} compiledURL
+ * @param {function(WebInspector.SourceMap)} callback
+ */
+WebInspector.SourceMap.load = function(sourceMapURL, compiledURL, callback)
+{
+ NetworkAgent.loadResourceForFrontend(WebInspector.resourceTreeModel.mainFrame.id, sourceMapURL, undefined, contentLoaded.bind(this));
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {number} statusCode
+ * @param {NetworkAgent.Headers} headers
+ * @param {string} content
+ */
+ function contentLoaded(error, statusCode, headers, content)
+ {
+ if (error || !content || statusCode >= 400) {
+ console.error("Could not load content for " + sourceMapURL + " : " + (error || ("HTTP status code: " + statusCode)));
+ callback(null);
+ return;
+ }
+
+ if (content.slice(0, 3) === ")]}")
+ content = content.substring(content.indexOf('\n'));
+ try {
+ var payload = /** @type {SourceMapV3} */ (JSON.parse(content));
+ var baseURL = sourceMapURL.startsWith("data:") ? compiledURL : sourceMapURL;
+ callback(new WebInspector.SourceMap(baseURL, payload));
+ } catch(e) {
+ console.error(e.message);
+ callback(null);
+ }
+ }
+}
+
+WebInspector.SourceMap.prototype = {
+ /**
+ * @return {Array.<string>}
+ */
+ sources: function()
+ {
+ return Object.keys(this._sources);
+ },
+
+ /**
+ * @param {string} sourceURL
+ * @return {string|undefined}
+ */
+ sourceContent: function(sourceURL)
+ {
+ return this._sourceContentByURL[sourceURL];
+ },
+
+ /**
+ * @param {string} sourceURL
+ * @param {WebInspector.ResourceType} contentType
+ * @return {WebInspector.ContentProvider}
+ */
+ sourceContentProvider: function(sourceURL, contentType)
+ {
+ var lastIndexOfDot = sourceURL.lastIndexOf(".");
+ var extension = lastIndexOfDot !== -1 ? sourceURL.substr(lastIndexOfDot + 1) : "";
+ var mimeType = WebInspector.ResourceType.mimeTypesForExtensions[extension.toLowerCase()];
+ var sourceContent = this.sourceContent(sourceURL);
+ if (sourceContent)
+ return new WebInspector.StaticContentProvider(contentType, sourceContent, mimeType);
+ return new WebInspector.CompilerSourceMappingContentProvider(sourceURL, contentType, mimeType);
+ },
+
+ /**
+ * @param {SourceMapV3} mappingPayload
+ */
+ _parseMappingPayload: function(mappingPayload)
+ {
+ if (mappingPayload.sections)
+ this._parseSections(mappingPayload.sections);
+ else
+ this._parseMap(mappingPayload, 0, 0);
+ },
+
+ /**
+ * @param {Array.<SourceMapV3.Section>} sections
+ */
+ _parseSections: function(sections)
+ {
+ for (var i = 0; i < sections.length; ++i) {
+ var section = sections[i];
+ this._parseMap(section.map, section.offset.line, section.offset.column);
+ }
+ },
+
+ /**
+ * @param {number} lineNumber in compiled resource
+ * @param {number} columnNumber in compiled resource
+ * @return {?Array}
+ */
+ findEntry: function(lineNumber, columnNumber)
+ {
+ var first = 0;
+ var count = this._mappings.length;
+ while (count > 1) {
+ var step = count >> 1;
+ var middle = first + step;
+ var mapping = this._mappings[middle];
+ if (lineNumber < mapping[0] || (lineNumber === mapping[0] && columnNumber < mapping[1]))
+ count = step;
+ else {
+ first = middle;
+ count -= step;
+ }
+ }
+ var entry = this._mappings[first];
+ if (!first && entry && (lineNumber < entry[0] || (lineNumber === entry[0] && columnNumber < entry[1])))
+ return null;
+ return entry;
+ },
+
+ /**
+ * @param {string} sourceURL of the originating resource
+ * @param {number} lineNumber in the originating resource
+ * @return {Array}
+ */
+ findEntryReversed: function(sourceURL, lineNumber)
+ {
+ var mappings = this._reverseMappingsBySourceURL[sourceURL];
+ for ( ; lineNumber < mappings.length; ++lineNumber) {
+ var mapping = mappings[lineNumber];
+ if (mapping)
+ return mapping;
+ }
+ return this._mappings[0];
+ },
+
+ /**
+ * @override
+ */
+ _parseMap: function(map, lineNumber, columnNumber)
+ {
+ var sourceIndex = 0;
+ var sourceLineNumber = 0;
+ var sourceColumnNumber = 0;
+ var nameIndex = 0;
+
+ var sources = [];
+ var originalToCanonicalURLMap = {};
+ for (var i = 0; i < map.sources.length; ++i) {
+ var originalSourceURL = map.sources[i];
+ var sourceRoot = map.sourceRoot || "";
+ if (sourceRoot && !sourceRoot.endsWith("/"))
+ sourceRoot += "/";
+ var href = sourceRoot + originalSourceURL;
+ var url = WebInspector.ParsedURL.completeURL(this._sourceMappingURL, href) || href;
+ originalToCanonicalURLMap[originalSourceURL] = url;
+ sources.push(url);
+ this._sources[url] = true;
+
+ if (map.sourcesContent && map.sourcesContent[i])
+ this._sourceContentByURL[url] = map.sourcesContent[i];
+ }
+
+ var stringCharIterator = new WebInspector.SourceMap.StringCharIterator(map.mappings);
+ var sourceURL = sources[sourceIndex];
+
+ while (true) {
+ if (stringCharIterator.peek() === ",")
+ stringCharIterator.next();
+ else {
+ while (stringCharIterator.peek() === ";") {
+ lineNumber += 1;
+ columnNumber = 0;
+ stringCharIterator.next();
+ }
+ if (!stringCharIterator.hasNext())
+ break;
+ }
+
+ columnNumber += this._decodeVLQ(stringCharIterator);
+ if (this._isSeparator(stringCharIterator.peek())) {
+ this._mappings.push([lineNumber, columnNumber]);
+ continue;
+ }
+
+ var sourceIndexDelta = this._decodeVLQ(stringCharIterator);
+ if (sourceIndexDelta) {
+ sourceIndex += sourceIndexDelta;
+ sourceURL = sources[sourceIndex];
+ }
+ sourceLineNumber += this._decodeVLQ(stringCharIterator);
+ sourceColumnNumber += this._decodeVLQ(stringCharIterator);
+ if (!this._isSeparator(stringCharIterator.peek()))
+ nameIndex += this._decodeVLQ(stringCharIterator);
+
+ this._mappings.push([lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber]);
+ }
+
+ for (var i = 0; i < this._mappings.length; ++i) {
+ var mapping = this._mappings[i];
+ var url = mapping[2];
+ if (!url)
+ continue;
+ if (!this._reverseMappingsBySourceURL[url])
+ this._reverseMappingsBySourceURL[url] = [];
+ var reverseMappings = this._reverseMappingsBySourceURL[url];
+ var sourceLine = mapping[3];
+ if (!reverseMappings[sourceLine])
+ reverseMappings[sourceLine] = [mapping[0], mapping[1]];
+ }
+ },
+
+ /**
+ * @param {string} char
+ * @return {boolean}
+ */
+ _isSeparator: function(char)
+ {
+ return char === "," || char === ";";
+ },
+
+ /**
+ * @param {WebInspector.SourceMap.StringCharIterator} stringCharIterator
+ * @return {number}
+ */
+ _decodeVLQ: function(stringCharIterator)
+ {
+ // Read unsigned value.
+ var result = 0;
+ var shift = 0;
+ do {
+ var digit = this._base64Map[stringCharIterator.next()];
+ result += (digit & this._VLQ_BASE_MASK) << shift;
+ shift += this._VLQ_BASE_SHIFT;
+ } while (digit & this._VLQ_CONTINUATION_MASK);
+
+ // Fix the sign.
+ var negative = result & 1;
+ result >>= 1;
+ return negative ? -result : result;
+ },
+
+ _VLQ_BASE_SHIFT: 5,
+ _VLQ_BASE_MASK: (1 << 5) - 1,
+ _VLQ_CONTINUATION_MASK: 1 << 5
+}
+
+/**
+ * @constructor
+ * @param {string} string
+ */
+WebInspector.SourceMap.StringCharIterator = function(string)
+{
+ this._string = string;
+ this._position = 0;
+}
+
+WebInspector.SourceMap.StringCharIterator.prototype = {
+ /**
+ * @return {string}
+ */
+ next: function()
+ {
+ return this._string.charAt(this._position++);
+ },
+
+ /**
+ * @return {string}
+ */
+ peek: function()
+ {
+ return this._string.charAt(this._position);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ hasNext: function()
+ {
+ return this._position < this._string.length;
+ }
+}