@weborigami/language 0.6.3 → 0.6.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weborigami/language",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "Web Origami expression language compiler and runtime",
5
5
  "type": "module",
6
6
  "main": "./main.js",
@@ -11,7 +11,7 @@
11
11
  "typescript": "5.9.3"
12
12
  },
13
13
  "dependencies": {
14
- "@weborigami/async-tree": "0.6.3",
14
+ "@weborigami/async-tree": "0.6.4",
15
15
  "exif-parser": "0.1.12",
16
16
  "watcher": "2.3.1",
17
17
  "yaml": "2.8.1"
@@ -62,7 +62,10 @@ export default function optimize(code, options = {}) {
62
62
 
63
63
  case ops.object:
64
64
  const entries = args;
65
- const propertyNames = entries.map((entry) => entryKey(entry));
65
+ // Filter out computed property keys when determining local variables
66
+ const propertyNames = entries
67
+ .map((entry) => entryKey(entry))
68
+ .filter((key) => key !== null);
66
69
  locals.push({
67
70
  type: REFERENCE_INHERITED,
68
71
  names: propertyNames,
@@ -79,16 +82,18 @@ export default function optimize(code, options = {}) {
79
82
  } else if (op === ops.object && index > 0) {
80
83
  const [key, value] = child;
81
84
  const adjustedLocals = avoidLocalRecursion(locals, key);
82
- return annotate(
83
- [
84
- key,
85
- optimize(/** @type {AnnotatedCode} */ (value), {
86
- ...options,
87
- locals: adjustedLocals,
88
- }),
89
- ],
90
- child.location
91
- );
85
+ const optimizedKey =
86
+ typeof key === "string"
87
+ ? key
88
+ : optimize(/** @type {AnnotatedCode} */ (key), {
89
+ ...options,
90
+ locals: adjustedLocals,
91
+ });
92
+ const optimizedValue = optimize(/** @type {AnnotatedCode} */ (value), {
93
+ ...options,
94
+ locals: adjustedLocals,
95
+ });
96
+ return annotate([optimizedKey, optimizedValue], child.location);
92
97
  } else if (Array.isArray(child) && "location" in child) {
93
98
  // Review: Aside from ops.object (above), what non-instruction arrays
94
99
  // does this descend into?
@@ -18,6 +18,7 @@ import {
18
18
  makeArray,
19
19
  makeBinaryOperation,
20
20
  makeCall,
21
+ makeCallChain,
21
22
  makeDeferredArguments,
22
23
  makeDocument,
23
24
  makeObject,
@@ -83,7 +84,7 @@ arguments "function arguments"
83
84
  / pathArguments
84
85
  / propertyAccess
85
86
  / computedPropertyAccess
86
- // / optionalChaining
87
+ / optional
87
88
  / templateLiteral
88
89
 
89
90
  arrayLiteral "array"
@@ -143,10 +144,7 @@ bitwiseXorOperator
143
144
  // `fn(arg1)(arg2)(arg3)`.
144
145
  callExpression "function call"
145
146
  = head:uriExpression tail:arguments* {
146
- return tail.reduce(
147
- (target, args) => makeCall(target, args, location()),
148
- head
149
- );
147
+ return makeCallChain(head, tail, location());
150
148
  }
151
149
 
152
150
  // A comma-separated list of expressions: `x, y, z`
@@ -168,9 +166,9 @@ computedPropertyAccess
168
166
  return annotate([markers.property, expression], location());
169
167
  }
170
168
 
171
- // A space before a computed property access. This is allowed when in not in
172
- // shell mode, but not in shell mode. In shell mode `foo [bar]` should parse as
173
- // a function call with a single argument of an array, not as a property access.
169
+ // A space before a computed property access. This is allowed when not in shell
170
+ // mode. In shell mode `foo [bar]` should parse as a function call with a single
171
+ // argument of an array, not as a property access.
174
172
  computedPropertySpace
175
173
  = shellMode
176
174
  / !shellMode __
@@ -383,16 +381,27 @@ identifierPart "JavaScript identifier continuation"
383
381
  identifierStart "JavaScript identifier start"
384
382
  = char:. &{ return char.match(/[$_\p{ID_Start}]/u) }
385
383
 
386
- implicitParenthesesCallExpression "function call with implicit parentheses"
387
- = head:arrowFunction args:(inlineSpace+ @implicitParensthesesArguments)? {
388
- return args ? makeCall(head, args, location()) : head;
384
+ // A single argument for an implicit parens call. This differs from
385
+ // `parenthesesArgument` in that the term can't be a pipeline.
386
+ implicitParenthesesArgument
387
+ = "..." arg:shorthandFunction {
388
+ return annotate([markers.spread, arg], location());
389
+ }
390
+ / shorthandFunction
391
+
392
+ // A separated list of arguments for an implicit parens call.
393
+ implicitParenthesesArgumentList "list"
394
+ = args:implicitParenthesesArgument|1.., separator| separator? {
395
+ return annotate(args, location());
389
396
  }
390
397
 
391
- // A separated list of values for an implicit parens call. This differs from
392
- // `list` in that the value term can't be a pipeline.
393
- implicitParensthesesArguments
394
- = shellMode values:shorthandFunction|1.., separator| separator? {
395
- return annotate(values, location());
398
+ // A separated list of values for an implicit parens call.
399
+ implicitParenthesesArguments
400
+ = shellMode inlineSpace+ @implicitParenthesesArgumentList
401
+
402
+ implicitParenthesesCallExpression "function call with implicit parentheses"
403
+ = head:arrowFunction args:implicitParenthesesArguments? {
404
+ return args ? makeCall(head, args, location()) : head;
396
405
  }
397
406
 
398
407
  inlineSpace
@@ -430,12 +439,6 @@ keyCharStart
430
439
  / "@"
431
440
  / "~"
432
441
 
433
- // A separated list of values
434
- list "list"
435
- = values:pipelineExpression|1.., separator| separator? {
436
- return annotate(values, location());
437
- }
438
-
439
442
  logicalAndExpression
440
443
  = head:bitwiseOrExpression tail:(__ "&&" __ @bitwiseOrExpression)* {
441
444
  return tail.length === 0
@@ -561,7 +564,8 @@ objectShorthandProperty "object identifier"
561
564
  }
562
565
 
563
566
  objectPublicKey
564
- = key:key slash:"/"? {
567
+ = "[" __ @pipelineExpression __ expectClosingBracket
568
+ / key:key slash:"/"? {
565
569
  return text();
566
570
  }
567
571
  / string:stringLiteral {
@@ -569,12 +573,20 @@ objectPublicKey
569
573
  return string[1];
570
574
  }
571
575
 
572
- optionalChaining
573
- = __ "?." __ property:identifier {
574
- return annotate([ops.optionalTraverse, property], location());
576
+ // Optional chaining
577
+ optional
578
+ = __ "?." args:parenthesesArguments {
579
+ return annotate([ops.optional, args], location());
580
+ }
581
+ / __ "?." access:computedPropertyAccess {
582
+ return annotate([ops.optional, access], location());
583
+ }
584
+ / __ "?." whitespaceOptionalForProgram property:identifierLiteral {
585
+ const propertyAccess = annotate([markers.property, property], location());
586
+ return annotate([ops.optional, propertyAccess], location());
575
587
  }
576
588
 
577
- // Name of a unction parameter
589
+ // Name of a function parameter
578
590
  parameter
579
591
  = key:key {
580
592
  return annotate([ops.literal, key], location());
@@ -591,9 +603,22 @@ parameterSingleton
591
603
  return annotate([param], location());
592
604
  }
593
605
 
606
+ // A single argument inside parentheses
607
+ parenthesesArgument
608
+ = "..." arg:pipelineExpression {
609
+ return annotate([markers.spread, arg], location());
610
+ }
611
+ / pipelineExpression
612
+
613
+ // A separated list of arguments inside parentheses
614
+ parenthesesArgumentList "list"
615
+ = args:parenthesesArgument|1.., separator| separator? {
616
+ return annotate(args, location());
617
+ }
618
+
594
619
  // Function arguments in parentheses
595
620
  parenthesesArguments "function arguments in parentheses"
596
- = "(" __ list:list? __ expectClosingParenthesis {
621
+ = inlineSpace* "(" __ list:parenthesesArgumentList? __ expectClosingParenthesis {
597
622
  return annotate(list ?? [undefined], location());
598
623
  }
599
624
 
@@ -764,7 +789,7 @@ slashFollows
764
789
 
765
790
  spreadElement
766
791
  = ellipsis __ value:expectPipelineExpression {
767
- return annotate([ops.spread, value], location());
792
+ return annotate([markers.spread, value], location());
768
793
  }
769
794
 
770
795
  stringLiteral "string"