1
- import { getLineInfo , TokContext , tokTypes as tt , Parser } from "acorn" ;
1
+ import { getLineInfo , TokContext , Token , tokTypes as tt , Parser } from "acorn" ;
2
2
import defaultGlobals from "./globals.js" ;
3
3
import findReferences from "./references.js" ;
4
4
import findFeatures from "./features.js" ;
@@ -106,6 +106,7 @@ export class CellParser extends Parser {
106
106
this . O_function = 0 ;
107
107
this . O_async = false ;
108
108
this . O_generator = false ;
109
+ this . O_destructuring = null ;
109
110
this . strict = true ;
110
111
this . enterScope ( SCOPE_FUNCTION | SCOPE_ASYNC | SCOPE_GENERATOR ) ;
111
112
}
@@ -133,8 +134,23 @@ export class CellParser extends Parser {
133
134
134
135
// A non-empty cell?
135
136
else if ( token . type !== tt . eof && token . type !== tt . semi ) {
136
- // A named cell?
137
- if ( token . type === tt . name ) {
137
+
138
+ // A destructuring cell, maybe?
139
+ // (But not an object expression or arrow function!)
140
+ if ( token . type === tt . parenL ) {
141
+ id = this . parseParenAndDistinguishExpression ( true ) ;
142
+ if ( id . type !== "ArrowFunctionExpression" && this . eat ( tt . eq ) ) {
143
+ id = this . toAssignable ( id , true , this . O_destructuring ) ;
144
+ this . checkCellDeclaration ( id ) ;
145
+ } else {
146
+ body = id ;
147
+ id = null ;
148
+ }
149
+ token = new Token ( this ) ;
150
+ }
151
+
152
+ // A simple named cell?
153
+ else if ( token . type === tt . name ) {
138
154
if ( token . value === "viewof" || token . value === "mutable" ) {
139
155
token = lookahead . getToken ( ) ;
140
156
if ( token . type !== tt . name ) {
@@ -152,22 +168,20 @@ export class CellParser extends Parser {
152
168
}
153
169
}
154
170
155
- // A block?
156
- if ( token . type === tt . braceL ) {
157
- body = this . parseBlock ( ) ;
171
+ // A block or an expression?
172
+ if ( body === null ) {
173
+ body = token . type === tt . braceL
174
+ ? this . parseBlock ( )
175
+ : this . parseExpression ( ) ;
158
176
}
159
177
160
- // An expression?
161
- // Possibly a function or class declaration?
162
- else {
163
- body = this . parseExpression ( ) ;
164
- if (
165
- id === null &&
166
- ( body . type === "FunctionExpression" ||
167
- body . type === "ClassExpression" )
168
- ) {
169
- id = body . id ;
170
- }
178
+ // Promote the name of a function or class declaration?
179
+ if (
180
+ id === null &&
181
+ ( body . type === "FunctionExpression" ||
182
+ body . type === "ClassExpression" )
183
+ ) {
184
+ id = body . id ;
171
185
}
172
186
}
173
187
@@ -184,12 +198,40 @@ export class CellParser extends Parser {
184
198
? node
185
199
: super . toAssignable ( node , isBinding , refDestructuringErrors ) ;
186
200
}
201
+ checkCellDeclaration ( node ) {
202
+ switch ( node . type ) {
203
+ case "Identifier" :
204
+ break ;
205
+ case "ObjectPattern" :
206
+ for ( const p of node . properties ) this . checkCellDeclaration ( p ) ;
207
+ break ;
208
+ case "ArrayPattern" :
209
+ for ( const e of node . elements ) e && this . checkCellDeclaration ( e ) ;
210
+ break ;
211
+ case "Property" :
212
+ this . checkCellDeclaration ( node . value ) ;
213
+ break ;
214
+ case "RestElement" :
215
+ this . checkCellDeclaration ( node . argument ) ;
216
+ break ;
217
+ case "AssignmentPattern" :
218
+ this . checkCellDeclaration ( node . left ) ;
219
+ break ;
220
+ default :
221
+ this . unexpected ( ) ;
222
+ break ;
223
+ }
224
+ }
187
225
checkLocal ( id ) {
188
226
const node = id . id || id ;
189
227
if ( defaultGlobals . has ( node . name ) || node . name === "arguments" ) {
190
228
this . raise ( node . start , `Identifier '${ node . name } ' is reserved` ) ;
191
229
}
192
230
}
231
+ checkExpressionErrors ( refDestructuringErrors , andThrow ) {
232
+ this . O_destructuring = refDestructuringErrors ;
233
+ return super . checkExpressionErrors ( refDestructuringErrors , andThrow ) ;
234
+ }
193
235
checkUnreserved ( node ) {
194
236
if ( node . name === "viewof" || node . name === "mutable" ) {
195
237
this . raise ( node . start , `Unexpected keyword '${ node . name } '` ) ;
0 commit comments