Skip to content

Sync constructors, backported to 0.7.3 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/read-wasm.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ module.exports = function readWasm() {
});
});
};
module.exports.sync = function readWasmSync() {
const wasmPath = path.join(__dirname, "mappings.wasm");
return fs.readFileSync(wasmPath).buffer;
};

module.exports.initialize = _ => {
console.debug("SourceMapConsumer.initialize is a no-op when running in node.js");
Expand Down
275 changes: 130 additions & 145 deletions lib/source-map-consumer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ const INTERNAL = Symbol("smcInternal");

class SourceMapConsumer {
constructor(aSourceMap, aSourceMapURL) {
// If the constructor was called by super(), just return Promise<this>.
// Yes, this is a hack to retain the pre-existing API of the base-class
// constructor also being an async factory function.
if (aSourceMap == INTERNAL) {
return Promise.resolve(this);
}

if (aSourceMap === INTERNAL) return this;
return _factory(aSourceMap, aSourceMapURL);
}

Expand Down Expand Up @@ -198,74 +192,71 @@ exports.SourceMapConsumer = SourceMapConsumer;
*/
class BasicSourceMapConsumer extends SourceMapConsumer {
constructor(aSourceMap, aSourceMapURL) {
return super(INTERNAL).then(that => {
let sourceMap = aSourceMap;
if (typeof aSourceMap === "string") {
sourceMap = util.parseSourceMapInput(aSourceMap);
}
super(INTERNAL);
let sourceMap = aSourceMap;
if (typeof aSourceMap === "string") {
sourceMap = util.parseSourceMapInput(aSourceMap);
}

const version = util.getArg(sourceMap, "version");
let sources = util.getArg(sourceMap, "sources");
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
// requires the array) to play nice here.
const names = util.getArg(sourceMap, "names", []);
let sourceRoot = util.getArg(sourceMap, "sourceRoot", null);
const sourcesContent = util.getArg(sourceMap, "sourcesContent", null);
const mappings = util.getArg(sourceMap, "mappings");
const file = util.getArg(sourceMap, "file", null);

// Once again, Sass deviates from the spec and supplies the version as a
// string rather than a number, so we use loose equality checking here.
if (version != that._version) {
throw new Error("Unsupported version: " + version);
}
const version = util.getArg(sourceMap, "version");
let sources = util.getArg(sourceMap, "sources");
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
// requires the array) to play nice here.
const names = util.getArg(sourceMap, "names", []);
let sourceRoot = util.getArg(sourceMap, "sourceRoot", null);
const sourcesContent = util.getArg(sourceMap, "sourcesContent", null);
const mappings = util.getArg(sourceMap, "mappings");
const file = util.getArg(sourceMap, "file", null);

// Once again, Sass deviates from the spec and supplies the version as a
// string rather than a number, so we use loose equality checking here.
if (version != this._version) {
throw new Error("Unsupported version: " + version);
}

if (sourceRoot) {
sourceRoot = util.normalize(sourceRoot);
}
if (sourceRoot) {
sourceRoot = util.normalize(sourceRoot);
}

sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
// "foo.js". Normalize these first so that future comparisons will succeed.
// See bugzil.la/1090768.
.map(util.normalize)
// Always ensure that absolute sources are internally stored relative to
// the source root, if the source root is absolute. Not doing this would
// be particularly problematic when the source root is a prefix of the
// source (valid, but why??). See github issue #199 and bugzil.la/1188982.
.map(function(source) {
return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)
? util.relative(sourceRoot, source)
: source;
});
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
// "foo.js". Normalize these first so that future comparisons will succeed.
// See bugzil.la/1090768.
.map(util.normalize)
// Always ensure that absolute sources are internally stored relative to
// the source root, if the source root is absolute. Not doing this would
// be particularly problematic when the source root is a prefix of the
// source (valid, but why??). See github issue #199 and bugzil.la/1188982.
.map(function(source) {
return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)
? util.relative(sourceRoot, source)
: source;
});

// Pass `true` below to allow duplicate names and sources. While source maps
// are intended to be compressed and deduplicated, the TypeScript compiler
// sometimes generates source maps with duplicates in them. See Github issue
// #72 and bugzil.la/889492.
that._names = ArraySet.fromArray(names.map(String), true);
that._sources = ArraySet.fromArray(sources, true);
// Pass `true` below to allow duplicate names and sources. While source maps
// are intended to be compressed and deduplicated, the TypeScript compiler
// sometimes generates source maps with duplicates in them. See Github issue
// #72 and bugzil.la/889492.
this._names = ArraySet.fromArray(names.map(String), true);
this._sources = ArraySet.fromArray(sources, true);

that._absoluteSources = that._sources.toArray().map(function(s) {
return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
});
this._absoluteSources = this._sources.toArray().map(function(s) {
return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
});

that.sourceRoot = sourceRoot;
that.sourcesContent = sourcesContent;
that._mappings = mappings;
that._sourceMapURL = aSourceMapURL;
that.file = file;
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
this._sourceMapURL = aSourceMapURL;
this.file = file;

that._computedColumnSpans = false;
that._mappingsPtr = 0;
that._wasm = null;
this._computedColumnSpans = false;
this._mappingsPtr = 0;
this._wasm = null;

return wasm().then(w => {
that._wasm = w;
return that;
});
});
const w = wasm.sync();
this._wasm = w;
}

/**
Expand Down Expand Up @@ -383,14 +374,14 @@ class BasicSourceMapConsumer extends SourceMapConsumer {
},
() => {
switch (order) {
case SourceMapConsumer.GENERATED_ORDER:
this._wasm.exports.by_generated_location(this._getMappingsPtr());
break;
case SourceMapConsumer.ORIGINAL_ORDER:
this._wasm.exports.by_original_location(this._getMappingsPtr());
break;
default:
throw new Error("Unknown order of iteration.");
case SourceMapConsumer.GENERATED_ORDER:
this._wasm.exports.by_generated_location(this._getMappingsPtr());
break;
case SourceMapConsumer.ORIGINAL_ORDER:
this._wasm.exports.by_original_location(this._getMappingsPtr());
break;
default:
throw new Error("Unknown order of iteration.");
}
}
);
Expand Down Expand Up @@ -746,62 +737,56 @@ exports.BasicSourceMapConsumer = BasicSourceMapConsumer;
*/
class IndexedSourceMapConsumer extends SourceMapConsumer {
constructor(aSourceMap, aSourceMapURL) {
return super(INTERNAL).then(that => {
let sourceMap = aSourceMap;
if (typeof aSourceMap === "string") {
sourceMap = util.parseSourceMapInput(aSourceMap);
}
super(INTERNAL);
let sourceMap = aSourceMap;
if (typeof aSourceMap === "string") {
sourceMap = util.parseSourceMapInput(aSourceMap);
}

const version = util.getArg(sourceMap, "version");
const sections = util.getArg(sourceMap, "sections");
const version = util.getArg(sourceMap, "version");
const sections = util.getArg(sourceMap, "sections");

if (version != that._version) {
throw new Error("Unsupported version: " + version);
if (version != this._version) {
throw new Error("Unsupported version: " + version);
}

this._sources = new ArraySet();
this._names = new ArraySet();
this.__generatedMappings = null;
this.__originalMappings = null;
this.__generatedMappingsUnsorted = null;
this.__originalMappingsUnsorted = null;

let lastOffset = {
line: -1,
column: 0
};
this._sections = sections.map(s => {
if (s.url) {
// The url field will require support for asynchronicity.
// See https://github.com/mozilla/source-map/issues/16
throw new Error("Support for url field in sections not implemented.");
}
const offset = util.getArg(s, "offset");
const offsetLine = util.getArg(offset, "line");
const offsetColumn = util.getArg(offset, "column");

that._sources = new ArraySet();
that._names = new ArraySet();
that.__generatedMappings = null;
that.__originalMappings = null;
that.__generatedMappingsUnsorted = null;
that.__originalMappingsUnsorted = null;
if (offsetLine < lastOffset.line ||
(offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
throw new Error("Section offsets must be ordered and non-overlapping.");
}
lastOffset = offset;

let lastOffset = {
line: -1,
column: 0
const consumer = new SourceMapConsumer(util.getArg(s, "map"), aSourceMapURL);
return {
generatedOffset: {
// The offset fields are 0-based, but we use 1-based indices when
// encoding/decoding from VLQ.
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
consumer
};
return Promise.all(sections.map(s => {
if (s.url) {
// The url field will require support for asynchronicity.
// See https://github.com/mozilla/source-map/issues/16
throw new Error("Support for url field in sections not implemented.");
}
const offset = util.getArg(s, "offset");
const offsetLine = util.getArg(offset, "line");
const offsetColumn = util.getArg(offset, "column");

if (offsetLine < lastOffset.line ||
(offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
throw new Error("Section offsets must be ordered and non-overlapping.");
}
lastOffset = offset;

const cons = new SourceMapConsumer(util.getArg(s, "map"), aSourceMapURL);
return cons.then(consumer => {
return {
generatedOffset: {
// The offset fields are 0-based, but we use 1-based indices when
// encoding/decoding from VLQ.
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
consumer
};
});
})).then(s => {
that._sections = s;
return that;
});
});
}

Expand Down Expand Up @@ -926,7 +911,7 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {
}

return (aNeedle.generatedColumn -
section.generatedOffset.generatedColumn);
section.generatedOffset.generatedColumn);
});
const section = this._sections[sectionIndex];

Expand All @@ -944,8 +929,8 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {
(section.generatedOffset.generatedLine - 1),
column: needle.generatedColumn -
(section.generatedOffset.generatedLine === needle.generatedLine
? section.generatedOffset.generatedColumn - 1
: 0),
? section.generatedOffset.generatedColumn - 1
: 0),
bias: aArgs.bias
});
}
Expand Down Expand Up @@ -1014,8 +999,8 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {
(section.generatedOffset.generatedLine - 1),
column: generatedPosition.column +
(section.generatedOffset.generatedLine === generatedPosition.line
? section.generatedOffset.generatedColumn - 1
: 0)
? section.generatedOffset.generatedColumn - 1
: 0)
};
return ret;
}
Expand Down Expand Up @@ -1068,8 +1053,8 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {
(section.generatedOffset.generatedLine - 1),
generatedColumn: mapping.generatedColumn +
(section.generatedOffset.generatedLine === mapping.generatedLine
? section.generatedOffset.generatedColumn - 1
: 0),
? section.generatedOffset.generatedColumn - 1
: 0),
originalLine: mapping.originalLine,
originalColumn: mapping.originalColumn,
name
Expand Down Expand Up @@ -1122,19 +1107,19 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {
* we are searching for in the given "haystack" of mappings.
*/
_findMapping(aNeedle, aMappings, aLineName,
aColumnName, aComparator, aBias) {
aColumnName, aComparator, aBias) {
// 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]);
+ aNeedle[aLineName]);
}
if (aNeedle[aColumnName] < 0) {
throw new TypeError("Column must be greater than or equal to 0, got "
+ aNeedle[aColumnName]);
+ aNeedle[aColumnName]);
}

return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
Expand Down Expand Up @@ -1169,11 +1154,11 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {
const mappings = [];

let index = this._findMapping(needle,
this._originalMappings,
"originalLine",
"originalColumn",
util.compareByOriginalPositions,
binarySearch.LEAST_UPPER_BOUND);
this._originalMappings,
"originalLine",
"originalColumn",
util.compareByOriginalPositions,
binarySearch.LEAST_UPPER_BOUND);
if (index >= 0) {
let mapping = this._originalMappings[index];

Expand Down Expand Up @@ -1205,8 +1190,8 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {
// Since mappings are sorted, this is guaranteed to find all mappings for
// the line we are searching for.
while (mapping &&
mapping.originalLine === line &&
mapping.originalColumn == originalColumn) {
mapping.originalLine === line &&
mapping.originalColumn == originalColumn) {
let lastColumn = mapping.lastGeneratedColumn;
if (this._computedColumnSpans && lastColumn === null) {
lastColumn = Infinity;
Expand Down Expand Up @@ -1244,9 +1229,9 @@ function _factory(aSourceMap, aSourceMapURL) {
}

const consumer = sourceMap.sections != null
? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
: new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
return Promise.resolve(consumer);
? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
: new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
return consumer;
}

function _factoryBSM(aSourceMap, aSourceMapURL) {
Expand Down
Loading