Skip to content
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

Sync constructors; still support async in browsers #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
14 changes: 7 additions & 7 deletions lib/read-wasm.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ const path = require("path");
module.exports = function readWasm() {
return new Promise((resolve, reject) => {
const wasmPath = path.join(__dirname, "mappings.wasm");
fs.readFile(wasmPath, null, (error, data) => {
if (error) {
reject(error);
return;
}

resolve(data.buffer);
return fs.readFile(wasmPath, null, (err, data) => {
if(err) reject(err);
else resolve(data.buffer);
});
});
};
module.exports.sync = function readWasmSync() {
const wasmPath = path.join(__dirname, "mappings.wasm");
return fs.readFileSync(wasmPath).buffer;
};

module.exports.initialize = _ => {
console.debug(
Expand Down
213 changes: 99 additions & 114 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 @@ -172,59 +166,56 @@ 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");
const sources = util.getArg(sourceMap, "sources").map(String);
// 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", []);
const 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");
const sources = util.getArg(sourceMap, "sources").map(String);
// 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", []);
const 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);
}

that._sourceLookupCache = new Map();
this._sourceLookupCache = new Map();

// 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 = ArraySet.fromArray(
that._sources.toArray().map(function(s) {
return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
}),
true
);
this._absoluteSources = ArraySet.fromArray(
this._sources.toArray().map(function (s) {
return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
}),
true
);

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 @@ -542,7 +533,7 @@ class BasicSourceMapConsumer extends SourceMapConsumer {
}
return (
this.sourcesContent.length >= this._sources.size() &&
!this.sourcesContent.some(function(sc) {
!this.sourcesContent.some(function (sc) {
return sc == null;
})
);
Expand Down Expand Up @@ -721,67 +712,61 @@ 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);
}

let lastOffset = {
line: -1,
column: 0
};
const s = 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");

let lastOffset = {
line: -1,
column: 0
};
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;

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;
});
});
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
};
})
this._sections = s;
return this;
}

/**
Expand Down Expand Up @@ -824,7 +809,7 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {

// Find the section containing the generated position we're trying to map
// to an original position.
const sectionIndex = binarySearch.search(needle, this._sections, function(
const sectionIndex = binarySearch.search(needle, this._sections, function (
aNeedle,
section
) {
Expand Down Expand Up @@ -862,7 +847,7 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {
* map, false otherwise.
*/
hasContentsOfAllSources() {
return this._sections.every(function(s) {
return this._sections.every(function (s) {
return s.consumer.hasContentsOfAllSources();
});
}
Expand Down Expand Up @@ -1003,7 +988,7 @@ class IndexedSourceMapConsumer extends SourceMapConsumer {
const columnShift = generatedOffset.generatedColumn - 1;

section.consumer.eachMapping(
function(mapping) {
function (mapping) {
if (mapping.generatedLine === 1) {
mapping.generatedColumn += columnShift;

Expand Down Expand Up @@ -1058,7 +1043,7 @@ function _factory(aSourceMap, aSourceMapURL) {
sourceMap.sections != null
? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
: new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
return Promise.resolve(consumer);
return consumer;
}

function _factoryBSM(aSourceMap, aSourceMapURL) {
Expand Down
Loading