react / wstein / node_modules / react / node_modules / envify / node_modules / jstransform / node_modules / source-map / lib / source-map / source-map-generator.js
80559 views/* -*- Mode: js; js-indent-level: 2; -*- */1/*2* Copyright 2011 Mozilla Foundation and contributors3* Licensed under the New BSD license. See LICENSE or:4* http://opensource.org/licenses/BSD-3-Clause5*/6if (typeof define !== 'function') {7var define = require('amdefine')(module, require);8}9define(function (require, exports, module) {1011var base64VLQ = require('./base64-vlq');12var util = require('./util');13var ArraySet = require('./array-set').ArraySet;1415/**16* An instance of the SourceMapGenerator represents a source map which is17* being built incrementally. To create a new one, you must pass an object18* with the following properties:19*20* - file: The filename of the generated source.21* - sourceRoot: An optional root for all URLs in this source map.22*/23function SourceMapGenerator(aArgs) {24this._file = util.getArg(aArgs, 'file');25this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);26this._sources = new ArraySet();27this._names = new ArraySet();28this._mappings = [];29this._sourcesContents = null;30}3132SourceMapGenerator.prototype._version = 3;3334/**35* Creates a new SourceMapGenerator based on a SourceMapConsumer36*37* @param aSourceMapConsumer The SourceMap.38*/39SourceMapGenerator.fromSourceMap =40function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {41var sourceRoot = aSourceMapConsumer.sourceRoot;42var generator = new SourceMapGenerator({43file: aSourceMapConsumer.file,44sourceRoot: sourceRoot45});46aSourceMapConsumer.eachMapping(function (mapping) {47var newMapping = {48generated: {49line: mapping.generatedLine,50column: mapping.generatedColumn51}52};5354if (mapping.source) {55newMapping.source = mapping.source;56if (sourceRoot) {57newMapping.source = util.relative(sourceRoot, newMapping.source);58}5960newMapping.original = {61line: mapping.originalLine,62column: mapping.originalColumn63};6465if (mapping.name) {66newMapping.name = mapping.name;67}68}6970generator.addMapping(newMapping);71});72aSourceMapConsumer.sources.forEach(function (sourceFile) {73var content = aSourceMapConsumer.sourceContentFor(sourceFile);74if (content) {75generator.setSourceContent(sourceFile, content);76}77});78return generator;79};8081/**82* Add a single mapping from original source line and column to the generated83* source's line and column for this source map being created. The mapping84* object should have the following properties:85*86* - generated: An object with the generated line and column positions.87* - original: An object with the original line and column positions.88* - source: The original source file (relative to the sourceRoot).89* - name: An optional original token name for this mapping.90*/91SourceMapGenerator.prototype.addMapping =92function SourceMapGenerator_addMapping(aArgs) {93var generated = util.getArg(aArgs, 'generated');94var original = util.getArg(aArgs, 'original', null);95var source = util.getArg(aArgs, 'source', null);96var name = util.getArg(aArgs, 'name', null);9798this._validateMapping(generated, original, source, name);99100if (source && !this._sources.has(source)) {101this._sources.add(source);102}103104if (name && !this._names.has(name)) {105this._names.add(name);106}107108this._mappings.push({109generatedLine: generated.line,110generatedColumn: generated.column,111originalLine: original != null && original.line,112originalColumn: original != null && original.column,113source: source,114name: name115});116};117118/**119* Set the source content for a source file.120*/121SourceMapGenerator.prototype.setSourceContent =122function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {123var source = aSourceFile;124if (this._sourceRoot) {125source = util.relative(this._sourceRoot, source);126}127128if (aSourceContent !== null) {129// Add the source content to the _sourcesContents map.130// Create a new _sourcesContents map if the property is null.131if (!this._sourcesContents) {132this._sourcesContents = {};133}134this._sourcesContents[util.toSetString(source)] = aSourceContent;135} else {136// Remove the source file from the _sourcesContents map.137// If the _sourcesContents map is empty, set the property to null.138delete this._sourcesContents[util.toSetString(source)];139if (Object.keys(this._sourcesContents).length === 0) {140this._sourcesContents = null;141}142}143};144145/**146* Applies the mappings of a sub-source-map for a specific source file to the147* source map being generated. Each mapping to the supplied source file is148* rewritten using the supplied source map. Note: The resolution for the149* resulting mappings is the minimium of this map and the supplied map.150*151* @param aSourceMapConsumer The source map to be applied.152* @param aSourceFile Optional. The filename of the source file.153* If omitted, SourceMapConsumer's file property will be used.154*/155SourceMapGenerator.prototype.applySourceMap =156function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) {157// If aSourceFile is omitted, we will use the file property of the SourceMap158if (!aSourceFile) {159aSourceFile = aSourceMapConsumer.file;160}161var sourceRoot = this._sourceRoot;162// Make "aSourceFile" relative if an absolute Url is passed.163if (sourceRoot) {164aSourceFile = util.relative(sourceRoot, aSourceFile);165}166// Applying the SourceMap can add and remove items from the sources and167// the names array.168var newSources = new ArraySet();169var newNames = new ArraySet();170171// Find mappings for the "aSourceFile"172this._mappings.forEach(function (mapping) {173if (mapping.source === aSourceFile && mapping.originalLine) {174// Check if it can be mapped by the source map, then update the mapping.175var original = aSourceMapConsumer.originalPositionFor({176line: mapping.originalLine,177column: mapping.originalColumn178});179if (original.source !== null) {180// Copy mapping181if (sourceRoot) {182mapping.source = util.relative(sourceRoot, original.source);183} else {184mapping.source = original.source;185}186mapping.originalLine = original.line;187mapping.originalColumn = original.column;188if (original.name !== null && mapping.name !== null) {189// Only use the identifier name if it's an identifier190// in both SourceMaps191mapping.name = original.name;192}193}194}195196var source = mapping.source;197if (source && !newSources.has(source)) {198newSources.add(source);199}200201var name = mapping.name;202if (name && !newNames.has(name)) {203newNames.add(name);204}205206}, this);207this._sources = newSources;208this._names = newNames;209210// Copy sourcesContents of applied map.211aSourceMapConsumer.sources.forEach(function (sourceFile) {212var content = aSourceMapConsumer.sourceContentFor(sourceFile);213if (content) {214if (sourceRoot) {215sourceFile = util.relative(sourceRoot, sourceFile);216}217this.setSourceContent(sourceFile, content);218}219}, this);220};221222/**223* A mapping can have one of the three levels of data:224*225* 1. Just the generated position.226* 2. The Generated position, original position, and original source.227* 3. Generated and original position, original source, as well as a name228* token.229*230* To maintain consistency, we validate that any new mapping being added falls231* in to one of these categories.232*/233SourceMapGenerator.prototype._validateMapping =234function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,235aName) {236if (aGenerated && 'line' in aGenerated && 'column' in aGenerated237&& aGenerated.line > 0 && aGenerated.column >= 0238&& !aOriginal && !aSource && !aName) {239// Case 1.240return;241}242else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated243&& aOriginal && 'line' in aOriginal && 'column' in aOriginal244&& aGenerated.line > 0 && aGenerated.column >= 0245&& aOriginal.line > 0 && aOriginal.column >= 0246&& aSource) {247// Cases 2 and 3.248return;249}250else {251throw new Error('Invalid mapping: ' + JSON.stringify({252generated: aGenerated,253source: aSource,254orginal: aOriginal,255name: aName256}));257}258};259260/**261* Serialize the accumulated mappings in to the stream of base 64 VLQs262* specified by the source map format.263*/264SourceMapGenerator.prototype._serializeMappings =265function SourceMapGenerator_serializeMappings() {266var previousGeneratedColumn = 0;267var previousGeneratedLine = 1;268var previousOriginalColumn = 0;269var previousOriginalLine = 0;270var previousName = 0;271var previousSource = 0;272var result = '';273var mapping;274275// The mappings must be guaranteed to be in sorted order before we start276// serializing them or else the generated line numbers (which are defined277// via the ';' separators) will be all messed up. Note: it might be more278// performant to maintain the sorting as we insert them, rather than as we279// serialize them, but the big O is the same either way.280this._mappings.sort(util.compareByGeneratedPositions);281282for (var i = 0, len = this._mappings.length; i < len; i++) {283mapping = this._mappings[i];284285if (mapping.generatedLine !== previousGeneratedLine) {286previousGeneratedColumn = 0;287while (mapping.generatedLine !== previousGeneratedLine) {288result += ';';289previousGeneratedLine++;290}291}292else {293if (i > 0) {294if (!util.compareByGeneratedPositions(mapping, this._mappings[i - 1])) {295continue;296}297result += ',';298}299}300301result += base64VLQ.encode(mapping.generatedColumn302- previousGeneratedColumn);303previousGeneratedColumn = mapping.generatedColumn;304305if (mapping.source) {306result += base64VLQ.encode(this._sources.indexOf(mapping.source)307- previousSource);308previousSource = this._sources.indexOf(mapping.source);309310// lines are stored 0-based in SourceMap spec version 3311result += base64VLQ.encode(mapping.originalLine - 1312- previousOriginalLine);313previousOriginalLine = mapping.originalLine - 1;314315result += base64VLQ.encode(mapping.originalColumn316- previousOriginalColumn);317previousOriginalColumn = mapping.originalColumn;318319if (mapping.name) {320result += base64VLQ.encode(this._names.indexOf(mapping.name)321- previousName);322previousName = this._names.indexOf(mapping.name);323}324}325}326327return result;328};329330SourceMapGenerator.prototype._generateSourcesContent =331function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {332return aSources.map(function (source) {333if (!this._sourcesContents) {334return null;335}336if (aSourceRoot) {337source = util.relative(aSourceRoot, source);338}339var key = util.toSetString(source);340return Object.prototype.hasOwnProperty.call(this._sourcesContents,341key)342? this._sourcesContents[key]343: null;344}, this);345};346347/**348* Externalize the source map.349*/350SourceMapGenerator.prototype.toJSON =351function SourceMapGenerator_toJSON() {352var map = {353version: this._version,354file: this._file,355sources: this._sources.toArray(),356names: this._names.toArray(),357mappings: this._serializeMappings()358};359if (this._sourceRoot) {360map.sourceRoot = this._sourceRoot;361}362if (this._sourcesContents) {363map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);364}365366return map;367};368369/**370* Render the source map being generated to a string.371*/372SourceMapGenerator.prototype.toString =373function SourceMapGenerator_toString() {374return JSON.stringify(this);375};376377exports.SourceMapGenerator = SourceMapGenerator;378379});380381382