Use object lookup instead of array

This commit is contained in:
Dan Abramov 2015-01-15 03:50:52 +03:00
parent a452f781b8
commit a1b326a0ab
2 changed files with 10 additions and 81 deletions

View File

@ -1,7 +1,6 @@
module.exports = Whitespace;
var _ = require("lodash");
var util = require("../util");
/**
* Returns `i`th number from `base`, continuing from 0 when `max` is reached.
@ -23,7 +22,7 @@ function getLookupIndex(i, base, max) {
function Whitespace(tokens, comments) {
this.tokens = _.sortBy(tokens.concat(comments), "start");
this.used = [];
this.used = {};
// Profiling this code shows that while generator passes over it, indexes
// returned by `getNewlinesBefore` and `getNewlinesAfter` are always increasing.
@ -97,6 +96,14 @@ Whitespace.prototype.getNewlinesAfter = function (node) {
Whitespace.prototype.getNewlinesBetween = function (startToken, endToken) {
var start = startToken ? startToken.loc.end.line : 1;
var end = endToken.loc.start.line;
var lines = 0;
return util.mergeIntegerRange(this.used, start, end);
for (var line = start; line < end; line++) {
if (typeof this.used[line] === 'undefined') {
this.used[line] = true;
lines++;
}
}
return lines;
};

View File

@ -204,84 +204,6 @@ exports.repeat = function (width, cha) {
return result;
};
/**
* Merges a range of integers defined by `start` and `end` into an existing
* array of `ranges`, optimizing for common cases and attempting to keep them
* sorted. Returns the count of integers that have been added to `ranges` during
* the call.
*
* @example
* > var ranges = [{ start: 1, end: 3}, { start: 8, end : 10 }];
* > mergeIntegerRange(ranges, 6, 9);
* 2
* > ranges
* [{ start: 1, end: 3}, { start: 6, end : 10 }];
*
* @param {Array} ranges An array of ranges that function will mutate
* @param {Number} start Beginning of range being added
* @param {Number} end End of range being added
* @returns {Number} pointsAdded How many new integers have been added
*/
exports.mergeIntegerRange = function (ranges, start, end) {
var pointsAdded = 0;
var insertIndex;
var rangeIndex;
var point;
var range;
var matchingRange;
var rangeImmediatelyToLeft;
var rangeImmediatelyToRight;
for (point = start; point < end; point++) {
matchingRange = null;
rangeImmediatelyToLeft = null;
rangeImmediatelyToRight = null;
insertIndex = ranges.length;
for (rangeIndex = 0; rangeIndex < ranges.length; rangeIndex++) {
range = ranges[rangeIndex];
if (point >= range.start && point <= range.end) {
matchingRange = range;
break;
}
if (point < range.start) {
insertIndex = rangeIndex;
}
if (point === range.end + 1) {
rangeImmediatelyToLeft = range;
}
if (point === range.start - 1) {
rangeImmediatelyToRight = range;
}
}
if (matchingRange)
continue;
pointsAdded++;
if (rangeImmediatelyToLeft && rangeImmediatelyToRight) {
ranges.splice(ranges.indexOf(rangeImmediatelyToRight), 1);
rangeImmediatelyToLeft.end = rangeImmediatelyToRight.end;
} else if (rangeImmediatelyToLeft) {
rangeImmediatelyToLeft.end = point;
} else if (rangeImmediatelyToRight) {
rangeImmediatelyToRight.start = point;
} else {
ranges.splice(insertIndex, 0, {
start: point,
end: point
});
}
}
return pointsAdded;
};
exports.normaliseAst = function (ast, comments, tokens) {
if (ast && ast.type === "Program") {
return t.file(ast, comments || [], tokens || []);