Skip to content

Commit 20249e5

Browse files
committed
More exhaustive needsDotDotForPropertyAccess
1 parent ceb5fac commit 20249e5

10 files changed

+199
-5
lines changed

src/compiler/emitter.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,9 +1054,11 @@ namespace ts {
10541054
// Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal
10551055
function needsDotDotForPropertyAccess(expression: Expression) {
10561056
if (expression.kind === SyntaxKind.NumericLiteral) {
1057-
// check if numeric literal was originally written with a dot
1057+
// check if numeric literal is a decimal literal that was originally written with a dot
10581058
const text = getLiteralTextOfNode(<LiteralExpression>expression);
1059-
return text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0;
1059+
return getNumericLiteralFlags(text, /*hint*/ NumericLiteralFlags.All) === NumericLiteralFlags.None
1060+
&& !(<LiteralExpression>expression).isOctalLiteral
1061+
&& text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0;
10601062
}
10611063
else if (isPropertyAccessExpression(expression) || isElementAccessExpression(expression)) {
10621064
// check if constant enum value is integer

src/compiler/utilities.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,16 +341,52 @@ namespace ts {
341341
}
342342

343343
export function isBinaryOrOctalIntegerLiteral(node: LiteralLikeNode, text: string) {
344-
if (node.kind === SyntaxKind.NumericLiteral && text.length > 1) {
344+
return node.kind === SyntaxKind.NumericLiteral
345+
&& (getNumericLiteralFlags(text, /*hint*/ NumericLiteralFlags.BinaryOrOctal) & NumericLiteralFlags.BinaryOrOctal) !== 0;
346+
}
347+
348+
export const enum NumericLiteralFlags {
349+
None = 0,
350+
Hexadecimal = 1 << 0,
351+
Binary = 1 << 1,
352+
Octal = 1 << 2,
353+
Scientific = 1 << 3,
354+
355+
BinaryOrOctal = Binary | Octal,
356+
BinaryOrOctalOrHexadecimal = BinaryOrOctal | Hexadecimal,
357+
All = Hexadecimal | Binary | Octal | Scientific,
358+
}
359+
360+
/**
361+
* Scans a numeric literal string to determine the form of the number.
362+
* @param text Numeric literal text
363+
* @param hint If `Scientific` or `All` is specified, performs a more expensive check to scan for scientific notation.
364+
*/
365+
export function getNumericLiteralFlags(text: string, hint?: NumericLiteralFlags) {
366+
if (text.length > 1) {
345367
switch (text.charCodeAt(1)) {
346368
case CharacterCodes.b:
347369
case CharacterCodes.B:
370+
return NumericLiteralFlags.Binary;
348371
case CharacterCodes.o:
349372
case CharacterCodes.O:
350-
return true;
373+
return NumericLiteralFlags.Octal;
374+
case CharacterCodes.x:
375+
case CharacterCodes.X:
376+
return NumericLiteralFlags.Hexadecimal;
377+
}
378+
379+
if (hint & NumericLiteralFlags.Scientific) {
380+
for (let i = text.length - 1; i >= 0; i--) {
381+
switch (text.charCodeAt(i)) {
382+
case CharacterCodes.e:
383+
case CharacterCodes.E:
384+
return NumericLiteralFlags.Scientific;
385+
}
386+
}
351387
}
352388
}
353-
return false;
389+
return NumericLiteralFlags.None;
354390
}
355391

356392
function getQuotedEscapedLiteralText(leftQuote: string, text: string, rightQuote: string) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//// [propertyAccessNumericLiterals.es6.ts]
2+
0xffffffff.toString();
3+
0o01234.toString();
4+
0b01101101.toString();
5+
1234..toString();
6+
1e0.toString();
7+
8+
9+
//// [propertyAccessNumericLiterals.es6.js]
10+
0xffffffff.toString();
11+
0o01234.toString();
12+
0b01101101.toString();
13+
1234..toString();
14+
1e0.toString();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
=== tests/cases/conformance/es6/propertyAccess/propertyAccessNumericLiterals.es6.ts ===
2+
0xffffffff.toString();
3+
>0xffffffff.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
4+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
5+
6+
0o01234.toString();
7+
>0o01234.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
8+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
9+
10+
0b01101101.toString();
11+
>0b01101101.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
12+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
13+
14+
1234..toString();
15+
>1234..toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
16+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
17+
18+
1e0.toString();
19+
>1e0.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
20+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
21+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
=== tests/cases/conformance/es6/propertyAccess/propertyAccessNumericLiterals.es6.ts ===
2+
0xffffffff.toString();
3+
>0xffffffff.toString() : string
4+
>0xffffffff.toString : (radix?: number) => string
5+
>0xffffffff : 4294967295
6+
>toString : (radix?: number) => string
7+
8+
0o01234.toString();
9+
>0o01234.toString() : string
10+
>0o01234.toString : (radix?: number) => string
11+
>0o01234 : 668
12+
>toString : (radix?: number) => string
13+
14+
0b01101101.toString();
15+
>0b01101101.toString() : string
16+
>0b01101101.toString : (radix?: number) => string
17+
>0b01101101 : 109
18+
>toString : (radix?: number) => string
19+
20+
1234..toString();
21+
>1234..toString() : string
22+
>1234..toString : (radix?: number) => string
23+
>1234. : 1234
24+
>toString : (radix?: number) => string
25+
26+
1e0.toString();
27+
>1e0.toString() : string
28+
>1e0.toString : (radix?: number) => string
29+
>1e0 : 1
30+
>toString : (radix?: number) => string
31+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [propertyAccessNumericLiterals.ts]
2+
0xffffffff.toString();
3+
0o01234.toString();
4+
0b01101101.toString();
5+
1234..toString();
6+
1e0.toString();
7+
000.toString();
8+
9+
//// [propertyAccessNumericLiterals.js]
10+
0xffffffff.toString();
11+
668..toString();
12+
109..toString();
13+
1234..toString();
14+
1e0.toString();
15+
000.toString();
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
=== tests/cases/conformance/expressions/propertyAccess/propertyAccessNumericLiterals.ts ===
2+
0xffffffff.toString();
3+
>0xffffffff.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
4+
>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
5+
6+
0o01234.toString();
7+
>0o01234.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
8+
>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
9+
10+
0b01101101.toString();
11+
>0b01101101.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
12+
>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
13+
14+
1234..toString();
15+
>1234..toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
16+
>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
17+
18+
1e0.toString();
19+
>1e0.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
20+
>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
21+
22+
000.toString();
23+
>000.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
24+
>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --))
25+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
=== tests/cases/conformance/expressions/propertyAccess/propertyAccessNumericLiterals.ts ===
2+
0xffffffff.toString();
3+
>0xffffffff.toString() : string
4+
>0xffffffff.toString : (radix?: number) => string
5+
>0xffffffff : 4294967295
6+
>toString : (radix?: number) => string
7+
8+
0o01234.toString();
9+
>0o01234.toString() : string
10+
>0o01234.toString : (radix?: number) => string
11+
>0o01234 : 668
12+
>toString : (radix?: number) => string
13+
14+
0b01101101.toString();
15+
>0b01101101.toString() : string
16+
>0b01101101.toString : (radix?: number) => string
17+
>0b01101101 : 109
18+
>toString : (radix?: number) => string
19+
20+
1234..toString();
21+
>1234..toString() : string
22+
>1234..toString : (radix?: number) => string
23+
>1234. : 1234
24+
>toString : (radix?: number) => string
25+
26+
1e0.toString();
27+
>1e0.toString() : string
28+
>1e0.toString : (radix?: number) => string
29+
>1e0 : 1
30+
>toString : (radix?: number) => string
31+
32+
000.toString();
33+
>000.toString() : string
34+
>000.toString : (radix?: number) => string
35+
>000 : 0
36+
>toString : (radix?: number) => string
37+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// @target: es6
2+
0xffffffff.toString();
3+
0o01234.toString();
4+
0b01101101.toString();
5+
1234..toString();
6+
1e0.toString();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @target: es3
2+
0xffffffff.toString();
3+
0o01234.toString();
4+
0b01101101.toString();
5+
1234..toString();
6+
1e0.toString();
7+
000.toString();

0 commit comments

Comments
 (0)