Skip to content

Commit

Permalink
Merge pull request #339 from eventualbuddha/fix-offsets
Browse files Browse the repository at this point in the history
Fix offset calculation for parsed nodes.
  • Loading branch information
michaelficarra committed May 29, 2015
2 parents 7f87fe8 + 9ac232b commit e1368e9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
2 changes: 1 addition & 1 deletion lib/parser.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 16 additions & 2 deletions src/grammar.pegcoffee
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,19 @@
r = p = rp = id

`
// XXX: this overrides the function with the same name generated by PEGjs; see comment within
// XXX: The functions below override the default code generated by PEGjs.
// CoffeeScriptRedux has a preprocessor that adds control characters to
// mark indents/outdents/etc for PEGjs. These characters cause the line,
// column, and offset values to differ from the original input source code,
// so this section exists to properly hide those control characters when
// reporting location information. See #117 & #335.

var csr$controlCharacterCount = 0;

function offset() {
return peg$reportedPos - csr$controlCharacterCount;
}

function peg$computePosDetails() {
function advanceCachedReportedPos() {
var ch;
Expand All @@ -274,16 +286,18 @@
peg$cachedPosDetails.line++;
peg$cachedPosDetails.column = 1;
peg$cachedPosDetails.seenCR = true;
// XXX: strip control characters when calculating position information; see #117
} else if(!/[\uEFEF\uEFFE\uEFFF]/.test(ch)) {
peg$cachedPosDetails.column++;
peg$cachedPosDetails.seenCR = false;
} else {
csr$controlCharacterCount++;
}
}
}

if (peg$cachedPos !== peg$reportedPos) {
if (peg$cachedPos > peg$reportedPos) {
csr$controlCharacterCount = 0;
peg$cachedPos = 0;
peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
}
Expand Down
17 changes: 13 additions & 4 deletions test/parser.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ suite 'Parser', ->
setup ->
@shouldParse = (input) -> doesNotThrow -> parse input
@shouldNotParse = (input) -> throws -> parse input
@checkNodeRaw = (node, source) =>
rawAtOffset = source[node.offset...(node.offset + node.raw.length)]
if node.raw isnt rawAtOffset
fail "expected #{node.className} raw to equal #{JSON.stringify(rawAtOffset)}, but was #{JSON.stringify(node.raw)}"
for own prop, child of node
if Array.isArray child
@checkNodeRaw element, source for element in child
else if child instanceof CoffeeScript.Nodes.Nodes
@checkNodeRaw child, source


test 'empty program', -> @shouldParse ''
Expand Down Expand Up @@ -176,9 +185,9 @@ suite 'Parser', ->
suite 'position/offset preservation', ->

test 'basic indentation', ->
ast = parse '''
source = '''
fn = ->
body
''', raw: yes
eq 3, ast.body.statements[0].expression.body.statements[0].column
eq 11, ast.body.statements[0].expression.body.statements[0].offset
'''
ast = parse source, raw: yes
@checkNodeRaw ast, source

0 comments on commit e1368e9

Please sign in to comment.