@weborigami/language 0.6.4 → 0.6.6
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/main.js +4 -0
- package/package.json +2 -2
- package/src/compiler/optimize.js +17 -11
- package/src/compiler/origami.pegjs +192 -58
- package/src/compiler/parse.js +2182 -1172
- package/src/compiler/parserHelpers.js +172 -10
- package/src/project/projectConfig.js +2 -2
- package/src/project/projectGlobals.js +2 -2
- package/src/project/projectRoot.js +5 -54
- package/src/project/projectRootFromPath.js +58 -0
- package/src/protocols/fetchAndHandleExtension.js +5 -0
- package/src/protocols/package.js +26 -39
- package/src/runtime/expressionObject.js +162 -150
- package/src/runtime/handleExtension.js +18 -2
- package/src/runtime/ops.js +30 -9
- package/test/compiler/compile.test.js +39 -0
- package/test/compiler/optimize.test.js +2 -1
- package/test/compiler/parse.test.js +355 -112
- package/test/project/{projectRoot.test.js → projectRootFromPath.test.js} +5 -5
- package/test/protocols/package.test.js +6 -1
- package/test/runtime/expressionObject.test.js +25 -10
- package/test/runtime/ops.test.js +32 -4
|
@@ -117,49 +117,231 @@ describe("Origami parser", () => {
|
|
|
117
117
|
);
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
[ops.literal, "b"],
|
|
136
|
-
[ops.literal, "c"],
|
|
137
|
-
],
|
|
138
|
-
[
|
|
139
|
-
[markers.traverse, [markers.reference, "fn"]],
|
|
140
|
-
[markers.traverse, [markers.reference, "a"]],
|
|
141
|
-
[markers.traverse, [markers.reference, "b"]],
|
|
142
|
-
[markers.traverse, [markers.reference, "c"]],
|
|
143
|
-
],
|
|
144
|
-
]);
|
|
145
|
-
assertParse("arrowFunction", "a => b => fn(a, b)", [
|
|
146
|
-
ops.lambda,
|
|
147
|
-
[[ops.literal, "a"]],
|
|
148
|
-
[
|
|
120
|
+
describe("arrowFunction", () => {
|
|
121
|
+
test("basic arrow functions", () => {
|
|
122
|
+
assertParse("arrowFunction", "() => foo", [
|
|
123
|
+
ops.lambda,
|
|
124
|
+
0,
|
|
125
|
+
[],
|
|
126
|
+
[markers.traverse, [markers.reference, "foo"]],
|
|
127
|
+
]);
|
|
128
|
+
assertParse("arrowFunction", "x => y", [
|
|
129
|
+
ops.lambda,
|
|
130
|
+
1,
|
|
131
|
+
[["x", [[ops.params, 0], 0]]],
|
|
132
|
+
[markers.traverse, [markers.reference, "y"]],
|
|
133
|
+
]);
|
|
134
|
+
assertParse("arrowFunction", "(a, b, c) ⇒ fn(a, b, c)", [
|
|
149
135
|
ops.lambda,
|
|
150
|
-
|
|
136
|
+
3,
|
|
137
|
+
[
|
|
138
|
+
["a", [[ops.params, 0], 0]],
|
|
139
|
+
["b", [[ops.params, 0], 1]],
|
|
140
|
+
["c", [[ops.params, 0], 2]],
|
|
141
|
+
],
|
|
151
142
|
[
|
|
152
143
|
[markers.traverse, [markers.reference, "fn"]],
|
|
153
144
|
[markers.traverse, [markers.reference, "a"]],
|
|
154
145
|
[markers.traverse, [markers.reference, "b"]],
|
|
146
|
+
[markers.traverse, [markers.reference, "c"]],
|
|
155
147
|
],
|
|
156
|
-
]
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
148
|
+
]);
|
|
149
|
+
// `async` keyword is effectively ignored
|
|
150
|
+
assertParse("arrowFunction", "async (x) => x", [
|
|
151
|
+
ops.lambda,
|
|
152
|
+
1,
|
|
153
|
+
[["x", [[ops.params, 0], 0]]],
|
|
154
|
+
[markers.traverse, [markers.reference, "x"]],
|
|
155
|
+
]);
|
|
156
|
+
// Can't omit a parameter like you can in an array
|
|
157
|
+
assertThrows("arrowFunction", "(, b) => b", "Expected an expression");
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test("arrow function with default parameters", () => {
|
|
161
|
+
assertParse("arrowFunction", "(a = 1, b = fn()) => a + b", [
|
|
162
|
+
ops.lambda,
|
|
163
|
+
0,
|
|
164
|
+
[
|
|
165
|
+
["a", [ops.defaultValue, [[ops.params, 0], 0], [ops.literal, 1]]],
|
|
166
|
+
[
|
|
167
|
+
"__temp0__",
|
|
168
|
+
[
|
|
169
|
+
ops.defaultValue,
|
|
170
|
+
[[ops.params, 0], 1],
|
|
171
|
+
[
|
|
172
|
+
ops.lambda,
|
|
173
|
+
0,
|
|
174
|
+
[],
|
|
175
|
+
[[markers.traverse, [markers.reference, "fn"]]],
|
|
176
|
+
],
|
|
177
|
+
],
|
|
178
|
+
],
|
|
179
|
+
["b", [[ops.inherited, 0], "__temp0__"]],
|
|
180
|
+
],
|
|
181
|
+
[
|
|
182
|
+
ops.addition,
|
|
183
|
+
[markers.traverse, [markers.reference, "a"]],
|
|
184
|
+
[markers.traverse, [markers.reference, "b"]],
|
|
185
|
+
],
|
|
186
|
+
]);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test("arrow function with rest parameter", () => {
|
|
190
|
+
assertParse("arrowFunction", "(head, ...tail) => tail", [
|
|
191
|
+
ops.lambda,
|
|
192
|
+
1,
|
|
193
|
+
[
|
|
194
|
+
["head", [[ops.params, 0], 0]],
|
|
195
|
+
["tail", [[[ops.params, 0], "slice"], 1]],
|
|
196
|
+
],
|
|
197
|
+
[markers.traverse, [markers.reference, "tail"]],
|
|
198
|
+
]);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test("array parameter destructuring", () => {
|
|
202
|
+
assertParse("arrowFunction", "([a, b, c]) => a + b + c", [
|
|
203
|
+
ops.lambda,
|
|
204
|
+
1,
|
|
205
|
+
[
|
|
206
|
+
["a", [[[ops.params, 0], 0], 0]],
|
|
207
|
+
["b", [[[ops.params, 0], 0], 1]],
|
|
208
|
+
["c", [[[ops.params, 0], 0], 2]],
|
|
209
|
+
],
|
|
210
|
+
[
|
|
211
|
+
ops.addition,
|
|
212
|
+
[
|
|
213
|
+
ops.addition,
|
|
214
|
+
[markers.traverse, [markers.reference, "a"]],
|
|
215
|
+
[markers.traverse, [markers.reference, "b"]],
|
|
216
|
+
],
|
|
217
|
+
[markers.traverse, [markers.reference, "c"]],
|
|
218
|
+
],
|
|
219
|
+
]);
|
|
220
|
+
assertParse("arrowFunction", "([a, , b]) => a * b", [
|
|
221
|
+
ops.lambda,
|
|
222
|
+
1,
|
|
223
|
+
[
|
|
224
|
+
["a", [[[ops.params, 0], 0], 0]],
|
|
225
|
+
["b", [[[ops.params, 0], 0], 2]],
|
|
226
|
+
],
|
|
227
|
+
[
|
|
228
|
+
ops.multiplication,
|
|
229
|
+
[markers.traverse, [markers.reference, "a"]],
|
|
230
|
+
[markers.traverse, [markers.reference, "b"]],
|
|
231
|
+
],
|
|
232
|
+
]);
|
|
233
|
+
assertParse("arrowFunction", "([a = 1, b = 2]) => a + b", [
|
|
234
|
+
ops.lambda,
|
|
235
|
+
1,
|
|
236
|
+
[
|
|
237
|
+
[
|
|
238
|
+
"a",
|
|
239
|
+
[ops.defaultValue, [[[ops.params, 0], 0], 0], [ops.literal, 1]],
|
|
240
|
+
],
|
|
241
|
+
[
|
|
242
|
+
"b",
|
|
243
|
+
[ops.defaultValue, [[[ops.params, 0], 0], 1], [ops.literal, 2]],
|
|
244
|
+
],
|
|
245
|
+
],
|
|
246
|
+
[
|
|
247
|
+
ops.addition,
|
|
248
|
+
[markers.traverse, [markers.reference, "a"]],
|
|
249
|
+
[markers.traverse, [markers.reference, "b"]],
|
|
250
|
+
],
|
|
251
|
+
]);
|
|
252
|
+
assertParse("arrowFunction", "([head, ...tail]) => tail", [
|
|
253
|
+
ops.lambda,
|
|
254
|
+
1,
|
|
255
|
+
[
|
|
256
|
+
["head", [[[ops.params, 0], 0], 0]],
|
|
257
|
+
["tail", [[[[ops.params, 0], 0], "slice"], 1]],
|
|
258
|
+
],
|
|
259
|
+
[markers.traverse, [markers.reference, "tail"]],
|
|
260
|
+
]);
|
|
261
|
+
assertParse("arrowFunction", "(head, ...{ length }) => length", [
|
|
262
|
+
ops.lambda,
|
|
263
|
+
1,
|
|
264
|
+
[
|
|
265
|
+
["head", [[ops.params, 0], 0]],
|
|
266
|
+
["length", [[[[ops.params, 0], "slice"], 1], "length"]],
|
|
267
|
+
],
|
|
268
|
+
[markers.traverse, [markers.reference, "length"]],
|
|
269
|
+
]);
|
|
270
|
+
assertThrows(
|
|
271
|
+
"arrowFunction",
|
|
272
|
+
"([a, a]) => a",
|
|
273
|
+
`Duplicate parameter name "a"`
|
|
274
|
+
);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
test("object parameter destructuring", () => {
|
|
278
|
+
assertParse("arrowFunction", "({ a, b: c }) => a + c", [
|
|
279
|
+
ops.lambda,
|
|
280
|
+
1,
|
|
281
|
+
[
|
|
282
|
+
["a", [[[ops.params, 0], 0], "a"]],
|
|
283
|
+
["c", [[[ops.params, 0], 0], "b"]],
|
|
284
|
+
],
|
|
285
|
+
[
|
|
286
|
+
ops.addition,
|
|
287
|
+
[markers.traverse, [markers.reference, "a"]],
|
|
288
|
+
[markers.traverse, [markers.reference, "c"]],
|
|
289
|
+
],
|
|
290
|
+
]);
|
|
291
|
+
assertParse("arrowFunction", "({ a: { b: { c }}}) => c", [
|
|
292
|
+
ops.lambda,
|
|
293
|
+
1,
|
|
294
|
+
[["c", [[[[[ops.params, 0], 0], "a"], "b"], "c"]]],
|
|
295
|
+
[markers.traverse, [markers.reference, "c"]],
|
|
296
|
+
]);
|
|
297
|
+
assertParse("arrowFunction", "({ a = 1 }) => a", [
|
|
298
|
+
ops.lambda,
|
|
299
|
+
1,
|
|
300
|
+
[
|
|
301
|
+
[
|
|
302
|
+
"a",
|
|
303
|
+
[ops.defaultValue, [[[ops.params, 0], 0], "a"], [ops.literal, 1]],
|
|
304
|
+
],
|
|
305
|
+
],
|
|
306
|
+
[markers.traverse, [markers.reference, "a"]],
|
|
307
|
+
]);
|
|
308
|
+
assertParse("arrowFunction", "({ a, b, ...rest }) => rest", [
|
|
309
|
+
ops.lambda,
|
|
310
|
+
1,
|
|
311
|
+
[
|
|
312
|
+
["a", [[[ops.params, 0], 0], "a"]],
|
|
313
|
+
["b", [[[ops.params, 0], 0], "b"]],
|
|
314
|
+
[
|
|
315
|
+
"rest",
|
|
316
|
+
[ops.objectRest, [[ops.params, 0], 0], [ops.array, "a", "b"]],
|
|
317
|
+
],
|
|
318
|
+
],
|
|
319
|
+
[markers.traverse, [markers.reference, "rest"]],
|
|
320
|
+
]);
|
|
321
|
+
assertThrows(
|
|
322
|
+
"arrowFunction",
|
|
323
|
+
"({ a: c, b: c }) => c",
|
|
324
|
+
`Duplicate parameter name "c"`
|
|
325
|
+
);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
test("functional arrow functions", () => {
|
|
329
|
+
assertParse("arrowFunction", "a => b => fn(a, b)", [
|
|
330
|
+
ops.lambda,
|
|
331
|
+
1,
|
|
332
|
+
[["a", [[ops.params, 0], 0]]],
|
|
333
|
+
[
|
|
334
|
+
ops.lambda,
|
|
335
|
+
1,
|
|
336
|
+
[["b", [[ops.params, 0], 0]]],
|
|
337
|
+
[
|
|
338
|
+
[markers.traverse, [markers.reference, "fn"]],
|
|
339
|
+
[markers.traverse, [markers.reference, "a"]],
|
|
340
|
+
[markers.traverse, [markers.reference, "b"]],
|
|
341
|
+
],
|
|
342
|
+
],
|
|
343
|
+
]);
|
|
344
|
+
});
|
|
163
345
|
});
|
|
164
346
|
|
|
165
347
|
test("bitwiseAndExpression", () => {
|
|
@@ -189,7 +371,7 @@ describe("Origami parser", () => {
|
|
|
189
371
|
describe("callExpression", () => {
|
|
190
372
|
test("call chains", () => {
|
|
191
373
|
assertParse("callExpression", "(foo.js())('arg')", [
|
|
192
|
-
[[markers.traverse, [markers.reference, "foo.js"]]
|
|
374
|
+
[[markers.traverse, [markers.reference, "foo.js"]]],
|
|
193
375
|
[ops.literal, "arg"],
|
|
194
376
|
]);
|
|
195
377
|
assertParse("callExpression", "fn('a')('b')", [
|
|
@@ -200,7 +382,7 @@ describe("Origami parser", () => {
|
|
|
200
382
|
[ops.literal, "b"],
|
|
201
383
|
]);
|
|
202
384
|
assertParse("callExpression", "(foo.js())(a, b)", [
|
|
203
|
-
[[markers.traverse, [markers.reference, "foo.js"]]
|
|
385
|
+
[[markers.traverse, [markers.reference, "foo.js"]]],
|
|
204
386
|
[markers.traverse, [markers.reference, "a"]],
|
|
205
387
|
[markers.traverse, [markers.reference, "b"]],
|
|
206
388
|
]);
|
|
@@ -222,7 +404,8 @@ describe("Origami parser", () => {
|
|
|
222
404
|
[markers.traverse, [markers.reference, "a"]],
|
|
223
405
|
[
|
|
224
406
|
ops.lambda,
|
|
225
|
-
|
|
407
|
+
1,
|
|
408
|
+
[["__optional__", [[ops.params, 0], 0]]],
|
|
226
409
|
[
|
|
227
410
|
ops.property,
|
|
228
411
|
[
|
|
@@ -239,7 +422,8 @@ describe("Origami parser", () => {
|
|
|
239
422
|
[markers.traverse, [markers.reference, "a"]],
|
|
240
423
|
[
|
|
241
424
|
ops.lambda,
|
|
242
|
-
|
|
425
|
+
1,
|
|
426
|
+
[["__optional__", [[ops.params, 0], 0]]],
|
|
243
427
|
[
|
|
244
428
|
ops.optional,
|
|
245
429
|
[
|
|
@@ -249,7 +433,8 @@ describe("Origami parser", () => {
|
|
|
249
433
|
],
|
|
250
434
|
[
|
|
251
435
|
ops.lambda,
|
|
252
|
-
|
|
436
|
+
1,
|
|
437
|
+
[["__optional__", [[ops.params, 0], 0]]],
|
|
253
438
|
[
|
|
254
439
|
ops.property,
|
|
255
440
|
[markers.traverse, [markers.reference, "__optional__"]],
|
|
@@ -267,7 +452,8 @@ describe("Origami parser", () => {
|
|
|
267
452
|
[markers.traverse, [markers.reference, "a"]],
|
|
268
453
|
[
|
|
269
454
|
ops.lambda,
|
|
270
|
-
|
|
455
|
+
1,
|
|
456
|
+
[["__optional__", [[ops.params, 0], 0]]],
|
|
271
457
|
[
|
|
272
458
|
ops.property,
|
|
273
459
|
[markers.traverse, [markers.reference, "__optional__"]],
|
|
@@ -283,7 +469,8 @@ describe("Origami parser", () => {
|
|
|
283
469
|
[markers.traverse, [markers.reference, "fn"]],
|
|
284
470
|
[
|
|
285
471
|
ops.lambda,
|
|
286
|
-
|
|
472
|
+
1,
|
|
473
|
+
[["__optional__", [[ops.params, 0], 0]]],
|
|
287
474
|
[
|
|
288
475
|
[markers.traverse, [markers.reference, "__optional__"]],
|
|
289
476
|
[ops.literal, 0],
|
|
@@ -292,10 +479,73 @@ describe("Origami parser", () => {
|
|
|
292
479
|
]);
|
|
293
480
|
});
|
|
294
481
|
|
|
482
|
+
test("paramArray", () => {
|
|
483
|
+
assertParse("paramArray", "[a, b, c]", [
|
|
484
|
+
markers.paramArray,
|
|
485
|
+
[markers.paramName, "a"],
|
|
486
|
+
[markers.paramName, "b"],
|
|
487
|
+
[markers.paramName, "c"],
|
|
488
|
+
]);
|
|
489
|
+
assertParse("paramArray", "[a, , b]", [
|
|
490
|
+
markers.paramArray,
|
|
491
|
+
[markers.paramName, "a"],
|
|
492
|
+
undefined,
|
|
493
|
+
[markers.paramName, "b"],
|
|
494
|
+
]);
|
|
495
|
+
assertParse("paramArray", "[head, ...tail]", [
|
|
496
|
+
markers.paramArray,
|
|
497
|
+
[markers.paramName, "head"],
|
|
498
|
+
[markers.paramRest, [markers.paramName, "tail"]],
|
|
499
|
+
]);
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
test("paramArrayEntry", () => {
|
|
503
|
+
assertParse("paramArrayEntry", "a", [markers.paramName, "a"]);
|
|
504
|
+
assertParse("paramArrayEntry", "a = 1", [
|
|
505
|
+
markers.paramInitializer,
|
|
506
|
+
[markers.paramName, "a"],
|
|
507
|
+
[ops.literal, 1],
|
|
508
|
+
]);
|
|
509
|
+
assertThrows("paramArrayEntry", "...rest", `but "." found`);
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
test("paramObject", () => {
|
|
513
|
+
assertParse("paramObject", "{}", [markers.paramObject]);
|
|
514
|
+
assertParse("paramObject", "{ a, b: c }", [
|
|
515
|
+
markers.paramObject,
|
|
516
|
+
["a", [markers.paramName, "a"]],
|
|
517
|
+
["b", [markers.paramName, "c"]],
|
|
518
|
+
]);
|
|
519
|
+
assertParse("paramObject", "{ a, b: { c } }", [
|
|
520
|
+
markers.paramObject,
|
|
521
|
+
["a", [markers.paramName, "a"]],
|
|
522
|
+
["b", [markers.paramObject, ["c", [markers.paramName, "c"]]]],
|
|
523
|
+
]);
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
test("paramObjectEntry", () => {
|
|
527
|
+
assertParse("paramObjectEntry", "a", ["a", [markers.paramName, "a"]]);
|
|
528
|
+
assertParse("paramObjectEntry", "a: b", ["a", [markers.paramName, "b"]]);
|
|
529
|
+
assertParse("paramObjectEntry", "[key]: param", [
|
|
530
|
+
[markers.traverse, [markers.reference, "key"]],
|
|
531
|
+
[markers.paramName, "param"],
|
|
532
|
+
]);
|
|
533
|
+
assertParse("paramObjectEntry", "a = 1", [
|
|
534
|
+
"a",
|
|
535
|
+
[markers.paramInitializer, [markers.paramName, "a"], [ops.literal, 1]],
|
|
536
|
+
]);
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
test("paramRest", () => {
|
|
540
|
+
assertParse("paramRest", "...rest", [
|
|
541
|
+
markers.paramRest,
|
|
542
|
+
[markers.paramName, "rest"],
|
|
543
|
+
]);
|
|
544
|
+
});
|
|
545
|
+
|
|
295
546
|
test("parentheses arguments", () => {
|
|
296
547
|
assertParse("callExpression", "fn()", [
|
|
297
548
|
[markers.traverse, [markers.reference, "fn"]],
|
|
298
|
-
undefined,
|
|
299
549
|
]);
|
|
300
550
|
assertParse("callExpression", "foo.js(arg)", [
|
|
301
551
|
[markers.traverse, [markers.reference, "foo.js"]],
|
|
@@ -312,7 +562,7 @@ describe("Origami parser", () => {
|
|
|
312
562
|
[markers.traverse, [markers.reference, "b"]],
|
|
313
563
|
]);
|
|
314
564
|
assertParse("callExpression", "fn()(arg)", [
|
|
315
|
-
[[markers.traverse, [markers.reference, "fn"]]
|
|
565
|
+
[[markers.traverse, [markers.reference, "fn"]]],
|
|
316
566
|
[markers.traverse, [markers.reference, "arg"]],
|
|
317
567
|
]);
|
|
318
568
|
});
|
|
@@ -366,19 +616,14 @@ describe("Origami parser", () => {
|
|
|
366
616
|
|
|
367
617
|
test("path and parentheses chains", () => {
|
|
368
618
|
assertParse("callExpression", "foo.js()/key", [
|
|
369
|
-
[[markers.traverse, [markers.reference, "foo.js"]]
|
|
619
|
+
[[markers.traverse, [markers.reference, "foo.js"]]],
|
|
370
620
|
[ops.literal, "key"],
|
|
371
621
|
]);
|
|
372
622
|
assertParse("callExpression", "tree/key()", [
|
|
373
623
|
[markers.traverse, [markers.reference, "tree/"], [ops.literal, "key"]],
|
|
374
|
-
undefined,
|
|
375
624
|
]);
|
|
376
625
|
assertParse("callExpression", "fn()/key()", [
|
|
377
|
-
[
|
|
378
|
-
[[markers.traverse, [markers.reference, "fn"]], undefined],
|
|
379
|
-
[ops.literal, "key"],
|
|
380
|
-
],
|
|
381
|
-
undefined,
|
|
626
|
+
[[[markers.traverse, [markers.reference, "fn"]]], [ops.literal, "key"]],
|
|
382
627
|
]);
|
|
383
628
|
assertParse("callExpression", "package:@weborigami/dropbox/auth(creds)", [
|
|
384
629
|
[
|
|
@@ -440,13 +685,13 @@ describe("Origami parser", () => {
|
|
|
440
685
|
assertParse("conditionalExpression", "false ? () => 1 : 0", [
|
|
441
686
|
ops.conditional,
|
|
442
687
|
[markers.traverse, [markers.reference, "false"]],
|
|
443
|
-
[ops.lambda, [], [ops.lambda, [], [ops.literal, 1]]],
|
|
688
|
+
[ops.lambda, 0, [], [ops.lambda, 0, [], [ops.literal, 1]]],
|
|
444
689
|
[ops.literal, 0],
|
|
445
690
|
]);
|
|
446
691
|
assertParse("conditionalExpression", "false ? () => 1 : 0", [
|
|
447
692
|
ops.conditional,
|
|
448
693
|
[markers.traverse, [markers.reference, "false"]],
|
|
449
|
-
[ops.lambda, [], [ops.lambda, [], [ops.literal, 1]]],
|
|
694
|
+
[ops.lambda, 0, [], [ops.lambda, 0, [], [ops.literal, 1]]],
|
|
450
695
|
[ops.literal, 0],
|
|
451
696
|
]);
|
|
452
697
|
});
|
|
@@ -479,6 +724,7 @@ describe("Origami parser", () => {
|
|
|
479
724
|
assertThrows("callExpression", "fn(a", "Expected right parenthesis");
|
|
480
725
|
assertThrows("doubleQuoteString", '"foo', "Expected closing quote");
|
|
481
726
|
assertThrows("guillemetString", "«foo", "Expected closing guillemet");
|
|
727
|
+
assertThrows("guillemetString", "»foo", "Expected closing guillemet");
|
|
482
728
|
assertThrows("objectGetter", "a =", "Expected an expression");
|
|
483
729
|
assertThrows("objectProperty", "a:", "Expected an expression");
|
|
484
730
|
assertThrows("singleQuoteString", "'foo", "Expected closing quote");
|
|
@@ -657,7 +903,8 @@ Body`,
|
|
|
657
903
|
[markers.traverse, [markers.reference, "fn"]],
|
|
658
904
|
[
|
|
659
905
|
ops.lambda,
|
|
660
|
-
|
|
906
|
+
1,
|
|
907
|
+
[["_", [[ops.params, 0], 0]]],
|
|
661
908
|
[ops.templateText, [ops.literal, ["x"]]],
|
|
662
909
|
],
|
|
663
910
|
]);
|
|
@@ -676,7 +923,8 @@ Body`,
|
|
|
676
923
|
[markers.traverse, [markers.reference, "map"]],
|
|
677
924
|
[
|
|
678
925
|
ops.lambda,
|
|
679
|
-
|
|
926
|
+
1,
|
|
927
|
+
[["_", [[ops.params, 0], 0]]],
|
|
680
928
|
[
|
|
681
929
|
ops.templateText,
|
|
682
930
|
[ops.literal, ["<li>", "</li>"]],
|
|
@@ -696,7 +944,8 @@ Body`,
|
|
|
696
944
|
]);
|
|
697
945
|
assertParse("expression", "=tag`Hello, ${_}!`", [
|
|
698
946
|
ops.lambda,
|
|
699
|
-
|
|
947
|
+
1,
|
|
948
|
+
[["_", [[ops.params, 0], 0]]],
|
|
700
949
|
[
|
|
701
950
|
[markers.traverse, [markers.reference, "tag"]],
|
|
702
951
|
[ops.literal, ["Hello, ", "!"]],
|
|
@@ -705,9 +954,10 @@ Body`,
|
|
|
705
954
|
]);
|
|
706
955
|
assertParse("expression", "(post, slug) => fn.js(post, slug)", [
|
|
707
956
|
ops.lambda,
|
|
957
|
+
2,
|
|
708
958
|
[
|
|
709
|
-
[ops.
|
|
710
|
-
[ops.
|
|
959
|
+
["post", [[ops.params, 0], 0]],
|
|
960
|
+
["slug", [[ops.params, 0], 1]],
|
|
711
961
|
],
|
|
712
962
|
[
|
|
713
963
|
[markers.traverse, [markers.reference, "fn.js"]],
|
|
@@ -777,8 +1027,9 @@ Body`,
|
|
|
777
1027
|
`,
|
|
778
1028
|
[
|
|
779
1029
|
ops.lambda,
|
|
780
|
-
|
|
781
|
-
[[
|
|
1030
|
+
1,
|
|
1031
|
+
[["name", [[ops.params, 0], 0]]],
|
|
1032
|
+
[[markers.traverse, [markers.reference, "_template"]]],
|
|
782
1033
|
],
|
|
783
1034
|
"program",
|
|
784
1035
|
false
|
|
@@ -796,7 +1047,6 @@ Body`,
|
|
|
796
1047
|
]);
|
|
797
1048
|
assertParse("group", "(fn())", [
|
|
798
1049
|
[markers.traverse, [markers.reference, "fn"]],
|
|
799
|
-
undefined,
|
|
800
1050
|
]);
|
|
801
1051
|
assertParse("group", "(a -> b)", [
|
|
802
1052
|
[markers.traverse, [markers.reference, "b"]],
|
|
@@ -848,7 +1098,7 @@ Body`,
|
|
|
848
1098
|
[markers.traverse, [markers.reference, "c"]],
|
|
849
1099
|
]);
|
|
850
1100
|
assertParse("implicitParenthesesCallExpression", "(fn()) 'arg'", [
|
|
851
|
-
[[markers.traverse, [markers.reference, "fn"]]
|
|
1101
|
+
[[markers.traverse, [markers.reference, "fn"]]],
|
|
852
1102
|
[ops.literal, "arg"],
|
|
853
1103
|
]);
|
|
854
1104
|
assertParse(
|
|
@@ -897,13 +1147,14 @@ Body`,
|
|
|
897
1147
|
assertParse("key", "a~b", "a~b");
|
|
898
1148
|
assertParse("key", "foo-bar", "foo-bar");
|
|
899
1149
|
assertParse("key", "package-lock.json", "package-lock.json");
|
|
1150
|
+
assertThrows("key", "...rest", `but "." found`);
|
|
900
1151
|
});
|
|
901
1152
|
|
|
902
1153
|
test("logicalAndExpression", () => {
|
|
903
1154
|
assertParse("logicalAndExpression", "true && false", [
|
|
904
1155
|
ops.logicalAnd,
|
|
905
1156
|
[markers.traverse, [markers.reference, "true"]],
|
|
906
|
-
[ops.lambda, [], [markers.traverse, [markers.reference, "false"]]],
|
|
1157
|
+
[ops.lambda, 0, [], [markers.traverse, [markers.reference, "false"]]],
|
|
907
1158
|
]);
|
|
908
1159
|
});
|
|
909
1160
|
|
|
@@ -916,13 +1167,13 @@ Body`,
|
|
|
916
1167
|
assertParse("logicalOrExpression", "false || false || true", [
|
|
917
1168
|
ops.logicalOr,
|
|
918
1169
|
[markers.traverse, [markers.reference, "false"]],
|
|
919
|
-
[ops.lambda, [], [markers.traverse, [markers.reference, "false"]]],
|
|
920
|
-
[ops.lambda, [], [markers.traverse, [markers.reference, "true"]]],
|
|
1170
|
+
[ops.lambda, 0, [], [markers.traverse, [markers.reference, "false"]]],
|
|
1171
|
+
[ops.lambda, 0, [], [markers.traverse, [markers.reference, "true"]]],
|
|
921
1172
|
]);
|
|
922
1173
|
assertParse("logicalOrExpression", "1 || 2 && 0", [
|
|
923
1174
|
ops.logicalOr,
|
|
924
1175
|
[ops.literal, 1],
|
|
925
|
-
[ops.lambda, [], [ops.logicalAnd, [ops.literal, 2], [ops.literal, 0]]],
|
|
1176
|
+
[ops.lambda, 0, [], [ops.logicalAnd, [ops.literal, 2], [ops.literal, 0]]],
|
|
926
1177
|
]);
|
|
927
1178
|
});
|
|
928
1179
|
|
|
@@ -969,20 +1220,34 @@ Body`,
|
|
|
969
1220
|
assertParse("nullishCoalescingExpression", "a ?? b", [
|
|
970
1221
|
ops.nullishCoalescing,
|
|
971
1222
|
[markers.traverse, [markers.reference, "a"]],
|
|
972
|
-
[ops.lambda, [], [markers.traverse, [markers.reference, "b"]]],
|
|
1223
|
+
[ops.lambda, 0, [], [markers.traverse, [markers.reference, "b"]]],
|
|
973
1224
|
]);
|
|
974
1225
|
assertParse("nullishCoalescingExpression", "a ?? b ?? c", [
|
|
975
1226
|
ops.nullishCoalescing,
|
|
976
1227
|
[markers.traverse, [markers.reference, "a"]],
|
|
977
|
-
[ops.lambda, [], [markers.traverse, [markers.reference, "b"]]],
|
|
978
|
-
[ops.lambda, [], [markers.traverse, [markers.reference, "c"]]],
|
|
1228
|
+
[ops.lambda, 0, [], [markers.traverse, [markers.reference, "b"]]],
|
|
1229
|
+
[ops.lambda, 0, [], [markers.traverse, [markers.reference, "c"]]],
|
|
979
1230
|
]);
|
|
980
1231
|
});
|
|
981
1232
|
|
|
982
|
-
test("
|
|
983
|
-
assertParse("
|
|
984
|
-
|
|
985
|
-
|
|
1233
|
+
test("numberLiteral", () => {
|
|
1234
|
+
assertParse("numberLiteral", "123", [ops.literal, 123]);
|
|
1235
|
+
});
|
|
1236
|
+
|
|
1237
|
+
test("number", () => {
|
|
1238
|
+
assertParse("number", "123", 123, undefined, false);
|
|
1239
|
+
assertParse("number", ".5", 0.5, undefined, false);
|
|
1240
|
+
assertParse("number", "123.45", 123.45, undefined, false);
|
|
1241
|
+
assertParse("number", "123_456", 123456, undefined, false);
|
|
1242
|
+
assertParse("number", "0e-5", 0e-5, undefined, false);
|
|
1243
|
+
assertParse("number", "175e-2", 175e-2, undefined, false);
|
|
1244
|
+
assertParse("number", "1e-3", 1e-3, undefined, false);
|
|
1245
|
+
assertParse("number", "123n", 123n, undefined, false);
|
|
1246
|
+
assertParse("number", "0b1010", 0b1010, undefined, false);
|
|
1247
|
+
assertParse("number", "0b100_100", 0b100100, undefined, false);
|
|
1248
|
+
assertParse("number", "0o755", 0o755, undefined, false);
|
|
1249
|
+
assertParse("number", "0x1A3F", 0x1a3f, undefined, false);
|
|
1250
|
+
assertParse("number", "0x1a_3f", 0x1a3f, undefined, false);
|
|
986
1251
|
});
|
|
987
1252
|
|
|
988
1253
|
describe("objectLiteral", () => {
|
|
@@ -1039,10 +1304,7 @@ Body`,
|
|
|
1039
1304
|
ops.object,
|
|
1040
1305
|
[
|
|
1041
1306
|
"b",
|
|
1042
|
-
[
|
|
1043
|
-
ops.getter,
|
|
1044
|
-
[[markers.traverse, [markers.reference, "fn"]], undefined],
|
|
1045
|
-
],
|
|
1307
|
+
[ops.getter, [[markers.traverse, [markers.reference, "fn"]]]],
|
|
1046
1308
|
],
|
|
1047
1309
|
],
|
|
1048
1310
|
],
|
|
@@ -1166,7 +1428,8 @@ Body`,
|
|
|
1166
1428
|
"a",
|
|
1167
1429
|
[
|
|
1168
1430
|
ops.lambda,
|
|
1169
|
-
|
|
1431
|
+
1,
|
|
1432
|
+
[["a", [[ops.params, 0], 0]]],
|
|
1170
1433
|
[markers.traverse, [markers.reference, "a"]],
|
|
1171
1434
|
],
|
|
1172
1435
|
]);
|
|
@@ -1233,7 +1496,7 @@ Body`,
|
|
|
1233
1496
|
});
|
|
1234
1497
|
|
|
1235
1498
|
test("parenthesesArguments", () => {
|
|
1236
|
-
assertParse("parenthesesArguments", "()", [
|
|
1499
|
+
assertParse("parenthesesArguments", "()", []);
|
|
1237
1500
|
assertParse("parenthesesArguments", "(a, b, c)", [
|
|
1238
1501
|
[markers.traverse, [markers.reference, "a"]],
|
|
1239
1502
|
[markers.traverse, [markers.reference, "b"]],
|
|
@@ -1463,12 +1726,14 @@ Body`,
|
|
|
1463
1726
|
test("shorthandFunction", () => {
|
|
1464
1727
|
assertParse("shorthandFunction", "=message", [
|
|
1465
1728
|
ops.lambda,
|
|
1466
|
-
|
|
1729
|
+
1,
|
|
1730
|
+
[["_", [[ops.params, 0], 0]]],
|
|
1467
1731
|
[markers.traverse, [markers.reference, "message"]],
|
|
1468
1732
|
]);
|
|
1469
1733
|
assertParse("shorthandFunction", "=`Hello, ${name}.`", [
|
|
1470
1734
|
ops.lambda,
|
|
1471
|
-
|
|
1735
|
+
1,
|
|
1736
|
+
[["_", [[ops.params, 0], 0]]],
|
|
1472
1737
|
[
|
|
1473
1738
|
ops.templateText,
|
|
1474
1739
|
[ops.literal, ["Hello, ", "."]],
|
|
@@ -1477,7 +1742,8 @@ Body`,
|
|
|
1477
1742
|
]);
|
|
1478
1743
|
assertParse("shorthandFunction", "=indent`hello`", [
|
|
1479
1744
|
ops.lambda,
|
|
1480
|
-
|
|
1745
|
+
1,
|
|
1746
|
+
[["_", [[ops.params, 0], 0]]],
|
|
1481
1747
|
[
|
|
1482
1748
|
[markers.traverse, [markers.reference, "indent"]],
|
|
1483
1749
|
[ops.literal, ["hello"]],
|
|
@@ -1510,6 +1776,7 @@ Body`,
|
|
|
1510
1776
|
assertParse("stringLiteral", `"foo\\"s bar"`, [ops.literal, `foo"s bar`]);
|
|
1511
1777
|
assertParse("stringLiteral", `'bar\\'s baz'`, [ops.literal, `bar's baz`]);
|
|
1512
1778
|
assertParse("stringLiteral", `«string»`, [ops.literal, "string"]);
|
|
1779
|
+
assertParse("stringLiteral", `»string«`, [ops.literal, "string"]);
|
|
1513
1780
|
assertParse("stringLiteral", `"\\0\\b\\f\\n\\r\\t\\v"`, [
|
|
1514
1781
|
ops.literal,
|
|
1515
1782
|
"\0\b\f\n\r\t\v",
|
|
@@ -1531,7 +1798,8 @@ Body`,
|
|
|
1531
1798
|
test("templateDocument with no front matter", () => {
|
|
1532
1799
|
assertParse("templateDocument", "Hello, world!", [
|
|
1533
1800
|
ops.lambda,
|
|
1534
|
-
|
|
1801
|
+
1,
|
|
1802
|
+
[["_", [[ops.params, 0], 0]]],
|
|
1535
1803
|
[ops.templateIndent, [ops.literal, ["Hello, world!"]]],
|
|
1536
1804
|
]);
|
|
1537
1805
|
});
|
|
@@ -1578,32 +1846,6 @@ Body text`,
|
|
|
1578
1846
|
);
|
|
1579
1847
|
});
|
|
1580
1848
|
|
|
1581
|
-
test.skip("templateDocument with Origami front matter", () => {
|
|
1582
|
-
assertParse(
|
|
1583
|
-
"templateDocument",
|
|
1584
|
-
`---
|
|
1585
|
-
{
|
|
1586
|
-
title: "Title"
|
|
1587
|
-
_body: _template()
|
|
1588
|
-
}
|
|
1589
|
-
---
|
|
1590
|
-
<h1>\${ title }</h1>
|
|
1591
|
-
`,
|
|
1592
|
-
[
|
|
1593
|
-
ops.object,
|
|
1594
|
-
["title", [ops.literal, "Title"]],
|
|
1595
|
-
[
|
|
1596
|
-
"_body",
|
|
1597
|
-
[
|
|
1598
|
-
ops.templateIndent,
|
|
1599
|
-
[ops.literal, ["<h1>", "</h1>\n"]],
|
|
1600
|
-
[markers.traverse, [markers.reference, "title"]],
|
|
1601
|
-
],
|
|
1602
|
-
],
|
|
1603
|
-
]
|
|
1604
|
-
);
|
|
1605
|
-
});
|
|
1606
|
-
|
|
1607
1849
|
test("templateLiteral", () => {
|
|
1608
1850
|
assertParse("templateLiteral", "`Hello, world.`", [
|
|
1609
1851
|
ops.templateText,
|
|
@@ -1631,7 +1873,8 @@ Body text`,
|
|
|
1631
1873
|
[markers.traverse, [markers.reference, "people"]],
|
|
1632
1874
|
[
|
|
1633
1875
|
ops.lambda,
|
|
1634
|
-
|
|
1876
|
+
1,
|
|
1877
|
+
[["_", [[ops.params, 0], 0]]],
|
|
1635
1878
|
[
|
|
1636
1879
|
ops.templateText,
|
|
1637
1880
|
[ops.literal, ["", ""]],
|