Skip to content

Commit

Permalink
Fix: Handle new lines inside block string correctly (#1637)
Browse files Browse the repository at this point in the history
* test(lexer): test if lexer advance line after block string

* fix(lexer): advance line, update lineStart inside block string

fix #1636

* test(lexer): more multiline block string cases
  • Loading branch information
langpavel authored and IvanGoncharov committed Dec 31, 2018
1 parent 1ba33fc commit 42db579
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
44 changes: 44 additions & 0 deletions src/language/__tests__/lexer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ function lexOne(str) {
return lexer.advance();
}

function lexSecond(str) {
const lexer = createLexer(new Source(str));
lexer.advance();
return lexer.advance();
}

function expectSyntaxError(text, message, location) {
expect(() => lexOne(text))
.to.throw('Syntax Error: ' + message)
Expand Down Expand Up @@ -359,6 +365,44 @@ describe('Lexer', () => {
});
});

it('advance line after lexing multiline block string', () => {
expect(
lexSecond(`"""
spans
multiple
lines
\n """ second_token`),
).to.contain({
kind: TokenKind.NAME,
start: 71,
end: 83,
line: 8,
column: 6,
value: 'second_token',
});

expect(
lexSecond(
[
'""" \n',
'spans \r\n',
'multiple \n\r',
'lines \n\n',
'"""\n second_token',
].join(''),
),
).to.contain({
kind: TokenKind.NAME,
start: 37,
end: 49,
line: 8,
column: 2,
value: 'second_token',
});
});

it('lex reports useful block string errors', () => {
expectSyntaxError('"""', 'Unterminated string.', { line: 1, column: 4 });

Expand Down
22 changes: 18 additions & 4 deletions src/language/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ function readToken(lexer: Lexer<*>, prev: Token): Token {
charCodeAt.call(body, pos + 1) === 34 &&
charCodeAt.call(body, pos + 2) === 34
) {
return readBlockString(source, pos, line, col, prev);
return readBlockString(source, pos, line, col, prev, lexer);
}
return readString(source, pos, line, col, prev);
}
Expand Down Expand Up @@ -625,7 +625,7 @@ function readString(source, start, line, col, prev): Token {
*
* """("?"?(\\"""|\\(?!=""")|[^"\\]))*"""
*/
function readBlockString(source, start, line, col, prev): Token {
function readBlockString(source, start, line, col, prev, lexer): Token {
const body = source.body;
let position = start + 3;
let chunkStart = position;
Expand Down Expand Up @@ -668,8 +668,22 @@ function readBlockString(source, start, line, col, prev): Token {
);
}

// Escape Triple-Quote (\""")
if (
if (code === 10) {
// new line
++position;
++lexer.line;
lexer.lineStart = position;
} else if (code === 13) {
// carriage return
if (charCodeAt.call(body, position + 1) === 10) {
position += 2;
} else {
++position;
}
++lexer.line;
lexer.lineStart = position;
} else if (
// Escape Triple-Quote (\""")
code === 92 &&
charCodeAt.call(body, position + 1) === 34 &&
charCodeAt.call(body, position + 2) === 34 &&
Expand Down

0 comments on commit 42db579

Please sign in to comment.