JS: Fix value of numeric literals containing underscores

This commit is contained in:
Asger Feldthaus
2020-04-01 12:24:42 +01:00
parent 9888f15a29
commit b5e110e39e
6 changed files with 134 additions and 4 deletions

View File

@@ -482,6 +482,7 @@ public class ESNextParser extends JSXParser {
if (code == '_') {
if (underscoreAllowed) {
seenUnderscoreNumericSeparator = true;
// no adjacent underscores
underscoreAllowed = false;
++this.pos;

View File

@@ -145,6 +145,11 @@ public class Parser {
private Stack<LabelInfo> labels;
protected int yieldPos, awaitPos;
/**
* Set to true by {@link ESNextParser#readInt} if the parsed integer contains an underscore.
*/
protected boolean seenUnderscoreNumericSeparator = false;
/**
* For readability purposes, we pass this instead of false as the argument to the
* hasDeclareKeyword parameter (which only exists in TypeScript).
@@ -654,7 +659,7 @@ public class Parser {
case 58:
++this.pos;
return this.finishToken(TokenType.colon);
case 35:
case 35:
++this.pos;
return this.finishToken(TokenType.pound);
case 63:
@@ -847,6 +852,10 @@ public class Parser {
}
String str = inputSubstring(start, this.pos);
if (seenUnderscoreNumericSeparator) {
str = str.replace("_", "");
seenUnderscoreNumericSeparator = false;
}
Number val = null;
if (isFloat) val = parseFloat(str);
else if (!octal || str.length() == 1) val = parseInt(str, 10);

View File

@@ -25,8 +25,98 @@ getIntValue
| tst.js:47:5:47:5 | 1 | 1 |
| tst.js:48:7:48:7 | 1 | 1 |
| tst.js:49:6:49:6 | 1 | 1 |
| tst.js:52:5:52:9 | 1_000 | 1 |
| tst.js:53:5:53:13 | 1_000_123 | 1 |
| tst.js:52:5:52:9 | 1_000 | 1000 |
| tst.js:53:5:53:13 | 1_000_123 | 1000123 |
| tst.js:54:5:54:17 | 1_000_000_000 | 1000000000 |
| tst.js:56:5:56:10 | 123_00 | 12300 |
| tst.js:57:5:57:10 | 12_300 | 12300 |
| tst.js:58:5:58:12 | 12345_00 | 1234500 |
| tst.js:59:5:59:12 | 123_4500 | 1234500 |
| tst.js:60:5:60:13 | 1_234_500 | 1234500 |
| tst.js:62:5:62:14 | 0xaa_bb_cc | 11189196 |
getFloatValue
| tst2.ts:1:21:1:21 | 1 | 1.0 |
| tst.js:6:1:6:1 | 1 | 1.0 |
| tst.js:11:2:11:2 | 1 | 1.0 |
| tst.js:12:2:12:2 | 0 | 0.0 |
| tst.js:26:3:26:3 | 0 | 0.0 |
| tst.js:29:6:29:6 | 0 | 0.0 |
| tst.js:35:1:35:1 | 1 | 1.0 |
| tst.js:35:5:35:5 | 2 | 2.0 |
| tst.js:35:9:35:9 | 3 | 3.0 |
| tst.js:37:2:37:2 | 1 | 1.0 |
| tst.js:39:4:39:4 | 1 | 1.0 |
| tst.js:40:1:40:1 | 1 | 1.0 |
| tst.js:42:1:42:1 | 1 | 1.0 |
| tst.js:42:4:42:4 | 2 | 2.0 |
| tst.js:42:7:42:7 | 3 | 3.0 |
| tst.js:43:4:43:4 | 2 | 2.0 |
| tst.js:43:7:43:7 | 3 | 3.0 |
| tst.js:44:1:44:1 | 1 | 1.0 |
| tst.js:44:7:44:7 | 3 | 3.0 |
| tst.js:45:1:45:1 | 1 | 1.0 |
| tst.js:45:4:45:4 | 2 | 2.0 |
| tst.js:47:5:47:5 | 1 | 1.0 |
| tst.js:48:7:48:7 | 1 | 1.0 |
| tst.js:49:6:49:6 | 1 | 1.0 |
| tst.js:52:5:52:9 | 1_000 | 1000.0 |
| tst.js:53:5:53:13 | 1_000_123 | 1000123.0 |
| tst.js:54:5:54:17 | 1_000_000_000 | 1.0E9 |
| tst.js:55:5:55:18 | 101_475_938.38 | 1.0147593838E8 |
| tst.js:56:5:56:10 | 123_00 | 12300.0 |
| tst.js:57:5:57:10 | 12_300 | 12300.0 |
| tst.js:58:5:58:12 | 12345_00 | 1234500.0 |
| tst.js:59:5:59:12 | 123_4500 | 1234500.0 |
| tst.js:60:5:60:13 | 1_234_500 | 1234500.0 |
| tst.js:61:5:61:10 | 1e1_00 | 1.0E100 |
| tst.js:62:5:62:14 | 0xaa_bb_cc | 1.1189196E7 |
getLiteralValue
| tst2.ts:1:21:1:21 | 1 | 1 |
| tst.js:1:1:1:3 | "a" | a |
| tst.js:2:1:2:3 | "b" | b |
| tst.js:2:7:2:9 | "c" | c |
| tst.js:3:1:3:3 | "d" | d |
| tst.js:3:7:3:9 | "e" | e |
| tst.js:3:13:3:15 | "f" | f |
| tst.js:6:1:6:1 | 1 | 1 |
| tst.js:8:1:8:5 | false | false |
| tst.js:9:1:9:4 | true | true |
| tst.js:11:2:11:2 | 1 | 1 |
| tst.js:12:2:12:2 | 0 | 0 |
| tst.js:14:1:14:4 | null | null |
| tst.js:20:1:20:3 | /x/ | /x/ |
| tst.js:24:5:24:7 | "x" | x |
| tst.js:26:3:26:3 | 0 | 0 |
| tst.js:29:6:29:6 | 0 | 0 |
| tst.js:35:1:35:1 | 1 | 1 |
| tst.js:35:5:35:5 | 2 | 2 |
| tst.js:35:9:35:9 | 3 | 3 |
| tst.js:37:2:37:2 | 1 | 1 |
| tst.js:39:4:39:4 | 1 | 1 |
| tst.js:40:1:40:1 | 1 | 1 |
| tst.js:42:1:42:1 | 1 | 1 |
| tst.js:42:4:42:4 | 2 | 2 |
| tst.js:42:7:42:7 | 3 | 3 |
| tst.js:43:4:43:4 | 2 | 2 |
| tst.js:43:7:43:7 | 3 | 3 |
| tst.js:44:1:44:1 | 1 | 1 |
| tst.js:44:7:44:7 | 3 | 3 |
| tst.js:45:1:45:1 | 1 | 1 |
| tst.js:45:4:45:4 | 2 | 2 |
| tst.js:47:5:47:5 | 1 | 1 |
| tst.js:48:7:48:7 | 1 | 1 |
| tst.js:49:6:49:6 | 1 | 1 |
| tst.js:52:5:52:9 | 1_000 | 1000 |
| tst.js:53:5:53:13 | 1_000_123 | 1000123 |
| tst.js:54:5:54:17 | 1_000_000_000 | 1000000000 |
| tst.js:55:5:55:18 | 101_475_938.38 | 1.0147593838E8 |
| tst.js:56:5:56:10 | 123_00 | 12300 |
| tst.js:57:5:57:10 | 12_300 | 12300 |
| tst.js:58:5:58:12 | 12345_00 | 1234500 |
| tst.js:59:5:59:12 | 123_4500 | 1234500 |
| tst.js:60:5:60:13 | 1_234_500 | 1234500 |
| tst.js:61:5:61:10 | 1e1_00 | 1.0E100 |
| tst.js:62:5:62:14 | 0xaa_bb_cc | 11189196 |
#select
| tst2.ts:1:13:1:21 | <number>1 |
| tst2.ts:1:21:1:21 | 1 |
@@ -95,3 +185,21 @@ getIntValue
| tst.js:52:5:52:9 | 1_000 |
| tst.js:53:1:53:13 | x = 1_000_123 |
| tst.js:53:5:53:13 | 1_000_123 |
| tst.js:54:1:54:17 | x = 1_000_000_000 |
| tst.js:54:5:54:17 | 1_000_000_000 |
| tst.js:55:1:55:18 | x = 101_475_938.38 |
| tst.js:55:5:55:18 | 101_475_938.38 |
| tst.js:56:1:56:10 | x = 123_00 |
| tst.js:56:5:56:10 | 123_00 |
| tst.js:57:1:57:10 | x = 12_300 |
| tst.js:57:5:57:10 | 12_300 |
| tst.js:58:1:58:12 | x = 12345_00 |
| tst.js:58:5:58:12 | 12345_00 |
| tst.js:59:1:59:12 | x = 123_4500 |
| tst.js:59:5:59:12 | 123_4500 |
| tst.js:60:1:60:13 | x = 1_234_500 |
| tst.js:60:5:60:13 | 1_234_500 |
| tst.js:61:1:61:10 | x = 1e1_00 |
| tst.js:61:5:61:10 | 1e1_00 |
| tst.js:62:1:62:14 | x = 0xaa_bb_cc |
| tst.js:62:5:62:14 | 0xaa_bb_cc |

View File

@@ -4,3 +4,7 @@ from ConstantExpr c
select c
query int getIntValue(Expr e) { result = e.getIntValue() }
query float getFloatValue(NumberLiteral e) { result = e.getFloatValue() }
query string getLiteralValue(Literal lit) { result = lit.getValue() }

View File

@@ -51,3 +51,12 @@ x += x;
x = 1_000;
x = 1_000_123;
x = 1_000_000_000;
x = 101_475_938.38;
x = 123_00;
x = 12_300;
x = 12345_00;
x = 123_4500;
x = 1_234_500;
x = 1e1_00;
x = 0xaa_bb_cc;

View File

@@ -1 +0,0 @@
| constants.js:12:27:12:31 | // OK | Error: analysis claims x >= 1_000 is always false |