@nativescript/core 9.1.4-next.0 → 9.2.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/application/application.ios.js +60 -96
- package/application/application.ios.js.map +1 -1
- package/application/scene-delegate-bridge.d.ts +1 -6
- package/application/scene-delegate-bridge.js +0 -16
- package/application/scene-delegate-bridge.js.map +1 -1
- package/config/config.interface.d.ts +46 -0
- package/fetch/index.d.ts +79 -0
- package/fetch/index.js +408 -0
- package/fetch/index.js.map +1 -0
- package/globals/index.js +1 -1
- package/globals/index.js.map +1 -1
- package/http/http-request-internal/index.ios.js +25 -12
- package/http/http-request-internal/index.ios.js.map +1 -1
- package/image-source/index.ios.js +6 -6
- package/image-source/index.ios.js.map +1 -1
- package/js-libs/easysax/easysax.d.ts +49 -7
- package/js-libs/easysax/easysax.js +631 -747
- package/js-libs/easysax/easysax.js.map +1 -0
- package/module-name-resolver/helpers.d.ts +1 -1
- package/module-name-resolver/index.d.ts +2 -2
- package/package.json +1 -1
- package/ui/animation/index.ios.js +2 -1
- package/ui/animation/index.ios.js.map +1 -1
- package/ui/builder/component-builder/index.d.ts +4 -4
- package/ui/builder/component-builder/index.js +1 -0
- package/ui/builder/component-builder/index.js.map +1 -1
- package/ui/builder/index.js.map +1 -1
- package/ui/core/bindable/expression-parser.d.ts +29 -0
- package/ui/core/bindable/expression-parser.js +2518 -0
- package/ui/core/bindable/expression-parser.js.map +1 -0
- package/ui/core/bindable/index.d.ts +1 -1
- package/ui/core/bindable/index.js.map +1 -1
- package/ui/core/properties/index.js +1 -0
- package/ui/core/properties/index.js.map +1 -1
- package/ui/core/view/index.android.js +12 -7
- package/ui/core/view/index.android.js.map +1 -1
- package/ui/dialogs/index.ios.js +1 -1
- package/ui/dialogs/index.ios.js.map +1 -1
- package/ui/gestures/index.ios.js +6 -6
- package/ui/gestures/index.ios.js.map +1 -1
- package/ui/segmented-bar/index.android.d.ts +3 -1
- package/ui/segmented-bar/index.android.js +72 -2
- package/ui/segmented-bar/index.android.js.map +1 -1
- package/ui/segmented-bar/index.d.ts +15 -0
- package/ui/segmented-bar/segmented-bar-common.d.ts +2 -0
- package/ui/segmented-bar/segmented-bar-common.js +5 -0
- package/ui/segmented-bar/segmented-bar-common.js.map +1 -1
- package/ui/styling/background-common.js +2 -2
- package/ui/styling/background-common.js.map +1 -1
- package/ui/styling/background.d.ts +1 -1
- package/ui/styling/background.ios.d.ts +1 -1
- package/ui/styling/background.ios.js +1 -1
- package/ui/styling/background.ios.js.map +1 -1
- package/ui/styling/style/index.d.ts +2 -2
- package/ui/styling/style/index.js.map +1 -1
- package/ui/tab-view/index.android.d.ts +5 -0
- package/ui/tab-view/index.android.js +84 -11
- package/ui/tab-view/index.android.js.map +1 -1
- package/ui/tab-view/index.d.ts +14 -0
- package/ui/tab-view/index.ios.js +2 -2
- package/ui/tab-view/index.ios.js.map +1 -1
- package/ui/tab-view/tab-navigation.android.d.ts +63 -0
- package/ui/tab-view/tab-navigation.android.js +380 -0
- package/ui/tab-view/tab-navigation.android.js.map +1 -0
- package/ui/tab-view/tab-view-common.d.ts +2 -0
- package/ui/tab-view/tab-view-common.js +5 -0
- package/ui/tab-view/tab-view-common.js.map +1 -1
- package/ui/text-base/index.ios.js +1 -1
- package/ui/text-base/index.ios.js.map +1 -1
- package/utils/native-helper-for-android.js +3 -1
- package/utils/native-helper-for-android.js.map +1 -1
- package/xhr/index.d.ts +5 -4
- package/xhr/index.js +14 -14
- package/xhr/index.js.map +1 -1
- package/xml/index.d.ts +2 -2
- package/fetch/index.mjs +0 -535
|
@@ -0,0 +1,2518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses binding expression text into the ESTree nodes that
|
|
3
|
+
* `acorn.parse(text, { ecmaVersion: 2020 })` produces (script source type,
|
|
4
|
+
* no locations, no preserved parens), positions and `raw` included.
|
|
5
|
+
*
|
|
6
|
+
* It mirrors acorn 8.15's structure (tokenizer contexts for regexp/division
|
|
7
|
+
* detection, destructuring error tracking, statement-level ASI) because
|
|
8
|
+
* equivalence depends on those details, not just on the grammar.
|
|
9
|
+
*
|
|
10
|
+
* Constructs that need statement lists or function bodies throw an
|
|
11
|
+
* "Unsupported" SyntaxError where acorn would parse them: statements other
|
|
12
|
+
* than expression, empty, block, labeled and `debugger` statements; function
|
|
13
|
+
* and class expressions; object methods, getters and setters; arrow
|
|
14
|
+
* functions with block bodies.
|
|
15
|
+
*/
|
|
16
|
+
const BEFORE_EXPR = 1;
|
|
17
|
+
const STARTS_EXPR = 2;
|
|
18
|
+
const IS_ASSIGN = 4;
|
|
19
|
+
const PREFIX = 8;
|
|
20
|
+
const POSTFIX = 16;
|
|
21
|
+
class TokenType {
|
|
22
|
+
constructor(label, flags, binop, keyword) {
|
|
23
|
+
this.label = label;
|
|
24
|
+
this.keyword = keyword;
|
|
25
|
+
this.beforeExpr = (flags & BEFORE_EXPR) !== 0;
|
|
26
|
+
this.startsExpr = (flags & STARTS_EXPR) !== 0;
|
|
27
|
+
this.isAssign = (flags & IS_ASSIGN) !== 0;
|
|
28
|
+
this.prefix = (flags & PREFIX) !== 0;
|
|
29
|
+
this.postfix = (flags & POSTFIX) !== 0;
|
|
30
|
+
this.binop = binop;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const keywordTypes = new Map();
|
|
34
|
+
function tok(label, flags) {
|
|
35
|
+
return new TokenType(label, flags, -1, '');
|
|
36
|
+
}
|
|
37
|
+
function binop(label, prec) {
|
|
38
|
+
return new TokenType(label, BEFORE_EXPR, prec, '');
|
|
39
|
+
}
|
|
40
|
+
function kw(name, flags, prec) {
|
|
41
|
+
const type = new TokenType(name, flags, prec, name);
|
|
42
|
+
keywordTypes.set(name, type);
|
|
43
|
+
return type;
|
|
44
|
+
}
|
|
45
|
+
const tt = {
|
|
46
|
+
num: tok('num', STARTS_EXPR),
|
|
47
|
+
regexp: tok('regexp', STARTS_EXPR),
|
|
48
|
+
string: tok('string', STARTS_EXPR),
|
|
49
|
+
name: tok('name', STARTS_EXPR),
|
|
50
|
+
privateId: tok('privateId', STARTS_EXPR),
|
|
51
|
+
eof: tok('eof', 0),
|
|
52
|
+
bracketL: tok('[', BEFORE_EXPR | STARTS_EXPR),
|
|
53
|
+
bracketR: tok(']', 0),
|
|
54
|
+
braceL: tok('{', BEFORE_EXPR | STARTS_EXPR),
|
|
55
|
+
braceR: tok('}', 0),
|
|
56
|
+
parenL: tok('(', BEFORE_EXPR | STARTS_EXPR),
|
|
57
|
+
parenR: tok(')', 0),
|
|
58
|
+
comma: tok(',', BEFORE_EXPR),
|
|
59
|
+
semi: tok(';', BEFORE_EXPR),
|
|
60
|
+
colon: tok(':', BEFORE_EXPR),
|
|
61
|
+
dot: tok('.', 0),
|
|
62
|
+
question: tok('?', BEFORE_EXPR),
|
|
63
|
+
questionDot: tok('?.', 0),
|
|
64
|
+
arrow: tok('=>', BEFORE_EXPR),
|
|
65
|
+
template: tok('template', 0),
|
|
66
|
+
invalidTemplate: tok('invalidTemplate', 0),
|
|
67
|
+
ellipsis: tok('...', BEFORE_EXPR),
|
|
68
|
+
backQuote: tok('`', STARTS_EXPR),
|
|
69
|
+
dollarBraceL: tok('${', BEFORE_EXPR | STARTS_EXPR),
|
|
70
|
+
eq: tok('=', BEFORE_EXPR | IS_ASSIGN),
|
|
71
|
+
assign: tok('_=', BEFORE_EXPR | IS_ASSIGN),
|
|
72
|
+
incDec: tok('++/--', PREFIX | POSTFIX | STARTS_EXPR),
|
|
73
|
+
prefix: tok('!/~', BEFORE_EXPR | PREFIX | STARTS_EXPR),
|
|
74
|
+
logicalOR: binop('||', 1),
|
|
75
|
+
logicalAND: binop('&&', 2),
|
|
76
|
+
bitwiseOR: binop('|', 3),
|
|
77
|
+
bitwiseXOR: binop('^', 4),
|
|
78
|
+
bitwiseAND: binop('&', 5),
|
|
79
|
+
equality: binop('==/!=/===/!==', 6),
|
|
80
|
+
relational: binop('</>/<=/>=', 7),
|
|
81
|
+
bitShift: binop('<</>>/>>>', 8),
|
|
82
|
+
plusMin: new TokenType('+/-', BEFORE_EXPR | PREFIX | STARTS_EXPR, 9, ''),
|
|
83
|
+
modulo: binop('%', 10),
|
|
84
|
+
star: binop('*', 10),
|
|
85
|
+
slash: binop('/', 10),
|
|
86
|
+
starstar: tok('**', BEFORE_EXPR),
|
|
87
|
+
coalesce: binop('??', 1),
|
|
88
|
+
_break: kw('break', 0, -1),
|
|
89
|
+
_case: kw('case', BEFORE_EXPR, -1),
|
|
90
|
+
_catch: kw('catch', 0, -1),
|
|
91
|
+
_continue: kw('continue', 0, -1),
|
|
92
|
+
_debugger: kw('debugger', 0, -1),
|
|
93
|
+
_default: kw('default', BEFORE_EXPR, -1),
|
|
94
|
+
_do: kw('do', BEFORE_EXPR, -1),
|
|
95
|
+
_else: kw('else', BEFORE_EXPR, -1),
|
|
96
|
+
_finally: kw('finally', 0, -1),
|
|
97
|
+
_for: kw('for', 0, -1),
|
|
98
|
+
_function: kw('function', STARTS_EXPR, -1),
|
|
99
|
+
_if: kw('if', 0, -1),
|
|
100
|
+
_return: kw('return', BEFORE_EXPR, -1),
|
|
101
|
+
_switch: kw('switch', 0, -1),
|
|
102
|
+
_throw: kw('throw', BEFORE_EXPR, -1),
|
|
103
|
+
_try: kw('try', 0, -1),
|
|
104
|
+
_var: kw('var', 0, -1),
|
|
105
|
+
_const: kw('const', 0, -1),
|
|
106
|
+
_while: kw('while', 0, -1),
|
|
107
|
+
_with: kw('with', 0, -1),
|
|
108
|
+
_new: kw('new', BEFORE_EXPR | STARTS_EXPR, -1),
|
|
109
|
+
_this: kw('this', STARTS_EXPR, -1),
|
|
110
|
+
_super: kw('super', STARTS_EXPR, -1),
|
|
111
|
+
_class: kw('class', STARTS_EXPR, -1),
|
|
112
|
+
_extends: kw('extends', BEFORE_EXPR, -1),
|
|
113
|
+
_export: kw('export', 0, -1),
|
|
114
|
+
_import: kw('import', STARTS_EXPR, -1),
|
|
115
|
+
_null: kw('null', STARTS_EXPR, -1),
|
|
116
|
+
_true: kw('true', STARTS_EXPR, -1),
|
|
117
|
+
_false: kw('false', STARTS_EXPR, -1),
|
|
118
|
+
_in: kw('in', BEFORE_EXPR, 7),
|
|
119
|
+
_instanceof: kw('instanceof', BEFORE_EXPR, 7),
|
|
120
|
+
_typeof: kw('typeof', BEFORE_EXPR | PREFIX | STARTS_EXPR, -1),
|
|
121
|
+
_void: kw('void', BEFORE_EXPR | PREFIX | STARTS_EXPR, -1),
|
|
122
|
+
_delete: kw('delete', BEFORE_EXPR | PREFIX | STARTS_EXPR, -1),
|
|
123
|
+
};
|
|
124
|
+
const UNSUPPORTED_STATEMENT_KEYWORDS = new Set([tt._break, tt._continue, tt._do, tt._for, tt._function, tt._class, tt._if, tt._switch, tt._throw, tt._try, tt._const, tt._var, tt._while, tt._with]);
|
|
125
|
+
class TokContext {
|
|
126
|
+
constructor(token, isExpr, isTemplate) {
|
|
127
|
+
this.token = token;
|
|
128
|
+
this.isExpr = isExpr;
|
|
129
|
+
this.preserveSpace = isTemplate;
|
|
130
|
+
this.isTemplate = isTemplate;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const ctxBStat = new TokContext('{', false, false);
|
|
134
|
+
const ctxBExpr = new TokContext('{', true, false);
|
|
135
|
+
const ctxBTmpl = new TokContext('${', false, false);
|
|
136
|
+
const ctxPStat = new TokContext('(', false, false);
|
|
137
|
+
const ctxPExpr = new TokContext('(', true, false);
|
|
138
|
+
const ctxQTmpl = new TokContext('`', true, true);
|
|
139
|
+
const ctxFStat = new TokContext('function', false, false);
|
|
140
|
+
const ctxFExpr = new TokContext('function', true, false);
|
|
141
|
+
const RESERVED_WORDS = new Set(['enum']);
|
|
142
|
+
const RESERVED_WORDS_STRICT = new Set(['enum', 'implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', 'yield']);
|
|
143
|
+
const RESERVED_WORDS_STRICT_BIND = new Set(['enum', 'implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', 'yield', 'eval', 'arguments']);
|
|
144
|
+
const SCOPE_TOP = 1;
|
|
145
|
+
const SCOPE_FUNCTION = 2;
|
|
146
|
+
const SCOPE_ASYNC = 4;
|
|
147
|
+
const SCOPE_ARROW = 16;
|
|
148
|
+
const SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION;
|
|
149
|
+
const BIND_NONE = 0;
|
|
150
|
+
const BIND_VAR = 1;
|
|
151
|
+
const REGEXP_FLAGS = 'gimsuy';
|
|
152
|
+
// Non-ASCII identifier characters as acorn 8.15 classifies them (its Unicode tables, not the
|
|
153
|
+
// host's): base-36 deltas of inclusive [first, last] code point pairs. Regenerate by scanning
|
|
154
|
+
// acorn's isIdentifierStart / isIdentifierChar over every code point.
|
|
155
|
+
const ID_START_RANGES = '4q,0,b,0,5,0,6,m,2,u,2,cp,5,b,f,4,8,0,2,0,3m,4,2,1,3,3,2,0,7,0,2,2,2,0,2,j,2,2a,2,3u,9,4l,2,11,3,0,7,14,20,q,5,3,1a,16,10,1,2,2q,2,0,g,1,8,1,b,2,3,0,h,0,2,t,u,2g,c,0,p,w,a,1,5,0,6,l,5,0,a,0,4,0,o,o,8,a,6,n,2,5,i,15,1n,1h,4,0,j,0,8,9,g,f,5,7,3,1,3,l,2,6,2,0,4,3,4,0,h,0,e,1,2,2,f,1,b,0,9,5,5,1,3,l,2,6,2,1,2,1,2,1,w,3,2,0,k,2,h,8,2,2,2,l,2,6,2,1,2,4,4,0,j,0,g,1,o,0,c,7,3,1,3,l,2,6,2,1,2,4,4,0,v,1,2,2,g,0,i,0,2,5,4,2,2,3,4,1,2,0,2,1,4,1,4,2,4,b,n,0,1h,7,2,2,2,m,2,f,4,0,r,2,3,0,3,1,v,0,5,7,2,2,2,m,2,9,2,4,4,0,w,1,2,1,g,1,i,8,2,2,2,14,3,0,h,0,6,2,9,2,p,5,6,h,4,n,2,8,2,0,3,6,1n,1b,2,1,d,6,1n,1,2,0,2,4,2,n,2,0,2,9,2,1,a,0,3,4,2,0,m,3,x,0,1s,7,2,z,s,4,38,16,l,0,h,5,5,3,4,0,4,1,8,2,5,c,d,0,i,11,2,0,6,0,3,16,2,98,2,3,3,6,2,0,2,3,3,14,2,3,3,w,2,3,3,6,2,0,2,3,3,e,2,1k,2,3,3,1u,12,f,h,2d,3,5,4,h7,3,g,2,p,6,22,4,a,8,h,e,i,f,h,f,c,2,2,g,1f,10,0,5,0,1w,2g,8,14,2,0,6,1x,b,u,1e,t,3,4,c,17,5,p,1j,m,a,1g,2b,0,2m,1a,i,7,1j,t,e,1,b,17,r,z,16,2,b,z,3,a,6,16,3,2,16,3,2,5,2,1,4,0,6,5b,1t,7p,3,5,3,11,3,5,3,7,2,0,2,0,2,0,2,u,3,1g,2,6,2,0,4,2,2,6,4,3,3,5,5,c,6,2,2,6,39,0,e,0,h,c,2u,0,5,0,3,9,2,0,3,5,7,0,2,0,2,0,2,f,3,3,6,4,5,0,i,14,22g,6c,7,3,4,1,d,11,2,0,6,0,3,1j,8,0,h,m,a,6,2,6,2,6,2,6,2,6,2,6,2,6,2,6,fb,2,q,8,8,4,3,4,5,2d,5,4,2,2h,2,3,6,16,2,2l,i,v,1d,f,e9,533,1t,h3g,1w,19,3,7g,4,f,b,1,l,1a,h,u,3,27,14,8,3,2u,3,1u,3,1,2,0,2,7,m,f,2,2,2,3,2,m,u,1f,f,1d,1r,5,4,0,2,1,c,r,b,m,q,s,8,1a,t,0,h,4,2,9,b,4,2,14,o,2,2,7,l,m,4,0,4,1d,2,0,4,1,3,4,3,0,2,0,p,2,3,a,8,2,d,5,3,5,3,5,a,6,2,6,2,16,2,d,7,36,u,8mb,d,m,5,1c,6it,a5,3,2x,13,6,d,4,6,0,2,9,2,c,2,4,2,0,2,1,2,1,2,2z,y,a2,j,1r,3,1h,15,b,39,4,2,3q,11,p,7,p,c,2g,4,5,3,5,3,5,3,2,10,b,2,p,2,i,2,1,2,e,3,d,z,3e,1y,1g,7g,s,4,1c,1c,v,e,t,6,11,b,t,3,z,5,7,2,4,17,4d,j,z,5,z,5,13,9,1f,d,a,2,e,2,6,2,1,2,a,2,e,2,6,2,1,4,1f,d,8m,a,l,b,7,p,5,2,15,2,8,1y,5,3,0,2,17,2,1,4,0,3,m,b,m,a,u,1u,i,2,1,b,l,b,p,1z,1j,7,1,1t,0,g,3,2,2,2,s,17,s,4,s,10,7,2,r,s,1h,b,l,b,i,e,h,33,20,1k,1e,e,1e,e,z,13,r,a,m,6z,15,7,1,h,2,1o,s,b,0,9,l,17,h,1b,k,s,m,d,1g,1m,1,3,0,e,18,x,o,r,z,u,0,3,0,9,y,4,0,d,1b,f,3,m,0,2,0,10,h,2,o,k,1,1s,6,2,0,2,3,2,e,2,9,8,1a,13,7,3,1,3,l,2,6,2,1,2,4,4,0,j,0,d,4,v,9,2,0,3,0,2,11,2,0,q,0,2,0,19,1g,j,3,l,2,v,1b,l,1,2,0,55,1a,16,3,11,1b,l,0,1o,16,e,0,20,q,12,6,56,17,39,1r,w,7,3,0,3,7,2,1,2,n,g,0,2,0,2n,7,3,12,h,0,2,0,t,0,b,13,8,0,m,0,c,19,k,0,j,20,5k,w,w,8,2,10,i,0,1e,t,35,6,2,1,2,11,m,0,q,5,2,1,2,v,f,0,94,i,g,0,2,c,2,x,3h,0,28,pl,2v,32,i,5f,219,2o,g,tr,i,5,q,32y,6,g6,5a2,t,1cz,fs,8,u,i,26,i,t,j,1b,h,3,w,k,6,i,c1,18,5w,1r,3l,22,6,0,1v,c,1t,1,2,0,t,4qf,9,yd,16,9,6w8,3,2,6,2,1,2,82,g,0,u,2,3,0,f,3,9,az,1s5,2y,6,c,4,8,8,9,4mf,2c,2,1y,2,1,3,0,3,1,3,3,2,b,2,0,2,6,2,1s,2,3,3,7,2,6,2,r,2,3,2,4,2,0,4,6,2,9f,3,o,2,o,2,u,2,o,2,u,2,o,2,u,2,o,2,u,2,o,2,7,1f9,u,7,5,7a,1p,43,18,b,6,h,0,8y,t,j,17,dh,r,6d,t,3,0,ds,6,2,3,2,1,2,e,2,5g,1o,1v,8,0,xh,3,2,q,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,g,6,2,2,4,2,g,3et,wyn,x,37d,7,65,3,4g1,f,5rk,g,h9,1wj,f1,15v,3t6,6,38f';
|
|
156
|
+
const ID_CONTINUE_ONLY_RANGES = '53,0,g9,33,o,0,70,4,7e,18,2,0,2,1,2,1,2,0,21,a,1d,u,7,0,2u,6,3,5,3,1,2,3,3,9,o,0,v,q,2k,a,g,9,y,8,a,0,p,3,2,8,2,2,2,4,18,2,1o,8,17,n,2,w,1j,2,2,h,2,6,b,1,3,9,i,2,1l,0,2,6,3,1,3,2,a,0,b,1,3,9,f,0,3,2,1l,0,2,4,5,1,3,2,4,0,l,b,4,0,c,2,1l,0,2,7,2,2,2,2,l,1,3,9,b,5,2,2,1l,0,2,6,3,1,3,2,8,2,b,1,3,9,j,0,1o,4,4,2,2,3,a,0,f,9,h,4,1k,0,2,6,2,2,2,3,8,1,c,1,3,9,i,2,1l,0,2,6,2,2,2,3,8,1,c,1,3,9,4,0,d,3,1k,1,2,6,2,2,2,3,a,0,b,1,3,9,i,2,1z,0,5,5,2,0,2,7,7,9,3,1,1q,0,3,6,d,7,2,9,2g,0,3,8,c,6,2,9,1r,1,7,9,c,0,2,0,2,0,5,1,1e,j,2,1,6,a,2,z,a,0,2t,j,2,9,d,3,5,2,2,2,3,6,4,3,e,b,2,e,jk,2,a,8,pt,3,t,2,u,1,v,1,1t,v,a,0,3,9,y,2,2,a,40,0,3b,b,5,b,b,9,3l,a,1p,4,1m,9,2,s,3,a,7,9,n,d,2,f,1e,4,1c,g,c,9,i,8,d,2,v,c,3,9,19,d,1d,j,9,9,7,9,3b,2,2,k,5,0,7,0,3,2,5j,1r,el,1,1e,1,k,0,3g,c,5,0,4,b,2db,2,3y,0,2p,v,ff,5,2y,1,2p,0,n51,9,1y,0,5,9,x,1,29,1,7l,0,4,0,5,0,o,4,5,0,2c,1,1f,h,b,9,7,h,e,a,t,7,q,c,19,3,1c,d,g,9,c,0,b,9,1c,d,d,0,9,1,3,9,y,2,1f,0,2,2,3,1,6,1,2,0,16,4,6,1,6l,7,2,1,3,9,fmt,0,ki,f,h,f,4,1,p,2,5d,9,12,0,12,0,ig,0,6b,0,46,4,86,9,120,2,2,1,6,3,15,2,5,0,4m,1,fy,3,9,9,7,9,w,4,8u,1,28,3,1z,a,1e,3,3f,2,1i,e,w,a,3,1,b,3,1a,a,8,0,1a,9,7,2,11,d,2,9,6,1,19,0,d,2,1d,d,9,3,2,b,2b,b,7,0,3,0,4e,b,6,9,7,3,1k,1,2,6,3,1,3,2,a,0,b,1,3,6,4,4,1w,8,2,0,3,0,2,3,2,4,2,0,f,1,2b,h,a,9,5,0,2a,j,d,9,5y,6,3,8,s,1,2b,g,g,9,2a,c,9,9,7,j,1m,e,5,9,6r,e,4m,9,1z,5,2,1,3,3,2,0,2,1,d,9,3c,6,3,6,4,0,t,9,15,6,2,3,9,0,a,a,1b,f,9j,9,1i,7,2,7,h,9,1l,l,2,d,3f,5,4,0,2,1,2,6,2,0,9,9,1d,4,2,1,2,4,9,9,96,3,a,1,2,0,1d,6,4,4,e,a,44m,0,7,e,8uh,r,1t3,9,2f,9,13,4,1o,6,q,9,ev,9,d2,0,2,1i,8,3,2a,0,c,1,f58,1,382,9,ef,19,3,m,f3,4,4,5,9,7,3,6,v,3,45,2,13e,1d,e9,1i,5,1d,9,0,f,0,n,4,2,e,11t,6,2,g,3,6,2,1,2,4,2t,0,4h,6,a,9,9x,0,1q,d,dv,d,6t,1,2,9,k6,6,32,6,6,9,3o7,9,gvt3,6n';
|
|
157
|
+
const STRING_LITERAL_PREFIX = /^(?:'((?:\\[\s\S]|[^'\\])*?)'|"((?:\\[\s\S]|[^"\\])*?)")/;
|
|
158
|
+
const DIRECTIVE_CONTINUATION = /[(`.[+\-/*%<>=,?^&]/;
|
|
159
|
+
const CRLF = /\r\n?/g;
|
|
160
|
+
const UNDERSCORES = /_/g;
|
|
161
|
+
const RELATIONAL_KEYWORD = /^in(stanceof)?$/;
|
|
162
|
+
function codePointToString(code) {
|
|
163
|
+
if (code <= 0xffff) {
|
|
164
|
+
return String.fromCharCode(code);
|
|
165
|
+
}
|
|
166
|
+
const c = code - 0x10000;
|
|
167
|
+
return String.fromCharCode((c >> 10) + 0xd800, (c & 1023) + 0xdc00);
|
|
168
|
+
}
|
|
169
|
+
function decodeRanges(data) {
|
|
170
|
+
const parts = data.split(',');
|
|
171
|
+
const out = [];
|
|
172
|
+
let value = 0;
|
|
173
|
+
for (let i = 0; i < parts.length; i++) {
|
|
174
|
+
value += parseInt(parts[i], 36);
|
|
175
|
+
out.push(value);
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
let decodedIdStartRanges = null;
|
|
180
|
+
let decodedIdContinueOnlyRanges = null;
|
|
181
|
+
function idStartRanges() {
|
|
182
|
+
if (decodedIdStartRanges == null) {
|
|
183
|
+
decodedIdStartRanges = decodeRanges(ID_START_RANGES);
|
|
184
|
+
}
|
|
185
|
+
return decodedIdStartRanges;
|
|
186
|
+
}
|
|
187
|
+
function idContinueOnlyRanges() {
|
|
188
|
+
if (decodedIdContinueOnlyRanges == null) {
|
|
189
|
+
decodedIdContinueOnlyRanges = decodeRanges(ID_CONTINUE_ONLY_RANGES);
|
|
190
|
+
}
|
|
191
|
+
return decodedIdContinueOnlyRanges;
|
|
192
|
+
}
|
|
193
|
+
function inRanges(code, ranges) {
|
|
194
|
+
let lo = 0;
|
|
195
|
+
let hi = ranges.length / 2 - 1;
|
|
196
|
+
while (lo <= hi) {
|
|
197
|
+
const mid = (lo + hi) >> 1;
|
|
198
|
+
if (code < ranges[mid * 2]) {
|
|
199
|
+
hi = mid - 1;
|
|
200
|
+
}
|
|
201
|
+
else if (code > ranges[mid * 2 + 1]) {
|
|
202
|
+
lo = mid + 1;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
function isIdentifierStart(code) {
|
|
211
|
+
if (code < 65) {
|
|
212
|
+
return code === 36;
|
|
213
|
+
}
|
|
214
|
+
if (code < 91) {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
if (code < 97) {
|
|
218
|
+
return code === 95;
|
|
219
|
+
}
|
|
220
|
+
if (code < 123) {
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
return code >= 0xaa && inRanges(code, idStartRanges());
|
|
224
|
+
}
|
|
225
|
+
function isIdentifierChar(code) {
|
|
226
|
+
if (code < 48) {
|
|
227
|
+
return code === 36;
|
|
228
|
+
}
|
|
229
|
+
if (code < 58) {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
if (code < 65) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
if (code < 91) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
if (code < 97) {
|
|
239
|
+
return code === 95;
|
|
240
|
+
}
|
|
241
|
+
if (code < 123) {
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
return code >= 0xaa && (inRanges(code, idStartRanges()) || inRanges(code, idContinueOnlyRanges()));
|
|
245
|
+
}
|
|
246
|
+
function isNewLine(code) {
|
|
247
|
+
return code === 10 || code === 13 || code === 0x2028 || code === 0x2029;
|
|
248
|
+
}
|
|
249
|
+
function isNonAsciiWhitespace(code) {
|
|
250
|
+
return code === 0x1680 || (code >= 0x2000 && code <= 0x200a) || code === 0x202f || code === 0x205f || code === 0x3000 || code === 0xfeff;
|
|
251
|
+
}
|
|
252
|
+
// The characters JavaScript's regexp `\s` matches.
|
|
253
|
+
function isRegExpWhitespace(code) {
|
|
254
|
+
return (code >= 9 && code <= 13) || code === 32 || code === 0xa0 || code === 0x2028 || code === 0x2029 || isNonAsciiWhitespace(code);
|
|
255
|
+
}
|
|
256
|
+
function stringToBigInt(str) {
|
|
257
|
+
if (typeof BigInt !== 'function') {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
return BigInt(str);
|
|
261
|
+
}
|
|
262
|
+
function isLocalVariableAccess(node) {
|
|
263
|
+
return node.type === 'Identifier';
|
|
264
|
+
}
|
|
265
|
+
class DestructuringErrors {
|
|
266
|
+
constructor() {
|
|
267
|
+
this.shorthandAssign = -1;
|
|
268
|
+
this.trailingComma = -1;
|
|
269
|
+
this.parenthesizedAssign = -1;
|
|
270
|
+
this.parenthesizedBind = -1;
|
|
271
|
+
this.doubleProto = -1;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
class ExpressionParser {
|
|
275
|
+
constructor(input) {
|
|
276
|
+
this.pos = 0;
|
|
277
|
+
this.type = tt.eof;
|
|
278
|
+
// Token text: identifier/keyword name, operator, string value or template chunk.
|
|
279
|
+
this.value = '';
|
|
280
|
+
this.numValue = null;
|
|
281
|
+
this.regexPattern = '';
|
|
282
|
+
this.regexFlags = '';
|
|
283
|
+
this.regexValue = null;
|
|
284
|
+
this.start = 0;
|
|
285
|
+
this.end = 0;
|
|
286
|
+
this.lastTokStart = 0;
|
|
287
|
+
this.lastTokEnd = 0;
|
|
288
|
+
this.context = [ctxBStat];
|
|
289
|
+
this.exprAllowed = true;
|
|
290
|
+
this.containsEsc = false;
|
|
291
|
+
this.inTemplateElement = false;
|
|
292
|
+
this.invalidTemplateEscape = false;
|
|
293
|
+
this.potentialArrowAt = -1;
|
|
294
|
+
this.yieldPos = 0;
|
|
295
|
+
this.awaitPos = 0;
|
|
296
|
+
this.awaitIdentPos = 0;
|
|
297
|
+
this.labels = [];
|
|
298
|
+
this.scopeFlags = [SCOPE_TOP];
|
|
299
|
+
this.input = input;
|
|
300
|
+
this.strict = this.strictDirective(0);
|
|
301
|
+
}
|
|
302
|
+
// ## Errors
|
|
303
|
+
raise(pos, message) {
|
|
304
|
+
let line = 1;
|
|
305
|
+
let lineStart = 0;
|
|
306
|
+
let i = 0;
|
|
307
|
+
while (i < pos && i < this.input.length) {
|
|
308
|
+
const ch = this.input.charCodeAt(i);
|
|
309
|
+
if (isNewLine(ch)) {
|
|
310
|
+
if (ch === 13 && this.codeAt(i + 1) === 10) {
|
|
311
|
+
i++;
|
|
312
|
+
}
|
|
313
|
+
line++;
|
|
314
|
+
lineStart = i + 1;
|
|
315
|
+
}
|
|
316
|
+
i++;
|
|
317
|
+
}
|
|
318
|
+
throw new SyntaxError(message + ' (' + line + ':' + (pos - lineStart) + ')');
|
|
319
|
+
}
|
|
320
|
+
unexpected(pos) {
|
|
321
|
+
return this.raise(pos, 'Unexpected token');
|
|
322
|
+
}
|
|
323
|
+
unsupported(pos, what) {
|
|
324
|
+
return this.raise(pos, 'Unsupported in binding expressions: ' + what);
|
|
325
|
+
}
|
|
326
|
+
// ## Character helpers
|
|
327
|
+
codeAt(i) {
|
|
328
|
+
return i < this.input.length ? this.input.charCodeAt(i) : -1;
|
|
329
|
+
}
|
|
330
|
+
fullCharCodeAtPos() {
|
|
331
|
+
const code = this.codeAt(this.pos);
|
|
332
|
+
if (code <= 0xd7ff || code >= 0xdc00) {
|
|
333
|
+
return code;
|
|
334
|
+
}
|
|
335
|
+
const next = this.codeAt(this.pos + 1);
|
|
336
|
+
return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00;
|
|
337
|
+
}
|
|
338
|
+
hasLineBreak(from, to) {
|
|
339
|
+
for (let i = from; i < to; i++) {
|
|
340
|
+
if (isNewLine(this.input.charCodeAt(i))) {
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
// Equivalent of acorn's `skipWhiteSpace` regexp: whitespace, `//` and `/* */` comments.
|
|
347
|
+
skipWhiteSpaceFrom(from) {
|
|
348
|
+
let p = from;
|
|
349
|
+
const len = this.input.length;
|
|
350
|
+
while (p < len) {
|
|
351
|
+
const ch = this.input.charCodeAt(p);
|
|
352
|
+
if (isRegExpWhitespace(ch)) {
|
|
353
|
+
p++;
|
|
354
|
+
}
|
|
355
|
+
else if (ch === 47 && this.codeAt(p + 1) === 47) {
|
|
356
|
+
p += 2;
|
|
357
|
+
while (p < len && !isNewLine(this.input.charCodeAt(p))) {
|
|
358
|
+
p++;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
else if (ch === 47 && this.codeAt(p + 1) === 42) {
|
|
362
|
+
const close = this.input.indexOf('*/', p + 2);
|
|
363
|
+
if (close === -1) {
|
|
364
|
+
return p;
|
|
365
|
+
}
|
|
366
|
+
p = close + 2;
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
return p;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return p;
|
|
373
|
+
}
|
|
374
|
+
strictDirective(from) {
|
|
375
|
+
let start = from;
|
|
376
|
+
for (;;) {
|
|
377
|
+
start = this.skipWhiteSpaceFrom(start);
|
|
378
|
+
const match = STRING_LITERAL_PREFIX.exec(this.input.slice(start));
|
|
379
|
+
if (match == null) {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
if ((match[1] || match[2]) === 'use strict') {
|
|
383
|
+
const afterLiteral = start + match[0].length;
|
|
384
|
+
const end = this.skipWhiteSpaceFrom(afterLiteral);
|
|
385
|
+
const next = this.input.charAt(end);
|
|
386
|
+
return next === ';' || next === '}' || (this.hasLineBreak(afterLiteral, end) && !(DIRECTIVE_CONTINUATION.test(next) || (next === '!' && this.input.charAt(end + 1) === '=')));
|
|
387
|
+
}
|
|
388
|
+
start += match[0].length;
|
|
389
|
+
start = this.skipWhiteSpaceFrom(start);
|
|
390
|
+
if (this.input.charAt(start) === ';') {
|
|
391
|
+
start++;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
// ## Scopes
|
|
396
|
+
enterScope(flags) {
|
|
397
|
+
this.scopeFlags.push(flags);
|
|
398
|
+
}
|
|
399
|
+
exitScope() {
|
|
400
|
+
this.scopeFlags.pop();
|
|
401
|
+
}
|
|
402
|
+
currentVarScopeFlags() {
|
|
403
|
+
for (let i = this.scopeFlags.length - 1; i >= 0; i--) {
|
|
404
|
+
const flags = this.scopeFlags[i];
|
|
405
|
+
if ((flags & SCOPE_VAR) !== 0) {
|
|
406
|
+
return flags;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return 0;
|
|
410
|
+
}
|
|
411
|
+
inAsync() {
|
|
412
|
+
return (this.currentVarScopeFlags() & SCOPE_ASYNC) !== 0;
|
|
413
|
+
}
|
|
414
|
+
canAwait() {
|
|
415
|
+
for (let i = this.scopeFlags.length - 1; i >= 0; i--) {
|
|
416
|
+
const flags = this.scopeFlags[i];
|
|
417
|
+
if ((flags & SCOPE_FUNCTION) !== 0) {
|
|
418
|
+
return (flags & SCOPE_ASYNC) !== 0;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
// ## Tokenizer
|
|
424
|
+
curContext() {
|
|
425
|
+
return this.context[this.context.length - 1];
|
|
426
|
+
}
|
|
427
|
+
next(ignoreEscapeSequenceInKeyword) {
|
|
428
|
+
if (!ignoreEscapeSequenceInKeyword && this.type.keyword !== '' && this.containsEsc) {
|
|
429
|
+
this.raise(this.start, 'Escape sequence in keyword ' + this.type.keyword);
|
|
430
|
+
}
|
|
431
|
+
this.lastTokEnd = this.end;
|
|
432
|
+
this.lastTokStart = this.start;
|
|
433
|
+
this.nextToken();
|
|
434
|
+
}
|
|
435
|
+
nextToken() {
|
|
436
|
+
const curContext = this.curContext();
|
|
437
|
+
if (!curContext.preserveSpace) {
|
|
438
|
+
this.skipSpace();
|
|
439
|
+
}
|
|
440
|
+
this.start = this.pos;
|
|
441
|
+
if (this.pos >= this.input.length) {
|
|
442
|
+
this.finishToken(tt.eof, '');
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
if (curContext.isTemplate) {
|
|
446
|
+
this.tryReadTemplateToken();
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
this.readToken(this.fullCharCodeAtPos());
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
readToken(code) {
|
|
453
|
+
if (isIdentifierStart(code) || code === 92) {
|
|
454
|
+
this.readWord();
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
this.getTokenFromCode(code);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
skipBlockComment() {
|
|
461
|
+
const end = this.input.indexOf('*/', (this.pos += 2));
|
|
462
|
+
if (end === -1) {
|
|
463
|
+
this.raise(this.pos - 2, 'Unterminated comment');
|
|
464
|
+
}
|
|
465
|
+
this.pos = end + 2;
|
|
466
|
+
}
|
|
467
|
+
skipLineComment(startSkip) {
|
|
468
|
+
this.pos += startSkip;
|
|
469
|
+
while (this.pos < this.input.length && !isNewLine(this.input.charCodeAt(this.pos))) {
|
|
470
|
+
this.pos++;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
skipSpace() {
|
|
474
|
+
while (this.pos < this.input.length) {
|
|
475
|
+
const ch = this.input.charCodeAt(this.pos);
|
|
476
|
+
if (ch === 32 || ch === 160) {
|
|
477
|
+
this.pos++;
|
|
478
|
+
}
|
|
479
|
+
else if (ch === 13) {
|
|
480
|
+
if (this.codeAt(this.pos + 1) === 10) {
|
|
481
|
+
this.pos++;
|
|
482
|
+
}
|
|
483
|
+
this.pos++;
|
|
484
|
+
}
|
|
485
|
+
else if (ch === 10 || ch === 8232 || ch === 8233) {
|
|
486
|
+
this.pos++;
|
|
487
|
+
}
|
|
488
|
+
else if (ch === 47) {
|
|
489
|
+
const next = this.codeAt(this.pos + 1);
|
|
490
|
+
if (next === 42) {
|
|
491
|
+
this.skipBlockComment();
|
|
492
|
+
}
|
|
493
|
+
else if (next === 47) {
|
|
494
|
+
this.skipLineComment(2);
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
else if ((ch > 8 && ch < 14) || (ch >= 5760 && isNonAsciiWhitespace(ch))) {
|
|
501
|
+
this.pos++;
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
finishToken(type, value) {
|
|
509
|
+
this.end = this.pos;
|
|
510
|
+
const prevType = this.type;
|
|
511
|
+
this.type = type;
|
|
512
|
+
this.value = value;
|
|
513
|
+
this.updateContext(prevType);
|
|
514
|
+
}
|
|
515
|
+
braceIsBlock(prevType) {
|
|
516
|
+
const parent = this.curContext();
|
|
517
|
+
if (parent === ctxFExpr || parent === ctxFStat) {
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
if (prevType === tt.colon && (parent === ctxBStat || parent === ctxBExpr)) {
|
|
521
|
+
return !parent.isExpr;
|
|
522
|
+
}
|
|
523
|
+
if (prevType === tt._return || (prevType === tt.name && this.exprAllowed)) {
|
|
524
|
+
return this.hasLineBreak(this.lastTokEnd, this.start);
|
|
525
|
+
}
|
|
526
|
+
if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR || prevType === tt.arrow) {
|
|
527
|
+
return true;
|
|
528
|
+
}
|
|
529
|
+
if (prevType === tt.braceL) {
|
|
530
|
+
return parent === ctxBStat;
|
|
531
|
+
}
|
|
532
|
+
if (prevType === tt._var || prevType === tt._const || prevType === tt.name) {
|
|
533
|
+
return false;
|
|
534
|
+
}
|
|
535
|
+
return !this.exprAllowed;
|
|
536
|
+
}
|
|
537
|
+
// Tracks whether a `/` starting the next token begins a regexp; acorn's token context rules.
|
|
538
|
+
updateContext(prevType) {
|
|
539
|
+
const type = this.type;
|
|
540
|
+
if (type.keyword !== '' && prevType === tt.dot) {
|
|
541
|
+
this.exprAllowed = false;
|
|
542
|
+
}
|
|
543
|
+
else if (type === tt.parenR || type === tt.braceR) {
|
|
544
|
+
if (this.context.length === 1) {
|
|
545
|
+
this.exprAllowed = true;
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
let out = this.context.pop();
|
|
549
|
+
if (out === ctxBStat && this.curContext().token === 'function') {
|
|
550
|
+
out = this.context.pop();
|
|
551
|
+
}
|
|
552
|
+
this.exprAllowed = !out.isExpr;
|
|
553
|
+
}
|
|
554
|
+
else if (type === tt.braceL) {
|
|
555
|
+
this.context.push(this.braceIsBlock(prevType) ? ctxBStat : ctxBExpr);
|
|
556
|
+
this.exprAllowed = true;
|
|
557
|
+
}
|
|
558
|
+
else if (type === tt.dollarBraceL) {
|
|
559
|
+
this.context.push(ctxBTmpl);
|
|
560
|
+
this.exprAllowed = true;
|
|
561
|
+
}
|
|
562
|
+
else if (type === tt.parenL) {
|
|
563
|
+
const statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while;
|
|
564
|
+
this.context.push(statementParens ? ctxPStat : ctxPExpr);
|
|
565
|
+
this.exprAllowed = true;
|
|
566
|
+
}
|
|
567
|
+
else if (type === tt.incDec) {
|
|
568
|
+
// exprAllowed stays unchanged
|
|
569
|
+
}
|
|
570
|
+
else if (type === tt._function || type === tt._class) {
|
|
571
|
+
if (prevType.beforeExpr && prevType !== tt._else && !(prevType === tt.semi && this.curContext() !== ctxPStat) && !(prevType === tt._return && this.hasLineBreak(this.lastTokEnd, this.start)) && !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === ctxBStat)) {
|
|
572
|
+
this.context.push(ctxFExpr);
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
this.context.push(ctxFStat);
|
|
576
|
+
}
|
|
577
|
+
this.exprAllowed = false;
|
|
578
|
+
}
|
|
579
|
+
else if (type === tt.colon) {
|
|
580
|
+
if (this.curContext().token === 'function') {
|
|
581
|
+
this.context.pop();
|
|
582
|
+
}
|
|
583
|
+
this.exprAllowed = true;
|
|
584
|
+
}
|
|
585
|
+
else if (type === tt.backQuote) {
|
|
586
|
+
if (this.curContext() === ctxQTmpl) {
|
|
587
|
+
this.context.pop();
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
this.context.push(ctxQTmpl);
|
|
591
|
+
}
|
|
592
|
+
this.exprAllowed = false;
|
|
593
|
+
}
|
|
594
|
+
else if (type === tt.star) {
|
|
595
|
+
this.exprAllowed = true;
|
|
596
|
+
}
|
|
597
|
+
else if (type === tt.name) {
|
|
598
|
+
this.exprAllowed = prevType !== tt.dot && this.value === 'of' && !this.exprAllowed;
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
this.exprAllowed = type.beforeExpr;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
overrideContext(tokenCtx) {
|
|
605
|
+
if (this.curContext() !== tokenCtx) {
|
|
606
|
+
this.context[this.context.length - 1] = tokenCtx;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
finishOp(type, size) {
|
|
610
|
+
const str = this.input.slice(this.pos, this.pos + size);
|
|
611
|
+
this.pos += size;
|
|
612
|
+
this.finishToken(type, str);
|
|
613
|
+
}
|
|
614
|
+
readTokenDot() {
|
|
615
|
+
const next = this.codeAt(this.pos + 1);
|
|
616
|
+
if (next >= 48 && next <= 57) {
|
|
617
|
+
this.readNumber(true);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
if (next === 46 && this.codeAt(this.pos + 2) === 46) {
|
|
621
|
+
this.pos += 3;
|
|
622
|
+
this.finishToken(tt.ellipsis, '');
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
++this.pos;
|
|
626
|
+
this.finishToken(tt.dot, '');
|
|
627
|
+
}
|
|
628
|
+
readTokenSlash() {
|
|
629
|
+
if (this.exprAllowed) {
|
|
630
|
+
++this.pos;
|
|
631
|
+
this.readRegexp();
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
if (this.codeAt(this.pos + 1) === 61) {
|
|
635
|
+
this.finishOp(tt.assign, 2);
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
this.finishOp(tt.slash, 1);
|
|
639
|
+
}
|
|
640
|
+
readTokenMultModuloExp(code) {
|
|
641
|
+
let next = this.codeAt(this.pos + 1);
|
|
642
|
+
let size = 1;
|
|
643
|
+
let tokentype = code === 42 ? tt.star : tt.modulo;
|
|
644
|
+
if (code === 42 && next === 42) {
|
|
645
|
+
++size;
|
|
646
|
+
tokentype = tt.starstar;
|
|
647
|
+
next = this.codeAt(this.pos + 2);
|
|
648
|
+
}
|
|
649
|
+
if (next === 61) {
|
|
650
|
+
this.finishOp(tt.assign, size + 1);
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
this.finishOp(tokentype, size);
|
|
654
|
+
}
|
|
655
|
+
readTokenPipeAmp(code) {
|
|
656
|
+
const next = this.codeAt(this.pos + 1);
|
|
657
|
+
if (next === code) {
|
|
658
|
+
this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2);
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
if (next === 61) {
|
|
662
|
+
this.finishOp(tt.assign, 2);
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1);
|
|
666
|
+
}
|
|
667
|
+
readTokenCaret() {
|
|
668
|
+
if (this.codeAt(this.pos + 1) === 61) {
|
|
669
|
+
this.finishOp(tt.assign, 2);
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
this.finishOp(tt.bitwiseXOR, 1);
|
|
673
|
+
}
|
|
674
|
+
readTokenPlusMin(code) {
|
|
675
|
+
const next = this.codeAt(this.pos + 1);
|
|
676
|
+
if (next === code) {
|
|
677
|
+
if (next === 45 && this.codeAt(this.pos + 2) === 62 && (this.lastTokEnd === 0 || this.hasLineBreak(this.lastTokEnd, this.pos))) {
|
|
678
|
+
// `-->` at the start of a line is an HTML-style line comment in scripts.
|
|
679
|
+
this.skipLineComment(3);
|
|
680
|
+
this.skipSpace();
|
|
681
|
+
this.nextToken();
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
this.finishOp(tt.incDec, 2);
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (next === 61) {
|
|
688
|
+
this.finishOp(tt.assign, 2);
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
this.finishOp(tt.plusMin, 1);
|
|
692
|
+
}
|
|
693
|
+
readTokenLtGt(code) {
|
|
694
|
+
const next = this.codeAt(this.pos + 1);
|
|
695
|
+
let size = 1;
|
|
696
|
+
if (next === code) {
|
|
697
|
+
size = code === 62 && this.codeAt(this.pos + 2) === 62 ? 3 : 2;
|
|
698
|
+
if (this.codeAt(this.pos + size) === 61) {
|
|
699
|
+
this.finishOp(tt.assign, size + 1);
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
this.finishOp(tt.bitShift, size);
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
if (next === 33 && code === 60 && this.codeAt(this.pos + 2) === 45 && this.codeAt(this.pos + 3) === 45) {
|
|
706
|
+
// `<!--` is an HTML-style line comment in scripts.
|
|
707
|
+
this.skipLineComment(4);
|
|
708
|
+
this.skipSpace();
|
|
709
|
+
this.nextToken();
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
if (next === 61) {
|
|
713
|
+
size = 2;
|
|
714
|
+
}
|
|
715
|
+
this.finishOp(tt.relational, size);
|
|
716
|
+
}
|
|
717
|
+
readTokenEqExcl(code) {
|
|
718
|
+
const next = this.codeAt(this.pos + 1);
|
|
719
|
+
if (next === 61) {
|
|
720
|
+
this.finishOp(tt.equality, this.codeAt(this.pos + 2) === 61 ? 3 : 2);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
if (code === 61 && next === 62) {
|
|
724
|
+
this.pos += 2;
|
|
725
|
+
this.finishToken(tt.arrow, '');
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
this.finishOp(code === 61 ? tt.eq : tt.prefix, 1);
|
|
729
|
+
}
|
|
730
|
+
readTokenQuestion() {
|
|
731
|
+
const next = this.codeAt(this.pos + 1);
|
|
732
|
+
if (next === 46) {
|
|
733
|
+
const next2 = this.codeAt(this.pos + 2);
|
|
734
|
+
// acorn compares NaN past the end, which makes `?.` at end of input a plain `?`.
|
|
735
|
+
if (next2 !== -1 && (next2 < 48 || next2 > 57)) {
|
|
736
|
+
this.finishOp(tt.questionDot, 2);
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
if (next === 63) {
|
|
741
|
+
this.finishOp(tt.coalesce, 2);
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
this.finishOp(tt.question, 1);
|
|
745
|
+
}
|
|
746
|
+
getTokenFromCode(code) {
|
|
747
|
+
switch (code) {
|
|
748
|
+
case 46:
|
|
749
|
+
this.readTokenDot();
|
|
750
|
+
return;
|
|
751
|
+
case 40:
|
|
752
|
+
++this.pos;
|
|
753
|
+
this.finishToken(tt.parenL, '');
|
|
754
|
+
return;
|
|
755
|
+
case 41:
|
|
756
|
+
++this.pos;
|
|
757
|
+
this.finishToken(tt.parenR, '');
|
|
758
|
+
return;
|
|
759
|
+
case 59:
|
|
760
|
+
++this.pos;
|
|
761
|
+
this.finishToken(tt.semi, '');
|
|
762
|
+
return;
|
|
763
|
+
case 44:
|
|
764
|
+
++this.pos;
|
|
765
|
+
this.finishToken(tt.comma, '');
|
|
766
|
+
return;
|
|
767
|
+
case 91:
|
|
768
|
+
++this.pos;
|
|
769
|
+
this.finishToken(tt.bracketL, '');
|
|
770
|
+
return;
|
|
771
|
+
case 93:
|
|
772
|
+
++this.pos;
|
|
773
|
+
this.finishToken(tt.bracketR, '');
|
|
774
|
+
return;
|
|
775
|
+
case 123:
|
|
776
|
+
++this.pos;
|
|
777
|
+
this.finishToken(tt.braceL, '');
|
|
778
|
+
return;
|
|
779
|
+
case 125:
|
|
780
|
+
++this.pos;
|
|
781
|
+
this.finishToken(tt.braceR, '');
|
|
782
|
+
return;
|
|
783
|
+
case 58:
|
|
784
|
+
++this.pos;
|
|
785
|
+
this.finishToken(tt.colon, '');
|
|
786
|
+
return;
|
|
787
|
+
case 96:
|
|
788
|
+
++this.pos;
|
|
789
|
+
this.finishToken(tt.backQuote, '');
|
|
790
|
+
return;
|
|
791
|
+
case 48: {
|
|
792
|
+
const next = this.codeAt(this.pos + 1);
|
|
793
|
+
if (next === 120 || next === 88) {
|
|
794
|
+
this.readRadixNumber(16);
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
if (next === 111 || next === 79) {
|
|
798
|
+
this.readRadixNumber(8);
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
if (next === 98 || next === 66) {
|
|
802
|
+
this.readRadixNumber(2);
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
this.readNumber(false);
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
case 49:
|
|
809
|
+
case 50:
|
|
810
|
+
case 51:
|
|
811
|
+
case 52:
|
|
812
|
+
case 53:
|
|
813
|
+
case 54:
|
|
814
|
+
case 55:
|
|
815
|
+
case 56:
|
|
816
|
+
case 57:
|
|
817
|
+
this.readNumber(false);
|
|
818
|
+
return;
|
|
819
|
+
case 34:
|
|
820
|
+
case 39:
|
|
821
|
+
this.readString(code);
|
|
822
|
+
return;
|
|
823
|
+
case 47:
|
|
824
|
+
this.readTokenSlash();
|
|
825
|
+
return;
|
|
826
|
+
case 37:
|
|
827
|
+
case 42:
|
|
828
|
+
this.readTokenMultModuloExp(code);
|
|
829
|
+
return;
|
|
830
|
+
case 124:
|
|
831
|
+
case 38:
|
|
832
|
+
this.readTokenPipeAmp(code);
|
|
833
|
+
return;
|
|
834
|
+
case 94:
|
|
835
|
+
this.readTokenCaret();
|
|
836
|
+
return;
|
|
837
|
+
case 43:
|
|
838
|
+
case 45:
|
|
839
|
+
this.readTokenPlusMin(code);
|
|
840
|
+
return;
|
|
841
|
+
case 60:
|
|
842
|
+
case 62:
|
|
843
|
+
this.readTokenLtGt(code);
|
|
844
|
+
return;
|
|
845
|
+
case 61:
|
|
846
|
+
case 33:
|
|
847
|
+
this.readTokenEqExcl(code);
|
|
848
|
+
return;
|
|
849
|
+
case 63:
|
|
850
|
+
this.readTokenQuestion();
|
|
851
|
+
return;
|
|
852
|
+
case 126:
|
|
853
|
+
this.finishOp(tt.prefix, 1);
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
|
|
857
|
+
}
|
|
858
|
+
readRegexp() {
|
|
859
|
+
let escaped = false;
|
|
860
|
+
let inClass = false;
|
|
861
|
+
const start = this.pos;
|
|
862
|
+
for (;;) {
|
|
863
|
+
if (this.pos >= this.input.length) {
|
|
864
|
+
this.raise(start, 'Unterminated regular expression');
|
|
865
|
+
}
|
|
866
|
+
const ch = this.input.charCodeAt(this.pos);
|
|
867
|
+
if (isNewLine(ch)) {
|
|
868
|
+
this.raise(start, 'Unterminated regular expression');
|
|
869
|
+
}
|
|
870
|
+
if (!escaped) {
|
|
871
|
+
if (ch === 91) {
|
|
872
|
+
inClass = true;
|
|
873
|
+
}
|
|
874
|
+
else if (ch === 93 && inClass) {
|
|
875
|
+
inClass = false;
|
|
876
|
+
}
|
|
877
|
+
else if (ch === 47 && !inClass) {
|
|
878
|
+
break;
|
|
879
|
+
}
|
|
880
|
+
escaped = ch === 92;
|
|
881
|
+
}
|
|
882
|
+
else {
|
|
883
|
+
escaped = false;
|
|
884
|
+
}
|
|
885
|
+
++this.pos;
|
|
886
|
+
}
|
|
887
|
+
const pattern = this.input.slice(start, this.pos);
|
|
888
|
+
++this.pos;
|
|
889
|
+
const flagsStart = this.pos;
|
|
890
|
+
const flags = this.readWord1();
|
|
891
|
+
if (this.containsEsc) {
|
|
892
|
+
this.unexpected(flagsStart);
|
|
893
|
+
}
|
|
894
|
+
for (let i = 0; i < flags.length; i++) {
|
|
895
|
+
const flag = flags.charAt(i);
|
|
896
|
+
if (REGEXP_FLAGS.indexOf(flag) === -1) {
|
|
897
|
+
this.raise(start, 'Invalid regular expression flag');
|
|
898
|
+
}
|
|
899
|
+
if (flags.indexOf(flag, i + 1) > -1) {
|
|
900
|
+
this.raise(start, 'Duplicate regular expression flag');
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
this.regexPattern = pattern;
|
|
904
|
+
this.regexFlags = flags;
|
|
905
|
+
this.regexValue = this.validateRegExp(start, pattern, flags);
|
|
906
|
+
this.finishToken(tt.regexp, '');
|
|
907
|
+
}
|
|
908
|
+
// The host RegExp engine validates the pattern. It accepts syntax newer than
|
|
909
|
+
// ES2020, so group modifiers and duplicate group names are rejected here first.
|
|
910
|
+
validateRegExp(start, pattern, flags) {
|
|
911
|
+
const groupNames = [];
|
|
912
|
+
let inClass = false;
|
|
913
|
+
let i = 0;
|
|
914
|
+
while (i < pattern.length) {
|
|
915
|
+
const ch = pattern.charCodeAt(i);
|
|
916
|
+
if (ch === 92) {
|
|
917
|
+
i += 2;
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
if (inClass) {
|
|
921
|
+
if (ch === 93) {
|
|
922
|
+
inClass = false;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
else if (ch === 91) {
|
|
926
|
+
inClass = true;
|
|
927
|
+
}
|
|
928
|
+
else if (ch === 40 && pattern.charCodeAt(i + 1) === 63) {
|
|
929
|
+
const kind = pattern.charCodeAt(i + 2);
|
|
930
|
+
if (kind === 60) {
|
|
931
|
+
const afterLt = pattern.charCodeAt(i + 3);
|
|
932
|
+
if (afterLt !== 61 && afterLt !== 33) {
|
|
933
|
+
const close = pattern.indexOf('>', i + 3);
|
|
934
|
+
if (close !== -1) {
|
|
935
|
+
const groupName = pattern.slice(i + 3, close);
|
|
936
|
+
if (groupNames.indexOf(groupName) !== -1) {
|
|
937
|
+
this.raise(start, 'Invalid regular expression: /' + pattern + '/: Duplicate capture group name');
|
|
938
|
+
}
|
|
939
|
+
groupNames.push(groupName);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
else if (kind !== 58 && kind !== 61 && kind !== 33) {
|
|
944
|
+
this.raise(start, 'Invalid regular expression: /' + pattern + '/: Invalid group');
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
i++;
|
|
948
|
+
}
|
|
949
|
+
let value = null;
|
|
950
|
+
try {
|
|
951
|
+
value = new RegExp(pattern, flags);
|
|
952
|
+
}
|
|
953
|
+
catch (e) {
|
|
954
|
+
this.raise(start, 'Invalid regular expression: /' + pattern + '/');
|
|
955
|
+
}
|
|
956
|
+
return value;
|
|
957
|
+
}
|
|
958
|
+
// Returns -1 when no digits were read (or, with `hasLen`, not exactly `len` digits).
|
|
959
|
+
readInt(radix, len, hasLen) {
|
|
960
|
+
const start = this.pos;
|
|
961
|
+
let total = 0;
|
|
962
|
+
let i = 0;
|
|
963
|
+
while (!hasLen || i < len) {
|
|
964
|
+
const code = this.codeAt(this.pos);
|
|
965
|
+
let val;
|
|
966
|
+
if (code >= 97) {
|
|
967
|
+
val = code - 97 + 10;
|
|
968
|
+
}
|
|
969
|
+
else if (code >= 65) {
|
|
970
|
+
val = code - 65 + 10;
|
|
971
|
+
}
|
|
972
|
+
else if (code >= 48 && code <= 57) {
|
|
973
|
+
val = code - 48;
|
|
974
|
+
}
|
|
975
|
+
else {
|
|
976
|
+
val = Infinity;
|
|
977
|
+
}
|
|
978
|
+
if (val >= radix) {
|
|
979
|
+
break;
|
|
980
|
+
}
|
|
981
|
+
total = total * radix + val;
|
|
982
|
+
i++;
|
|
983
|
+
this.pos++;
|
|
984
|
+
}
|
|
985
|
+
if (this.pos === start || (hasLen && this.pos - start !== len)) {
|
|
986
|
+
return -1;
|
|
987
|
+
}
|
|
988
|
+
return total;
|
|
989
|
+
}
|
|
990
|
+
readRadixNumber(radix) {
|
|
991
|
+
const start = this.pos;
|
|
992
|
+
this.pos += 2;
|
|
993
|
+
let val = this.readInt(radix, 0, false);
|
|
994
|
+
if (val === -1) {
|
|
995
|
+
this.raise(this.start + 2, 'Expected number in radix ' + radix);
|
|
996
|
+
}
|
|
997
|
+
if (this.codeAt(this.pos) === 110) {
|
|
998
|
+
val = stringToBigInt(this.input.slice(start, this.pos));
|
|
999
|
+
++this.pos;
|
|
1000
|
+
}
|
|
1001
|
+
else if (isIdentifierStart(this.fullCharCodeAtPos())) {
|
|
1002
|
+
this.raise(this.pos, 'Identifier directly after number');
|
|
1003
|
+
}
|
|
1004
|
+
this.numValue = val;
|
|
1005
|
+
this.finishToken(tt.num, '');
|
|
1006
|
+
}
|
|
1007
|
+
readNumber(startsWithDot) {
|
|
1008
|
+
const start = this.pos;
|
|
1009
|
+
if (!startsWithDot && this.readInt(10, 0, false) === -1) {
|
|
1010
|
+
this.raise(start, 'Invalid number');
|
|
1011
|
+
}
|
|
1012
|
+
let octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
|
|
1013
|
+
if (octal && this.strict) {
|
|
1014
|
+
this.raise(start, 'Invalid number');
|
|
1015
|
+
}
|
|
1016
|
+
let next = this.codeAt(this.pos);
|
|
1017
|
+
if (!octal && !startsWithDot && next === 110) {
|
|
1018
|
+
const bigValue = stringToBigInt(this.input.slice(start, this.pos));
|
|
1019
|
+
++this.pos;
|
|
1020
|
+
if (isIdentifierStart(this.fullCharCodeAtPos())) {
|
|
1021
|
+
this.raise(this.pos, 'Identifier directly after number');
|
|
1022
|
+
}
|
|
1023
|
+
this.numValue = bigValue;
|
|
1024
|
+
this.finishToken(tt.num, '');
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
if (octal) {
|
|
1028
|
+
for (let i = start; i < this.pos; i++) {
|
|
1029
|
+
const digit = this.input.charCodeAt(i);
|
|
1030
|
+
if (digit === 56 || digit === 57) {
|
|
1031
|
+
octal = false;
|
|
1032
|
+
break;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
if (next === 46 && !octal) {
|
|
1037
|
+
++this.pos;
|
|
1038
|
+
this.readInt(10, 0, false);
|
|
1039
|
+
next = this.codeAt(this.pos);
|
|
1040
|
+
}
|
|
1041
|
+
if ((next === 69 || next === 101) && !octal) {
|
|
1042
|
+
next = this.codeAt(++this.pos);
|
|
1043
|
+
if (next === 43 || next === 45) {
|
|
1044
|
+
++this.pos;
|
|
1045
|
+
}
|
|
1046
|
+
if (this.readInt(10, 0, false) === -1) {
|
|
1047
|
+
this.raise(start, 'Invalid number');
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
if (isIdentifierStart(this.fullCharCodeAtPos())) {
|
|
1051
|
+
this.raise(this.pos, 'Identifier directly after number');
|
|
1052
|
+
}
|
|
1053
|
+
const str = this.input.slice(start, this.pos);
|
|
1054
|
+
this.numValue = octal ? parseInt(str, 8) : parseFloat(str);
|
|
1055
|
+
this.finishToken(tt.num, '');
|
|
1056
|
+
}
|
|
1057
|
+
readCodePoint() {
|
|
1058
|
+
const ch = this.codeAt(this.pos);
|
|
1059
|
+
let code;
|
|
1060
|
+
if (ch === 123) {
|
|
1061
|
+
const codePos = ++this.pos;
|
|
1062
|
+
code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos, true);
|
|
1063
|
+
if (this.invalidTemplateEscape) {
|
|
1064
|
+
return 0;
|
|
1065
|
+
}
|
|
1066
|
+
++this.pos;
|
|
1067
|
+
if (code > 0x10ffff) {
|
|
1068
|
+
this.invalidStringToken(codePos, 'Code point out of bounds');
|
|
1069
|
+
return 0;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
else {
|
|
1073
|
+
code = this.readHexChar(4, true);
|
|
1074
|
+
}
|
|
1075
|
+
return code;
|
|
1076
|
+
}
|
|
1077
|
+
readString(quote) {
|
|
1078
|
+
let out = '';
|
|
1079
|
+
let chunkStart = ++this.pos;
|
|
1080
|
+
for (;;) {
|
|
1081
|
+
if (this.pos >= this.input.length) {
|
|
1082
|
+
this.raise(this.start, 'Unterminated string constant');
|
|
1083
|
+
}
|
|
1084
|
+
const ch = this.input.charCodeAt(this.pos);
|
|
1085
|
+
if (ch === quote) {
|
|
1086
|
+
break;
|
|
1087
|
+
}
|
|
1088
|
+
if (ch === 92) {
|
|
1089
|
+
out += this.input.slice(chunkStart, this.pos);
|
|
1090
|
+
out += this.readEscapedChar(false);
|
|
1091
|
+
chunkStart = this.pos;
|
|
1092
|
+
}
|
|
1093
|
+
else if (ch === 0x2028 || ch === 0x2029) {
|
|
1094
|
+
++this.pos;
|
|
1095
|
+
}
|
|
1096
|
+
else {
|
|
1097
|
+
if (isNewLine(ch)) {
|
|
1098
|
+
this.raise(this.start, 'Unterminated string constant');
|
|
1099
|
+
}
|
|
1100
|
+
++this.pos;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
out += this.input.slice(chunkStart, this.pos++);
|
|
1104
|
+
this.finishToken(tt.string, out);
|
|
1105
|
+
}
|
|
1106
|
+
tryReadTemplateToken() {
|
|
1107
|
+
this.inTemplateElement = true;
|
|
1108
|
+
this.invalidTemplateEscape = false;
|
|
1109
|
+
this.readTmplToken();
|
|
1110
|
+
if (this.invalidTemplateEscape) {
|
|
1111
|
+
this.invalidTemplateEscape = false;
|
|
1112
|
+
this.readInvalidTemplateToken();
|
|
1113
|
+
}
|
|
1114
|
+
this.inTemplateElement = false;
|
|
1115
|
+
}
|
|
1116
|
+
// Inside a template an invalid escape is not an error yet (tagged templates allow it):
|
|
1117
|
+
// the scan stops where acorn's sentinel throw would and restarts as an invalid template token.
|
|
1118
|
+
invalidStringToken(position, message) {
|
|
1119
|
+
if (this.inTemplateElement) {
|
|
1120
|
+
this.invalidTemplateEscape = true;
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
1123
|
+
this.raise(position, message);
|
|
1124
|
+
}
|
|
1125
|
+
readTmplToken() {
|
|
1126
|
+
let out = '';
|
|
1127
|
+
let chunkStart = this.pos;
|
|
1128
|
+
for (;;) {
|
|
1129
|
+
if (this.pos >= this.input.length) {
|
|
1130
|
+
this.raise(this.start, 'Unterminated template');
|
|
1131
|
+
}
|
|
1132
|
+
const ch = this.input.charCodeAt(this.pos);
|
|
1133
|
+
if (ch === 96 || (ch === 36 && this.codeAt(this.pos + 1) === 123)) {
|
|
1134
|
+
if (this.pos === this.start && (this.type === tt.template || this.type === tt.invalidTemplate)) {
|
|
1135
|
+
if (ch === 36) {
|
|
1136
|
+
this.pos += 2;
|
|
1137
|
+
this.finishToken(tt.dollarBraceL, '');
|
|
1138
|
+
}
|
|
1139
|
+
else {
|
|
1140
|
+
++this.pos;
|
|
1141
|
+
this.finishToken(tt.backQuote, '');
|
|
1142
|
+
}
|
|
1143
|
+
return;
|
|
1144
|
+
}
|
|
1145
|
+
out += this.input.slice(chunkStart, this.pos);
|
|
1146
|
+
this.finishToken(tt.template, out);
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
if (ch === 92) {
|
|
1150
|
+
out += this.input.slice(chunkStart, this.pos);
|
|
1151
|
+
out += this.readEscapedChar(true);
|
|
1152
|
+
if (this.invalidTemplateEscape) {
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
chunkStart = this.pos;
|
|
1156
|
+
}
|
|
1157
|
+
else if (isNewLine(ch)) {
|
|
1158
|
+
out += this.input.slice(chunkStart, this.pos);
|
|
1159
|
+
++this.pos;
|
|
1160
|
+
if (ch === 13) {
|
|
1161
|
+
if (this.codeAt(this.pos) === 10) {
|
|
1162
|
+
++this.pos;
|
|
1163
|
+
}
|
|
1164
|
+
out += '\n';
|
|
1165
|
+
}
|
|
1166
|
+
else if (ch === 10) {
|
|
1167
|
+
out += '\n';
|
|
1168
|
+
}
|
|
1169
|
+
else {
|
|
1170
|
+
out += String.fromCharCode(ch);
|
|
1171
|
+
}
|
|
1172
|
+
chunkStart = this.pos;
|
|
1173
|
+
}
|
|
1174
|
+
else {
|
|
1175
|
+
++this.pos;
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
readInvalidTemplateToken() {
|
|
1180
|
+
while (this.pos < this.input.length) {
|
|
1181
|
+
const ch = this.input.charCodeAt(this.pos);
|
|
1182
|
+
if (ch === 92) {
|
|
1183
|
+
++this.pos;
|
|
1184
|
+
}
|
|
1185
|
+
else if (ch === 96 || (ch === 36 && this.codeAt(this.pos + 1) === 123)) {
|
|
1186
|
+
this.finishToken(tt.invalidTemplate, this.input.slice(this.start, this.pos));
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
this.pos++;
|
|
1190
|
+
}
|
|
1191
|
+
this.raise(this.start, 'Unterminated template');
|
|
1192
|
+
}
|
|
1193
|
+
readEscapedChar(inTemplate) {
|
|
1194
|
+
const ch = this.codeAt(++this.pos);
|
|
1195
|
+
++this.pos;
|
|
1196
|
+
switch (ch) {
|
|
1197
|
+
case 110:
|
|
1198
|
+
return '\n';
|
|
1199
|
+
case 114:
|
|
1200
|
+
return '\r';
|
|
1201
|
+
case 120:
|
|
1202
|
+
return String.fromCharCode(this.readHexChar(2, true));
|
|
1203
|
+
case 117:
|
|
1204
|
+
return codePointToString(this.readCodePoint());
|
|
1205
|
+
case 116:
|
|
1206
|
+
return '\t';
|
|
1207
|
+
case 98:
|
|
1208
|
+
return '\b';
|
|
1209
|
+
case 118:
|
|
1210
|
+
return '\u000b';
|
|
1211
|
+
case 102:
|
|
1212
|
+
return '\f';
|
|
1213
|
+
case 13:
|
|
1214
|
+
if (this.codeAt(this.pos) === 10) {
|
|
1215
|
+
++this.pos;
|
|
1216
|
+
}
|
|
1217
|
+
return '';
|
|
1218
|
+
case 10:
|
|
1219
|
+
return '';
|
|
1220
|
+
}
|
|
1221
|
+
if (ch === 56 || ch === 57) {
|
|
1222
|
+
if (this.strict) {
|
|
1223
|
+
this.invalidStringToken(this.pos - 1, 'Invalid escape sequence');
|
|
1224
|
+
return '';
|
|
1225
|
+
}
|
|
1226
|
+
if (inTemplate) {
|
|
1227
|
+
this.invalidStringToken(this.pos - 1, 'Invalid escape sequence in template string');
|
|
1228
|
+
return '';
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
if (ch >= 48 && ch <= 55) {
|
|
1232
|
+
let octalEnd = this.pos;
|
|
1233
|
+
while (octalEnd < this.pos + 2 && octalEnd < this.input.length && this.input.charCodeAt(octalEnd) >= 48 && this.input.charCodeAt(octalEnd) <= 55) {
|
|
1234
|
+
octalEnd++;
|
|
1235
|
+
}
|
|
1236
|
+
let octalStr = this.input.slice(this.pos - 1, octalEnd);
|
|
1237
|
+
let octal = parseInt(octalStr, 8);
|
|
1238
|
+
if (octal > 255) {
|
|
1239
|
+
octalStr = octalStr.slice(0, -1);
|
|
1240
|
+
octal = parseInt(octalStr, 8);
|
|
1241
|
+
}
|
|
1242
|
+
this.pos += octalStr.length - 1;
|
|
1243
|
+
const after = this.codeAt(this.pos);
|
|
1244
|
+
if ((octalStr !== '0' || after === 56 || after === 57) && (this.strict || inTemplate)) {
|
|
1245
|
+
this.invalidStringToken(this.pos - 1 - octalStr.length, inTemplate ? 'Octal literal in template string' : 'Octal literal in strict mode');
|
|
1246
|
+
return '';
|
|
1247
|
+
}
|
|
1248
|
+
return String.fromCharCode(octal);
|
|
1249
|
+
}
|
|
1250
|
+
if (ch === -1 || isNewLine(ch)) {
|
|
1251
|
+
return '';
|
|
1252
|
+
}
|
|
1253
|
+
return String.fromCharCode(ch);
|
|
1254
|
+
}
|
|
1255
|
+
readHexChar(len, hasLen) {
|
|
1256
|
+
const codePos = this.pos;
|
|
1257
|
+
const n = this.readInt(16, len, hasLen);
|
|
1258
|
+
if (n === -1) {
|
|
1259
|
+
this.invalidStringToken(codePos, 'Bad character escape sequence');
|
|
1260
|
+
return 0;
|
|
1261
|
+
}
|
|
1262
|
+
return n;
|
|
1263
|
+
}
|
|
1264
|
+
readWord1() {
|
|
1265
|
+
this.containsEsc = false;
|
|
1266
|
+
let word = '';
|
|
1267
|
+
let first = true;
|
|
1268
|
+
let chunkStart = this.pos;
|
|
1269
|
+
while (this.pos < this.input.length) {
|
|
1270
|
+
const ch = this.fullCharCodeAtPos();
|
|
1271
|
+
if (isIdentifierChar(ch)) {
|
|
1272
|
+
this.pos += ch <= 0xffff ? 1 : 2;
|
|
1273
|
+
}
|
|
1274
|
+
else if (ch === 92) {
|
|
1275
|
+
this.containsEsc = true;
|
|
1276
|
+
word += this.input.slice(chunkStart, this.pos);
|
|
1277
|
+
const escStart = this.pos;
|
|
1278
|
+
if (this.codeAt(++this.pos) !== 117) {
|
|
1279
|
+
this.invalidStringToken(this.pos, 'Expecting Unicode escape sequence \\uXXXX');
|
|
1280
|
+
}
|
|
1281
|
+
++this.pos;
|
|
1282
|
+
const esc = this.readCodePoint();
|
|
1283
|
+
if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc))) {
|
|
1284
|
+
this.invalidStringToken(escStart, 'Invalid Unicode escape');
|
|
1285
|
+
}
|
|
1286
|
+
word += codePointToString(esc);
|
|
1287
|
+
chunkStart = this.pos;
|
|
1288
|
+
}
|
|
1289
|
+
else {
|
|
1290
|
+
break;
|
|
1291
|
+
}
|
|
1292
|
+
first = false;
|
|
1293
|
+
}
|
|
1294
|
+
return word + this.input.slice(chunkStart, this.pos);
|
|
1295
|
+
}
|
|
1296
|
+
readWord() {
|
|
1297
|
+
const word = this.readWord1();
|
|
1298
|
+
let type = tt.name;
|
|
1299
|
+
const keyword = keywordTypes.get(word);
|
|
1300
|
+
if (keyword !== undefined) {
|
|
1301
|
+
type = keyword;
|
|
1302
|
+
}
|
|
1303
|
+
this.finishToken(type, word);
|
|
1304
|
+
}
|
|
1305
|
+
// ## Parser utilities
|
|
1306
|
+
startNode() {
|
|
1307
|
+
return { type: '', start: this.start, end: 0 };
|
|
1308
|
+
}
|
|
1309
|
+
startNodeAt(pos) {
|
|
1310
|
+
return { type: '', start: pos, end: 0 };
|
|
1311
|
+
}
|
|
1312
|
+
finishNode(node, type) {
|
|
1313
|
+
node.type = type;
|
|
1314
|
+
node.end = this.lastTokEnd;
|
|
1315
|
+
return node;
|
|
1316
|
+
}
|
|
1317
|
+
finishNodeAt(node, type, pos) {
|
|
1318
|
+
node.type = type;
|
|
1319
|
+
node.end = pos;
|
|
1320
|
+
return node;
|
|
1321
|
+
}
|
|
1322
|
+
copyIdentifier(node) {
|
|
1323
|
+
return { type: node.type, start: node.start, end: node.end, name: node.name };
|
|
1324
|
+
}
|
|
1325
|
+
eat(type) {
|
|
1326
|
+
if (this.type === type) {
|
|
1327
|
+
this.next(false);
|
|
1328
|
+
return true;
|
|
1329
|
+
}
|
|
1330
|
+
return false;
|
|
1331
|
+
}
|
|
1332
|
+
isContextual(name) {
|
|
1333
|
+
return this.type === tt.name && this.value === name && !this.containsEsc;
|
|
1334
|
+
}
|
|
1335
|
+
canInsertSemicolon() {
|
|
1336
|
+
return this.type === tt.eof || this.type === tt.braceR || this.hasLineBreak(this.lastTokEnd, this.start);
|
|
1337
|
+
}
|
|
1338
|
+
semicolon() {
|
|
1339
|
+
if (!this.eat(tt.semi) && !this.canInsertSemicolon()) {
|
|
1340
|
+
this.unexpected(this.start);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
afterTrailingComma(tokType, notNext) {
|
|
1344
|
+
if (this.type === tokType) {
|
|
1345
|
+
if (!notNext) {
|
|
1346
|
+
this.next(false);
|
|
1347
|
+
}
|
|
1348
|
+
return true;
|
|
1349
|
+
}
|
|
1350
|
+
return false;
|
|
1351
|
+
}
|
|
1352
|
+
expect(type) {
|
|
1353
|
+
if (!this.eat(type)) {
|
|
1354
|
+
this.unexpected(this.start);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
checkPatternErrors(refErrors, isAssign) {
|
|
1358
|
+
if (refErrors == null) {
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
if (refErrors.trailingComma > -1) {
|
|
1362
|
+
this.raise(refErrors.trailingComma, 'Comma is not permitted after the rest element');
|
|
1363
|
+
}
|
|
1364
|
+
const parens = isAssign ? refErrors.parenthesizedAssign : refErrors.parenthesizedBind;
|
|
1365
|
+
if (parens > -1) {
|
|
1366
|
+
this.raise(parens, isAssign ? 'Assigning to rvalue' : 'Parenthesized pattern');
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
checkExpressionErrors(refErrors, andThrow) {
|
|
1370
|
+
if (refErrors == null) {
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
if (!andThrow) {
|
|
1374
|
+
return refErrors.shorthandAssign >= 0 || refErrors.doubleProto >= 0;
|
|
1375
|
+
}
|
|
1376
|
+
if (refErrors.shorthandAssign >= 0) {
|
|
1377
|
+
this.raise(refErrors.shorthandAssign, 'Shorthand property assignments are valid only in destructuring patterns');
|
|
1378
|
+
}
|
|
1379
|
+
if (refErrors.doubleProto >= 0) {
|
|
1380
|
+
this.raise(refErrors.doubleProto, 'Redefinition of __proto__ property');
|
|
1381
|
+
}
|
|
1382
|
+
return false;
|
|
1383
|
+
}
|
|
1384
|
+
checkYieldAwaitInDefaultParams() {
|
|
1385
|
+
if (this.yieldPos !== 0 && (this.awaitPos === 0 || this.yieldPos < this.awaitPos)) {
|
|
1386
|
+
this.raise(this.yieldPos, 'Yield expression cannot be a default value');
|
|
1387
|
+
}
|
|
1388
|
+
if (this.awaitPos !== 0) {
|
|
1389
|
+
this.raise(this.awaitPos, 'Await expression cannot be a default value');
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
isSimpleAssignTarget(expr) {
|
|
1393
|
+
return expr.type === 'Identifier' || expr.type === 'MemberExpression';
|
|
1394
|
+
}
|
|
1395
|
+
// ## Statements
|
|
1396
|
+
parseProgram() {
|
|
1397
|
+
this.nextToken();
|
|
1398
|
+
let expression = undefined;
|
|
1399
|
+
while (this.type !== tt.eof) {
|
|
1400
|
+
const statement = this.parseStatement('', true);
|
|
1401
|
+
if (expression === undefined && statement.type === 'ExpressionStatement') {
|
|
1402
|
+
expression = statement.expression;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
return expression;
|
|
1406
|
+
}
|
|
1407
|
+
isLet(context) {
|
|
1408
|
+
if (!this.isContextual('let')) {
|
|
1409
|
+
return false;
|
|
1410
|
+
}
|
|
1411
|
+
const next = this.skipWhiteSpaceFrom(this.pos);
|
|
1412
|
+
let nextCh = this.codeAt(next);
|
|
1413
|
+
if (nextCh === 91 || nextCh === 92) {
|
|
1414
|
+
return true;
|
|
1415
|
+
}
|
|
1416
|
+
if (context !== '') {
|
|
1417
|
+
return false;
|
|
1418
|
+
}
|
|
1419
|
+
if (nextCh === 123 || (nextCh > 0xd7ff && nextCh < 0xdc00)) {
|
|
1420
|
+
return true;
|
|
1421
|
+
}
|
|
1422
|
+
if (isIdentifierStart(nextCh)) {
|
|
1423
|
+
let p = next + 1;
|
|
1424
|
+
while (isIdentifierChar((nextCh = this.codeAt(p)))) {
|
|
1425
|
+
++p;
|
|
1426
|
+
}
|
|
1427
|
+
if (nextCh === 92 || (nextCh > 0xd7ff && nextCh < 0xdc00)) {
|
|
1428
|
+
return true;
|
|
1429
|
+
}
|
|
1430
|
+
if (!RELATIONAL_KEYWORD.test(this.input.slice(next, p))) {
|
|
1431
|
+
return true;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
return false;
|
|
1435
|
+
}
|
|
1436
|
+
isAsyncFunction() {
|
|
1437
|
+
if (!this.isContextual('async')) {
|
|
1438
|
+
return false;
|
|
1439
|
+
}
|
|
1440
|
+
const next = this.skipWhiteSpaceFrom(this.pos);
|
|
1441
|
+
if (this.hasLineBreak(this.pos, next) || this.input.slice(next, next + 8) !== 'function') {
|
|
1442
|
+
return false;
|
|
1443
|
+
}
|
|
1444
|
+
if (next + 8 === this.input.length) {
|
|
1445
|
+
return true;
|
|
1446
|
+
}
|
|
1447
|
+
const after = this.codeAt(next + 8);
|
|
1448
|
+
return !(isIdentifierChar(after) || (after > 0xd7ff && after < 0xdc00));
|
|
1449
|
+
}
|
|
1450
|
+
parseStatement(context, topLevel) {
|
|
1451
|
+
const starttype = this.type;
|
|
1452
|
+
const node = this.startNode();
|
|
1453
|
+
if (this.isLet(context)) {
|
|
1454
|
+
this.unsupported(this.start, 'let declaration');
|
|
1455
|
+
}
|
|
1456
|
+
if (UNSUPPORTED_STATEMENT_KEYWORDS.has(starttype)) {
|
|
1457
|
+
return this.unsupported(this.start, starttype.keyword + ' statement');
|
|
1458
|
+
}
|
|
1459
|
+
if (starttype === tt._return) {
|
|
1460
|
+
return this.raise(this.start, "'return' outside of function");
|
|
1461
|
+
}
|
|
1462
|
+
if (starttype === tt._debugger) {
|
|
1463
|
+
this.next(false);
|
|
1464
|
+
this.semicolon();
|
|
1465
|
+
return this.finishNode(node, 'DebuggerStatement');
|
|
1466
|
+
}
|
|
1467
|
+
if (starttype === tt.braceL) {
|
|
1468
|
+
return this.parseBlock(node);
|
|
1469
|
+
}
|
|
1470
|
+
if (starttype === tt.semi) {
|
|
1471
|
+
this.next(false);
|
|
1472
|
+
return this.finishNode(node, 'EmptyStatement');
|
|
1473
|
+
}
|
|
1474
|
+
if (starttype === tt._import || starttype === tt._export) {
|
|
1475
|
+
if (starttype === tt._import) {
|
|
1476
|
+
const nextCh = this.codeAt(this.skipWhiteSpaceFrom(this.pos));
|
|
1477
|
+
if (nextCh === 40 || nextCh === 46) {
|
|
1478
|
+
return this.parseExpressionStatement(node, this.parseExpression(null));
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
if (!topLevel) {
|
|
1482
|
+
return this.raise(this.start, "'import' and 'export' may only appear at the top level");
|
|
1483
|
+
}
|
|
1484
|
+
return this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
|
|
1485
|
+
}
|
|
1486
|
+
if (this.isAsyncFunction()) {
|
|
1487
|
+
return this.unsupported(this.start, 'async function');
|
|
1488
|
+
}
|
|
1489
|
+
const maybeName = this.value;
|
|
1490
|
+
const expr = this.parseExpression(null);
|
|
1491
|
+
if (starttype === tt.name && expr.type === 'Identifier' && this.eat(tt.colon)) {
|
|
1492
|
+
return this.parseLabeledStatement(node, maybeName, expr, context);
|
|
1493
|
+
}
|
|
1494
|
+
return this.parseExpressionStatement(node, expr);
|
|
1495
|
+
}
|
|
1496
|
+
parseLabeledStatement(node, maybeName, expr, context) {
|
|
1497
|
+
for (let i = 0; i < this.labels.length; i++) {
|
|
1498
|
+
if (this.labels[i] === maybeName) {
|
|
1499
|
+
this.raise(expr.start, "Label '" + maybeName + "' is already declared");
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
this.labels.push(maybeName);
|
|
1503
|
+
node.body = this.parseStatement(context !== '' ? (context.indexOf('label') === -1 ? context + 'label' : context) : 'label', false);
|
|
1504
|
+
this.labels.pop();
|
|
1505
|
+
node.label = expr;
|
|
1506
|
+
return this.finishNode(node, 'LabeledStatement');
|
|
1507
|
+
}
|
|
1508
|
+
parseExpressionStatement(node, expr) {
|
|
1509
|
+
node.expression = expr;
|
|
1510
|
+
this.semicolon();
|
|
1511
|
+
return this.finishNode(node, 'ExpressionStatement');
|
|
1512
|
+
}
|
|
1513
|
+
parseBlock(node) {
|
|
1514
|
+
const body = [];
|
|
1515
|
+
node.body = body;
|
|
1516
|
+
this.expect(tt.braceL);
|
|
1517
|
+
while (this.type !== tt.braceR) {
|
|
1518
|
+
body.push(this.parseStatement('', false));
|
|
1519
|
+
}
|
|
1520
|
+
this.next(false);
|
|
1521
|
+
return this.finishNode(node, 'BlockStatement');
|
|
1522
|
+
}
|
|
1523
|
+
// ## Expressions
|
|
1524
|
+
parseExpression(refErrors) {
|
|
1525
|
+
const startPos = this.start;
|
|
1526
|
+
const expr = this.parseMaybeAssign(refErrors);
|
|
1527
|
+
if (this.type === tt.comma) {
|
|
1528
|
+
const node = this.startNodeAt(startPos);
|
|
1529
|
+
const expressions = [expr];
|
|
1530
|
+
node.expressions = expressions;
|
|
1531
|
+
while (this.eat(tt.comma)) {
|
|
1532
|
+
expressions.push(this.parseMaybeAssign(refErrors));
|
|
1533
|
+
}
|
|
1534
|
+
return this.finishNode(node, 'SequenceExpression');
|
|
1535
|
+
}
|
|
1536
|
+
return expr;
|
|
1537
|
+
}
|
|
1538
|
+
parseMaybeAssign(refErrorsIn) {
|
|
1539
|
+
if (this.isContextual('yield')) {
|
|
1540
|
+
this.exprAllowed = false;
|
|
1541
|
+
}
|
|
1542
|
+
let refErrors = refErrorsIn;
|
|
1543
|
+
let ownDestructuringErrors = false;
|
|
1544
|
+
let oldParenAssign = -1;
|
|
1545
|
+
let oldTrailingComma = -1;
|
|
1546
|
+
let oldDoubleProto = -1;
|
|
1547
|
+
if (refErrors != null) {
|
|
1548
|
+
oldParenAssign = refErrors.parenthesizedAssign;
|
|
1549
|
+
oldTrailingComma = refErrors.trailingComma;
|
|
1550
|
+
oldDoubleProto = refErrors.doubleProto;
|
|
1551
|
+
refErrors.parenthesizedAssign = -1;
|
|
1552
|
+
refErrors.trailingComma = -1;
|
|
1553
|
+
}
|
|
1554
|
+
else {
|
|
1555
|
+
refErrors = new DestructuringErrors();
|
|
1556
|
+
ownDestructuringErrors = true;
|
|
1557
|
+
}
|
|
1558
|
+
const startPos = this.start;
|
|
1559
|
+
if (this.type === tt.parenL || this.type === tt.name) {
|
|
1560
|
+
this.potentialArrowAt = this.start;
|
|
1561
|
+
}
|
|
1562
|
+
let left = this.parseMaybeConditional(refErrors);
|
|
1563
|
+
if (this.type.isAssign) {
|
|
1564
|
+
const node = this.startNodeAt(startPos);
|
|
1565
|
+
node.operator = this.value;
|
|
1566
|
+
if (this.type === tt.eq) {
|
|
1567
|
+
left = this.toAssignable(left, false, refErrors);
|
|
1568
|
+
}
|
|
1569
|
+
if (!ownDestructuringErrors) {
|
|
1570
|
+
refErrors.parenthesizedAssign = -1;
|
|
1571
|
+
refErrors.trailingComma = -1;
|
|
1572
|
+
refErrors.doubleProto = -1;
|
|
1573
|
+
}
|
|
1574
|
+
if (refErrors.shorthandAssign >= left.start) {
|
|
1575
|
+
refErrors.shorthandAssign = -1;
|
|
1576
|
+
}
|
|
1577
|
+
if (this.type === tt.eq) {
|
|
1578
|
+
this.checkLValPattern(left, BIND_NONE, null);
|
|
1579
|
+
}
|
|
1580
|
+
else {
|
|
1581
|
+
this.checkLValSimple(left, BIND_NONE, null);
|
|
1582
|
+
}
|
|
1583
|
+
node.left = left;
|
|
1584
|
+
this.next(false);
|
|
1585
|
+
node.right = this.parseMaybeAssign(null);
|
|
1586
|
+
if (oldDoubleProto > -1) {
|
|
1587
|
+
refErrors.doubleProto = oldDoubleProto;
|
|
1588
|
+
}
|
|
1589
|
+
return this.finishNode(node, 'AssignmentExpression');
|
|
1590
|
+
}
|
|
1591
|
+
else if (ownDestructuringErrors) {
|
|
1592
|
+
this.checkExpressionErrors(refErrors, true);
|
|
1593
|
+
}
|
|
1594
|
+
if (oldParenAssign > -1) {
|
|
1595
|
+
refErrors.parenthesizedAssign = oldParenAssign;
|
|
1596
|
+
}
|
|
1597
|
+
if (oldTrailingComma > -1) {
|
|
1598
|
+
refErrors.trailingComma = oldTrailingComma;
|
|
1599
|
+
}
|
|
1600
|
+
return left;
|
|
1601
|
+
}
|
|
1602
|
+
parseMaybeConditional(refErrors) {
|
|
1603
|
+
const startPos = this.start;
|
|
1604
|
+
const expr = this.parseExprOps(refErrors);
|
|
1605
|
+
if (this.checkExpressionErrors(refErrors, false)) {
|
|
1606
|
+
return expr;
|
|
1607
|
+
}
|
|
1608
|
+
if (this.eat(tt.question)) {
|
|
1609
|
+
const node = this.startNodeAt(startPos);
|
|
1610
|
+
node.test = expr;
|
|
1611
|
+
node.consequent = this.parseMaybeAssign(null);
|
|
1612
|
+
this.expect(tt.colon);
|
|
1613
|
+
node.alternate = this.parseMaybeAssign(null);
|
|
1614
|
+
return this.finishNode(node, 'ConditionalExpression');
|
|
1615
|
+
}
|
|
1616
|
+
return expr;
|
|
1617
|
+
}
|
|
1618
|
+
parseExprOps(refErrors) {
|
|
1619
|
+
const startPos = this.start;
|
|
1620
|
+
const expr = this.parseMaybeUnary(refErrors, false, false);
|
|
1621
|
+
if (this.checkExpressionErrors(refErrors, false)) {
|
|
1622
|
+
return expr;
|
|
1623
|
+
}
|
|
1624
|
+
if (expr.start === startPos && expr.type === 'ArrowFunctionExpression') {
|
|
1625
|
+
return expr;
|
|
1626
|
+
}
|
|
1627
|
+
return this.parseExprOp(expr, startPos, -1);
|
|
1628
|
+
}
|
|
1629
|
+
parseExprOp(left, leftStartPos, minPrec) {
|
|
1630
|
+
let prec = this.type.binop;
|
|
1631
|
+
if (prec !== -1 && prec > minPrec) {
|
|
1632
|
+
const logical = this.type === tt.logicalOR || this.type === tt.logicalAND;
|
|
1633
|
+
const coalesce = this.type === tt.coalesce;
|
|
1634
|
+
if (coalesce) {
|
|
1635
|
+
// `??` binds like `&&` so its right side cannot absorb a mixed `||`/`&&`.
|
|
1636
|
+
prec = tt.logicalAND.binop;
|
|
1637
|
+
}
|
|
1638
|
+
const op = this.value;
|
|
1639
|
+
this.next(false);
|
|
1640
|
+
const startPos = this.start;
|
|
1641
|
+
const right = this.parseExprOp(this.parseMaybeUnary(null, false, false), startPos, prec);
|
|
1642
|
+
const node = this.buildBinary(leftStartPos, left, right, op, logical || coalesce);
|
|
1643
|
+
if ((logical && this.type === tt.coalesce) || (coalesce && (this.type === tt.logicalOR || this.type === tt.logicalAND))) {
|
|
1644
|
+
this.raise(this.start, 'Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses');
|
|
1645
|
+
}
|
|
1646
|
+
return this.parseExprOp(node, leftStartPos, minPrec);
|
|
1647
|
+
}
|
|
1648
|
+
return left;
|
|
1649
|
+
}
|
|
1650
|
+
buildBinary(startPos, left, right, op, logical) {
|
|
1651
|
+
const node = this.startNodeAt(startPos);
|
|
1652
|
+
node.left = left;
|
|
1653
|
+
node.operator = op;
|
|
1654
|
+
node.right = right;
|
|
1655
|
+
return this.finishNode(node, logical ? 'LogicalExpression' : 'BinaryExpression');
|
|
1656
|
+
}
|
|
1657
|
+
parseMaybeUnary(refErrors, sawUnaryIn, incDec) {
|
|
1658
|
+
let sawUnary = sawUnaryIn;
|
|
1659
|
+
const startPos = this.start;
|
|
1660
|
+
let expr;
|
|
1661
|
+
if (this.isContextual('await') && this.canAwait()) {
|
|
1662
|
+
expr = this.parseAwait();
|
|
1663
|
+
sawUnary = true;
|
|
1664
|
+
}
|
|
1665
|
+
else if (this.type.prefix) {
|
|
1666
|
+
const node = this.startNode();
|
|
1667
|
+
const update = this.type === tt.incDec;
|
|
1668
|
+
node.operator = this.value;
|
|
1669
|
+
node.prefix = true;
|
|
1670
|
+
this.next(false);
|
|
1671
|
+
node.argument = this.parseMaybeUnary(null, true, update);
|
|
1672
|
+
this.checkExpressionErrors(refErrors, true);
|
|
1673
|
+
if (update) {
|
|
1674
|
+
this.checkLValSimple(node.argument, BIND_NONE, null);
|
|
1675
|
+
}
|
|
1676
|
+
else if (this.strict && node.operator === 'delete' && isLocalVariableAccess(node.argument)) {
|
|
1677
|
+
this.raise(node.start, 'Deleting local variable in strict mode');
|
|
1678
|
+
}
|
|
1679
|
+
else {
|
|
1680
|
+
sawUnary = true;
|
|
1681
|
+
}
|
|
1682
|
+
expr = this.finishNode(node, update ? 'UpdateExpression' : 'UnaryExpression');
|
|
1683
|
+
}
|
|
1684
|
+
else {
|
|
1685
|
+
expr = this.parseExprSubscripts(refErrors);
|
|
1686
|
+
if (this.checkExpressionErrors(refErrors, false)) {
|
|
1687
|
+
return expr;
|
|
1688
|
+
}
|
|
1689
|
+
while (this.type.postfix && !this.canInsertSemicolon()) {
|
|
1690
|
+
const node = this.startNodeAt(startPos);
|
|
1691
|
+
node.operator = this.value;
|
|
1692
|
+
node.prefix = false;
|
|
1693
|
+
node.argument = expr;
|
|
1694
|
+
this.checkLValSimple(expr, BIND_NONE, null);
|
|
1695
|
+
this.next(false);
|
|
1696
|
+
expr = this.finishNode(node, 'UpdateExpression');
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
if (!incDec && this.eat(tt.starstar)) {
|
|
1700
|
+
if (sawUnary) {
|
|
1701
|
+
this.unexpected(this.lastTokStart);
|
|
1702
|
+
}
|
|
1703
|
+
return this.buildBinary(startPos, expr, this.parseMaybeUnary(null, false, false), '**', false);
|
|
1704
|
+
}
|
|
1705
|
+
return expr;
|
|
1706
|
+
}
|
|
1707
|
+
parseExprSubscripts(refErrors) {
|
|
1708
|
+
const startPos = this.start;
|
|
1709
|
+
const expr = this.parseExprAtom(refErrors, false);
|
|
1710
|
+
if (expr.type === 'ArrowFunctionExpression' && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ')') {
|
|
1711
|
+
return expr;
|
|
1712
|
+
}
|
|
1713
|
+
const result = this.parseSubscripts(expr, startPos, false);
|
|
1714
|
+
if (refErrors != null && result.type === 'MemberExpression') {
|
|
1715
|
+
if (refErrors.parenthesizedAssign >= result.start) {
|
|
1716
|
+
refErrors.parenthesizedAssign = -1;
|
|
1717
|
+
}
|
|
1718
|
+
if (refErrors.parenthesizedBind >= result.start) {
|
|
1719
|
+
refErrors.parenthesizedBind = -1;
|
|
1720
|
+
}
|
|
1721
|
+
if (refErrors.trailingComma >= result.start) {
|
|
1722
|
+
refErrors.trailingComma = -1;
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
return result;
|
|
1726
|
+
}
|
|
1727
|
+
parseSubscripts(baseIn, startPos, noCalls) {
|
|
1728
|
+
let base = baseIn;
|
|
1729
|
+
const maybeAsyncArrow = base.type === 'Identifier' && base.name === 'async' && this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && this.potentialArrowAt === base.start;
|
|
1730
|
+
let optionalChained = false;
|
|
1731
|
+
for (;;) {
|
|
1732
|
+
let element = this.parseSubscript(base, startPos, noCalls, maybeAsyncArrow, optionalChained);
|
|
1733
|
+
if (element.optional === true) {
|
|
1734
|
+
optionalChained = true;
|
|
1735
|
+
}
|
|
1736
|
+
if (element === base || element.type === 'ArrowFunctionExpression') {
|
|
1737
|
+
if (optionalChained) {
|
|
1738
|
+
const chainNode = this.startNodeAt(startPos);
|
|
1739
|
+
chainNode.expression = element;
|
|
1740
|
+
element = this.finishNode(chainNode, 'ChainExpression');
|
|
1741
|
+
}
|
|
1742
|
+
return element;
|
|
1743
|
+
}
|
|
1744
|
+
base = element;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
parseSubscript(base, startPos, noCalls, maybeAsyncArrow, optionalChained) {
|
|
1748
|
+
const optional = this.eat(tt.questionDot);
|
|
1749
|
+
if (noCalls && optional) {
|
|
1750
|
+
this.raise(this.lastTokStart, 'Optional chaining cannot appear in the callee of new expressions');
|
|
1751
|
+
}
|
|
1752
|
+
const computed = this.eat(tt.bracketL);
|
|
1753
|
+
if (computed || (optional && this.type !== tt.parenL && this.type !== tt.backQuote) || this.eat(tt.dot)) {
|
|
1754
|
+
const node = this.startNodeAt(startPos);
|
|
1755
|
+
node.object = base;
|
|
1756
|
+
if (computed) {
|
|
1757
|
+
node.property = this.parseExpression(null);
|
|
1758
|
+
this.expect(tt.bracketR);
|
|
1759
|
+
}
|
|
1760
|
+
else {
|
|
1761
|
+
node.property = this.parseIdent(true);
|
|
1762
|
+
}
|
|
1763
|
+
node.computed = computed;
|
|
1764
|
+
node.optional = optional;
|
|
1765
|
+
return this.finishNode(node, 'MemberExpression');
|
|
1766
|
+
}
|
|
1767
|
+
if (!noCalls && this.eat(tt.parenL)) {
|
|
1768
|
+
const refErrors = new DestructuringErrors();
|
|
1769
|
+
const oldYieldPos = this.yieldPos;
|
|
1770
|
+
const oldAwaitPos = this.awaitPos;
|
|
1771
|
+
const oldAwaitIdentPos = this.awaitIdentPos;
|
|
1772
|
+
this.yieldPos = 0;
|
|
1773
|
+
this.awaitPos = 0;
|
|
1774
|
+
this.awaitIdentPos = 0;
|
|
1775
|
+
const exprList = this.parseExprList(tt.parenR, true, false, refErrors);
|
|
1776
|
+
if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
|
|
1777
|
+
this.checkPatternErrors(refErrors, false);
|
|
1778
|
+
this.checkYieldAwaitInDefaultParams();
|
|
1779
|
+
if (this.awaitIdentPos > 0) {
|
|
1780
|
+
this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function");
|
|
1781
|
+
}
|
|
1782
|
+
this.yieldPos = oldYieldPos;
|
|
1783
|
+
this.awaitPos = oldAwaitPos;
|
|
1784
|
+
this.awaitIdentPos = oldAwaitIdentPos;
|
|
1785
|
+
return this.parseArrowExpression(this.startNodeAt(startPos), exprList, true);
|
|
1786
|
+
}
|
|
1787
|
+
this.checkExpressionErrors(refErrors, true);
|
|
1788
|
+
this.yieldPos = oldYieldPos || this.yieldPos;
|
|
1789
|
+
this.awaitPos = oldAwaitPos || this.awaitPos;
|
|
1790
|
+
this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;
|
|
1791
|
+
const node = this.startNodeAt(startPos);
|
|
1792
|
+
node.callee = base;
|
|
1793
|
+
node.arguments = exprList;
|
|
1794
|
+
node.optional = optional;
|
|
1795
|
+
return this.finishNode(node, 'CallExpression');
|
|
1796
|
+
}
|
|
1797
|
+
if (this.type === tt.backQuote) {
|
|
1798
|
+
if (optional || optionalChained) {
|
|
1799
|
+
this.raise(this.start, 'Optional chaining cannot appear in the tag of tagged template expressions');
|
|
1800
|
+
}
|
|
1801
|
+
const node = this.startNodeAt(startPos);
|
|
1802
|
+
node.tag = base;
|
|
1803
|
+
node.quasi = this.parseTemplate(true);
|
|
1804
|
+
return this.finishNode(node, 'TaggedTemplateExpression');
|
|
1805
|
+
}
|
|
1806
|
+
return base;
|
|
1807
|
+
}
|
|
1808
|
+
parseExprAtom(refErrors, forNew) {
|
|
1809
|
+
// A `/` the tokenizer read as division is a regexp when an operand is expected.
|
|
1810
|
+
if (this.type === tt.slash) {
|
|
1811
|
+
this.readRegexp();
|
|
1812
|
+
}
|
|
1813
|
+
const canBeArrow = this.potentialArrowAt === this.start;
|
|
1814
|
+
const type = this.type;
|
|
1815
|
+
if (type === tt._super) {
|
|
1816
|
+
return this.raise(this.start, "'super' keyword outside a method");
|
|
1817
|
+
}
|
|
1818
|
+
if (type === tt._this) {
|
|
1819
|
+
const node = this.startNode();
|
|
1820
|
+
this.next(false);
|
|
1821
|
+
return this.finishNode(node, 'ThisExpression');
|
|
1822
|
+
}
|
|
1823
|
+
if (type === tt.name) {
|
|
1824
|
+
const startPos = this.start;
|
|
1825
|
+
const containsEsc = this.containsEsc;
|
|
1826
|
+
let id = this.parseIdent(false);
|
|
1827
|
+
if (!containsEsc && id.name === 'async' && !this.canInsertSemicolon() && this.type === tt._function) {
|
|
1828
|
+
return this.unsupported(this.start, 'async function expression');
|
|
1829
|
+
}
|
|
1830
|
+
if (canBeArrow && !this.canInsertSemicolon()) {
|
|
1831
|
+
if (this.eat(tt.arrow)) {
|
|
1832
|
+
return this.parseArrowExpression(this.startNodeAt(startPos), [id], false);
|
|
1833
|
+
}
|
|
1834
|
+
if (id.name === 'async' && this.type === tt.name && !containsEsc) {
|
|
1835
|
+
id = this.parseIdent(false);
|
|
1836
|
+
if (this.canInsertSemicolon() || !this.eat(tt.arrow)) {
|
|
1837
|
+
this.unexpected(this.start);
|
|
1838
|
+
}
|
|
1839
|
+
return this.parseArrowExpression(this.startNodeAt(startPos), [id], true);
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
return id;
|
|
1843
|
+
}
|
|
1844
|
+
if (type === tt.regexp) {
|
|
1845
|
+
const pattern = this.regexPattern;
|
|
1846
|
+
const flags = this.regexFlags;
|
|
1847
|
+
const node = this.parseLiteral(this.regexValue);
|
|
1848
|
+
node.regex = { pattern: pattern, flags: flags };
|
|
1849
|
+
return node;
|
|
1850
|
+
}
|
|
1851
|
+
if (type === tt.num) {
|
|
1852
|
+
return this.parseLiteral(this.numValue);
|
|
1853
|
+
}
|
|
1854
|
+
if (type === tt.string) {
|
|
1855
|
+
return this.parseLiteral(this.value);
|
|
1856
|
+
}
|
|
1857
|
+
if (type === tt._null || type === tt._true || type === tt._false) {
|
|
1858
|
+
const node = this.startNode();
|
|
1859
|
+
node.value = type === tt._null ? null : type === tt._true;
|
|
1860
|
+
node.raw = type.keyword;
|
|
1861
|
+
this.next(false);
|
|
1862
|
+
return this.finishNode(node, 'Literal');
|
|
1863
|
+
}
|
|
1864
|
+
if (type === tt.parenL) {
|
|
1865
|
+
const start = this.start;
|
|
1866
|
+
const expr = this.parseParenAndDistinguishExpression(canBeArrow);
|
|
1867
|
+
if (refErrors != null) {
|
|
1868
|
+
if (refErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) {
|
|
1869
|
+
refErrors.parenthesizedAssign = start;
|
|
1870
|
+
}
|
|
1871
|
+
if (refErrors.parenthesizedBind < 0) {
|
|
1872
|
+
refErrors.parenthesizedBind = start;
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
return expr;
|
|
1876
|
+
}
|
|
1877
|
+
if (type === tt.bracketL) {
|
|
1878
|
+
const node = this.startNode();
|
|
1879
|
+
this.next(false);
|
|
1880
|
+
node.elements = this.parseExprList(tt.bracketR, true, true, refErrors);
|
|
1881
|
+
return this.finishNode(node, 'ArrayExpression');
|
|
1882
|
+
}
|
|
1883
|
+
if (type === tt.braceL) {
|
|
1884
|
+
this.overrideContext(ctxBExpr);
|
|
1885
|
+
return this.parseObj(false, refErrors);
|
|
1886
|
+
}
|
|
1887
|
+
if (type === tt._function) {
|
|
1888
|
+
return this.unsupported(this.start, 'function expression');
|
|
1889
|
+
}
|
|
1890
|
+
if (type === tt._class) {
|
|
1891
|
+
return this.unsupported(this.start, 'class expression');
|
|
1892
|
+
}
|
|
1893
|
+
if (type === tt._new) {
|
|
1894
|
+
return this.parseNew();
|
|
1895
|
+
}
|
|
1896
|
+
if (type === tt.backQuote) {
|
|
1897
|
+
return this.parseTemplate(false);
|
|
1898
|
+
}
|
|
1899
|
+
if (type === tt._import) {
|
|
1900
|
+
return this.parseExprImport(forNew);
|
|
1901
|
+
}
|
|
1902
|
+
return this.unexpected(this.start);
|
|
1903
|
+
}
|
|
1904
|
+
parseExprImport(forNew) {
|
|
1905
|
+
const node = this.startNode();
|
|
1906
|
+
if (this.containsEsc) {
|
|
1907
|
+
this.raise(this.start, 'Escape sequence in keyword import');
|
|
1908
|
+
}
|
|
1909
|
+
this.next(false);
|
|
1910
|
+
if (this.type === tt.parenL && !forNew) {
|
|
1911
|
+
this.next(false);
|
|
1912
|
+
node.source = this.parseMaybeAssign(null);
|
|
1913
|
+
if (!this.eat(tt.parenR)) {
|
|
1914
|
+
const errorPos = this.start;
|
|
1915
|
+
if (this.eat(tt.comma) && this.eat(tt.parenR)) {
|
|
1916
|
+
this.raise(errorPos, 'Trailing comma is not allowed in import()');
|
|
1917
|
+
}
|
|
1918
|
+
this.unexpected(errorPos);
|
|
1919
|
+
}
|
|
1920
|
+
return this.finishNode(node, 'ImportExpression');
|
|
1921
|
+
}
|
|
1922
|
+
if (this.type === tt.dot) {
|
|
1923
|
+
return this.raise(node.start, "Cannot use 'import.meta' outside a module");
|
|
1924
|
+
}
|
|
1925
|
+
return this.unexpected(this.start);
|
|
1926
|
+
}
|
|
1927
|
+
parseLiteral(value) {
|
|
1928
|
+
const node = this.startNode();
|
|
1929
|
+
node.value = value;
|
|
1930
|
+
const raw = this.input.slice(this.start, this.end);
|
|
1931
|
+
node.raw = raw;
|
|
1932
|
+
if (raw.charCodeAt(raw.length - 1) === 110) {
|
|
1933
|
+
node.bigint = value != null ? value.toString() : raw.slice(0, -1).replace(UNDERSCORES, '');
|
|
1934
|
+
}
|
|
1935
|
+
this.next(false);
|
|
1936
|
+
return this.finishNode(node, 'Literal');
|
|
1937
|
+
}
|
|
1938
|
+
parseParenAndDistinguishExpression(canBeArrow) {
|
|
1939
|
+
const startPos = this.start;
|
|
1940
|
+
this.next(false);
|
|
1941
|
+
const innerStartPos = this.start;
|
|
1942
|
+
const exprList = [];
|
|
1943
|
+
let first = true;
|
|
1944
|
+
let lastIsComma = false;
|
|
1945
|
+
const refErrors = new DestructuringErrors();
|
|
1946
|
+
const oldYieldPos = this.yieldPos;
|
|
1947
|
+
const oldAwaitPos = this.awaitPos;
|
|
1948
|
+
let spreadStart = 0;
|
|
1949
|
+
this.yieldPos = 0;
|
|
1950
|
+
this.awaitPos = 0;
|
|
1951
|
+
while (this.type !== tt.parenR) {
|
|
1952
|
+
if (first) {
|
|
1953
|
+
first = false;
|
|
1954
|
+
}
|
|
1955
|
+
else {
|
|
1956
|
+
this.expect(tt.comma);
|
|
1957
|
+
}
|
|
1958
|
+
if (this.afterTrailingComma(tt.parenR, true)) {
|
|
1959
|
+
lastIsComma = true;
|
|
1960
|
+
break;
|
|
1961
|
+
}
|
|
1962
|
+
else if (this.type === tt.ellipsis) {
|
|
1963
|
+
spreadStart = this.start;
|
|
1964
|
+
exprList.push(this.parseRestBinding());
|
|
1965
|
+
if (this.type === tt.comma) {
|
|
1966
|
+
this.raise(this.start, 'Comma is not permitted after the rest element');
|
|
1967
|
+
}
|
|
1968
|
+
break;
|
|
1969
|
+
}
|
|
1970
|
+
else {
|
|
1971
|
+
exprList.push(this.parseMaybeAssign(refErrors));
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
const innerEndPos = this.lastTokEnd;
|
|
1975
|
+
this.expect(tt.parenR);
|
|
1976
|
+
if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
|
|
1977
|
+
this.checkPatternErrors(refErrors, false);
|
|
1978
|
+
this.checkYieldAwaitInDefaultParams();
|
|
1979
|
+
this.yieldPos = oldYieldPos;
|
|
1980
|
+
this.awaitPos = oldAwaitPos;
|
|
1981
|
+
return this.parseArrowExpression(this.startNodeAt(startPos), exprList, false);
|
|
1982
|
+
}
|
|
1983
|
+
if (exprList.length === 0 || lastIsComma) {
|
|
1984
|
+
this.unexpected(this.lastTokStart);
|
|
1985
|
+
}
|
|
1986
|
+
if (spreadStart !== 0) {
|
|
1987
|
+
this.unexpected(spreadStart);
|
|
1988
|
+
}
|
|
1989
|
+
this.checkExpressionErrors(refErrors, true);
|
|
1990
|
+
this.yieldPos = oldYieldPos || this.yieldPos;
|
|
1991
|
+
this.awaitPos = oldAwaitPos || this.awaitPos;
|
|
1992
|
+
if (exprList.length > 1) {
|
|
1993
|
+
const val = this.startNodeAt(innerStartPos);
|
|
1994
|
+
val.expressions = exprList;
|
|
1995
|
+
return this.finishNodeAt(val, 'SequenceExpression', innerEndPos);
|
|
1996
|
+
}
|
|
1997
|
+
return exprList[0];
|
|
1998
|
+
}
|
|
1999
|
+
parseNew() {
|
|
2000
|
+
if (this.containsEsc) {
|
|
2001
|
+
this.raise(this.start, 'Escape sequence in keyword new');
|
|
2002
|
+
}
|
|
2003
|
+
const node = this.startNode();
|
|
2004
|
+
this.next(false);
|
|
2005
|
+
if (this.type === tt.dot) {
|
|
2006
|
+
return this.raise(node.start, "'new.target' can only be used in functions and class static block");
|
|
2007
|
+
}
|
|
2008
|
+
const startPos = this.start;
|
|
2009
|
+
node.callee = this.parseSubscripts(this.parseExprAtom(null, true), startPos, true);
|
|
2010
|
+
if (this.eat(tt.parenL)) {
|
|
2011
|
+
node.arguments = this.parseExprList(tt.parenR, true, false, null);
|
|
2012
|
+
}
|
|
2013
|
+
else {
|
|
2014
|
+
node.arguments = [];
|
|
2015
|
+
}
|
|
2016
|
+
return this.finishNode(node, 'NewExpression');
|
|
2017
|
+
}
|
|
2018
|
+
parseTemplateElement(isTagged) {
|
|
2019
|
+
const elem = this.startNode();
|
|
2020
|
+
if (this.type === tt.invalidTemplate) {
|
|
2021
|
+
if (!isTagged) {
|
|
2022
|
+
this.raise(this.start, 'Bad escape sequence in untagged template literal');
|
|
2023
|
+
}
|
|
2024
|
+
elem.value = { raw: this.value.replace(CRLF, '\n'), cooked: null };
|
|
2025
|
+
}
|
|
2026
|
+
else {
|
|
2027
|
+
elem.value = { raw: this.input.slice(this.start, this.end).replace(CRLF, '\n'), cooked: this.value };
|
|
2028
|
+
}
|
|
2029
|
+
this.next(false);
|
|
2030
|
+
elem.tail = this.type === tt.backQuote;
|
|
2031
|
+
return this.finishNode(elem, 'TemplateElement');
|
|
2032
|
+
}
|
|
2033
|
+
parseTemplate(isTagged) {
|
|
2034
|
+
const node = this.startNode();
|
|
2035
|
+
this.next(false);
|
|
2036
|
+
const expressions = [];
|
|
2037
|
+
node.expressions = expressions;
|
|
2038
|
+
let curElt = this.parseTemplateElement(isTagged);
|
|
2039
|
+
const quasis = [curElt];
|
|
2040
|
+
node.quasis = quasis;
|
|
2041
|
+
while (!curElt.tail) {
|
|
2042
|
+
if (this.type === tt.eof) {
|
|
2043
|
+
this.raise(this.pos, 'Unterminated template literal');
|
|
2044
|
+
}
|
|
2045
|
+
this.expect(tt.dollarBraceL);
|
|
2046
|
+
expressions.push(this.parseExpression(null));
|
|
2047
|
+
this.expect(tt.braceR);
|
|
2048
|
+
curElt = this.parseTemplateElement(isTagged);
|
|
2049
|
+
quasis.push(curElt);
|
|
2050
|
+
}
|
|
2051
|
+
this.next(false);
|
|
2052
|
+
return this.finishNode(node, 'TemplateLiteral');
|
|
2053
|
+
}
|
|
2054
|
+
isAsyncProp(prop) {
|
|
2055
|
+
return !prop.computed && prop.key.type === 'Identifier' && prop.key.name === 'async' && (this.type === tt.name || this.type === tt.num || this.type === tt.string || this.type === tt.bracketL || this.type.keyword !== '' || this.type === tt.star) && !this.hasLineBreak(this.lastTokEnd, this.start);
|
|
2056
|
+
}
|
|
2057
|
+
parseObj(isPattern, refErrors) {
|
|
2058
|
+
const node = this.startNode();
|
|
2059
|
+
let first = true;
|
|
2060
|
+
let sawProto = false;
|
|
2061
|
+
const properties = [];
|
|
2062
|
+
node.properties = properties;
|
|
2063
|
+
this.next(false);
|
|
2064
|
+
while (!this.eat(tt.braceR)) {
|
|
2065
|
+
if (!first) {
|
|
2066
|
+
this.expect(tt.comma);
|
|
2067
|
+
if (this.afterTrailingComma(tt.braceR, false)) {
|
|
2068
|
+
break;
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
else {
|
|
2072
|
+
first = false;
|
|
2073
|
+
}
|
|
2074
|
+
const prop = this.parseProperty(isPattern, refErrors);
|
|
2075
|
+
if (!isPattern && this.isProtoInit(prop)) {
|
|
2076
|
+
if (sawProto) {
|
|
2077
|
+
if (refErrors != null) {
|
|
2078
|
+
if (refErrors.doubleProto < 0) {
|
|
2079
|
+
refErrors.doubleProto = prop.key.start;
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
else {
|
|
2083
|
+
this.raise(prop.key.start, 'Redefinition of __proto__ property');
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
sawProto = true;
|
|
2087
|
+
}
|
|
2088
|
+
properties.push(prop);
|
|
2089
|
+
}
|
|
2090
|
+
return this.finishNode(node, isPattern ? 'ObjectPattern' : 'ObjectExpression');
|
|
2091
|
+
}
|
|
2092
|
+
isProtoInit(prop) {
|
|
2093
|
+
if (prop.type === 'SpreadElement' || prop.computed || prop.method || prop.shorthand) {
|
|
2094
|
+
return false;
|
|
2095
|
+
}
|
|
2096
|
+
const key = prop.key;
|
|
2097
|
+
let name;
|
|
2098
|
+
if (key.type === 'Identifier') {
|
|
2099
|
+
name = key.name;
|
|
2100
|
+
}
|
|
2101
|
+
else if (key.type === 'Literal') {
|
|
2102
|
+
name = String(key.value);
|
|
2103
|
+
}
|
|
2104
|
+
else {
|
|
2105
|
+
return false;
|
|
2106
|
+
}
|
|
2107
|
+
return name === '__proto__' && prop.kind === 'init';
|
|
2108
|
+
}
|
|
2109
|
+
parseProperty(isPattern, refErrors) {
|
|
2110
|
+
const prop = this.startNode();
|
|
2111
|
+
if (this.eat(tt.ellipsis)) {
|
|
2112
|
+
if (isPattern) {
|
|
2113
|
+
prop.argument = this.parseIdent(false);
|
|
2114
|
+
if (this.type === tt.comma) {
|
|
2115
|
+
this.raise(this.start, 'Comma is not permitted after the rest element');
|
|
2116
|
+
}
|
|
2117
|
+
return this.finishNode(prop, 'RestElement');
|
|
2118
|
+
}
|
|
2119
|
+
prop.argument = this.parseMaybeAssign(refErrors);
|
|
2120
|
+
if (this.type === tt.comma && refErrors != null && refErrors.trailingComma < 0) {
|
|
2121
|
+
refErrors.trailingComma = this.start;
|
|
2122
|
+
}
|
|
2123
|
+
return this.finishNode(prop, 'SpreadElement');
|
|
2124
|
+
}
|
|
2125
|
+
prop.method = false;
|
|
2126
|
+
prop.shorthand = false;
|
|
2127
|
+
let startPos = 0;
|
|
2128
|
+
if (isPattern || refErrors != null) {
|
|
2129
|
+
startPos = this.start;
|
|
2130
|
+
}
|
|
2131
|
+
if (!isPattern && this.type === tt.star) {
|
|
2132
|
+
this.unsupported(this.start, 'generator method');
|
|
2133
|
+
}
|
|
2134
|
+
const containsEsc = this.containsEsc;
|
|
2135
|
+
this.parsePropertyName(prop);
|
|
2136
|
+
if (!isPattern && !containsEsc && this.isAsyncProp(prop)) {
|
|
2137
|
+
this.unsupported(prop.start, 'async method');
|
|
2138
|
+
}
|
|
2139
|
+
this.parsePropertyValue(prop, isPattern, startPos, refErrors, containsEsc);
|
|
2140
|
+
return this.finishNode(prop, 'Property');
|
|
2141
|
+
}
|
|
2142
|
+
parsePropertyValue(prop, isPattern, startPos, refErrors, containsEsc) {
|
|
2143
|
+
if (this.eat(tt.colon)) {
|
|
2144
|
+
prop.value = isPattern ? this.parseMaybeDefault(this.start, null) : this.parseMaybeAssign(refErrors);
|
|
2145
|
+
prop.kind = 'init';
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
2148
|
+
if (this.type === tt.parenL) {
|
|
2149
|
+
if (isPattern) {
|
|
2150
|
+
this.unexpected(this.start);
|
|
2151
|
+
}
|
|
2152
|
+
this.unsupported(prop.start, 'object method');
|
|
2153
|
+
}
|
|
2154
|
+
const key = prop.key;
|
|
2155
|
+
if (!isPattern && !containsEsc && !prop.computed && key.type === 'Identifier' && (key.name === 'get' || key.name === 'set') && this.type !== tt.comma && this.type !== tt.braceR && this.type !== tt.eq) {
|
|
2156
|
+
this.unsupported(prop.start, 'getter or setter');
|
|
2157
|
+
}
|
|
2158
|
+
if (!prop.computed && key.type === 'Identifier') {
|
|
2159
|
+
this.checkUnreserved(key);
|
|
2160
|
+
if (key.name === 'await' && this.awaitIdentPos === 0) {
|
|
2161
|
+
this.awaitIdentPos = startPos;
|
|
2162
|
+
}
|
|
2163
|
+
if (isPattern) {
|
|
2164
|
+
prop.value = this.parseMaybeDefault(startPos, this.copyIdentifier(key));
|
|
2165
|
+
}
|
|
2166
|
+
else if (this.type === tt.eq && refErrors != null) {
|
|
2167
|
+
if (refErrors.shorthandAssign < 0) {
|
|
2168
|
+
refErrors.shorthandAssign = this.start;
|
|
2169
|
+
}
|
|
2170
|
+
prop.value = this.parseMaybeDefault(startPos, this.copyIdentifier(key));
|
|
2171
|
+
}
|
|
2172
|
+
else {
|
|
2173
|
+
prop.value = this.copyIdentifier(key);
|
|
2174
|
+
}
|
|
2175
|
+
prop.kind = 'init';
|
|
2176
|
+
prop.shorthand = true;
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
this.unexpected(this.start);
|
|
2180
|
+
}
|
|
2181
|
+
parsePropertyName(prop) {
|
|
2182
|
+
if (this.eat(tt.bracketL)) {
|
|
2183
|
+
prop.computed = true;
|
|
2184
|
+
prop.key = this.parseMaybeAssign(null);
|
|
2185
|
+
this.expect(tt.bracketR);
|
|
2186
|
+
return;
|
|
2187
|
+
}
|
|
2188
|
+
prop.computed = false;
|
|
2189
|
+
prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom(null, false) : this.parseIdent(true);
|
|
2190
|
+
}
|
|
2191
|
+
parseArrowExpression(node, params, isAsync) {
|
|
2192
|
+
const oldYieldPos = this.yieldPos;
|
|
2193
|
+
const oldAwaitPos = this.awaitPos;
|
|
2194
|
+
const oldAwaitIdentPos = this.awaitIdentPos;
|
|
2195
|
+
this.enterScope(SCOPE_FUNCTION | (isAsync ? SCOPE_ASYNC : 0) | SCOPE_ARROW);
|
|
2196
|
+
node.id = null;
|
|
2197
|
+
node.expression = false;
|
|
2198
|
+
node.generator = false;
|
|
2199
|
+
node.async = isAsync;
|
|
2200
|
+
this.yieldPos = 0;
|
|
2201
|
+
this.awaitPos = 0;
|
|
2202
|
+
this.awaitIdentPos = 0;
|
|
2203
|
+
node.params = this.toAssignableList(params, true);
|
|
2204
|
+
if (this.type === tt.braceL) {
|
|
2205
|
+
this.unsupported(this.start, 'arrow function block body');
|
|
2206
|
+
}
|
|
2207
|
+
node.body = this.parseMaybeAssign(null);
|
|
2208
|
+
node.expression = true;
|
|
2209
|
+
const nameHash = new Set();
|
|
2210
|
+
const paramList = node.params;
|
|
2211
|
+
for (let i = 0; i < paramList.length; i++) {
|
|
2212
|
+
this.checkLValInnerPattern(paramList[i], BIND_VAR, nameHash);
|
|
2213
|
+
}
|
|
2214
|
+
this.exitScope();
|
|
2215
|
+
this.yieldPos = oldYieldPos;
|
|
2216
|
+
this.awaitPos = oldAwaitPos;
|
|
2217
|
+
this.awaitIdentPos = oldAwaitIdentPos;
|
|
2218
|
+
return this.finishNode(node, 'ArrowFunctionExpression');
|
|
2219
|
+
}
|
|
2220
|
+
parseExprList(close, allowTrailingComma, allowEmpty, refErrors) {
|
|
2221
|
+
const elts = [];
|
|
2222
|
+
let first = true;
|
|
2223
|
+
while (!this.eat(close)) {
|
|
2224
|
+
if (!first) {
|
|
2225
|
+
this.expect(tt.comma);
|
|
2226
|
+
if (allowTrailingComma && this.afterTrailingComma(close, false)) {
|
|
2227
|
+
break;
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
else {
|
|
2231
|
+
first = false;
|
|
2232
|
+
}
|
|
2233
|
+
let elt;
|
|
2234
|
+
if (allowEmpty && this.type === tt.comma) {
|
|
2235
|
+
elt = null;
|
|
2236
|
+
}
|
|
2237
|
+
else if (this.type === tt.ellipsis) {
|
|
2238
|
+
elt = this.parseSpread(refErrors);
|
|
2239
|
+
if (refErrors != null && this.type === tt.comma && refErrors.trailingComma < 0) {
|
|
2240
|
+
refErrors.trailingComma = this.start;
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
else {
|
|
2244
|
+
elt = this.parseMaybeAssign(refErrors);
|
|
2245
|
+
}
|
|
2246
|
+
elts.push(elt);
|
|
2247
|
+
}
|
|
2248
|
+
return elts;
|
|
2249
|
+
}
|
|
2250
|
+
parseSpread(refErrors) {
|
|
2251
|
+
const node = this.startNode();
|
|
2252
|
+
this.next(false);
|
|
2253
|
+
node.argument = this.parseMaybeAssign(refErrors);
|
|
2254
|
+
return this.finishNode(node, 'SpreadElement');
|
|
2255
|
+
}
|
|
2256
|
+
checkUnreserved(node) {
|
|
2257
|
+
const name = node.name;
|
|
2258
|
+
if (this.inAsync() && name === 'await') {
|
|
2259
|
+
this.raise(node.start, "Cannot use 'await' as identifier inside an async function");
|
|
2260
|
+
}
|
|
2261
|
+
if (keywordTypes.has(name)) {
|
|
2262
|
+
this.raise(node.start, "Unexpected keyword '" + name + "'");
|
|
2263
|
+
}
|
|
2264
|
+
const reserved = this.strict ? RESERVED_WORDS_STRICT : RESERVED_WORDS;
|
|
2265
|
+
if (reserved.has(name)) {
|
|
2266
|
+
this.raise(node.start, "The keyword '" + name + "' is reserved");
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
parseIdent(liberal) {
|
|
2270
|
+
const node = this.parseIdentNode();
|
|
2271
|
+
this.next(liberal);
|
|
2272
|
+
this.finishNode(node, 'Identifier');
|
|
2273
|
+
if (!liberal) {
|
|
2274
|
+
this.checkUnreserved(node);
|
|
2275
|
+
if (node.name === 'await' && this.awaitIdentPos === 0) {
|
|
2276
|
+
this.awaitIdentPos = node.start;
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
return node;
|
|
2280
|
+
}
|
|
2281
|
+
parseIdentNode() {
|
|
2282
|
+
const node = this.startNode();
|
|
2283
|
+
if (this.type === tt.name) {
|
|
2284
|
+
node.name = this.value;
|
|
2285
|
+
}
|
|
2286
|
+
else if (this.type.keyword !== '') {
|
|
2287
|
+
node.name = this.type.keyword;
|
|
2288
|
+
// `class`/`function` pushed a function context that a property name never closes.
|
|
2289
|
+
if ((node.name === 'class' || node.name === 'function') && (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
|
|
2290
|
+
this.context.pop();
|
|
2291
|
+
}
|
|
2292
|
+
this.type = tt.name;
|
|
2293
|
+
}
|
|
2294
|
+
else {
|
|
2295
|
+
this.unexpected(this.start);
|
|
2296
|
+
}
|
|
2297
|
+
return node;
|
|
2298
|
+
}
|
|
2299
|
+
parseAwait() {
|
|
2300
|
+
if (this.awaitPos === 0) {
|
|
2301
|
+
this.awaitPos = this.start;
|
|
2302
|
+
}
|
|
2303
|
+
const node = this.startNode();
|
|
2304
|
+
this.next(false);
|
|
2305
|
+
node.argument = this.parseMaybeUnary(null, true, false);
|
|
2306
|
+
return this.finishNode(node, 'AwaitExpression');
|
|
2307
|
+
}
|
|
2308
|
+
// ## Patterns
|
|
2309
|
+
parseRestBinding() {
|
|
2310
|
+
const node = this.startNode();
|
|
2311
|
+
this.next(false);
|
|
2312
|
+
node.argument = this.parseBindingAtom();
|
|
2313
|
+
return this.finishNode(node, 'RestElement');
|
|
2314
|
+
}
|
|
2315
|
+
parseBindingAtom() {
|
|
2316
|
+
if (this.type === tt.bracketL) {
|
|
2317
|
+
const node = this.startNode();
|
|
2318
|
+
this.next(false);
|
|
2319
|
+
node.elements = this.parseBindingList(tt.bracketR);
|
|
2320
|
+
return this.finishNode(node, 'ArrayPattern');
|
|
2321
|
+
}
|
|
2322
|
+
if (this.type === tt.braceL) {
|
|
2323
|
+
return this.parseObj(true, null);
|
|
2324
|
+
}
|
|
2325
|
+
return this.parseIdent(false);
|
|
2326
|
+
}
|
|
2327
|
+
parseBindingList(close) {
|
|
2328
|
+
const elts = [];
|
|
2329
|
+
let first = true;
|
|
2330
|
+
while (!this.eat(close)) {
|
|
2331
|
+
if (first) {
|
|
2332
|
+
first = false;
|
|
2333
|
+
}
|
|
2334
|
+
else {
|
|
2335
|
+
this.expect(tt.comma);
|
|
2336
|
+
}
|
|
2337
|
+
if (this.type === tt.comma) {
|
|
2338
|
+
elts.push(null);
|
|
2339
|
+
}
|
|
2340
|
+
else if (this.afterTrailingComma(close, false)) {
|
|
2341
|
+
break;
|
|
2342
|
+
}
|
|
2343
|
+
else if (this.type === tt.ellipsis) {
|
|
2344
|
+
elts.push(this.parseRestBinding());
|
|
2345
|
+
if (this.type === tt.comma) {
|
|
2346
|
+
this.raise(this.start, 'Comma is not permitted after the rest element');
|
|
2347
|
+
}
|
|
2348
|
+
this.expect(close);
|
|
2349
|
+
break;
|
|
2350
|
+
}
|
|
2351
|
+
else {
|
|
2352
|
+
elts.push(this.parseMaybeDefault(this.start, null));
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
return elts;
|
|
2356
|
+
}
|
|
2357
|
+
parseMaybeDefault(startPos, leftIn) {
|
|
2358
|
+
const left = leftIn != null ? leftIn : this.parseBindingAtom();
|
|
2359
|
+
if (!this.eat(tt.eq)) {
|
|
2360
|
+
return left;
|
|
2361
|
+
}
|
|
2362
|
+
const node = this.startNodeAt(startPos);
|
|
2363
|
+
node.left = left;
|
|
2364
|
+
node.right = this.parseMaybeAssign(null);
|
|
2365
|
+
return this.finishNode(node, 'AssignmentPattern');
|
|
2366
|
+
}
|
|
2367
|
+
// Converts an expression to a pattern in place where acorn mutates `type`;
|
|
2368
|
+
// an AssignmentExpression becomes a new AssignmentPattern node, so callers store the result.
|
|
2369
|
+
toAssignable(node, isBinding, refErrors) {
|
|
2370
|
+
if (node == null) {
|
|
2371
|
+
if (refErrors != null) {
|
|
2372
|
+
this.checkPatternErrors(refErrors, true);
|
|
2373
|
+
}
|
|
2374
|
+
return node;
|
|
2375
|
+
}
|
|
2376
|
+
switch (node.type) {
|
|
2377
|
+
case 'Identifier':
|
|
2378
|
+
if (this.inAsync() && node.name === 'await') {
|
|
2379
|
+
this.raise(node.start, "Cannot use 'await' as identifier inside an async function");
|
|
2380
|
+
}
|
|
2381
|
+
return node;
|
|
2382
|
+
case 'ObjectPattern':
|
|
2383
|
+
case 'ArrayPattern':
|
|
2384
|
+
case 'AssignmentPattern':
|
|
2385
|
+
case 'RestElement':
|
|
2386
|
+
return node;
|
|
2387
|
+
case 'ObjectExpression': {
|
|
2388
|
+
node.type = 'ObjectPattern';
|
|
2389
|
+
if (refErrors != null) {
|
|
2390
|
+
this.checkPatternErrors(refErrors, true);
|
|
2391
|
+
}
|
|
2392
|
+
const properties = node.properties;
|
|
2393
|
+
for (let i = 0; i < properties.length; i++) {
|
|
2394
|
+
const prop = this.toAssignable(properties[i], isBinding, null);
|
|
2395
|
+
properties[i] = prop;
|
|
2396
|
+
if (prop.type === 'RestElement' && (prop.argument.type === 'ArrayPattern' || prop.argument.type === 'ObjectPattern')) {
|
|
2397
|
+
this.raise(prop.argument.start, 'Unexpected token');
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
return node;
|
|
2401
|
+
}
|
|
2402
|
+
case 'Property':
|
|
2403
|
+
if (node.kind !== 'init') {
|
|
2404
|
+
this.raise(node.key.start, "Object pattern can't contain getter or setter");
|
|
2405
|
+
}
|
|
2406
|
+
node.value = this.toAssignable(node.value, isBinding, null);
|
|
2407
|
+
return node;
|
|
2408
|
+
case 'ArrayExpression':
|
|
2409
|
+
node.type = 'ArrayPattern';
|
|
2410
|
+
if (refErrors != null) {
|
|
2411
|
+
this.checkPatternErrors(refErrors, true);
|
|
2412
|
+
}
|
|
2413
|
+
this.toAssignableList(node.elements, isBinding);
|
|
2414
|
+
return node;
|
|
2415
|
+
case 'SpreadElement':
|
|
2416
|
+
node.type = 'RestElement';
|
|
2417
|
+
node.argument = this.toAssignable(node.argument, isBinding, null);
|
|
2418
|
+
if (node.argument.type === 'AssignmentPattern') {
|
|
2419
|
+
this.raise(node.argument.start, 'Rest elements cannot have a default value');
|
|
2420
|
+
}
|
|
2421
|
+
return node;
|
|
2422
|
+
case 'AssignmentExpression': {
|
|
2423
|
+
if (node.operator !== '=') {
|
|
2424
|
+
this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
|
|
2425
|
+
}
|
|
2426
|
+
const pattern = { type: 'AssignmentPattern', start: node.start, end: node.end, left: node.left, right: node.right };
|
|
2427
|
+
pattern.left = this.toAssignable(node.left, isBinding, null);
|
|
2428
|
+
return pattern;
|
|
2429
|
+
}
|
|
2430
|
+
case 'ChainExpression':
|
|
2431
|
+
return this.raise(node.start, 'Optional chaining cannot appear in left-hand side');
|
|
2432
|
+
case 'MemberExpression':
|
|
2433
|
+
if (!isBinding) {
|
|
2434
|
+
return node;
|
|
2435
|
+
}
|
|
2436
|
+
return this.raise(node.start, 'Assigning to rvalue');
|
|
2437
|
+
}
|
|
2438
|
+
return this.raise(node.start, 'Assigning to rvalue');
|
|
2439
|
+
}
|
|
2440
|
+
toAssignableList(exprList, isBinding) {
|
|
2441
|
+
for (let i = 0; i < exprList.length; i++) {
|
|
2442
|
+
const elt = exprList[i];
|
|
2443
|
+
if (elt != null) {
|
|
2444
|
+
exprList[i] = this.toAssignable(elt, isBinding, null);
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
return exprList;
|
|
2448
|
+
}
|
|
2449
|
+
checkLValSimple(expr, bindingType, checkClashes) {
|
|
2450
|
+
const isBind = bindingType !== BIND_NONE;
|
|
2451
|
+
switch (expr.type) {
|
|
2452
|
+
case 'Identifier':
|
|
2453
|
+
if (this.strict && RESERVED_WORDS_STRICT_BIND.has(expr.name)) {
|
|
2454
|
+
this.raise(expr.start, (isBind ? 'Binding ' : 'Assigning to ') + expr.name + ' in strict mode');
|
|
2455
|
+
}
|
|
2456
|
+
if (isBind && checkClashes != null) {
|
|
2457
|
+
if (checkClashes.has(expr.name)) {
|
|
2458
|
+
this.raise(expr.start, 'Argument name clash');
|
|
2459
|
+
}
|
|
2460
|
+
checkClashes.add(expr.name);
|
|
2461
|
+
}
|
|
2462
|
+
return;
|
|
2463
|
+
case 'ChainExpression':
|
|
2464
|
+
this.raise(expr.start, 'Optional chaining cannot appear in left-hand side');
|
|
2465
|
+
return;
|
|
2466
|
+
case 'MemberExpression':
|
|
2467
|
+
if (isBind) {
|
|
2468
|
+
this.raise(expr.start, 'Binding member expression');
|
|
2469
|
+
}
|
|
2470
|
+
return;
|
|
2471
|
+
}
|
|
2472
|
+
this.raise(expr.start, (isBind ? 'Binding' : 'Assigning to') + ' rvalue');
|
|
2473
|
+
}
|
|
2474
|
+
checkLValPattern(expr, bindingType, checkClashes) {
|
|
2475
|
+
if (expr.type === 'ObjectPattern') {
|
|
2476
|
+
const properties = expr.properties;
|
|
2477
|
+
for (let i = 0; i < properties.length; i++) {
|
|
2478
|
+
this.checkLValInnerPattern(properties[i], bindingType, checkClashes);
|
|
2479
|
+
}
|
|
2480
|
+
return;
|
|
2481
|
+
}
|
|
2482
|
+
if (expr.type === 'ArrayPattern') {
|
|
2483
|
+
const elements = expr.elements;
|
|
2484
|
+
for (let i = 0; i < elements.length; i++) {
|
|
2485
|
+
if (elements[i] != null) {
|
|
2486
|
+
this.checkLValInnerPattern(elements[i], bindingType, checkClashes);
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
return;
|
|
2490
|
+
}
|
|
2491
|
+
this.checkLValSimple(expr, bindingType, checkClashes);
|
|
2492
|
+
}
|
|
2493
|
+
checkLValInnerPattern(expr, bindingType, checkClashes) {
|
|
2494
|
+
if (expr.type === 'Property') {
|
|
2495
|
+
this.checkLValInnerPattern(expr.value, bindingType, checkClashes);
|
|
2496
|
+
}
|
|
2497
|
+
else if (expr.type === 'AssignmentPattern') {
|
|
2498
|
+
this.checkLValPattern(expr.left, bindingType, checkClashes);
|
|
2499
|
+
}
|
|
2500
|
+
else if (expr.type === 'RestElement') {
|
|
2501
|
+
this.checkLValPattern(expr.argument, bindingType, checkClashes);
|
|
2502
|
+
}
|
|
2503
|
+
else {
|
|
2504
|
+
this.checkLValPattern(expr, bindingType, checkClashes);
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
/**
|
|
2509
|
+
* Returns the expression of the first top-level ExpressionStatement in `text`,
|
|
2510
|
+
* the node `acorn.parse(text, { ecmaVersion: 2020 })` yields there, or
|
|
2511
|
+
* `undefined` when the text holds no such statement (e.g. `{ a: 1 }` is a block).
|
|
2512
|
+
* Throws a SyntaxError for invalid input and for the unsupported constructs
|
|
2513
|
+
* listed at the top of this file.
|
|
2514
|
+
*/
|
|
2515
|
+
export function parseExpressionNode(text) {
|
|
2516
|
+
return new ExpressionParser(text).parseProgram();
|
|
2517
|
+
}
|
|
2518
|
+
//# sourceMappingURL=expression-parser.js.map
|