Skip to content

Commit 1c5dcc9

Browse files
committed
RFC: Number lexer lookahead restriction
Implements and adds the tests described by graphql/graphql-spec#601
1 parent d73ad97 commit 1c5dcc9

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

src/language/__tests__/lexer-test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,41 @@ describe('Lexer', () => {
708708
);
709709
});
710710

711+
it('lex does not allow name-start after a number', () => {
712+
expectSyntaxError('0xF1', 'Invalid number, expected digit but got: "x".', {
713+
line: 1,
714+
column: 2,
715+
});
716+
expectSyntaxError('0b10', 'Invalid number, expected digit but got: "b".', {
717+
line: 1,
718+
column: 2,
719+
});
720+
expectSyntaxError(
721+
'123abc',
722+
'Invalid number, expected digit but got: "a".',
723+
{ line: 1, column: 4 },
724+
);
725+
expectSyntaxError('1_234', 'Invalid number, expected digit but got: "_".', {
726+
line: 1,
727+
column: 2,
728+
});
729+
expect(() => lexSecond('1ß')).to.throw(
730+
'Syntax Error: Cannot parse the unexpected character "\\u00DF".',
731+
);
732+
expectSyntaxError('1.23f', 'Invalid number, expected digit but got: "f".', {
733+
line: 1,
734+
column: 5,
735+
});
736+
expectSyntaxError(
737+
'1.234_5',
738+
'Invalid number, expected digit but got: "_".',
739+
{ line: 1, column: 6 },
740+
);
741+
expect(() => lexSecond('1.2ß')).to.throw(
742+
'Syntax Error: Cannot parse the unexpected character "\\u00DF".',
743+
);
744+
});
745+
711746
it('lexes punctuation', () => {
712747
expect(lexOne('!')).to.contain({
713748
kind: TokenKind.BANG,

src/language/lexer.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,8 @@ function readNumber(source, start, firstCode, line, col, prev): Token {
447447
code = body.charCodeAt(position);
448448
}
449449
450-
// Numbers cannot be followed by . or e
451-
if (code === 46 || code === 69 || code === 101) {
450+
// Numbers cannot be followed by . or NameStart
451+
if (code === 46 || isNameStart(code)) {
452452
throw syntaxError(
453453
source,
454454
position,
@@ -738,3 +738,10 @@ function readName(source, start, line, col, prev): Token {
738738
body.slice(start, position),
739739
);
740740
}
741+
742+
// _ A-Z a-z
743+
function isNameStart(code): boolean {
744+
return (
745+
code === 95 || (code >= 65 && code <= 90) || (code >= 97 && code <= 122)
746+
);
747+
}

0 commit comments

Comments
 (0)