Skip to content

Commit c3145db

Browse files
committed
cell destructuring
1 parent 09901d0 commit c3145db

13 files changed

+518
-17
lines changed

src/parse.js

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {getLineInfo, TokContext, tokTypes as tt, Parser} from "acorn";
1+
import {getLineInfo, TokContext, Token, tokTypes as tt, Parser} from "acorn";
22
import defaultGlobals from "./globals.js";
33
import findReferences from "./references.js";
44
import findFeatures from "./features.js";
@@ -106,6 +106,7 @@ export class CellParser extends Parser {
106106
this.O_function = 0;
107107
this.O_async = false;
108108
this.O_generator = false;
109+
this.O_destructuring = null;
109110
this.strict = true;
110111
this.enterScope(SCOPE_FUNCTION | SCOPE_ASYNC | SCOPE_GENERATOR);
111112
}
@@ -133,8 +134,22 @@ export class CellParser extends Parser {
133134

134135
// A non-empty cell?
135136
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+
} else {
145+
body = id;
146+
id = null;
147+
}
148+
token = new Token(this);
149+
}
150+
151+
// A simple named cell?
152+
else if (token.type === tt.name) {
138153
if (token.value === "viewof" || token.value === "mutable") {
139154
token = lookahead.getToken();
140155
if (token.type !== tt.name) {
@@ -152,22 +167,20 @@ export class CellParser extends Parser {
152167
}
153168
}
154169

155-
// A block?
156-
if (token.type === tt.braceL) {
157-
body = this.parseBlock();
170+
// A block or an expression?
171+
if (body === null) {
172+
body = token.type === tt.braceL
173+
? this.parseBlock()
174+
: this.parseExpression();
158175
}
159176

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-
}
177+
// Promote the name of a function or class declaration?
178+
if (
179+
id === null &&
180+
(body.type === "FunctionExpression" ||
181+
body.type === "ClassExpression")
182+
) {
183+
id = body.id;
171184
}
172185
}
173186

@@ -190,6 +203,10 @@ export class CellParser extends Parser {
190203
this.raise(node.start, `Identifier '${node.name}' is reserved`);
191204
}
192205
}
206+
checkExpressionErrors(refDestructuringErrors, andThrow) {
207+
this.O_destructuring = refDestructuringErrors;
208+
return super.checkExpressionErrors(refDestructuringErrors, andThrow);
209+
}
193210
checkUnreserved(node) {
194211
if (node.name === "viewof" || node.name === "mutable") {
195212
this.raise(node.start, `Unexpected keyword '${node.name}'`);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
([foo, ...bar]) = [1, 2, 3]

test/input/destructure-block.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
({foo, bar}) = {
2+
return {foo: 1, bar: 2};
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
([x, y = x + await z]) = [1]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
([x, y = 2]) = [1]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
({default: confetti}) = import("https://cdn.skypack.dev/canvas-confetti")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
({foo, bar}) = ({foo: 1, bar: 2})
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"type": "Cell",
3+
"start": 0,
4+
"end": 28,
5+
"id": {
6+
"type": "ArrayPattern",
7+
"start": 1,
8+
"end": 14,
9+
"elements": [
10+
{
11+
"type": "Identifier",
12+
"start": 2,
13+
"end": 5,
14+
"name": "foo"
15+
},
16+
{
17+
"type": "RestElement",
18+
"start": 7,
19+
"end": 13,
20+
"argument": {
21+
"type": "Identifier",
22+
"start": 10,
23+
"end": 13,
24+
"name": "bar"
25+
}
26+
}
27+
]
28+
},
29+
"body": {
30+
"type": "ArrayExpression",
31+
"start": 18,
32+
"end": 27,
33+
"elements": [
34+
{
35+
"type": "Literal",
36+
"start": 19,
37+
"end": 20,
38+
"value": 1,
39+
"raw": "1"
40+
},
41+
{
42+
"type": "Literal",
43+
"start": 22,
44+
"end": 23,
45+
"value": 2,
46+
"raw": "2"
47+
},
48+
{
49+
"type": "Literal",
50+
"start": 25,
51+
"end": 26,
52+
"value": 3,
53+
"raw": "3"
54+
}
55+
]
56+
},
57+
"async": false,
58+
"generator": false,
59+
"references": [],
60+
"fileAttachments": [],
61+
"databaseClients": [],
62+
"secrets": []
63+
}

test/output/destructure-block.js.json

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
{
2+
"type": "Cell",
3+
"start": 0,
4+
"end": 46,
5+
"id": {
6+
"type": "ObjectPattern",
7+
"start": 1,
8+
"end": 11,
9+
"properties": [
10+
{
11+
"type": "Property",
12+
"start": 2,
13+
"end": 5,
14+
"method": false,
15+
"shorthand": true,
16+
"computed": false,
17+
"key": {
18+
"type": "Identifier",
19+
"start": 2,
20+
"end": 5,
21+
"name": "foo"
22+
},
23+
"kind": "init",
24+
"value": {
25+
"type": "Identifier",
26+
"start": 2,
27+
"end": 5,
28+
"name": "foo"
29+
}
30+
},
31+
{
32+
"type": "Property",
33+
"start": 7,
34+
"end": 10,
35+
"method": false,
36+
"shorthand": true,
37+
"computed": false,
38+
"key": {
39+
"type": "Identifier",
40+
"start": 7,
41+
"end": 10,
42+
"name": "bar"
43+
},
44+
"kind": "init",
45+
"value": {
46+
"type": "Identifier",
47+
"start": 7,
48+
"end": 10,
49+
"name": "bar"
50+
}
51+
}
52+
]
53+
},
54+
"body": {
55+
"type": "BlockStatement",
56+
"start": 15,
57+
"end": 45,
58+
"body": [
59+
{
60+
"type": "ReturnStatement",
61+
"start": 19,
62+
"end": 43,
63+
"argument": {
64+
"type": "ObjectExpression",
65+
"start": 26,
66+
"end": 42,
67+
"properties": [
68+
{
69+
"type": "Property",
70+
"start": 27,
71+
"end": 33,
72+
"method": false,
73+
"shorthand": false,
74+
"computed": false,
75+
"key": {
76+
"type": "Identifier",
77+
"start": 27,
78+
"end": 30,
79+
"name": "foo"
80+
},
81+
"value": {
82+
"type": "Literal",
83+
"start": 32,
84+
"end": 33,
85+
"value": 1,
86+
"raw": "1"
87+
},
88+
"kind": "init"
89+
},
90+
{
91+
"type": "Property",
92+
"start": 35,
93+
"end": 41,
94+
"method": false,
95+
"shorthand": false,
96+
"computed": false,
97+
"key": {
98+
"type": "Identifier",
99+
"start": 35,
100+
"end": 38,
101+
"name": "bar"
102+
},
103+
"value": {
104+
"type": "Literal",
105+
"start": 40,
106+
"end": 41,
107+
"value": 2,
108+
"raw": "2"
109+
},
110+
"kind": "init"
111+
}
112+
]
113+
}
114+
}
115+
]
116+
},
117+
"async": false,
118+
"generator": false,
119+
"references": [],
120+
"fileAttachments": [],
121+
"databaseClients": [],
122+
"secrets": []
123+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{
2+
"type": "Cell",
3+
"start": 0,
4+
"end": 29,
5+
"id": {
6+
"type": "ArrayPattern",
7+
"start": 1,
8+
"end": 21,
9+
"elements": [
10+
{
11+
"type": "Identifier",
12+
"start": 2,
13+
"end": 3,
14+
"name": "x"
15+
},
16+
{
17+
"type": "AssignmentPattern",
18+
"start": 5,
19+
"end": 20,
20+
"left": {
21+
"type": "Identifier",
22+
"start": 5,
23+
"end": 6,
24+
"name": "y"
25+
},
26+
"right": {
27+
"type": "BinaryExpression",
28+
"start": 9,
29+
"end": 20,
30+
"left": {
31+
"type": "Identifier",
32+
"start": 9,
33+
"end": 10,
34+
"name": "x"
35+
},
36+
"operator": "+",
37+
"right": {
38+
"type": "AwaitExpression",
39+
"start": 13,
40+
"end": 20,
41+
"argument": {
42+
"type": "Identifier",
43+
"start": 19,
44+
"end": 20,
45+
"name": "z"
46+
}
47+
}
48+
}
49+
}
50+
]
51+
},
52+
"body": {
53+
"type": "ArrayExpression",
54+
"start": 25,
55+
"end": 28,
56+
"elements": [
57+
{
58+
"type": "Literal",
59+
"start": 26,
60+
"end": 27,
61+
"value": 1,
62+
"raw": "1"
63+
}
64+
]
65+
},
66+
"async": true,
67+
"generator": false,
68+
"references": [],
69+
"fileAttachments": [],
70+
"databaseClients": [],
71+
"secrets": []
72+
}

0 commit comments

Comments
 (0)