tree-sitter-bynk 0.141.0 → 0.163.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/grammar.js +128 -38
- package/package.json +1 -1
- package/queries/highlights.scm +16 -3
- package/src/grammar.json +518 -154
- package/src/node-types.json +1719 -920
- package/src/parser.c +51448 -42038
package/grammar.js
CHANGED
|
@@ -59,6 +59,12 @@ module.exports = grammar({
|
|
|
59
59
|
// closing `)` is followed — or not — by `=>`.
|
|
60
60
|
[$.lambda_param, $._primary],
|
|
61
61
|
[$._primary, $.lambda_expr],
|
|
62
|
+
// v0.145: a match-arm `if`-guard is an `_expression` immediately followed by
|
|
63
|
+
// the arm's `=>`. When the guard opens with `(`, one token can't tell a unit
|
|
64
|
+
// literal `()` (a guard, with `=>` opening the arm) from a zero-param lambda
|
|
65
|
+
// `() =>` (the guard itself). GLR keeps both alive; only the unit parse
|
|
66
|
+
// completes the arm.
|
|
67
|
+
[$.lambda_expr, $.unit_literal],
|
|
62
68
|
// v0.117: after `expect Cap.op called`, one token of lookahead can't tell a
|
|
63
69
|
// following `<n> times` count from the end of the observation — GLR keeps
|
|
64
70
|
// both parses alive until the next token decides.
|
|
@@ -220,7 +226,7 @@ module.exports = grammar({
|
|
|
220
226
|
),
|
|
221
227
|
|
|
222
228
|
_test_body_item: ($) =>
|
|
223
|
-
choice($.uses_decl, $.consumes_decl, $.
|
|
229
|
+
choice($.uses_decl, $.consumes_decl, $.stub_clause, $.case, $.property_decl),
|
|
224
230
|
|
|
225
231
|
// -- Headers / clauses --
|
|
226
232
|
|
|
@@ -278,6 +284,9 @@ module.exports = grammar({
|
|
|
278
284
|
seq(
|
|
279
285
|
"type",
|
|
280
286
|
field("name", $.identifier),
|
|
287
|
+
// v0.157 (ADR 0183): optional `[A, B]` type parameters — only a record
|
|
288
|
+
// body may be generic (enforced by the checker, not the grammar).
|
|
289
|
+
optional(seq("[", sep1(field("type_param", $.identifier), ","), "]")),
|
|
281
290
|
"=",
|
|
282
291
|
field("body", $._type_body),
|
|
283
292
|
),
|
|
@@ -326,7 +335,28 @@ module.exports = grammar({
|
|
|
326
335
|
optional(seq("=", field("init", $._expression))),
|
|
327
336
|
),
|
|
328
337
|
|
|
329
|
-
|
|
338
|
+
// v0.154 (ADR 0178): a sum body may carry a trailing `embeds E as V, …`
|
|
339
|
+
// clause declaring error embeddings the `?` operator auto-converts.
|
|
340
|
+
// `embeds`/`as` are contextual — matched only in this position.
|
|
341
|
+
sum_type: ($) =>
|
|
342
|
+
prec.right(
|
|
343
|
+
seq(
|
|
344
|
+
repeat1($.sum_variant),
|
|
345
|
+
optional(
|
|
346
|
+
seq(
|
|
347
|
+
"embeds",
|
|
348
|
+
sep1(
|
|
349
|
+
seq(
|
|
350
|
+
field("source", $._type_ref),
|
|
351
|
+
"as",
|
|
352
|
+
field("variant", $.constant_name),
|
|
353
|
+
),
|
|
354
|
+
",",
|
|
355
|
+
),
|
|
356
|
+
),
|
|
357
|
+
),
|
|
358
|
+
),
|
|
359
|
+
),
|
|
330
360
|
sum_variant: ($) =>
|
|
331
361
|
seq(
|
|
332
362
|
"|",
|
|
@@ -356,7 +386,10 @@ module.exports = grammar({
|
|
|
356
386
|
"}",
|
|
357
387
|
),
|
|
358
388
|
|
|
359
|
-
|
|
389
|
+
// #548: refinement predicates join with `&&` — the one conjunction spelling,
|
|
390
|
+
// shared with contracts/`expect` (was the `and` keyword before the
|
|
391
|
+
// keyword-hygiene batch). The catalogue stays conjunction-only (no `||`/`!`).
|
|
392
|
+
refinement: ($) => sep1($._refinement_pred, "&&"),
|
|
360
393
|
_refinement_pred: ($) =>
|
|
361
394
|
choice(
|
|
362
395
|
$.pred_call,
|
|
@@ -388,9 +421,21 @@ module.exports = grammar({
|
|
|
388
421
|
$.unit_type,
|
|
389
422
|
$.validation_error_type,
|
|
390
423
|
$.generic_type_ref,
|
|
424
|
+
$.applied_type_ref,
|
|
391
425
|
$.identifier,
|
|
392
426
|
),
|
|
393
427
|
|
|
428
|
+
// v0.157 (ADR 0183): `Name[Arg, …]` — an application of a user-declared
|
|
429
|
+
// generic type. Distinct from `generic_type_ref` (the fixed built-in
|
|
430
|
+
// generics); the head is a user identifier.
|
|
431
|
+
applied_type_ref: ($) =>
|
|
432
|
+
seq(
|
|
433
|
+
field("name", $.identifier),
|
|
434
|
+
"[",
|
|
435
|
+
sep1(field("arg", $._type_ref), ","),
|
|
436
|
+
"]",
|
|
437
|
+
),
|
|
438
|
+
|
|
394
439
|
// v0.20a: a function type — `A -> B`, `(A, B) -> C`, `() -> B`,
|
|
395
440
|
// right-associative (prec.right). A parenthesised parameter list is only
|
|
396
441
|
// a function type when followed by `->`; bare `()` stays the unit type.
|
|
@@ -404,6 +449,7 @@ module.exports = grammar({
|
|
|
404
449
|
$.unit_type,
|
|
405
450
|
$.validation_error_type,
|
|
406
451
|
$.generic_type_ref,
|
|
452
|
+
$.applied_type_ref,
|
|
407
453
|
$.identifier,
|
|
408
454
|
seq("(", sep1($._type_ref, ","), optional(","), ")"),
|
|
409
455
|
),
|
|
@@ -540,6 +586,10 @@ module.exports = grammar({
|
|
|
540
586
|
"service",
|
|
541
587
|
field("name", $.identifier),
|
|
542
588
|
optional(field("protocol", $.service_protocol)),
|
|
589
|
+
// v0.155: optional service-level `by`/`given` defaults on the header —
|
|
590
|
+
// the ambient contract every handler inherits unless it declares its own.
|
|
591
|
+
optional(field("default_by", $.by_clause)),
|
|
592
|
+
optional(field("default_given", $.given_clause)),
|
|
543
593
|
"{",
|
|
544
594
|
// v0.131 (ADR 0158): the optional `cors { }` policy, in header position
|
|
545
595
|
// before the handlers (a `from http` concern; the checker restricts it).
|
|
@@ -547,6 +597,9 @@ module.exports = grammar({
|
|
|
547
597
|
// v0.141 (ADR 0164): the optional `security { }` policy, likewise a
|
|
548
598
|
// header-position `from http` concern restricted by the checker.
|
|
549
599
|
optional(field("security", $.security_policy)),
|
|
600
|
+
// v0.142 (ADR 0166): the optional `limits { }` policy, likewise a
|
|
601
|
+
// header-position `from http` concern restricted by the checker.
|
|
602
|
+
optional(field("limits", $.limits_policy)),
|
|
550
603
|
repeat($.handler),
|
|
551
604
|
"}",
|
|
552
605
|
),
|
|
@@ -574,9 +627,23 @@ module.exports = grammar({
|
|
|
574
627
|
),
|
|
575
628
|
security_field: ($) =>
|
|
576
629
|
seq(field("name", $.identifier), ":", field("value", $._expression)),
|
|
630
|
+
// v0.142: `limits { <name>: <value>, … }`. `limits` is a contextual
|
|
631
|
+
// keyword (like `cors`/`security`); field names are ordinary identifiers
|
|
632
|
+
// matched against the closed set by the checker.
|
|
633
|
+
limits_policy: ($) =>
|
|
634
|
+
seq(
|
|
635
|
+
"limits",
|
|
636
|
+
"{",
|
|
637
|
+
repeat(seq($.limits_field, optional(","))),
|
|
638
|
+
"}",
|
|
639
|
+
),
|
|
640
|
+
limits_field: ($) =>
|
|
641
|
+
seq(field("name", $.identifier), ":", field("value", $._expression)),
|
|
577
642
|
// v0.44: `from <protocol>` on the service header.
|
|
578
|
-
// v0.103: `from
|
|
579
|
-
// types. `
|
|
643
|
+
// v0.103: `from websocket(in: I, out: O)` binds the inbound/outbound frame
|
|
644
|
+
// types. `websocket`, `in`, and `out` are contextual (resolved by `word`).
|
|
645
|
+
// #548: `websocket` lowercased to match the other protocol sources (was
|
|
646
|
+
// `WebSocket`).
|
|
580
647
|
service_protocol: ($) =>
|
|
581
648
|
seq(
|
|
582
649
|
"from",
|
|
@@ -585,7 +652,7 @@ module.exports = grammar({
|
|
|
585
652
|
"cron",
|
|
586
653
|
seq("queue", "(", field("name", $.string_literal), ")"),
|
|
587
654
|
seq(
|
|
588
|
-
"
|
|
655
|
+
"websocket",
|
|
589
656
|
"(",
|
|
590
657
|
"in",
|
|
591
658
|
":",
|
|
@@ -688,13 +755,13 @@ module.exports = grammar({
|
|
|
688
755
|
"on",
|
|
689
756
|
"call",
|
|
690
757
|
optional(field("method", $.identifier)),
|
|
691
|
-
optional(field("by", $.by_clause)),
|
|
692
758
|
"(",
|
|
693
759
|
optional(sep1($.param, ",")),
|
|
694
760
|
optional(","),
|
|
695
761
|
")",
|
|
696
762
|
"->",
|
|
697
763
|
field("return_type", $._type_ref),
|
|
764
|
+
optional(field("by", $.by_clause)),
|
|
698
765
|
optional(field("given", $.given_clause)),
|
|
699
766
|
field("body", $.block),
|
|
700
767
|
),
|
|
@@ -707,13 +774,13 @@ module.exports = grammar({
|
|
|
707
774
|
"(",
|
|
708
775
|
field("path", $.string_literal),
|
|
709
776
|
")",
|
|
710
|
-
optional(field("by", $.by_clause)),
|
|
711
777
|
"(",
|
|
712
778
|
optional(sep1($.param, ",")),
|
|
713
779
|
optional(","),
|
|
714
780
|
")",
|
|
715
781
|
"->",
|
|
716
782
|
field("return_type", $._type_ref),
|
|
783
|
+
optional(field("by", $.by_clause)),
|
|
717
784
|
optional(field("given", $.given_clause)),
|
|
718
785
|
field("body", $.block),
|
|
719
786
|
),
|
|
@@ -726,13 +793,13 @@ module.exports = grammar({
|
|
|
726
793
|
"(",
|
|
727
794
|
field("schedule", $.string_literal),
|
|
728
795
|
")",
|
|
729
|
-
optional(field("by", $.by_clause)),
|
|
730
796
|
"(",
|
|
731
797
|
optional(sep1($.param, ",")),
|
|
732
798
|
optional(","),
|
|
733
799
|
")",
|
|
734
800
|
"->",
|
|
735
801
|
field("return_type", $._type_ref),
|
|
802
|
+
optional(field("by", $.by_clause)),
|
|
736
803
|
optional(field("given", $.given_clause)),
|
|
737
804
|
field("body", $.block),
|
|
738
805
|
),
|
|
@@ -742,30 +809,30 @@ module.exports = grammar({
|
|
|
742
809
|
seq(
|
|
743
810
|
"on",
|
|
744
811
|
"message",
|
|
745
|
-
optional(field("by", $.by_clause)),
|
|
746
812
|
"(",
|
|
747
813
|
optional(sep1($.param, ",")),
|
|
748
814
|
optional(","),
|
|
749
815
|
")",
|
|
750
816
|
"->",
|
|
751
817
|
field("return_type", $._type_ref),
|
|
818
|
+
optional(field("by", $.by_clause)),
|
|
752
819
|
optional(field("given", $.given_clause)),
|
|
753
820
|
field("body", $.block),
|
|
754
821
|
),
|
|
755
822
|
// v0.103/v0.106: `on open` / `on close` lifecycle handlers of a
|
|
756
|
-
// `from
|
|
823
|
+
// `from websocket` service. `open`/`close` are contextual (resolved by
|
|
757
824
|
// `word`). `on message` (the inbound-frame handler) reuses queue_handler.
|
|
758
825
|
ws_open_handler: ($) =>
|
|
759
826
|
seq(
|
|
760
827
|
"on",
|
|
761
828
|
"open",
|
|
762
|
-
optional(field("by", $.by_clause)),
|
|
763
829
|
"(",
|
|
764
830
|
optional(sep1($.param, ",")),
|
|
765
831
|
optional(","),
|
|
766
832
|
")",
|
|
767
833
|
"->",
|
|
768
834
|
field("return_type", $._type_ref),
|
|
835
|
+
optional(field("by", $.by_clause)),
|
|
769
836
|
optional(field("given", $.given_clause)),
|
|
770
837
|
field("body", $.block),
|
|
771
838
|
),
|
|
@@ -773,13 +840,13 @@ module.exports = grammar({
|
|
|
773
840
|
seq(
|
|
774
841
|
"on",
|
|
775
842
|
"close",
|
|
776
|
-
optional(field("by", $.by_clause)),
|
|
777
843
|
"(",
|
|
778
844
|
optional(sep1($.param, ",")),
|
|
779
845
|
optional(","),
|
|
780
846
|
")",
|
|
781
847
|
"->",
|
|
782
848
|
field("return_type", $._type_ref),
|
|
849
|
+
optional(field("by", $.by_clause)),
|
|
783
850
|
optional(field("given", $.given_clause)),
|
|
784
851
|
field("body", $.block),
|
|
785
852
|
),
|
|
@@ -789,9 +856,18 @@ module.exports = grammar({
|
|
|
789
856
|
seq("given", sep1(field("capability", $.qualified_name), ",")),
|
|
790
857
|
|
|
791
858
|
// v0.45: an actor declaration — a boundary contract. Normal form
|
|
792
|
-
// `actor Name { auth = Scheme (, identity = Type)? }
|
|
793
|
-
//
|
|
794
|
-
//
|
|
859
|
+
// `actor Name { auth = Scheme (, identity = Type)? }`. The refinement form
|
|
860
|
+
// `actor Admin = Base where <predicate>` narrows a base actor by an
|
|
861
|
+
// authorisation claim (`actor Admin = User where hasClaim("admin")`).
|
|
862
|
+
//
|
|
863
|
+
// #548: the predicate is a full `_expression`, matching what the compiler
|
|
864
|
+
// parses (a general expression). It is *not* the type-refinement catalogue
|
|
865
|
+
// (`Matches`/`InRange`/…, rule `refinement`) — that mis-modelled `hasClaim`
|
|
866
|
+
// as an ERROR. As with function contracts, the grammar parses the broad
|
|
867
|
+
// expression and a static-semantics rule restricts it to the closed
|
|
868
|
+
// actor-claim catalogue (`hasClaim`/`claimEquals` composed with `&&`/`||`/`!`;
|
|
869
|
+
// `bynk.actor.refinement_predicate_unsupported`). See spec §5 / grammar
|
|
870
|
+
// reference for the three `where` predicate tiers.
|
|
795
871
|
actor_decl: ($) =>
|
|
796
872
|
seq(
|
|
797
873
|
"actor",
|
|
@@ -814,13 +890,14 @@ module.exports = grammar({
|
|
|
814
890
|
"=",
|
|
815
891
|
field("base", $.identifier),
|
|
816
892
|
"where",
|
|
817
|
-
field("predicate", $.
|
|
893
|
+
field("predicate", $._expression),
|
|
818
894
|
),
|
|
819
895
|
),
|
|
820
896
|
),
|
|
821
|
-
// The closed, compiler-known scheme set. `None`/`Internal` are
|
|
822
|
-
//
|
|
823
|
-
|
|
897
|
+
// The closed, compiler-known scheme set. `None`/`Internal` are zero-crypto;
|
|
898
|
+
// `Bearer` (JWT/HS256), `Signature` (HMAC over the body), and `Oidc`
|
|
899
|
+
// (JWKS/RS256+ES256) are compiler-generated verifiers.
|
|
900
|
+
scheme: () => choice("None", "Internal", "Bearer", "Signature", "Oidc"),
|
|
824
901
|
// v0.51: the keyed-args scheme config — `(key = value, …)`. Values are
|
|
825
902
|
// string or integer literals; the checker validates which keys each scheme
|
|
826
903
|
// admits (Bearer: secret; Signature: secret/header/timestamp/tolerance).
|
|
@@ -854,16 +931,15 @@ module.exports = grammar({
|
|
|
854
931
|
// -- v0.7: test bodies --
|
|
855
932
|
|
|
856
933
|
// v0.118 (testing track slice 6): a test-scope stub for one capability
|
|
857
|
-
// operation — `
|
|
858
|
-
//
|
|
859
|
-
//
|
|
860
|
-
// is `
|
|
861
|
-
// `returns
|
|
862
|
-
//
|
|
863
|
-
|
|
864
|
-
provides_clause: ($) =>
|
|
934
|
+
// operation — `stub Cap.op(<arg pattern>, …) <rhs>`. Only admitted inside a
|
|
935
|
+
// suite/case body. An arg pattern is `_` (any) or a value expression; the
|
|
936
|
+
// right-hand side is `returns <expr>`, `returns each [ <outcome>, … ]` (a
|
|
937
|
+
// scripted sequence, where an outcome is `fails` or an expr), or `fails`.
|
|
938
|
+
// `returns`/`each`/`fails` are contextual words. Keyword `stub` since the
|
|
939
|
+
// keyword-hygiene batch (#548); formerly a pun on `provides`.
|
|
940
|
+
stub_clause: ($) =>
|
|
865
941
|
seq(
|
|
866
|
-
"
|
|
942
|
+
"stub",
|
|
867
943
|
field("cap", $.identifier),
|
|
868
944
|
".",
|
|
869
945
|
field("op", $.identifier),
|
|
@@ -893,7 +969,7 @@ module.exports = grammar({
|
|
|
893
969
|
),
|
|
894
970
|
),
|
|
895
971
|
// v0.118: an optional `as <tier>` classifier plus a body of leading
|
|
896
|
-
// `
|
|
972
|
+
// `stub` clauses, then the ordinary statements and tail. The tier words
|
|
897
973
|
// (`unit`/`integration`/`system`) are contextual, as on `suite_decl`.
|
|
898
974
|
case: ($) =>
|
|
899
975
|
seq(
|
|
@@ -901,7 +977,7 @@ module.exports = grammar({
|
|
|
901
977
|
field("name", $.string_literal),
|
|
902
978
|
optional(seq("as", field("tier", choice("unit", "integration", "system")))),
|
|
903
979
|
"{",
|
|
904
|
-
repeat($.
|
|
980
|
+
repeat($.stub_clause),
|
|
905
981
|
repeat($._statement),
|
|
906
982
|
optional(field("tail", $._expression)),
|
|
907
983
|
"}",
|
|
@@ -948,6 +1024,7 @@ module.exports = grammar({
|
|
|
948
1024
|
$.let_stmt,
|
|
949
1025
|
$.effect_let_stmt,
|
|
950
1026
|
$.effect_send_stmt,
|
|
1027
|
+
$.do_stmt,
|
|
951
1028
|
$.assign_stmt,
|
|
952
1029
|
prec(1, $.expect_expr),
|
|
953
1030
|
),
|
|
@@ -970,6 +1047,9 @@ module.exports = grammar({
|
|
|
970
1047
|
),
|
|
971
1048
|
// v0.79: `~> expr` — an asynchronous fire-and-forget send (no binder).
|
|
972
1049
|
effect_send_stmt: ($) => seq("~>", field("value", $._expression)),
|
|
1050
|
+
// v0.146 (ADR 0170): `do expr` — perform a unit effect as a statement
|
|
1051
|
+
// (the binder-free `let _ <- expr` for an `Effect[()]`).
|
|
1052
|
+
do_stmt: ($) => seq("do", field("value", $._expression)),
|
|
973
1053
|
// v0.81 (storage track): `name := expr` — a `Cell` store write.
|
|
974
1054
|
assign_stmt: ($) =>
|
|
975
1055
|
seq(field("target", $.identifier), ":=", field("value", $._expression)),
|
|
@@ -1043,13 +1123,14 @@ module.exports = grammar({
|
|
|
1043
1123
|
),
|
|
1044
1124
|
),
|
|
1045
1125
|
|
|
1126
|
+
// v0.146 (ADR 0170): `else` is optional. A missing `else` defaults to a
|
|
1127
|
+
// unit branch (legal only for a unit then-branch, enforced by the checker).
|
|
1046
1128
|
if_expr: ($) =>
|
|
1047
1129
|
seq(
|
|
1048
1130
|
"if",
|
|
1049
1131
|
field("cond", $._expression),
|
|
1050
1132
|
field("then", $.block),
|
|
1051
|
-
"else",
|
|
1052
|
-
field("else", choice($.if_expr, $.block)),
|
|
1133
|
+
optional(seq("else", field("else", choice($.if_expr, $.block)))),
|
|
1053
1134
|
),
|
|
1054
1135
|
|
|
1055
1136
|
match_expr: ($) =>
|
|
@@ -1066,6 +1147,10 @@ module.exports = grammar({
|
|
|
1066
1147
|
prec.right(
|
|
1067
1148
|
seq(
|
|
1068
1149
|
field("pattern", $._pattern),
|
|
1150
|
+
// v0.145 (ADR 0169): an optional trailing `if <Bool-expr>` guard,
|
|
1151
|
+
// between the pattern and `=>`, gating the arm over its bindings. The
|
|
1152
|
+
// `if` reuses the existing keyword token (already highlighted).
|
|
1153
|
+
optional(seq("if", field("guard", $._expression))),
|
|
1069
1154
|
"=>",
|
|
1070
1155
|
// `_expression` already includes `block` via `_primary`, so a
|
|
1071
1156
|
// `{ … }` arm body is covered without a separate alternative.
|
|
@@ -1105,14 +1190,19 @@ module.exports = grammar({
|
|
|
1105
1190
|
),
|
|
1106
1191
|
),
|
|
1107
1192
|
),
|
|
1193
|
+
// v0.145 (ADR 0169, decision B): a variant payload matches its field against
|
|
1194
|
+
// a full sub-`_pattern` (one recursion point), so `Some(Ok(x))` /
|
|
1195
|
+
// `Err(PollClosed)` parse as nested `variant_pattern` nodes rather than flat
|
|
1196
|
+
// bindings. A bare lowercase identifier is a payload-less `variant_pattern`
|
|
1197
|
+
// (a binding, recovered in the highlight query by capitalisation); `_` is a
|
|
1198
|
+
// `wildcard_pattern`; an uppercase-led one discriminates a nested variant.
|
|
1108
1199
|
_pattern_binding: ($) =>
|
|
1109
1200
|
choice(
|
|
1110
1201
|
$.named_binding,
|
|
1111
|
-
$.
|
|
1202
|
+
$._pattern,
|
|
1112
1203
|
),
|
|
1113
1204
|
named_binding: ($) =>
|
|
1114
|
-
seq(field("field", $.identifier), ":", field("name",
|
|
1115
|
-
positional_binding: ($) => choice($.identifier, "_"),
|
|
1205
|
+
seq(field("field", $.identifier), ":", field("name", $._pattern)),
|
|
1116
1206
|
|
|
1117
1207
|
is_expr: ($) =>
|
|
1118
1208
|
prec.left(
|
|
@@ -1312,12 +1402,12 @@ module.exports = grammar({
|
|
|
1312
1402
|
// overshadowing `identifier`; we use a regex.
|
|
1313
1403
|
constant_name: () => /[A-Z][A-Za-z0-9_]*/,
|
|
1314
1404
|
|
|
1315
|
-
number_literal: () => /[0-9]
|
|
1405
|
+
number_literal: () => /[0-9]+(_[0-9]+)*/,
|
|
1316
1406
|
// v0.21: a float literal — fraction with a digit on both sides of the
|
|
1317
1407
|
// `.`, an exponent, or both. Longest-match keeps `1.toFloat()` lexing
|
|
1318
1408
|
// as a method call on an integer literal.
|
|
1319
1409
|
float_literal: () =>
|
|
1320
|
-
/[0-9]
|
|
1410
|
+
/[0-9]+(_[0-9]+)*\.[0-9]+(_[0-9]+)*([eE][+-]?[0-9]+(_[0-9]+)*)?|[0-9]+(_[0-9]+)*[eE][+-]?[0-9]+(_[0-9]+)*/,
|
|
1321
1411
|
string_literal: ($) =>
|
|
1322
1412
|
seq(
|
|
1323
1413
|
'"',
|
package/package.json
CHANGED
package/queries/highlights.scm
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"match"
|
|
13
13
|
"is"
|
|
14
14
|
"expect"
|
|
15
|
+
"do"
|
|
15
16
|
"on"
|
|
16
17
|
"given"
|
|
17
18
|
"call"
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
"http"
|
|
20
21
|
"cron"
|
|
21
22
|
"queue"
|
|
23
|
+
"websocket"
|
|
22
24
|
"schedule"
|
|
23
25
|
"message"
|
|
24
26
|
] @keyword
|
|
@@ -36,11 +38,13 @@
|
|
|
36
38
|
"fn"
|
|
37
39
|
"capability"
|
|
38
40
|
"provides"
|
|
41
|
+
"stub"
|
|
39
42
|
"service"
|
|
40
43
|
"agent"
|
|
41
44
|
"store"
|
|
42
45
|
"cors"
|
|
43
46
|
"security"
|
|
47
|
+
"limits"
|
|
44
48
|
"exports"
|
|
45
49
|
"key"
|
|
46
50
|
"suite"
|
|
@@ -59,11 +63,11 @@
|
|
|
59
63
|
|
|
60
64
|
[
|
|
61
65
|
"where"
|
|
62
|
-
"and"
|
|
63
66
|
"implies"
|
|
64
67
|
"enum"
|
|
65
68
|
"for"
|
|
66
69
|
"all"
|
|
70
|
+
"embeds"
|
|
67
71
|
] @keyword.operator
|
|
68
72
|
|
|
69
73
|
; v0.117: the observation sugar words — contextual (these tokens exist only
|
|
@@ -79,7 +83,7 @@
|
|
|
79
83
|
] @keyword.operator
|
|
80
84
|
|
|
81
85
|
; v0.118: the contextual test-tier words on a `suite`/`case` header (after `as`)
|
|
82
|
-
; and the `
|
|
86
|
+
; and the `stub` clause right-hand-side words. Like the observation words,
|
|
83
87
|
; these tokens exist only in their clauses, so a global match never repaints an
|
|
84
88
|
; ordinary identifier of the same spelling.
|
|
85
89
|
[
|
|
@@ -108,6 +112,10 @@
|
|
|
108
112
|
(type_decl name: (identifier) @type)
|
|
109
113
|
(opaque_type) @type
|
|
110
114
|
(generic_type_ref arg: (identifier) @type)
|
|
115
|
+
; v0.157 (ADR 0183): a user generic-type application — the head name and each
|
|
116
|
+
; argument are types.
|
|
117
|
+
(applied_type_ref name: (identifier) @type)
|
|
118
|
+
(applied_type_ref arg: (identifier) @type)
|
|
111
119
|
(record_field type: (identifier) @type)
|
|
112
120
|
(variant_payload_field type: (identifier) @type)
|
|
113
121
|
(param type: (identifier) @type)
|
|
@@ -150,7 +158,6 @@
|
|
|
150
158
|
(field_init name: (identifier) @field)
|
|
151
159
|
(field_init shorthand: (identifier) @field)
|
|
152
160
|
(named_binding field: (identifier) @field)
|
|
153
|
-
(positional_binding (identifier) @variable)
|
|
154
161
|
|
|
155
162
|
; -- Variants & constants --
|
|
156
163
|
|
|
@@ -160,6 +167,12 @@
|
|
|
160
167
|
; pattern variant as a constant.
|
|
161
168
|
((variant_pattern variant: (identifier) @constant)
|
|
162
169
|
(#match? @constant "^[A-Z]"))
|
|
170
|
+
; v0.145 (ADR 0169): a lowercase-led pattern variant is a payload *binding* (the
|
|
171
|
+
; universal capitalisation convention) — a bare `n` or the leaf of a nested
|
|
172
|
+
; pattern like `Some(n)`. Highlight it as a variable, mirroring the retired
|
|
173
|
+
; `positional_binding` capture now that the payload position is a full pattern.
|
|
174
|
+
((variant_pattern variant: (identifier) @variable)
|
|
175
|
+
(#match? @variable "^[a-z_]"))
|
|
163
176
|
(boolean_literal) @constant.builtin
|
|
164
177
|
|
|
165
178
|
; -- Literals --
|