Skip to content
This repository was archived by the owner on Mar 23, 2024. It is now read-only.

Commit 90fae1a

Browse files
committed
[Perf] Reduce location computations
1 parent 4bd3800 commit 90fae1a

File tree

4 files changed

+61
-33
lines changed

4 files changed

+61
-33
lines changed

lib/errors.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,11 @@ Errors.prototype = {
8080
* @private
8181
*/
8282
_addError: function(errorInfo) {
83-
var position = Errors.getPosition(errorInfo.element, errorInfo.offset);
8483
this._errorList.push({
8584
filename: this._file.getFilename(),
8685
rule: this._currentRule,
8786
message: this._prepareMessage(errorInfo),
8887
element: errorInfo.element,
89-
line: position.line,
90-
column: position.column,
9188
offset: errorInfo.offset,
9289
additional: errorInfo.additional,
9390
fixed: errorInfo.fixed
@@ -175,6 +172,17 @@ Errors.prototype = {
175172
this._errorList = this._errorList.filter(filter);
176173
},
177174

175+
/**
176+
* @param {TokenIndex} tokenIndex
177+
*/
178+
calculateErrorLocations: function(tokenIndex) {
179+
this._errorList.forEach(function(error) {
180+
var pos = Errors.getPosition(error.element, error.offset, tokenIndex);
181+
error.line = pos.line;
182+
error.column = pos.column;
183+
});
184+
},
185+
178186
/**
179187
* Formats error for further output.
180188
*
@@ -280,9 +288,10 @@ function renderPointer(column, colorize) {
280288
*
281289
* @param {Object} [element]
282290
* @param {Number} [offset]
291+
* @param {TokenIndex} [tokenIndex]
283292
* @return {Object}
284293
*/
285-
Errors.getPosition = function(element, offset) {
294+
Errors.getPosition = function(element, offset, tokenIndex) {
286295
if (!element) {
287296
return EMPTY_POS;
288297
}
@@ -295,13 +304,11 @@ Errors.getPosition = function(element, offset) {
295304
}
296305
}
297306

298-
var loc = element.getLoc();
299-
if (!loc) {
307+
var pos = tokenIndex ? tokenIndex.getElementLoc(element) : element.getLoc().start;
308+
if (!pos) {
300309
return EMPTY_POS;
301310
}
302311

303-
var pos = loc.start;
304-
305312
if (offset === 0) {
306313
return pos;
307314
}
@@ -331,13 +338,11 @@ Errors.getPosition = function(element, offset) {
331338
column: offset - previousOffset
332339
};
333340
} else {
334-
pos = {
341+
return {
335342
line: pos.line,
336343
column: pos.column + offset
337344
};
338345
}
339-
340-
return pos;
341346
};
342347

343348
module.exports = Errors;

lib/string-checker.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,16 +163,15 @@ StringChecker.prototype = {
163163
});
164164

165165
var program = file.getProgram();
166-
if (program && program.getFirstToken()) {
167-
var tokenIndex = new TokenIndex(program.getFirstToken());
168-
errors.filter(function(error) {
169-
if (error.element) {
170-
return tokenIndex.isRuleEnabled(error.rule, error.element);
171-
} else {
172-
return true;
173-
}
174-
});
175-
}
166+
var tokenIndex = new TokenIndex(program.getFirstToken());
167+
errors.calculateErrorLocations(tokenIndex);
168+
errors.filter(function(error) {
169+
if (error.element) {
170+
return tokenIndex.isRuleEnabled(error.rule, error.element);
171+
} else {
172+
return true;
173+
}
174+
});
176175

177176
// sort errors list to show errors as they appear in source
178177
errors.getErrorList().sort(function(a, b) {

lib/token-index.js

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function parseRuleNames(text, enabled) {
3333
* @param {Element} firstToken
3434
* @constructor
3535
*/
36-
function PragmaIndex(firstToken) {
36+
function TokenIndex(firstToken) {
3737
this._buildIndex(firstToken);
3838
}
3939

@@ -43,18 +43,36 @@ function PragmaIndex(firstToken) {
4343
* @param {Element} firstToken
4444
* @private
4545
*/
46-
PragmaIndex.prototype._buildIndex = function(firstToken) {
46+
TokenIndex.prototype._buildIndex = function(firstToken) {
4747
this._hasPragmas = false;
4848

4949
var tokens = [];
5050
var index = [];
51+
var positions = [];
5152
var currentPosition = 0;
5253
var currentToken = firstToken;
5354
var lastBlockState = {'*': true};
5455
var tokenState;
56+
var previousLoc = {line: 1, column: 0};
5557

5658
while (currentToken) {
5759
tokens.push(currentToken);
60+
currentToken.__loc = previousLoc;
61+
62+
var newlineCount = currentToken.getNewlineCount();
63+
if (newlineCount > 0) {
64+
var lines = currentToken.getSourceCodeLines();
65+
previousLoc = {
66+
line: previousLoc.line + newlineCount,
67+
column: lines[lines.length - 1].length
68+
};
69+
} else {
70+
previousLoc = {
71+
line: previousLoc.line,
72+
column: previousLoc.column + currentToken.getSourceCodeLength()
73+
};
74+
}
75+
5876
if (currentToken.isComment) {
5977
var value = currentToken.value;
6078
var blockMatch = BLOCK_REGEXP.exec(value);
@@ -106,6 +124,7 @@ PragmaIndex.prototype._buildIndex = function(firstToken) {
106124
}
107125
this._tokens = tokens;
108126
this._index = index;
127+
this._positions = positions;
109128
};
110129

111130
/**
@@ -115,7 +134,7 @@ PragmaIndex.prototype._buildIndex = function(firstToken) {
115134
* @param {Element} element
116135
* @returns {Boolean}
117136
*/
118-
PragmaIndex.prototype.isRuleEnabled = function(ruleName, element) {
137+
TokenIndex.prototype.isRuleEnabled = function(ruleName, element) {
119138
if (!this._hasPragmas) {
120139
return true;
121140
}
@@ -132,5 +151,18 @@ PragmaIndex.prototype.isRuleEnabled = function(ruleName, element) {
132151
return true;
133152
};
134153

135-
module.exports = PragmaIndex;
154+
/**
155+
* Return calculated element location.
156+
*
157+
* @param {Element} element
158+
* @returns {Object}
159+
*/
160+
TokenIndex.prototype.getElementLoc = function(element) {
161+
return element.getFirstToken().__loc || {
162+
line: 1,
163+
column: 0
164+
};
165+
};
166+
167+
module.exports = TokenIndex;
136168

test/specs/errors.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,6 @@ describe('errors', function() {
136136
var error = errors.getErrorList()[0];
137137

138138
expect(error.rule).to.equal('anyRule');
139-
expect(error.line).to.equal(1);
140-
expect(error.column).to.equal(0);
141139
});
142140
});
143141

@@ -157,8 +155,6 @@ describe('errors', function() {
157155
var error = errors.getErrorList()[0];
158156

159157
expect(error.rule).to.equal('anyRule');
160-
expect(error.line).to.equal(1);
161-
expect(error.column).to.equal(0);
162158
expect(error.additional).to.equal('test');
163159
});
164160
});
@@ -226,11 +222,7 @@ describe('errors', function() {
226222
errors.stripErrorList(2);
227223
expect(errors).to.have.error.count.equal(2);
228224
expect(errors.getErrorList()[0].message).to.equal('disallowQuotedKeysInObjects: msg1');
229-
expect(errors.getErrorList()[0].line).to.equal(1);
230-
expect(errors.getErrorList()[0].column).to.equal(0);
231225
expect(errors.getErrorList()[1].message).to.equal('disallowQuotedKeysInObjects: msg2');
232-
expect(errors.getErrorList()[1].line).to.equal(1);
233-
expect(errors.getErrorList()[1].column).to.equal(0);
234226
});
235227
});
236228
});

0 commit comments

Comments
 (0)