Skip to content

Commit 76515dc

Browse files
committed
improve errors around around dots (#4176)
extracted from @leebyron 's excellent #3807 will reduce that diff
1 parent 8a85a69 commit 76515dc

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

src/language/__tests__/lexer-test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ describe('Lexer', () => {
165165
});
166166
});
167167

168+
it('reports unexpected characters', () => {
169+
expectSyntaxError('.').to.deep.equal({
170+
message: 'Syntax Error: Unexpected character: ".".',
171+
locations: [{ line: 1, column: 1 }],
172+
});
173+
});
174+
168175
it('errors respect whitespace', () => {
169176
let caughtError;
170177
try {
@@ -852,7 +859,8 @@ describe('Lexer', () => {
852859
});
853860

854861
expectSyntaxError('.123').to.deep.equal({
855-
message: 'Syntax Error: Unexpected character: ".".',
862+
message:
863+
'Syntax Error: Invalid number, expected digit before ".", did you mean "0.123"?',
856864
locations: [{ line: 1, column: 1 }],
857865
});
858866

@@ -1030,7 +1038,7 @@ describe('Lexer', () => {
10301038

10311039
it('lex reports useful unknown character error', () => {
10321040
expectSyntaxError('..').to.deep.equal({
1033-
message: 'Syntax Error: Unexpected character: ".".',
1041+
message: 'Syntax Error: Unexpected "..", did you mean "..."?',
10341042
locations: [{ line: 1, column: 1 }],
10351043
});
10361044

src/language/lexer.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,14 +282,31 @@ function readNextToken(lexer: Lexer, start: number): Token {
282282
return createToken(lexer, TokenKind.PAREN_L, position, position + 1);
283283
case 0x0029: // )
284284
return createToken(lexer, TokenKind.PAREN_R, position, position + 1);
285-
case 0x002e: // .
286-
if (
287-
body.charCodeAt(position + 1) === 0x002e &&
288-
body.charCodeAt(position + 2) === 0x002e
289-
) {
285+
case 0x002e: {
286+
// .
287+
const nextCode = body.charCodeAt(position + 1);
288+
if (nextCode === 0x002e && body.charCodeAt(position + 2) === 0x002e) {
290289
return createToken(lexer, TokenKind.SPREAD, position, position + 3);
291290
}
291+
if (nextCode === 0x002e) {
292+
throw syntaxError(
293+
lexer.source,
294+
position,
295+
'Unexpected "..", did you mean "..."?',
296+
);
297+
} else if (isDigit(nextCode)) {
298+
const digits = lexer.source.body.slice(
299+
position + 1,
300+
readDigits(lexer, position + 1, nextCode),
301+
);
302+
throw syntaxError(
303+
lexer.source,
304+
position,
305+
`Invalid number, expected digit before ".", did you mean "0.${digits}"?`,
306+
);
307+
}
292308
break;
309+
}
293310
case 0x003a: // :
294311
return createToken(lexer, TokenKind.COLON, position, position + 1);
295312
case 0x003d: // =

0 commit comments

Comments
 (0)