Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / escodegen / node_modules / source-map / lib / source-map / indexed-source-map-consumer.js
1 /* -*- Mode: js; js-indent-level: 2; -*- */
2 /*
3  * Copyright 2011 Mozilla Foundation and contributors
4  * Licensed under the New BSD license. See LICENSE or:
5  * http://opensource.org/licenses/BSD-3-Clause
6  */
7 if (typeof define !== 'function') {
8     var define = require('amdefine')(module, require);
9 }
10 define(function (require, exports, module) {
11
12   var util = require('./util');
13   var binarySearch = require('./binary-search');
14   var SourceMapConsumer = require('./source-map-consumer').SourceMapConsumer;
15   var BasicSourceMapConsumer = require('./basic-source-map-consumer').BasicSourceMapConsumer;
16
17   /**
18    * An IndexedSourceMapConsumer instance represents a parsed source map which
19    * we can query for information. It differs from BasicSourceMapConsumer in
20    * that it takes "indexed" source maps (i.e. ones with a "sections" field) as
21    * input.
22    *
23    * The only parameter is a raw source map (either as a JSON string, or already
24    * parsed to an object). According to the spec for indexed source maps, they
25    * have the following attributes:
26    *
27    *   - version: Which version of the source map spec this map is following.
28    *   - file: Optional. The generated file this source map is associated with.
29    *   - sections: A list of section definitions.
30    *
31    * Each value under the "sections" field has two fields:
32    *   - offset: The offset into the original specified at which this section
33    *       begins to apply, defined as an object with a "line" and "column"
34    *       field.
35    *   - map: A source map definition. This source map could also be indexed,
36    *       but doesn't have to be.
37    *
38    * Instead of the "map" field, it's also possible to have a "url" field
39    * specifying a URL to retrieve a source map from, but that's currently
40    * unsupported.
41    *
42    * Here's an example source map, taken from the source map spec[0], but
43    * modified to omit a section which uses the "url" field.
44    *
45    *  {
46    *    version : 3,
47    *    file: "app.js",
48    *    sections: [{
49    *      offset: {line:100, column:10},
50    *      map: {
51    *        version : 3,
52    *        file: "section.js",
53    *        sources: ["foo.js", "bar.js"],
54    *        names: ["src", "maps", "are", "fun"],
55    *        mappings: "AAAA,E;;ABCDE;"
56    *      }
57    *    }],
58    *  }
59    *
60    * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
61    */
62   function IndexedSourceMapConsumer(aSourceMap) {
63     var sourceMap = aSourceMap;
64     if (typeof aSourceMap === 'string') {
65       sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
66     }
67
68     var version = util.getArg(sourceMap, 'version');
69     var sections = util.getArg(sourceMap, 'sections');
70
71     if (version != this._version) {
72       throw new Error('Unsupported version: ' + version);
73     }
74
75     var lastOffset = {
76       line: -1,
77       column: 0
78     };
79     this._sections = sections.map(function (s) {
80       if (s.url) {
81         // The url field will require support for asynchronicity.
82         // See https://github.com/mozilla/source-map/issues/16
83         throw new Error('Support for url field in sections not implemented.');
84       }
85       var offset = util.getArg(s, 'offset');
86       var offsetLine = util.getArg(offset, 'line');
87       var offsetColumn = util.getArg(offset, 'column');
88
89       if (offsetLine < lastOffset.line ||
90           (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
91         throw new Error('Section offsets must be ordered and non-overlapping.');
92       }
93       lastOffset = offset;
94
95       return {
96         generatedOffset: {
97           // The offset fields are 0-based, but we use 1-based indices when
98           // encoding/decoding from VLQ.
99           generatedLine: offsetLine + 1,
100           generatedColumn: offsetColumn + 1
101         },
102         consumer: new SourceMapConsumer(util.getArg(s, 'map'))
103       }
104     });
105   }
106
107   IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
108   IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;
109
110   /**
111    * The version of the source mapping spec that we are consuming.
112    */
113   IndexedSourceMapConsumer.prototype._version = 3;
114
115   /**
116    * The list of original sources.
117    */
118   Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
119     get: function () {
120       var sources = [];
121       for (var i = 0; i < this._sections.length; i++) {
122         for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
123           sources.push(this._sections[i].consumer.sources[j]);
124         }
125       };
126       return sources;
127     }
128   });
129
130   /**
131    * Returns the original source, line, and column information for the generated
132    * source's line and column positions provided. The only argument is an object
133    * with the following properties:
134    *
135    *   - line: The line number in the generated source.
136    *   - column: The column number in the generated source.
137    *
138    * and an object is returned with the following properties:
139    *
140    *   - source: The original source file, or null.
141    *   - line: The line number in the original source, or null.
142    *   - column: The column number in the original source, or null.
143    *   - name: The original identifier, or null.
144    */
145   IndexedSourceMapConsumer.prototype.originalPositionFor =
146     function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
147       var needle = {
148         generatedLine: util.getArg(aArgs, 'line'),
149         generatedColumn: util.getArg(aArgs, 'column')
150       };
151
152       // Find the section containing the generated position we're trying to map
153       // to an original position.
154       var sectionIndex = binarySearch.search(needle, this._sections,
155         function(needle, section) {
156           var cmp = needle.generatedLine - section.generatedOffset.generatedLine;
157           if (cmp) {
158             return cmp;
159           }
160
161           return (needle.generatedColumn -
162                   section.generatedOffset.generatedColumn);
163         });
164       var section = this._sections[sectionIndex];
165
166       if (!section) {
167         return {
168           source: null,
169           line: null,
170           column: null,
171           name: null
172         };
173       }
174
175       return section.consumer.originalPositionFor({
176         line: needle.generatedLine -
177           (section.generatedOffset.generatedLine - 1),
178         column: needle.generatedColumn -
179           (section.generatedOffset.generatedLine === needle.generatedLine
180            ? section.generatedOffset.generatedColumn - 1
181            : 0)
182       });
183     };
184
185   /**
186    * Returns the original source content. The only argument is the url of the
187    * original source file. Returns null if no original source content is
188    * available.
189    */
190   IndexedSourceMapConsumer.prototype.sourceContentFor =
191     function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
192       for (var i = 0; i < this._sections.length; i++) {
193         var section = this._sections[i];
194
195         var content = section.consumer.sourceContentFor(aSource, true);
196         if (content) {
197           return content;
198         }
199       }
200       if (nullOnMissing) {
201         return null;
202       }
203       else {
204         throw new Error('"' + aSource + '" is not in the SourceMap.');
205       }
206     };
207
208   /**
209    * Returns the generated line and column information for the original source,
210    * line, and column positions provided. The only argument is an object with
211    * the following properties:
212    *
213    *   - source: The filename of the original source.
214    *   - line: The line number in the original source.
215    *   - column: The column number in the original source.
216    *
217    * and an object is returned with the following properties:
218    *
219    *   - line: The line number in the generated source, or null.
220    *   - column: The column number in the generated source, or null.
221    */
222   IndexedSourceMapConsumer.prototype.generatedPositionFor =
223     function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
224       for (var i = 0; i < this._sections.length; i++) {
225         var section = this._sections[i];
226
227         // Only consider this section if the requested source is in the list of
228         // sources of the consumer.
229         if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) {
230           continue;
231         }
232         var generatedPosition = section.consumer.generatedPositionFor(aArgs);
233         if (generatedPosition) {
234           var ret = {
235             line: generatedPosition.line +
236               (section.generatedOffset.generatedLine - 1),
237             column: generatedPosition.column +
238               (section.generatedOffset.generatedLine === generatedPosition.line
239                ? section.generatedOffset.generatedColumn - 1
240                : 0)
241           };
242           return ret;
243         }
244       }
245
246       return {
247         line: null,
248         column: null
249       };
250     };
251
252   /**
253    * Parse the mappings in a string in to a data structure which we can easily
254    * query (the ordered arrays in the `this.__generatedMappings` and
255    * `this.__originalMappings` properties).
256    */
257   IndexedSourceMapConsumer.prototype._parseMappings =
258     function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {
259       this.__generatedMappings = [];
260       this.__originalMappings = [];
261       for (var i = 0; i < this._sections.length; i++) {
262         var section = this._sections[i];
263         var sectionMappings = section.consumer._generatedMappings;
264         for (var j = 0; j < sectionMappings.length; j++) {
265           var mapping = sectionMappings[i];
266
267           var source = mapping.source;
268           var sourceRoot = section.consumer.sourceRoot;
269
270           if (source != null && sourceRoot != null) {
271             source = util.join(sourceRoot, source);
272           }
273
274           // The mappings coming from the consumer for the section have
275           // generated positions relative to the start of the section, so we
276           // need to offset them to be relative to the start of the concatenated
277           // generated file.
278           var adjustedMapping = {
279             source: source,
280             generatedLine: mapping.generatedLine +
281               (section.generatedOffset.generatedLine - 1),
282             generatedColumn: mapping.column +
283               (section.generatedOffset.generatedLine === mapping.generatedLine)
284               ? section.generatedOffset.generatedColumn - 1
285               : 0,
286             originalLine: mapping.originalLine,
287             originalColumn: mapping.originalColumn,
288             name: mapping.name
289           };
290
291           this.__generatedMappings.push(adjustedMapping);
292           if (typeof adjustedMapping.originalLine === 'number') {
293             this.__originalMappings.push(adjustedMapping);
294           }
295         };
296       };
297
298     this.__generatedMappings.sort(util.compareByGeneratedPositions);
299     this.__originalMappings.sort(util.compareByOriginalPositions);
300   };
301
302   exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
303 });