Skip to content

Commit

Permalink
fix: Reject identifier or keyword immediately following a numeric lit…
Browse files Browse the repository at this point in the history
…eral (#1662)
  • Loading branch information
dcodeIO committed Feb 3, 2021
1 parent 4dc6567 commit 7a46aa9
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/diagnosticMessages.generated.ts
Expand Up @@ -116,6 +116,7 @@ export enum DiagnosticCode {
A_definite_assignment_assertion_is_not_permitted_in_this_context = 1255,
A_class_may_only_extend_another_class = 1311,
A_parameter_property_cannot_be_declared_using_a_rest_parameter = 1317,
An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal = 1351,
Duplicate_identifier_0 = 2300,
Cannot_find_name_0 = 2304,
Module_0_has_no_exported_member_1 = 2305,
Expand Down Expand Up @@ -295,6 +296,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
case 1255: return "A definite assignment assertion '!' is not permitted in this context.";
case 1311: return "A class may only extend another class.";
case 1317: return "A parameter property cannot be declared using a rest parameter.";
case 1351: return "An identifier or keyword cannot immediately follow a numeric literal.";
case 2300: return "Duplicate identifier '{0}'.";
case 2304: return "Cannot find name '{0}'.";
case 2305: return "Module '{0}' has no exported member '{1}'.";
Expand Down
1 change: 1 addition & 0 deletions src/diagnosticMessages.json
Expand Up @@ -111,6 +111,7 @@
"A definite assignment assertion '!' is not permitted in this context.": 1255,
"A class may only extend another class.": 1311,
"A parameter property cannot be declared using a rest parameter.": 1317,
"An identifier or keyword cannot immediately follow a numeric literal.": 1351,

"Duplicate identifier '{0}'.": 2300,
"Cannot find name '{0}'.": 2304,
Expand Down
12 changes: 10 additions & 2 deletions src/parser.ts
Expand Up @@ -3800,10 +3800,14 @@ export class Parser extends DiagnosticEmitter {
return Node.createStringLiteralExpression(tn.readString(), tn.range(startPos, tn.pos));
}
case Token.INTEGERLITERAL: {
return Node.createIntegerLiteralExpression(tn.readInteger(), tn.range(startPos, tn.pos));
let value = tn.readInteger();
tn.checkForIdentifierStartAfterNumericLiteral();
return Node.createIntegerLiteralExpression(value, tn.range(startPos, tn.pos));
}
case Token.FLOATLITERAL: {
return Node.createFloatLiteralExpression(tn.readFloat(), tn.range(startPos, tn.pos));
let value = tn.readFloat();
tn.checkForIdentifierStartAfterNumericLiteral();
return Node.createFloatLiteralExpression(value, tn.range(startPos, tn.pos));
}
// RegexpLiteralExpression
// note that this also continues on invalid ones so the surrounding AST remains intact
Expand Down Expand Up @@ -4207,10 +4211,12 @@ export class Parser extends DiagnosticEmitter {
}
case Token.INTEGERLITERAL: {
tn.readInteger();
tn.checkForIdentifierStartAfterNumericLiteral();
break;
}
case Token.FLOATLITERAL: {
tn.readFloat();
tn.checkForIdentifierStartAfterNumericLiteral();
break;
}
case Token.OPENBRACE: {
Expand Down Expand Up @@ -4255,10 +4261,12 @@ export class Parser extends DiagnosticEmitter {
}
case Token.INTEGERLITERAL: {
tn.readInteger();
tn.checkForIdentifierStartAfterNumericLiteral();
break;
}
case Token.FLOATLITERAL: {
tn.readFloat();
tn.checkForIdentifierStartAfterNumericLiteral();
break;
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/tokenizer.ts
Expand Up @@ -1611,6 +1611,17 @@ export class Tokenizer extends DiagnosticEmitter {
return String.fromCharCode(value);
}

checkForIdentifierStartAfterNumericLiteral(): void {
// TODO: BigInt n
var pos = this.pos;
if (pos < this.end && isIdentifierStart(this.source.text.charCodeAt(pos))) {
this.error(
DiagnosticCode.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal,
this.range(pos)
);
}
}

readUnicodeEscape(): string {
return this.readHexadecimalEscape(4);
}
Expand Down
16 changes: 16 additions & 0 deletions tests/parser/literals.ts
Expand Up @@ -60,3 +60,19 @@
"1\"23";
"1\"2\\3";
"\0\n\\n\r";

// invalid
1..;
3u8;
4b;
5-;
6=;
7_;
1.a;
2.0b;

// technically invalid, but not handled by AS yet, TS1005: ';' expected
3 4;
5 c;
6.7 d;
a b;
22 changes: 22 additions & 0 deletions tests/parser/literals.ts.fixture.ts
Expand Up @@ -60,3 +60,25 @@
"1\"23";
"1\"2\\3";
"\0\n\\n\r";
4;
b;
7;
1;
a;
2;
b;
3;
4;
5;
c;
6.7;
d;
a;
b;
// ERROR 1109: "Expression expected." in literals.ts(65,4+1)
// ERROR 1351: "An identifier or keyword cannot immediately follow a numeric literal." in literals.ts(66,2+0)
// ERROR 1351: "An identifier or keyword cannot immediately follow a numeric literal." in literals.ts(67,2+0)
// ERROR 1109: "Expression expected." in literals.ts(68,3+1)
// ERROR 6188: "Numeric separators are not allowed here." in literals.ts(70,2+0)
// ERROR 1351: "An identifier or keyword cannot immediately follow a numeric literal." in literals.ts(71,3+0)
// ERROR 1351: "An identifier or keyword cannot immediately follow a numeric literal." in literals.ts(72,4+0)

0 comments on commit 7a46aa9

Please sign in to comment.