|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var base64VLQ = require('./base64-vlq'); |
|
var util = require('./util'); |
|
var ArraySet = require('./array-set').ArraySet; |
|
var MappingList = require('./mapping-list').MappingList; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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._ignoreInvalidMapping = util.getArg(aArgs, 'ignoreInvalidMapping', false); |
|
this._sources = new ArraySet(); |
|
this._names = new ArraySet(); |
|
this._mappings = new MappingList(); |
|
this._sourcesContents = null; |
|
} |
|
|
|
SourceMapGenerator.prototype._version = 3; |
|
|
|
|
|
|
|
|
|
|
|
|
|
SourceMapGenerator.fromSourceMap = |
|
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer, generatorOps) { |
|
var sourceRoot = aSourceMapConsumer.sourceRoot; |
|
var generator = new SourceMapGenerator(Object.assign(generatorOps || {}, { |
|
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; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) { |
|
if (this._validateMapping(generated, original, source, name) === false) { |
|
return; |
|
} |
|
} |
|
|
|
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 |
|
}); |
|
}; |
|
|
|
|
|
|
|
|
|
SourceMapGenerator.prototype.setSourceContent = |
|
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { |
|
var source = aSourceFile; |
|
if (this._sourceRoot != null) { |
|
source = util.relative(this._sourceRoot, source); |
|
} |
|
|
|
if (aSourceContent != null) { |
|
|
|
|
|
if (!this._sourcesContents) { |
|
this._sourcesContents = Object.create(null); |
|
} |
|
this._sourcesContents[util.toSetString(source)] = aSourceContent; |
|
} else if (this._sourcesContents) { |
|
|
|
|
|
delete this._sourcesContents[util.toSetString(source)]; |
|
if (Object.keys(this._sourcesContents).length === 0) { |
|
this._sourcesContents = null; |
|
} |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SourceMapGenerator.prototype.applySourceMap = |
|
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { |
|
var sourceFile = aSourceFile; |
|
|
|
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; |
|
|
|
if (sourceRoot != null) { |
|
sourceFile = util.relative(sourceRoot, sourceFile); |
|
} |
|
|
|
|
|
var newSources = new ArraySet(); |
|
var newNames = new ArraySet(); |
|
|
|
|
|
this._mappings.unsortedForEach(function (mapping) { |
|
if (mapping.source === sourceFile && mapping.originalLine != null) { |
|
|
|
var original = aSourceMapConsumer.originalPositionFor({ |
|
line: mapping.originalLine, |
|
column: mapping.originalColumn |
|
}); |
|
if (original.source != null) { |
|
|
|
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; |
|
|
|
|
|
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); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SourceMapGenerator.prototype._validateMapping = |
|
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, |
|
aName) { |
|
|
|
|
|
|
|
|
|
if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { |
|
var message = '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 (this._ignoreInvalidMapping) { |
|
if (typeof console !== 'undefined' && console.warn) { |
|
console.warn(message); |
|
} |
|
return false; |
|
} else { |
|
throw new Error(message); |
|
} |
|
} |
|
|
|
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated |
|
&& aGenerated.line > 0 && aGenerated.column >= 0 |
|
&& !aOriginal && !aSource && !aName) { |
|
|
|
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) { |
|
|
|
return; |
|
} |
|
else { |
|
var message = 'Invalid mapping: ' + JSON.stringify({ |
|
generated: aGenerated, |
|
source: aSource, |
|
original: aOriginal, |
|
name: aName |
|
}); |
|
|
|
if (this._ignoreInvalidMapping) { |
|
if (typeof console !== 'undefined' && console.warn) { |
|
console.warn(message); |
|
} |
|
return false; |
|
} else { |
|
throw new Error(message) |
|
} |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
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); |
|
}; |
|
|
|
|
|
|
|
|
|
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; |
|
}; |
|
|
|
|
|
|
|
|
|
SourceMapGenerator.prototype.toString = |
|
function SourceMapGenerator_toString() { |
|
return JSON.stringify(this.toJSON()); |
|
}; |
|
|
|
exports.SourceMapGenerator = SourceMapGenerator; |
|
|