Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / source-map / lib / source-map / source-map-generator.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 base64VLQ = require('./base64-vlq');
13   var util = require('./util');
14   var ArraySet = require('./array-set').ArraySet;
15   var MappingList = require('./mapping-list').MappingList;
16
17   /**
18    * An instance of the SourceMapGenerator represents a source map which is
19    * being built incrementally. You may pass an object with the following
20    * properties:
21    *
22    *   - file: The filename of the generated source.
23    *   - sourceRoot: A root for all relative URLs in this source map.
24    */
25   function SourceMapGenerator(aArgs) {
26     if (!aArgs) {
27       aArgs = {};
28     }
29     this._file = util.getArg(aArgs, 'file', null);
30     this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
31     this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
32     this._sources = new ArraySet();
33     this._names = new ArraySet();
34     this._mappings = new MappingList();
35     this._sourcesContents = null;
36   }
37
38   SourceMapGenerator.prototype._version = 3;
39
40   /**
41    * Creates a new SourceMapGenerator based on a SourceMapConsumer
42    *
43    * @param aSourceMapConsumer The SourceMap.
44    */
45   SourceMapGenerator.fromSourceMap =
46     function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
47       var sourceRoot = aSourceMapConsumer.sourceRoot;
48       var generator = new SourceMapGenerator({
49         file: aSourceMapConsumer.file,
50         sourceRoot: sourceRoot
51       });
52       aSourceMapConsumer.eachMapping(function (mapping) {
53         var newMapping = {
54           generated: {
55             line: mapping.generatedLine,
56             column: mapping.generatedColumn
57           }
58         };
59
60         if (mapping.source != null) {
61           newMapping.source = mapping.source;
62           if (sourceRoot != null) {
63             newMapping.source = util.relative(sourceRoot, newMapping.source);
64           }
65
66           newMapping.original = {
67             line: mapping.originalLine,
68             column: mapping.originalColumn
69           };
70
71           if (mapping.name != null) {
72             newMapping.name = mapping.name;
73           }
74         }
75
76         generator.addMapping(newMapping);
77       });
78       aSourceMapConsumer.sources.forEach(function (sourceFile) {
79         var content = aSourceMapConsumer.sourceContentFor(sourceFile);
80         if (content != null) {
81           generator.setSourceContent(sourceFile, content);
82         }
83       });
84       return generator;
85     };
86
87   /**
88    * Add a single mapping from original source line and column to the generated
89    * source's line and column for this source map being created. The mapping
90    * object should have the following properties:
91    *
92    *   - generated: An object with the generated line and column positions.
93    *   - original: An object with the original line and column positions.
94    *   - source: The original source file (relative to the sourceRoot).
95    *   - name: An optional original token name for this mapping.
96    */
97   SourceMapGenerator.prototype.addMapping =
98     function SourceMapGenerator_addMapping(aArgs) {
99       var generated = util.getArg(aArgs, 'generated');
100       var original = util.getArg(aArgs, 'original', null);
101       var source = util.getArg(aArgs, 'source', null);
102       var name = util.getArg(aArgs, 'name', null);
103
104       if (!this._skipValidation) {
105         this._validateMapping(generated, original, source, name);
106       }
107
108       if (source != null && !this._sources.has(source)) {
109         this._sources.add(source);
110       }
111
112       if (name != null && !this._names.has(name)) {
113         this._names.add(name);
114       }
115
116       this._mappings.add({
117         generatedLine: generated.line,
118         generatedColumn: generated.column,
119         originalLine: original != null && original.line,
120         originalColumn: original != null && original.column,
121         source: source,
122         name: name
123       });
124     };
125
126   /**
127    * Set the source content for a source file.
128    */
129   SourceMapGenerator.prototype.setSourceContent =
130     function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
131       var source = aSourceFile;
132       if (this._sourceRoot != null) {
133         source = util.relative(this._sourceRoot, source);
134       }
135
136       if (aSourceContent != null) {
137         // Add the source content to the _sourcesContents map.
138         // Create a new _sourcesContents map if the property is null.
139         if (!this._sourcesContents) {
140           this._sourcesContents = {};
141         }
142         this._sourcesContents[util.toSetString(source)] = aSourceContent;
143       } else if (this._sourcesContents) {
144         // Remove the source file from the _sourcesContents map.
145         // If the _sourcesContents map is empty, set the property to null.
146         delete this._sourcesContents[util.toSetString(source)];
147         if (Object.keys(this._sourcesContents).length === 0) {
148           this._sourcesContents = null;
149         }
150       }
151     };
152
153   /**
154    * Applies the mappings of a sub-source-map for a specific source file to the
155    * source map being generated. Each mapping to the supplied source file is
156    * rewritten using the supplied source map. Note: The resolution for the
157    * resulting mappings is the minimium of this map and the supplied map.
158    *
159    * @param aSourceMapConsumer The source map to be applied.
160    * @param aSourceFile Optional. The filename of the source file.
161    *        If omitted, SourceMapConsumer's file property will be used.
162    * @param aSourceMapPath Optional. The dirname of the path to the source map
163    *        to be applied. If relative, it is relative to the SourceMapConsumer.
164    *        This parameter is needed when the two source maps aren't in the same
165    *        directory, and the source map to be applied contains relative source
166    *        paths. If so, those relative source paths need to be rewritten
167    *        relative to the SourceMapGenerator.
168    */
169   SourceMapGenerator.prototype.applySourceMap =
170     function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
171       var sourceFile = aSourceFile;
172       // If aSourceFile is omitted, we will use the file property of the SourceMap
173       if (aSourceFile == null) {
174         if (aSourceMapConsumer.file == null) {
175           throw new Error(
176             'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
177             'or the source map\'s "file" property. Both were omitted.'
178           );
179         }
180         sourceFile = aSourceMapConsumer.file;
181       }
182       var sourceRoot = this._sourceRoot;
183       // Make "sourceFile" relative if an absolute Url is passed.
184       if (sourceRoot != null) {
185         sourceFile = util.relative(sourceRoot, sourceFile);
186       }
187       // Applying the SourceMap can add and remove items from the sources and
188       // the names array.
189       var newSources = new ArraySet();
190       var newNames = new ArraySet();
191
192       // Find mappings for the "sourceFile"
193       this._mappings.unsortedForEach(function (mapping) {
194         if (mapping.source === sourceFile && mapping.originalLine != null) {
195           // Check if it can be mapped by the source map, then update the mapping.
196           var original = aSourceMapConsumer.originalPositionFor({
197             line: mapping.originalLine,
198             column: mapping.originalColumn
199           });
200           if (original.source != null) {
201             // Copy mapping
202             mapping.source = original.source;
203             if (aSourceMapPath != null) {
204               mapping.source = util.join(aSourceMapPath, mapping.source)
205             }
206             if (sourceRoot != null) {
207               mapping.source = util.relative(sourceRoot, mapping.source);
208             }
209             mapping.originalLine = original.line;
210             mapping.originalColumn = original.column;
211             if (original.name != null) {
212               mapping.name = original.name;
213             }
214           }
215         }
216
217         var source = mapping.source;
218         if (source != null && !newSources.has(source)) {
219           newSources.add(source);
220         }
221
222         var name = mapping.name;
223         if (name != null && !newNames.has(name)) {
224           newNames.add(name);
225         }
226
227       }, this);
228       this._sources = newSources;
229       this._names = newNames;
230
231       // Copy sourcesContents of applied map.
232       aSourceMapConsumer.sources.forEach(function (sourceFile) {
233         var content = aSourceMapConsumer.sourceContentFor(sourceFile);
234         if (content != null) {
235           if (aSourceMapPath != null) {
236             sourceFile = util.join(aSourceMapPath, sourceFile);
237           }
238           if (sourceRoot != null) {
239             sourceFile = util.relative(sourceRoot, sourceFile);
240           }
241           this.setSourceContent(sourceFile, content);
242         }
243       }, this);
244     };
245
246   /**
247    * A mapping can have one of the three levels of data:
248    *
249    *   1. Just the generated position.
250    *   2. The Generated position, original position, and original source.
251    *   3. Generated and original position, original source, as well as a name
252    *      token.
253    *
254    * To maintain consistency, we validate that any new mapping being added falls
255    * in to one of these categories.
256    */
257   SourceMapGenerator.prototype._validateMapping =
258     function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
259                                                 aName) {
260       if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
261           && aGenerated.line > 0 && aGenerated.column >= 0
262           && !aOriginal && !aSource && !aName) {
263         // Case 1.
264         return;
265       }
266       else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
267                && aOriginal && 'line' in aOriginal && 'column' in aOriginal
268                && aGenerated.line > 0 && aGenerated.column >= 0
269                && aOriginal.line > 0 && aOriginal.column >= 0
270                && aSource) {
271         // Cases 2 and 3.
272         return;
273       }
274       else {
275         throw new Error('Invalid mapping: ' + JSON.stringify({
276           generated: aGenerated,
277           source: aSource,
278           original: aOriginal,
279           name: aName
280         }));
281       }
282     };
283
284   /**
285    * Serialize the accumulated mappings in to the stream of base 64 VLQs
286    * specified by the source map format.
287    */
288   SourceMapGenerator.prototype._serializeMappings =
289     function SourceMapGenerator_serializeMappings() {
290       var previousGeneratedColumn = 0;
291       var previousGeneratedLine = 1;
292       var previousOriginalColumn = 0;
293       var previousOriginalLine = 0;
294       var previousName = 0;
295       var previousSource = 0;
296       var result = '';
297       var mapping;
298
299       var mappings = this._mappings.toArray();
300       for (var i = 0, len = mappings.length; i < len; i++) {
301         mapping = mappings[i];
302
303         if (mapping.generatedLine !== previousGeneratedLine) {
304           previousGeneratedColumn = 0;
305           while (mapping.generatedLine !== previousGeneratedLine) {
306             result += ';';
307             previousGeneratedLine++;
308           }
309         }
310         else {
311           if (i > 0) {
312             if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
313               continue;
314             }
315             result += ',';
316           }
317         }
318
319         result += base64VLQ.encode(mapping.generatedColumn
320                                    - previousGeneratedColumn);
321         previousGeneratedColumn = mapping.generatedColumn;
322
323         if (mapping.source != null) {
324           result += base64VLQ.encode(this._sources.indexOf(mapping.source)
325                                      - previousSource);
326           previousSource = this._sources.indexOf(mapping.source);
327
328           // lines are stored 0-based in SourceMap spec version 3
329           result += base64VLQ.encode(mapping.originalLine - 1
330                                      - previousOriginalLine);
331           previousOriginalLine = mapping.originalLine - 1;
332
333           result += base64VLQ.encode(mapping.originalColumn
334                                      - previousOriginalColumn);
335           previousOriginalColumn = mapping.originalColumn;
336
337           if (mapping.name != null) {
338             result += base64VLQ.encode(this._names.indexOf(mapping.name)
339                                        - previousName);
340             previousName = this._names.indexOf(mapping.name);
341           }
342         }
343       }
344
345       return result;
346     };
347
348   SourceMapGenerator.prototype._generateSourcesContent =
349     function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
350       return aSources.map(function (source) {
351         if (!this._sourcesContents) {
352           return null;
353         }
354         if (aSourceRoot != null) {
355           source = util.relative(aSourceRoot, source);
356         }
357         var key = util.toSetString(source);
358         return Object.prototype.hasOwnProperty.call(this._sourcesContents,
359                                                     key)
360           ? this._sourcesContents[key]
361           : null;
362       }, this);
363     };
364
365   /**
366    * Externalize the source map.
367    */
368   SourceMapGenerator.prototype.toJSON =
369     function SourceMapGenerator_toJSON() {
370       var map = {
371         version: this._version,
372         sources: this._sources.toArray(),
373         names: this._names.toArray(),
374         mappings: this._serializeMappings()
375       };
376       if (this._file != null) {
377         map.file = this._file;
378       }
379       if (this._sourceRoot != null) {
380         map.sourceRoot = this._sourceRoot;
381       }
382       if (this._sourcesContents) {
383         map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
384       }
385
386       return map;
387     };
388
389   /**
390    * Render the source map being generated to a string.
391    */
392   SourceMapGenerator.prototype.toString =
393     function SourceMapGenerator_toString() {
394       return JSON.stringify(this.toJSON());
395     };
396
397   exports.SourceMapGenerator = SourceMapGenerator;
398
399 });