Cache result of forEachLine for ~4% time reduction.

This commit is contained in:
David Anson 2015-06-16 17:50:55 -07:00
parent 3e208b7bc5
commit 483597c82a
2 changed files with 31 additions and 24 deletions

View file

@ -12,7 +12,7 @@
"rules": {
"no-alert": 2,
"no-array-constructor": 2,
"no-bitwise": 2,
"no-bitwise": 0,
"no-caller": 2,
"no-catch-shadow": 2,
"no-comma-dangle": 2,

View file

@ -38,22 +38,32 @@ function filterTokens(params, type, callback) {
// Calls the provided function for each line (with context)
function forEachLine(params, callback) {
// Identify lines in code blocks
var codeLines = [];
filterTokens(params, "code_block", function forToken(token) {
for (var i = token.map[0]; i < token.map[1]; i++) {
codeLines.push(i);
}
});
// Identify lines in code fences (with info about transitions)
var inFence = false;
if (!params.forEachLine) {
var lineMetadata = new Array(params.lines.length);
var inFence = false;
// Find fenced code by pattern (parser ignores "``` close fence")
params.lines.forEach(function forLine(line, lineIndex) {
var metadata = 0;
if (/^(```|~~~)/.test(line)) {
metadata = inFence ? -2 : 2;
inFence = !inFence;
} else if (inFence) {
metadata = 1;
}
lineMetadata[lineIndex] = metadata;
});
// Find code blocks normally
filterTokens(params, "code_block", function forToken(token) {
for (var i = token.map[0]; i < token.map[1]; i++) {
lineMetadata[i] = 1;
}
});
params.forEachLine = lineMetadata;
}
// Invoke callback
params.lines.forEach(function forLine(line, lineIndex) {
var onFence = /^(```|~~~)/.test(line);
if (onFence) {
inFence = !inFence;
}
var inCodeBlock = (codeLines.indexOf(lineIndex) !== -1);
callback(line, lineIndex, inFence || inCodeBlock, onFence);
var metadata = params.forEachLine[lineIndex];
callback(line, lineIndex, !!metadata, (metadata >> 1));
});
}
@ -581,13 +591,11 @@ module.exports = [
"desc": "Fenced code blocks should be surrounded by blank lines",
"tags": [ "code", "blank_lines" ],
"func": function MD031(params, errors) {
forEachLine(params, function forLine(line, lineIndex, inCode, onFence) {
if (onFence &&
((inCode && (lineIndex - 1 >= 0) &&
params.lines[lineIndex - 1].length) ||
(!inCode && (lineIndex + 1 < params.lines.length) &&
params.lines[lineIndex + 1].length))) {
errors.push(lineIndex + 1);
var lines = params.lines;
forEachLine(params, function forLine(line, i, inCode, onFence) {
if (((onFence > 0) && (i - 1 >= 0) && lines[i - 1].length) ||
((onFence < 0) && (i + 1 < lines.length) && lines[i + 1].length)) {
errors.push(i + 1);
}
});
}
@ -610,7 +618,6 @@ module.exports = [
}
inList = listMarker;
}
inList = inList && !onFence;
prevLine = line;
});
}