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 pos = 0;',
' var reportedPos = 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 reportFailures = 0;', // 0 = report, anything > 0 = do not report
' var rightmostFailuresPos = 0;', ' var rightmostFailuresPos = 0;',
' var rightmostFailuresExpected = [];', ' var rightmostFailuresExpected = [];',
@ -370,16 +372,48 @@ module.exports = function(ast, options) {
' return \'\\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), \'0\', length);', ' 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() {', ' function offset() {',
' return reportedPos;', ' return reportedPos;',
' }', ' }',
' ', ' ',
' function line() {', ' function line() {',
' return computePosDetails(reportedPos).line;', ' return computeReportedPosDetails().line;',
' }', ' }',
' ', ' ',
' function column() {', ' function column() {',
' return computePosDetails(reportedPos).column;', ' return computeReportedPosDetails().column;',
' }', ' }',
' ', ' ',
' function matchFailed(failure) {', ' function matchFailed(failure) {',
@ -414,37 +448,6 @@ module.exports = function(ast, options) {
' return cleanExpected;', ' 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', ' #if node.initializer',
' #block emit(node.initializer)', ' #block emit(node.initializer)',
' #end', ' #end',
@ -476,16 +479,16 @@ module.exports = function(ast, options) {
' * handle these states.', ' * handle these states.',
' */', ' */',
' if (result === null || pos !== input.length) {', ' if (result === null || pos !== input.length) {',
' var offset = Math.max(pos, rightmostFailuresPos);', ' reportedPos = Math.max(pos, rightmostFailuresPos);',
' var found = offset < input.length ? input.charAt(offset) : null;', ' var found = reportedPos < input.length ? input.charAt(reportedPos) : null;',
' var errorPosition = computePosDetails(Math.max(pos, rightmostFailuresPos));', ' var reportedPosDetails = computeReportedPosDetails();',
' ', ' ',
' throw new this.SyntaxError(', ' throw new this.SyntaxError(',
' cleanupExpected(rightmostFailuresExpected),', ' cleanupExpected(rightmostFailuresExpected),',
' found,', ' found,',
' offset,', ' reportedPos,',
' errorPosition.line,', ' reportedPosDetails.line,',
' errorPosition.column', ' reportedPosDetails.column',
' );', ' );',
' }', ' }',
' ', ' ',

Loading…
Cancel
Save