Position tracking: Cache position info computed by |line| and |column|

Cache the last reported position info. If the position advances, the
code uses the cache and only computes the differnece. If the position
goes back, the cache is simply dropped.
redux
David Majda 12 years ago
parent 3333cdd18d
commit 28860e88df

@ -334,6 +334,8 @@ module.exports = function(ast, options) {
' ',
' var pos = 0;',
' var reportedPos = 0;',
' var cachedReportedPos = 0;',
' var cachedReportedPosDetails = { line: 1, column: 1, seenCR: false };',
' var reportFailures = 0;', // 0 = report, anything > 0 = do not report
' var rightmostFailuresPos = 0;',
' var rightmostFailuresExpected = [];',
@ -370,16 +372,48 @@ module.exports = function(ast, options) {
' return \'\\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), \'0\', length);',
' }',
' ',
' function computeReportedPosDetails() {',
' function advanceCachedReportedPos() {',
' var ch;',
' ',
' for (; cachedReportedPos < reportedPos; cachedReportedPos++) {',
' ch = input.charAt(cachedReportedPos);',
' if (ch === "\\n") {',
' if (!cachedReportedPosDetails.seenCR) { cachedReportedPosDetails.line++; }',
' cachedReportedPosDetails.column = 1;',
' cachedReportedPosDetails.seenCR = false;',
' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
' cachedReportedPosDetails.line++;',
' cachedReportedPosDetails.column = 1;',
' cachedReportedPosDetails.seenCR = true;',
' } else {',
' cachedReportedPosDetails.column++;',
' cachedReportedPosDetails.seenCR = false;',
' }',
' }',
' }',
' ',
' if (cachedReportedPos !== reportedPos) {',
' if (cachedReportedPos > reportedPos) {',
' cachedReportedPos = 0;',
' cachedReportedPosDetails = { line: 1, column: 1, seenCR: false };',
' }',
' advanceCachedReportedPos();',
' }',
' ',
' return cachedReportedPosDetails;',
' }',
' ',
' function offset() {',
' return reportedPos;',
' }',
' ',
' function line() {',
' return computePosDetails(reportedPos).line;',
' return computeReportedPosDetails().line;',
' }',
' ',
' function column() {',
' return computePosDetails(reportedPos).column;',
' return computeReportedPosDetails().column;',
' }',
' ',
' function matchFailed(failure) {',
@ -414,37 +448,6 @@ module.exports = function(ast, options) {
' return cleanExpected;',
' }',
' ',
' function computePosDetails(pos) {',
' /*',
' * The first idea was to use |String.split| to break the input up to the',
' * error position along newlines and derive the line and column from',
' * there. However IE\'s |split| implementation is so broken that it was',
' * enough to prevent it.',
' */',
' ',
' var line = 1;',
' var column = 1;',
' var seenCR = false;',
' ',
' for (var i = 0; i < pos; i++) {',
' var ch = input.charAt(i);',
' if (ch === "\\n") {',
' if (!seenCR) { line++; }',
' column = 1;',
' seenCR = false;',
' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
' line++;',
' column = 1;',
' seenCR = true;',
' } else {',
' column++;',
' seenCR = false;',
' }',
' }',
' ',
' return { line: line, column: column };',
' }',
' ',
' #if node.initializer',
' #block emit(node.initializer)',
' #end',
@ -476,16 +479,16 @@ module.exports = function(ast, options) {
' * handle these states.',
' */',
' if (result === null || pos !== input.length) {',
' var offset = Math.max(pos, rightmostFailuresPos);',
' var found = offset < input.length ? input.charAt(offset) : null;',
' var errorPosition = computePosDetails(Math.max(pos, rightmostFailuresPos));',
' reportedPos = Math.max(pos, rightmostFailuresPos);',
' var found = reportedPos < input.length ? input.charAt(reportedPos) : null;',
' var reportedPosDetails = computeReportedPosDetails();',
' ',
' throw new this.SyntaxError(',
' cleanupExpected(rightmostFailuresExpected),',
' found,',
' offset,',
' errorPosition.line,',
' errorPosition.column',
' reportedPos,',
' reportedPosDetails.line,',
' reportedPosDetails.column',
' );',
' }',
' ',

Loading…
Cancel
Save