| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 | 
							- /* -*- Mode: js; js-indent-level: 2; -*- */
 
- /*
 
-  * Copyright 2011 Mozilla Foundation and contributors
 
-  * Licensed under the New BSD license. See LICENSE or:
 
-  * http://opensource.org/licenses/BSD-3-Clause
 
-  */
 
- var base64VLQ = require('./base64-vlq');
 
- var util = require('./util');
 
- var ArraySet = require('./array-set').ArraySet;
 
- var MappingList = require('./mapping-list').MappingList;
 
- /**
 
-  * An instance of the SourceMapGenerator represents a source map which is
 
-  * being built incrementally. You may pass an object with the following
 
-  * properties:
 
-  *
 
-  *   - file: The filename of the generated source.
 
-  *   - sourceRoot: A root for all relative URLs in this source map.
 
-  */
 
- function SourceMapGenerator(aArgs) {
 
-   if (!aArgs) {
 
-     aArgs = {};
 
-   }
 
-   this._file = util.getArg(aArgs, 'file', null);
 
-   this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
 
-   this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
 
-   this._sources = new ArraySet();
 
-   this._names = new ArraySet();
 
-   this._mappings = new MappingList();
 
-   this._sourcesContents = null;
 
- }
 
- SourceMapGenerator.prototype._version = 3;
 
- /**
 
-  * Creates a new SourceMapGenerator based on a SourceMapConsumer
 
-  *
 
-  * @param aSourceMapConsumer The SourceMap.
 
-  */
 
- SourceMapGenerator.fromSourceMap =
 
-   function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
 
-     var sourceRoot = aSourceMapConsumer.sourceRoot;
 
-     var generator = new SourceMapGenerator({
 
-       file: aSourceMapConsumer.file,
 
-       sourceRoot: sourceRoot
 
-     });
 
-     aSourceMapConsumer.eachMapping(function (mapping) {
 
-       var newMapping = {
 
-         generated: {
 
-           line: mapping.generatedLine,
 
-           column: mapping.generatedColumn
 
-         }
 
-       };
 
-       if (mapping.source != null) {
 
-         newMapping.source = mapping.source;
 
-         if (sourceRoot != null) {
 
-           newMapping.source = util.relative(sourceRoot, newMapping.source);
 
-         }
 
-         newMapping.original = {
 
-           line: mapping.originalLine,
 
-           column: mapping.originalColumn
 
-         };
 
-         if (mapping.name != null) {
 
-           newMapping.name = mapping.name;
 
-         }
 
-       }
 
-       generator.addMapping(newMapping);
 
-     });
 
-     aSourceMapConsumer.sources.forEach(function (sourceFile) {
 
-       var sourceRelative = sourceFile;
 
-       if (sourceRoot !== null) {
 
-         sourceRelative = util.relative(sourceRoot, sourceFile);
 
-       }
 
-       if (!generator._sources.has(sourceRelative)) {
 
-         generator._sources.add(sourceRelative);
 
-       }
 
-       var content = aSourceMapConsumer.sourceContentFor(sourceFile);
 
-       if (content != null) {
 
-         generator.setSourceContent(sourceFile, content);
 
-       }
 
-     });
 
-     return generator;
 
-   };
 
- /**
 
-  * Add a single mapping from original source line and column to the generated
 
-  * source's line and column for this source map being created. The mapping
 
-  * object should have the following properties:
 
-  *
 
-  *   - generated: An object with the generated line and column positions.
 
-  *   - original: An object with the original line and column positions.
 
-  *   - source: The original source file (relative to the sourceRoot).
 
-  *   - name: An optional original token name for this mapping.
 
-  */
 
- SourceMapGenerator.prototype.addMapping =
 
-   function SourceMapGenerator_addMapping(aArgs) {
 
-     var generated = util.getArg(aArgs, 'generated');
 
-     var original = util.getArg(aArgs, 'original', null);
 
-     var source = util.getArg(aArgs, 'source', null);
 
-     var name = util.getArg(aArgs, 'name', null);
 
-     if (!this._skipValidation) {
 
-       this._validateMapping(generated, original, source, name);
 
-     }
 
-     if (source != null) {
 
-       source = String(source);
 
-       if (!this._sources.has(source)) {
 
-         this._sources.add(source);
 
-       }
 
-     }
 
-     if (name != null) {
 
-       name = String(name);
 
-       if (!this._names.has(name)) {
 
-         this._names.add(name);
 
-       }
 
-     }
 
-     this._mappings.add({
 
-       generatedLine: generated.line,
 
-       generatedColumn: generated.column,
 
-       originalLine: original != null && original.line,
 
-       originalColumn: original != null && original.column,
 
-       source: source,
 
-       name: name
 
-     });
 
-   };
 
- /**
 
-  * Set the source content for a source file.
 
-  */
 
- SourceMapGenerator.prototype.setSourceContent =
 
-   function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
 
-     var source = aSourceFile;
 
-     if (this._sourceRoot != null) {
 
-       source = util.relative(this._sourceRoot, source);
 
-     }
 
-     if (aSourceContent != null) {
 
-       // Add the source content to the _sourcesContents map.
 
-       // Create a new _sourcesContents map if the property is null.
 
-       if (!this._sourcesContents) {
 
-         this._sourcesContents = Object.create(null);
 
-       }
 
-       this._sourcesContents[util.toSetString(source)] = aSourceContent;
 
-     } else if (this._sourcesContents) {
 
-       // Remove the source file from the _sourcesContents map.
 
-       // If the _sourcesContents map is empty, set the property to null.
 
-       delete this._sourcesContents[util.toSetString(source)];
 
-       if (Object.keys(this._sourcesContents).length === 0) {
 
-         this._sourcesContents = null;
 
-       }
 
-     }
 
-   };
 
- /**
 
-  * Applies the mappings of a sub-source-map for a specific source file to the
 
-  * source map being generated. Each mapping to the supplied source file is
 
-  * rewritten using the supplied source map. Note: The resolution for the
 
-  * resulting mappings is the minimium of this map and the supplied map.
 
-  *
 
-  * @param aSourceMapConsumer The source map to be applied.
 
-  * @param aSourceFile Optional. The filename of the source file.
 
-  *        If omitted, SourceMapConsumer's file property will be used.
 
-  * @param aSourceMapPath Optional. The dirname of the path to the source map
 
-  *        to be applied. If relative, it is relative to the SourceMapConsumer.
 
-  *        This parameter is needed when the two source maps aren't in the same
 
-  *        directory, and the source map to be applied contains relative source
 
-  *        paths. If so, those relative source paths need to be rewritten
 
-  *        relative to the SourceMapGenerator.
 
-  */
 
- SourceMapGenerator.prototype.applySourceMap =
 
-   function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
 
-     var sourceFile = aSourceFile;
 
-     // If aSourceFile is omitted, we will use the file property of the SourceMap
 
-     if (aSourceFile == null) {
 
-       if (aSourceMapConsumer.file == null) {
 
-         throw new Error(
 
-           'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
 
-           'or the source map\'s "file" property. Both were omitted.'
 
-         );
 
-       }
 
-       sourceFile = aSourceMapConsumer.file;
 
-     }
 
-     var sourceRoot = this._sourceRoot;
 
-     // Make "sourceFile" relative if an absolute Url is passed.
 
-     if (sourceRoot != null) {
 
-       sourceFile = util.relative(sourceRoot, sourceFile);
 
-     }
 
-     // Applying the SourceMap can add and remove items from the sources and
 
-     // the names array.
 
-     var newSources = new ArraySet();
 
-     var newNames = new ArraySet();
 
-     // Find mappings for the "sourceFile"
 
-     this._mappings.unsortedForEach(function (mapping) {
 
-       if (mapping.source === sourceFile && mapping.originalLine != null) {
 
-         // Check if it can be mapped by the source map, then update the mapping.
 
-         var original = aSourceMapConsumer.originalPositionFor({
 
-           line: mapping.originalLine,
 
-           column: mapping.originalColumn
 
-         });
 
-         if (original.source != null) {
 
-           // Copy mapping
 
-           mapping.source = original.source;
 
-           if (aSourceMapPath != null) {
 
-             mapping.source = util.join(aSourceMapPath, mapping.source)
 
-           }
 
-           if (sourceRoot != null) {
 
-             mapping.source = util.relative(sourceRoot, mapping.source);
 
-           }
 
-           mapping.originalLine = original.line;
 
-           mapping.originalColumn = original.column;
 
-           if (original.name != null) {
 
-             mapping.name = original.name;
 
-           }
 
-         }
 
-       }
 
-       var source = mapping.source;
 
-       if (source != null && !newSources.has(source)) {
 
-         newSources.add(source);
 
-       }
 
-       var name = mapping.name;
 
-       if (name != null && !newNames.has(name)) {
 
-         newNames.add(name);
 
-       }
 
-     }, this);
 
-     this._sources = newSources;
 
-     this._names = newNames;
 
-     // Copy sourcesContents of applied map.
 
-     aSourceMapConsumer.sources.forEach(function (sourceFile) {
 
-       var content = aSourceMapConsumer.sourceContentFor(sourceFile);
 
-       if (content != null) {
 
-         if (aSourceMapPath != null) {
 
-           sourceFile = util.join(aSourceMapPath, sourceFile);
 
-         }
 
-         if (sourceRoot != null) {
 
-           sourceFile = util.relative(sourceRoot, sourceFile);
 
-         }
 
-         this.setSourceContent(sourceFile, content);
 
-       }
 
-     }, this);
 
-   };
 
- /**
 
-  * A mapping can have one of the three levels of data:
 
-  *
 
-  *   1. Just the generated position.
 
-  *   2. The Generated position, original position, and original source.
 
-  *   3. Generated and original position, original source, as well as a name
 
-  *      token.
 
-  *
 
-  * To maintain consistency, we validate that any new mapping being added falls
 
-  * in to one of these categories.
 
-  */
 
- SourceMapGenerator.prototype._validateMapping =
 
-   function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
 
-                                               aName) {
 
-     // When aOriginal is truthy but has empty values for .line and .column,
 
-     // it is most likely a programmer error. In this case we throw a very
 
-     // specific error message to try to guide them the right way.
 
-     // For example: https://github.com/Polymer/polymer-bundler/pull/519
 
-     if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
 
-         throw new Error(
 
-             'original.line and original.column are not numbers -- you probably meant to omit ' +
 
-             'the original mapping entirely and only map the generated position. If so, pass ' +
 
-             'null for the original mapping instead of an object with empty or null values.'
 
-         );
 
-     }
 
-     if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
 
-         && aGenerated.line > 0 && aGenerated.column >= 0
 
-         && !aOriginal && !aSource && !aName) {
 
-       // Case 1.
 
-       return;
 
-     }
 
-     else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
 
-              && aOriginal && 'line' in aOriginal && 'column' in aOriginal
 
-              && aGenerated.line > 0 && aGenerated.column >= 0
 
-              && aOriginal.line > 0 && aOriginal.column >= 0
 
-              && aSource) {
 
-       // Cases 2 and 3.
 
-       return;
 
-     }
 
-     else {
 
-       throw new Error('Invalid mapping: ' + JSON.stringify({
 
-         generated: aGenerated,
 
-         source: aSource,
 
-         original: aOriginal,
 
-         name: aName
 
-       }));
 
-     }
 
-   };
 
- /**
 
-  * Serialize the accumulated mappings in to the stream of base 64 VLQs
 
-  * specified by the source map format.
 
-  */
 
- SourceMapGenerator.prototype._serializeMappings =
 
-   function SourceMapGenerator_serializeMappings() {
 
-     var previousGeneratedColumn = 0;
 
-     var previousGeneratedLine = 1;
 
-     var previousOriginalColumn = 0;
 
-     var previousOriginalLine = 0;
 
-     var previousName = 0;
 
-     var previousSource = 0;
 
-     var result = '';
 
-     var next;
 
-     var mapping;
 
-     var nameIdx;
 
-     var sourceIdx;
 
-     var mappings = this._mappings.toArray();
 
-     for (var i = 0, len = mappings.length; i < len; i++) {
 
-       mapping = mappings[i];
 
-       next = ''
 
-       if (mapping.generatedLine !== previousGeneratedLine) {
 
-         previousGeneratedColumn = 0;
 
-         while (mapping.generatedLine !== previousGeneratedLine) {
 
-           next += ';';
 
-           previousGeneratedLine++;
 
-         }
 
-       }
 
-       else {
 
-         if (i > 0) {
 
-           if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
 
-             continue;
 
-           }
 
-           next += ',';
 
-         }
 
-       }
 
-       next += base64VLQ.encode(mapping.generatedColumn
 
-                                  - previousGeneratedColumn);
 
-       previousGeneratedColumn = mapping.generatedColumn;
 
-       if (mapping.source != null) {
 
-         sourceIdx = this._sources.indexOf(mapping.source);
 
-         next += base64VLQ.encode(sourceIdx - previousSource);
 
-         previousSource = sourceIdx;
 
-         // lines are stored 0-based in SourceMap spec version 3
 
-         next += base64VLQ.encode(mapping.originalLine - 1
 
-                                    - previousOriginalLine);
 
-         previousOriginalLine = mapping.originalLine - 1;
 
-         next += base64VLQ.encode(mapping.originalColumn
 
-                                    - previousOriginalColumn);
 
-         previousOriginalColumn = mapping.originalColumn;
 
-         if (mapping.name != null) {
 
-           nameIdx = this._names.indexOf(mapping.name);
 
-           next += base64VLQ.encode(nameIdx - previousName);
 
-           previousName = nameIdx;
 
-         }
 
-       }
 
-       result += next;
 
-     }
 
-     return result;
 
-   };
 
- SourceMapGenerator.prototype._generateSourcesContent =
 
-   function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
 
-     return aSources.map(function (source) {
 
-       if (!this._sourcesContents) {
 
-         return null;
 
-       }
 
-       if (aSourceRoot != null) {
 
-         source = util.relative(aSourceRoot, source);
 
-       }
 
-       var key = util.toSetString(source);
 
-       return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
 
-         ? this._sourcesContents[key]
 
-         : null;
 
-     }, this);
 
-   };
 
- /**
 
-  * Externalize the source map.
 
-  */
 
- SourceMapGenerator.prototype.toJSON =
 
-   function SourceMapGenerator_toJSON() {
 
-     var map = {
 
-       version: this._version,
 
-       sources: this._sources.toArray(),
 
-       names: this._names.toArray(),
 
-       mappings: this._serializeMappings()
 
-     };
 
-     if (this._file != null) {
 
-       map.file = this._file;
 
-     }
 
-     if (this._sourceRoot != null) {
 
-       map.sourceRoot = this._sourceRoot;
 
-     }
 
-     if (this._sourcesContents) {
 
-       map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
 
-     }
 
-     return map;
 
-   };
 
- /**
 
-  * Render the source map being generated to a string.
 
-  */
 
- SourceMapGenerator.prototype.toString =
 
-   function SourceMapGenerator_toString() {
 
-     return JSON.stringify(this.toJSON());
 
-   };
 
- exports.SourceMapGenerator = SourceMapGenerator;
 
 
  |