react / wstein / node_modules / browserify / node_modules / insert-module-globals / node_modules / combine-source-map / 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;14var MappingList = require('./mapping-list').MappingList;1516/**17* An instance of the SourceMapGenerator represents a source map which is18* being built incrementally. You may pass an object with the following19* properties:20*21* - file: The filename of the generated source.22* - sourceRoot: A root for all relative URLs in this source map.23*/24function SourceMapGenerator(aArgs) {25if (!aArgs) {26aArgs = {};27}28this._file = util.getArg(aArgs, 'file', null);29this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);30this._skipValidation = util.getArg(aArgs, 'skipValidation', false);31this._sources = new ArraySet();32this._names = new ArraySet();33this._mappings = new MappingList();34this._sourcesContents = null;35}3637SourceMapGenerator.prototype._version = 3;3839/**40* Creates a new SourceMapGenerator based on a SourceMapConsumer41*42* @param aSourceMapConsumer The SourceMap.43*/44SourceMapGenerator.fromSourceMap =45function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {46var sourceRoot = aSourceMapConsumer.sourceRoot;47var generator = new SourceMapGenerator({48file: aSourceMapConsumer.file,49sourceRoot: sourceRoot50});51aSourceMapConsumer.eachMapping(function (mapping) {52var newMapping = {53generated: {54line: mapping.generatedLine,55column: mapping.generatedColumn56}57};5859if (mapping.source != null) {60newMapping.source = mapping.source;61if (sourceRoot != null) {62newMapping.source = util.relative(sourceRoot, newMapping.source);63}6465newMapping.original = {66line: mapping.originalLine,67column: mapping.originalColumn68};6970if (mapping.name != null) {71newMapping.name = mapping.name;72}73}7475generator.addMapping(newMapping);76});77aSourceMapConsumer.sources.forEach(function (sourceFile) {78var content = aSourceMapConsumer.sourceContentFor(sourceFile);79if (content != null) {80generator.setSourceContent(sourceFile, content);81}82});83return generator;84};8586/**87* Add a single mapping from original source line and column to the generated88* source's line and column for this source map being created. The mapping89* object should have the following properties:90*91* - generated: An object with the generated line and column positions.92* - original: An object with the original line and column positions.93* - source: The original source file (relative to the sourceRoot).94* - name: An optional original token name for this mapping.95*/96SourceMapGenerator.prototype.addMapping =97function SourceMapGenerator_addMapping(aArgs) {98var generated = util.getArg(aArgs, 'generated');99var original = util.getArg(aArgs, 'original', null);100var source = util.getArg(aArgs, 'source', null);101var name = util.getArg(aArgs, 'name', null);102103if (!this._skipValidation) {104this._validateMapping(generated, original, source, name);105}106107if (source != null && !this._sources.has(source)) {108this._sources.add(source);109}110111if (name != null && !this._names.has(name)) {112this._names.add(name);113}114115this._mappings.add({116generatedLine: generated.line,117generatedColumn: generated.column,118originalLine: original != null && original.line,119originalColumn: original != null && original.column,120source: source,121name: name122});123};124125/**126* Set the source content for a source file.127*/128SourceMapGenerator.prototype.setSourceContent =129function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {130var source = aSourceFile;131if (this._sourceRoot != null) {132source = util.relative(this._sourceRoot, source);133}134135if (aSourceContent != null) {136// Add the source content to the _sourcesContents map.137// Create a new _sourcesContents map if the property is null.138if (!this._sourcesContents) {139this._sourcesContents = {};140}141this._sourcesContents[util.toSetString(source)] = aSourceContent;142} else if (this._sourcesContents) {143// Remove the source file from the _sourcesContents map.144// If the _sourcesContents map is empty, set the property to null.145delete this._sourcesContents[util.toSetString(source)];146if (Object.keys(this._sourcesContents).length === 0) {147this._sourcesContents = null;148}149}150};151152/**153* Applies the mappings of a sub-source-map for a specific source file to the154* source map being generated. Each mapping to the supplied source file is155* rewritten using the supplied source map. Note: The resolution for the156* resulting mappings is the minimium of this map and the supplied map.157*158* @param aSourceMapConsumer The source map to be applied.159* @param aSourceFile Optional. The filename of the source file.160* If omitted, SourceMapConsumer's file property will be used.161* @param aSourceMapPath Optional. The dirname of the path to the source map162* to be applied. If relative, it is relative to the SourceMapConsumer.163* This parameter is needed when the two source maps aren't in the same164* directory, and the source map to be applied contains relative source165* paths. If so, those relative source paths need to be rewritten166* relative to the SourceMapGenerator.167*/168SourceMapGenerator.prototype.applySourceMap =169function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {170var sourceFile = aSourceFile;171// If aSourceFile is omitted, we will use the file property of the SourceMap172if (aSourceFile == null) {173if (aSourceMapConsumer.file == null) {174throw new Error(175'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +176'or the source map\'s "file" property. Both were omitted.'177);178}179sourceFile = aSourceMapConsumer.file;180}181var sourceRoot = this._sourceRoot;182// Make "sourceFile" relative if an absolute Url is passed.183if (sourceRoot != null) {184sourceFile = util.relative(sourceRoot, sourceFile);185}186// Applying the SourceMap can add and remove items from the sources and187// the names array.188var newSources = new ArraySet();189var newNames = new ArraySet();190191// Find mappings for the "sourceFile"192this._mappings.unsortedForEach(function (mapping) {193if (mapping.source === sourceFile && mapping.originalLine != null) {194// Check if it can be mapped by the source map, then update the mapping.195var original = aSourceMapConsumer.originalPositionFor({196line: mapping.originalLine,197column: mapping.originalColumn198});199if (original.source != null) {200// Copy mapping201mapping.source = original.source;202if (aSourceMapPath != null) {203mapping.source = util.join(aSourceMapPath, mapping.source)204}205if (sourceRoot != null) {206mapping.source = util.relative(sourceRoot, mapping.source);207}208mapping.originalLine = original.line;209mapping.originalColumn = original.column;210if (original.name != null) {211mapping.name = original.name;212}213}214}215216var source = mapping.source;217if (source != null && !newSources.has(source)) {218newSources.add(source);219}220221var name = mapping.name;222if (name != null && !newNames.has(name)) {223newNames.add(name);224}225226}, this);227this._sources = newSources;228this._names = newNames;229230// Copy sourcesContents of applied map.231aSourceMapConsumer.sources.forEach(function (sourceFile) {232var content = aSourceMapConsumer.sourceContentFor(sourceFile);233if (content != null) {234if (aSourceMapPath != null) {235sourceFile = util.join(aSourceMapPath, sourceFile);236}237if (sourceRoot != null) {238sourceFile = util.relative(sourceRoot, sourceFile);239}240this.setSourceContent(sourceFile, content);241}242}, this);243};244245/**246* A mapping can have one of the three levels of data:247*248* 1. Just the generated position.249* 2. The Generated position, original position, and original source.250* 3. Generated and original position, original source, as well as a name251* token.252*253* To maintain consistency, we validate that any new mapping being added falls254* in to one of these categories.255*/256SourceMapGenerator.prototype._validateMapping =257function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,258aName) {259if (aGenerated && 'line' in aGenerated && 'column' in aGenerated260&& aGenerated.line > 0 && aGenerated.column >= 0261&& !aOriginal && !aSource && !aName) {262// Case 1.263return;264}265else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated266&& aOriginal && 'line' in aOriginal && 'column' in aOriginal267&& aGenerated.line > 0 && aGenerated.column >= 0268&& aOriginal.line > 0 && aOriginal.column >= 0269&& aSource) {270// Cases 2 and 3.271return;272}273else {274throw new Error('Invalid mapping: ' + JSON.stringify({275generated: aGenerated,276source: aSource,277original: aOriginal,278name: aName279}));280}281};282283/**284* Serialize the accumulated mappings in to the stream of base 64 VLQs285* specified by the source map format.286*/287SourceMapGenerator.prototype._serializeMappings =288function SourceMapGenerator_serializeMappings() {289var previousGeneratedColumn = 0;290var previousGeneratedLine = 1;291var previousOriginalColumn = 0;292var previousOriginalLine = 0;293var previousName = 0;294var previousSource = 0;295var result = '';296var mapping;297298var mappings = this._mappings.toArray();299300for (var i = 0, len = mappings.length; i < len; i++) {301mapping = mappings[i];302303if (mapping.generatedLine !== previousGeneratedLine) {304previousGeneratedColumn = 0;305while (mapping.generatedLine !== previousGeneratedLine) {306result += ';';307previousGeneratedLine++;308}309}310else {311if (i > 0) {312if (!util.compareByGeneratedPositions(mapping, mappings[i - 1])) {313continue;314}315result += ',';316}317}318319result += base64VLQ.encode(mapping.generatedColumn320- previousGeneratedColumn);321previousGeneratedColumn = mapping.generatedColumn;322323if (mapping.source != null) {324result += base64VLQ.encode(this._sources.indexOf(mapping.source)325- previousSource);326previousSource = this._sources.indexOf(mapping.source);327328// lines are stored 0-based in SourceMap spec version 3329result += base64VLQ.encode(mapping.originalLine - 1330- previousOriginalLine);331previousOriginalLine = mapping.originalLine - 1;332333result += base64VLQ.encode(mapping.originalColumn334- previousOriginalColumn);335previousOriginalColumn = mapping.originalColumn;336337if (mapping.name != null) {338result += base64VLQ.encode(this._names.indexOf(mapping.name)339- previousName);340previousName = this._names.indexOf(mapping.name);341}342}343}344345return result;346};347348SourceMapGenerator.prototype._generateSourcesContent =349function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {350return aSources.map(function (source) {351if (!this._sourcesContents) {352return null;353}354if (aSourceRoot != null) {355source = util.relative(aSourceRoot, source);356}357var key = util.toSetString(source);358return Object.prototype.hasOwnProperty.call(this._sourcesContents,359key)360? this._sourcesContents[key]361: null;362}, this);363};364365/**366* Externalize the source map.367*/368SourceMapGenerator.prototype.toJSON =369function SourceMapGenerator_toJSON() {370var map = {371version: this._version,372sources: this._sources.toArray(),373names: this._names.toArray(),374mappings: this._serializeMappings()375};376if (this._file != null) {377map.file = this._file;378}379if (this._sourceRoot != null) {380map.sourceRoot = this._sourceRoot;381}382if (this._sourcesContents) {383map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);384}385386return map;387};388389/**390* Render the source map being generated to a string.391*/392SourceMapGenerator.prototype.toString =393function SourceMapGenerator_toString() {394return JSON.stringify(this);395};396397exports.SourceMapGenerator = SourceMapGenerator;398399});400401402