source-map
Advanced tools
Comparing version
@@ -14,11 +14,2 @@ /* -*- Mode: js; js-indent-level: 2; -*- */ | ||
// TODO: bug 673487 | ||
// | ||
// Sometime in the future, if we decide we need to be able to query where in | ||
// the generated source a piece of the original code came from, we may want to | ||
// add a slot `_originalMappings` which would be an object keyed by the | ||
// original source and whose value would be an array of mappings ordered by | ||
// original line/col rather than generated (which is what we have now in | ||
// `_generatedMappings`). | ||
/** | ||
@@ -72,6 +63,8 @@ * A SourceMapConsumer instance represents a parsed source map which we can | ||
this._sources = ArraySet.fromArray(sources); | ||
this._sourceRoot = sourceRoot; | ||
this.file = file; | ||
// `this._generatedMappings` hold the parsed mapping coordinates from the | ||
// source map's "mappings" attribute. Each object in the array is of the | ||
// form | ||
// `this._generatedMappings` and `this._originalMappings` hold the parsed | ||
// mapping coordinates from the source map's "mappings" attribute. Each | ||
// object in the array is of the form | ||
// | ||
@@ -93,3 +86,8 @@ // { | ||
// `null`. | ||
// | ||
// `this._generatedMappings` is ordered by the generated positions. | ||
// | ||
// `this._originalMappings` is ordered by the original positions. | ||
this._generatedMappings = []; | ||
this._originalMappings = []; | ||
this._parseMappings(mappings, sourceRoot); | ||
@@ -104,2 +102,13 @@ } | ||
/** | ||
* The list of original sources. | ||
*/ | ||
Object.defineProperty(SourceMapConsumer.prototype, 'sources', { | ||
get: function () { | ||
return this._sources.toArray().map(function (s) { | ||
return this._sourceRoot ? util.join(this._sourceRoot, s) : s; | ||
}, this); | ||
} | ||
}); | ||
/** | ||
* Parse the mappings in a string in to a data structure which we can easily | ||
@@ -182,7 +191,64 @@ * query (an ordered list in this._generatedMappings). | ||
this._generatedMappings.push(mapping); | ||
this._originalMappings.push(mapping); | ||
} | ||
} | ||
this._originalMappings.sort(this._compareOriginalPositions); | ||
}; | ||
/** | ||
* Comparator between two mappings where the original positions are compared. | ||
*/ | ||
SourceMapConsumer.prototype._compareOriginalPositions = | ||
function SourceMapConsumer_compareOriginalPositions(mappingA, mappingB) { | ||
if (mappingA.source > mappingB.source) { | ||
return 1; | ||
} | ||
else if (mappingA.source < mappingB.source) { | ||
return -1; | ||
} | ||
else { | ||
var cmp = mappingA.originalLine - mappingB.originalLine; | ||
return cmp === 0 | ||
? mappingA.originalColumn - mappingB.originalColumn | ||
: cmp; | ||
} | ||
}; | ||
/** | ||
* Comparator between two mappings where the generated positions are compared. | ||
*/ | ||
SourceMapConsumer.prototype._compareGeneratedPositions = | ||
function SourceMapConsumer_compareGeneratedPositions(mappingA, mappingB) { | ||
var cmp = mappingA.generatedLine - mappingB.generatedLine; | ||
return cmp === 0 | ||
? mappingA.generatedColumn - mappingB.generatedColumn | ||
: cmp; | ||
}; | ||
/** | ||
* Find the mapping that best matches the hypothetical "needle" mapping that | ||
* we are searching for in the given "haystack" of mappings. | ||
*/ | ||
SourceMapConsumer.prototype._findMapping = | ||
function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, | ||
aColumnName, aComparator) { | ||
// To return the position we are searching for, we must first find the | ||
// mapping for the given position and then return the opposite position it | ||
// points to. Because the mappings are sorted, we can use binary search to | ||
// find the best mapping. | ||
if (aNeedle[aLineName] <= 0) { | ||
throw new TypeError('Line must be greater than or equal to 1, got ' | ||
+ aNeedle[aLineName]); | ||
} | ||
if (aNeedle[aColumnName] < 0) { | ||
throw new TypeError('Column must be greater than or equal to 0, got ' | ||
+ aNeedle[aColumnName]); | ||
} | ||
return binarySearch.search(aNeedle, aMappings, aComparator); | ||
}; | ||
/** | ||
* Returns the original source, line, and column information for the generated | ||
@@ -204,18 +270,2 @@ * source's line and column positions provided. The only argument is an object | ||
function SourceMapConsumer_originalPositionFor(aArgs) { | ||
// To return the original position, we must first find the mapping for the | ||
// given generated position and then return the original position it | ||
// points to. Because the mappings are sorted by generated line/column, we | ||
// can use binary search to find the best mapping. | ||
// To perform a binary search on the mappings, we must be able to compare | ||
// two mappings. | ||
function compare(mappingA, mappingB) { | ||
var cmp = mappingA.generatedLine - mappingB.generatedLine; | ||
return cmp === 0 | ||
? mappingA.generatedColumn - mappingB.generatedColumn | ||
: cmp; | ||
} | ||
// This is the mock of the mapping we are looking for: the needle in the | ||
// haystack of mappings. | ||
var needle = { | ||
@@ -226,11 +276,8 @@ generatedLine: util.getArg(aArgs, 'line'), | ||
if (needle.generatedLine <= 0) { | ||
throw new TypeError('Line must be greater than or equal to 1.'); | ||
} | ||
if (needle.generatedColumn < 0) { | ||
throw new TypeError('Column must be greater than or equal to 0.'); | ||
} | ||
var mapping = this._findMapping(needle, | ||
this._generatedMappings, | ||
"generatedLine", | ||
"generatedColumn", | ||
this._compareGeneratedPositions) | ||
var mapping = binarySearch.search(needle, this._generatedMappings, compare); | ||
if (mapping) { | ||
@@ -251,3 +298,43 @@ return { | ||
}; | ||
}; | ||
/** | ||
* Returns the generated line and column information for the original source, | ||
* line, and column positions provided. The only argument is an object with | ||
* the following properties: | ||
* | ||
* - source: The filename of the original source. | ||
* - line: The line number in the original source. | ||
* - column: The column number in the original source. | ||
* | ||
* and an object is returned with the following properties: | ||
* | ||
* - line: The line number in the generated source, or null. | ||
* - column: The column number in the generated source, or null. | ||
*/ | ||
SourceMapConsumer.prototype.generatedPositionFor = | ||
function SourceMapConsumer_generatedPositionFor(aArgs) { | ||
var needle = { | ||
source: util.getArg(aArgs, 'source'), | ||
originalLine: util.getArg(aArgs, 'line'), | ||
originalColumn: util.getArg(aArgs, 'column') | ||
}; | ||
var mapping = this._findMapping(needle, | ||
this._originalMappings, | ||
"originalLine", | ||
"originalColumn", | ||
this._compareOriginalPositions) | ||
if (mapping) { | ||
return { | ||
line: util.getArg(mapping, 'generatedLine', null), | ||
column: util.getArg(mapping, 'generatedColumn', null) | ||
}; | ||
} | ||
return { | ||
line: null, | ||
column: null | ||
}; | ||
}; | ||
@@ -254,0 +341,0 @@ |
@@ -133,2 +133,3 @@ /* -*- Mode: js; js-indent-level: 2; -*- */ | ||
ensureDir("dist"); | ||
ensureDir("dist/test"); | ||
@@ -135,0 +136,0 @@ buildFirefox(); |
{ | ||
"name": "source-map", | ||
"description": "Generates and consumes source maps", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"homepage": "https://github.com/mozilla/source-map", | ||
"author": "Nick Fitzgerald <nfitzgerald@mozilla.com>", | ||
"contributors": [ ], | ||
"contributors": [], | ||
"repository": { | ||
@@ -12,11 +12,21 @@ "type": "git", | ||
}, | ||
"directories": { "lib" : "./lib" }, | ||
"directories": { | ||
"lib": "./lib" | ||
}, | ||
"main": "./lib/source-map.js", | ||
"engines": { "node" : ">=0.4.0" }, | ||
"engines": { | ||
"node": ">=0.4.0" | ||
}, | ||
"licenses": [ | ||
{ "type": "BSD", "url" : "http://opensource.org/licenses/BSD-3-Clause" } | ||
{ | ||
"type": "BSD", | ||
"url": "http://opensource.org/licenses/BSD-3-Clause" | ||
} | ||
], | ||
"dependencies": { | ||
"requirejs": "==0.26.0" | ||
}, | ||
"devDependencies": { | ||
"dryice": "~0.4.8" | ||
} | ||
} |
@@ -105,2 +105,20 @@ # Source Map | ||
#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition) | ||
Returns the generated line and column information for the original source, | ||
line, and column positions provided. The only argument is an object with | ||
the following properties: | ||
* `source`: The filename of the original source. | ||
* `line`: The line number in the original source. | ||
* `column`: The column number in the original source. | ||
and an object is returned with the following properties: | ||
* `line`: The line number in the generated source, or null. | ||
* `column`: The column number in the generated source, or null. | ||
### SourceMapGenerator | ||
@@ -107,0 +125,0 @@ |
@@ -51,12 +51,20 @@ /* -*- Mode: js; js-indent-level: 2; -*- */ | ||
// Fuzzy | ||
util.assertMapping(2, 0, null, null, null, null, smc, assert); | ||
util.assertMapping(2, 9, '/wu/tang/gza.coffee', 1, 0, null, smc, assert); | ||
util.assertMapping(3, 0, '/wu/tang/gza.coffee', 1, 0, null, smc, assert); | ||
util.assertMapping(3, 9, '/wu/tang/gza.coffee', 2, 0, null, smc, assert); | ||
util.assertMapping(4, 0, '/wu/tang/gza.coffee', 2, 0, null, smc, assert); | ||
util.assertMapping(4, 9, '/wu/tang/gza.coffee', 3, 0, null, smc, assert); | ||
util.assertMapping(5, 0, '/wu/tang/gza.coffee', 3, 0, null, smc, assert); | ||
util.assertMapping(5, 9, '/wu/tang/gza.coffee', 4, 0, null, smc, assert); | ||
// Original to generated | ||
util.assertMapping(2, 0, null, null, null, null, smc, assert, true); | ||
util.assertMapping(2, 9, '/wu/tang/gza.coffee', 1, 0, null, smc, assert, true); | ||
util.assertMapping(3, 0, '/wu/tang/gza.coffee', 1, 0, null, smc, assert, true); | ||
util.assertMapping(3, 9, '/wu/tang/gza.coffee', 2, 0, null, smc, assert, true); | ||
util.assertMapping(4, 0, '/wu/tang/gza.coffee', 2, 0, null, smc, assert, true); | ||
util.assertMapping(4, 9, '/wu/tang/gza.coffee', 3, 0, null, smc, assert, true); | ||
util.assertMapping(5, 0, '/wu/tang/gza.coffee', 3, 0, null, smc, assert, true); | ||
util.assertMapping(5, 9, '/wu/tang/gza.coffee', 4, 0, null, smc, assert, true); | ||
// Generated to original | ||
util.assertMapping(2, 2, '/wu/tang/gza.coffee', 1, 1, null, smc, assert, null, true); | ||
util.assertMapping(3, 2, '/wu/tang/gza.coffee', 2, 3, null, smc, assert, null, true); | ||
util.assertMapping(4, 2, '/wu/tang/gza.coffee', 3, 6, null, smc, assert, null, true); | ||
util.assertMapping(5, 2, '/wu/tang/gza.coffee', 4, 9, null, smc, assert, null, true); | ||
}; | ||
}); |
@@ -20,2 +20,11 @@ /* -*- Mode: js; js-indent-level: 2; -*- */ | ||
exports['test that the `sources` field has the original sources'] = function (assert, util) { | ||
var map = new SourceMapConsumer(util.testMap); | ||
var sources = map.sources; | ||
assert.equal(sources[0], '/the/root/one.js'); | ||
assert.equal(sources[1], '/the/root/two.js'); | ||
assert.equal(sources.length, 2); | ||
}; | ||
exports['test that the source root is reflected in a mapping\'s source field'] = function (assert, util) { | ||
@@ -57,8 +66,14 @@ var map = new SourceMapConsumer(util.testMap); | ||
exports['test mapping tokens back fuzzy'] = function (assert, util) { | ||
exports['test mapping tokens fuzzy'] = function (assert, util) { | ||
var map = new SourceMapConsumer(util.testMap); | ||
util.assertMapping(1, 20, '/the/root/one.js', 1, 21, 'bar', map, assert); | ||
util.assertMapping(1, 30, '/the/root/one.js', 2, 10, 'baz', map, assert); | ||
util.assertMapping(2, 12, '/the/root/two.js', 1, 11, null, map, assert); | ||
// Finding original positions | ||
util.assertMapping(1, 20, '/the/root/one.js', 1, 21, 'bar', map, assert, true); | ||
util.assertMapping(1, 30, '/the/root/one.js', 2, 10, 'baz', map, assert, true); | ||
util.assertMapping(2, 12, '/the/root/two.js', 1, 11, null, map, assert, true); | ||
// Finding generated positions | ||
util.assertMapping(1, 18, '/the/root/one.js', 1, 22, 'bar', map, assert, null, true); | ||
util.assertMapping(1, 28, '/the/root/one.js', 2, 13, 'baz', map, assert, null, true); | ||
util.assertMapping(2, 9, '/the/root/two.js', 1, 16, null, map, assert, null, true); | ||
}; | ||
@@ -65,0 +80,0 @@ |
@@ -38,19 +38,36 @@ /* -*- Mode: js; js-indent-level: 2; -*- */ | ||
function assertMapping(generatedLine, generatedColumn, originalSource, | ||
originalLine, originalColumn, name, map, assert) { | ||
var mapping = map.originalPositionFor({ | ||
line: generatedLine, | ||
column: generatedColumn | ||
}); | ||
assert.equal(mapping.name, name, | ||
'Incorrect name, expected ' + JSON.stringify(name) | ||
+ ', got ' + JSON.stringify(mapping.name)); | ||
assert.equal(mapping.line, originalLine, | ||
'Incorrect line, expected ' + JSON.stringify(originalLine) | ||
+ ', got ' + JSON.stringify(mapping.line)); | ||
assert.equal(mapping.column, originalColumn, | ||
'Incorrect column, expected ' + JSON.stringify(originalColumn) | ||
+ ', got ' + JSON.stringify(mapping.column)); | ||
assert.equal(mapping.source, originalSource, | ||
'Incorrect source, expected ' + JSON.stringify(originalSource) | ||
+ ', got ' + JSON.stringify(mapping.source)); | ||
originalLine, originalColumn, name, map, assert, | ||
dontTestGenerated, dontTestOriginal) { | ||
if (!dontTestOriginal) { | ||
var origMapping = map.originalPositionFor({ | ||
line: generatedLine, | ||
column: generatedColumn | ||
}); | ||
assert.equal(origMapping.name, name, | ||
'Incorrect name, expected ' + JSON.stringify(name) | ||
+ ', got ' + JSON.stringify(origMapping.name)); | ||
assert.equal(origMapping.line, originalLine, | ||
'Incorrect line, expected ' + JSON.stringify(originalLine) | ||
+ ', got ' + JSON.stringify(origMapping.line)); | ||
assert.equal(origMapping.column, originalColumn, | ||
'Incorrect column, expected ' + JSON.stringify(originalColumn) | ||
+ ', got ' + JSON.stringify(origMapping.column)); | ||
assert.equal(origMapping.source, originalSource, | ||
'Incorrect source, expected ' + JSON.stringify(originalSource) | ||
+ ', got ' + JSON.stringify(origMapping.source)); | ||
} | ||
if (!dontTestGenerated) { | ||
var genMapping = map.generatedPositionFor({ | ||
source: originalSource, | ||
line: originalLine, | ||
column: originalColumn | ||
}); | ||
assert.equal(genMapping.line, generatedLine, | ||
'Incorrect line, expected ' + JSON.stringify(generatedLine) | ||
+ ', got ' + JSON.stringify(genMapping.line)); | ||
assert.equal(genMapping.column, generatedColumn, | ||
'Incorrect column, expected ' + JSON.stringify(generatedColumn) | ||
+ ', got ' + JSON.stringify(genMapping.column)); | ||
} | ||
} | ||
@@ -57,0 +74,0 @@ exports.assertMapping = assertMapping; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
85612
6.87%2041
6.03%243
8%1
Infinity%