tree-sitter-bynk 0.238.0 → 0.243.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 CHANGED
@@ -184,12 +184,16 @@ module.exports = grammar({
184
184
  $.fn_decl,
185
185
  $.messages_decl,
186
186
  // Permissive: capability/service/etc. can syntactically appear
187
- // anywhere — the LSP reports semantic placement errors.
187
+ // anywhere — the LSP reports semantic placement errors. Events
188
+ // track slice 0 (spine #936): `event` follows the same permissive
189
+ // precedent (`bynk.event.outside_context` rejects it here, at the
190
+ // checker, not the grammar).
188
191
  $.capability_decl,
189
192
  $.provider_decl,
190
193
  $.service_decl,
191
194
  $.agent_decl,
192
195
  $.actor_decl,
196
+ $.event_decl,
193
197
  ),
194
198
 
195
199
  _context_body_item: ($) =>
@@ -205,6 +209,7 @@ module.exports = grammar({
205
209
  $.agent_decl,
206
210
  $.actor_decl,
207
211
  $.messages_decl,
212
+ $.event_decl,
208
213
  ),
209
214
 
210
215
  // v0.17: adapter items — a binding clause, capabilities, boundary types,
@@ -226,6 +231,7 @@ module.exports = grammar({
226
231
  $.agent_decl,
227
232
  $.actor_decl,
228
233
  $.messages_decl,
234
+ $.event_decl,
229
235
  ),
230
236
 
231
237
  _test_body_item: ($) =>
@@ -338,6 +344,23 @@ module.exports = grammar({
338
344
  optional(seq("=", field("init", $._expression))),
339
345
  ),
340
346
 
347
+ // Events track, slice 0 (spine #936): `event Name = { fields }` — a
348
+ // typed fact a context may emit and other contexts' subscriber services
349
+ // may receive. Record body only (mirrors `record_type`, not the full
350
+ // `_type_body` choice — no sum/opaque/refined event shapes). Slice 3b
351
+ // (#978) adds an optional `@schema(N)` annotation, reusing
352
+ // `store_annotation` (the same generic `@name(args)` shape `messages_decl`
353
+ // already reuses) rather than a new rule — the closed registry (today:
354
+ // `@schema` alone) is a checker concern, not a grammar one.
355
+ event_decl: ($) =>
356
+ seq(
357
+ "event",
358
+ field("name", $.identifier),
359
+ repeat(field("annotation", $.store_annotation)),
360
+ "=",
361
+ field("body", $.record_type),
362
+ ),
363
+
341
364
  // v0.154 (ADR 0178): a sum body may carry a trailing `embeds E as V, …`
342
365
  // clause declaring error embeddings the `?` operator auto-converts.
343
366
  // `embeds`/`as` are contextual — matched only in this position.
@@ -702,6 +725,12 @@ module.exports = grammar({
702
725
  // types. `websocket`, `in`, and `out` are contextual (resolved by `word`).
703
726
  // #548: `websocket` lowercased to match the other protocol sources (was
704
727
  // `WebSocket`).
728
+ // Events track, slice 0 (spine #936): `from Events(E)`, optionally
729
+ // filtered by a slice-1 structural pattern, `from Events(E { field:
730
+ // value, .. })`. `Events`, capitalised, is matched as plain `identifier`
731
+ // text the same way `websocket` is matched lowercase — it names the
732
+ // `Events` capability directly, not a built-in type name, so no lexer
733
+ // reservation.
705
734
  service_protocol: ($) =>
706
735
  seq(
707
736
  "from",
@@ -722,6 +751,47 @@ module.exports = grammar({
722
751
  optional(","),
723
752
  ")",
724
753
  ),
754
+ seq(
755
+ "Events",
756
+ "(",
757
+ field("event_type", $._type_ref),
758
+ optional(field("pattern", $.event_pattern)),
759
+ ")",
760
+ ),
761
+ ),
762
+ ),
763
+ // Events track, slice 1 (spine #936): the structural delivery filter on
764
+ // a subscription header. A trailing `..` is mandatory whenever any field
765
+ // is listed — mirrors the hand-written parser's `bynk.parse.
766
+ // event_pattern_empty` rejection of `Events(E { })`. `..` is one literal
767
+ // token here (not two `.`s), keeping this grammar in agreement with the
768
+ // Rust lexer's dedicated `DotDot` token.
769
+ event_pattern: ($) =>
770
+ seq(
771
+ "{",
772
+ repeat(seq(field("field", $.event_pattern_field), ",")),
773
+ "..",
774
+ "}",
775
+ ),
776
+ event_pattern_field: ($) =>
777
+ seq(
778
+ field("name", $.identifier),
779
+ ":",
780
+ field("value", $.event_pattern_value),
781
+ ),
782
+ // A closed set, mirroring `literal_pattern` plus a nullary-variant
783
+ // reference (`variant_pattern` without a payload list — no nested
784
+ // sub-patterns in v1). The checker separately rejects a payload-carrying
785
+ // variant (`bynk.event.pattern_variant_payload`) since the grammar has
786
+ // no payload-list position here to reject it structurally.
787
+ event_pattern_value: ($) =>
788
+ choice(
789
+ seq(optional("-"), $.number_literal),
790
+ $.string_literal,
791
+ $.boolean_literal,
792
+ seq(
793
+ optional(seq(field("type", $.identifier), ".")),
794
+ field("variant", $.identifier),
725
795
  ),
726
796
  ),
727
797
 
@@ -807,6 +877,27 @@ module.exports = grammar({
807
877
  // queue-handler shape (the protocol on the service header disambiguates).
808
878
  $.ws_open_handler,
809
879
  $.ws_close_handler,
880
+ // Events track, slice 0 (spine #936): a `from Events(E)` service's
881
+ // one handler.
882
+ $.event_handler,
883
+ ),
884
+ // Events track, slice 0 (spine #936): `on event(e: E) -> Effect[()] { … }`
885
+ // — a `from Events(E)` subscriber's one handler. Same generic shape as
886
+ // every other handler form (params/by/given/body all uniform); the
887
+ // checker verifies the param count/type against the service header.
888
+ event_handler: ($) =>
889
+ seq(
890
+ "on",
891
+ "event",
892
+ "(",
893
+ optional(sep1($.param, ",")),
894
+ optional(","),
895
+ ")",
896
+ "->",
897
+ field("return_type", $._type_ref),
898
+ optional(field("by", $.by_clause)),
899
+ optional(field("given", $.given_clause)),
900
+ field("body", $.block),
810
901
  ),
811
902
  call_handler: ($) =>
812
903
  seq(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-sitter-bynk",
3
- "version": "0.238.0",
3
+ "version": "0.243.0",
4
4
  "description": "Tree-sitter grammar for the Bynk DSL (v0–v0.16).",
5
5
  "main": "bindings/node",
6
6
  "types": "bindings/node",
@@ -23,6 +23,7 @@
23
23
  "websocket"
24
24
  "schedule"
25
25
  "message"
26
+ "Events"
26
27
  ] @keyword
27
28
 
28
29
  [
@@ -55,6 +56,7 @@
55
56
  "requires"
56
57
  "ensures"
57
58
  "messages"
59
+ "event"
58
60
  ] @keyword.declaration
59
61
 
60
62
  [
@@ -111,6 +113,12 @@
111
113
 
112
114
  ; User-defined type names appear in type positions.
113
115
  (type_decl name: (identifier) @type)
116
+ ; Events track slice 0/1 (spine #936): an `event` declaration names a type,
117
+ ; like `type_decl`; the header's `event_type` and a pattern field's
118
+ ; qualifier both reference one.
119
+ (event_decl name: (identifier) @type)
120
+ (service_protocol event_type: (identifier) @type)
121
+ (event_pattern_value type: (identifier) @type)
114
122
  (opaque_type) @type
115
123
  (generic_type_ref arg: (identifier) @type)
116
124
  ; v0.157 (ADR 0183): a user generic-type application — the head name and each
@@ -159,6 +167,8 @@
159
167
  (field_init name: (identifier) @field)
160
168
  (field_init shorthand: (identifier) @field)
161
169
  (named_binding field: (identifier) @field)
170
+ ; Events track slice 1 (spine #936): a subscription pattern's field name.
171
+ (event_pattern_field name: (identifier) @field)
162
172
 
163
173
  ; -- Variants & constants --
164
174
 
@@ -174,6 +184,13 @@
174
184
  ; `positional_binding` capture now that the payload position is a full pattern.
175
185
  ((variant_pattern variant: (identifier) @variable)
176
186
  (#match? @variable "^[a-z_]"))
187
+ ; Events track slice 1 (spine #936): a subscription pattern's variant value
188
+ ; (`region: Region.Domestic` / bare `Domestic`) — always a nullary reference
189
+ ; (the checker rejects a payload-carrying variant), so unlike
190
+ ; `variant_pattern` there is no binding-vs-tag ambiguity; still keyed on
191
+ ; capitalisation for consistency with every other variant reference.
192
+ ((event_pattern_value variant: (identifier) @constant)
193
+ (#match? @constant "^[A-Z]"))
177
194
  (boolean_literal) @constant.builtin
178
195
 
179
196
  ; -- Literals --
package/src/grammar.json CHANGED
@@ -406,6 +406,10 @@
406
406
  {
407
407
  "type": "SYMBOL",
408
408
  "name": "actor_decl"
409
+ },
410
+ {
411
+ "type": "SYMBOL",
412
+ "name": "event_decl"
409
413
  }
410
414
  ]
411
415
  },
@@ -455,6 +459,10 @@
455
459
  {
456
460
  "type": "SYMBOL",
457
461
  "name": "messages_decl"
462
+ },
463
+ {
464
+ "type": "SYMBOL",
465
+ "name": "event_decl"
458
466
  }
459
467
  ]
460
468
  },
@@ -508,6 +516,10 @@
508
516
  {
509
517
  "type": "SYMBOL",
510
518
  "name": "messages_decl"
519
+ },
520
+ {
521
+ "type": "SYMBOL",
522
+ "name": "event_decl"
511
523
  }
512
524
  ]
513
525
  },
@@ -1194,6 +1206,46 @@
1194
1206
  }
1195
1207
  ]
1196
1208
  },
1209
+ "event_decl": {
1210
+ "type": "SEQ",
1211
+ "members": [
1212
+ {
1213
+ "type": "STRING",
1214
+ "value": "event"
1215
+ },
1216
+ {
1217
+ "type": "FIELD",
1218
+ "name": "name",
1219
+ "content": {
1220
+ "type": "SYMBOL",
1221
+ "name": "identifier"
1222
+ }
1223
+ },
1224
+ {
1225
+ "type": "REPEAT",
1226
+ "content": {
1227
+ "type": "FIELD",
1228
+ "name": "annotation",
1229
+ "content": {
1230
+ "type": "SYMBOL",
1231
+ "name": "store_annotation"
1232
+ }
1233
+ }
1234
+ },
1235
+ {
1236
+ "type": "STRING",
1237
+ "value": "="
1238
+ },
1239
+ {
1240
+ "type": "FIELD",
1241
+ "name": "body",
1242
+ "content": {
1243
+ "type": "SYMBOL",
1244
+ "name": "record_type"
1245
+ }
1246
+ }
1247
+ ]
1248
+ },
1197
1249
  "sum_type": {
1198
1250
  "type": "PREC_RIGHT",
1199
1251
  "value": 0,
@@ -3170,6 +3222,181 @@
3170
3222
  "value": ")"
3171
3223
  }
3172
3224
  ]
3225
+ },
3226
+ {
3227
+ "type": "SEQ",
3228
+ "members": [
3229
+ {
3230
+ "type": "STRING",
3231
+ "value": "Events"
3232
+ },
3233
+ {
3234
+ "type": "STRING",
3235
+ "value": "("
3236
+ },
3237
+ {
3238
+ "type": "FIELD",
3239
+ "name": "event_type",
3240
+ "content": {
3241
+ "type": "SYMBOL",
3242
+ "name": "_type_ref"
3243
+ }
3244
+ },
3245
+ {
3246
+ "type": "CHOICE",
3247
+ "members": [
3248
+ {
3249
+ "type": "FIELD",
3250
+ "name": "pattern",
3251
+ "content": {
3252
+ "type": "SYMBOL",
3253
+ "name": "event_pattern"
3254
+ }
3255
+ },
3256
+ {
3257
+ "type": "BLANK"
3258
+ }
3259
+ ]
3260
+ },
3261
+ {
3262
+ "type": "STRING",
3263
+ "value": ")"
3264
+ }
3265
+ ]
3266
+ }
3267
+ ]
3268
+ }
3269
+ ]
3270
+ },
3271
+ "event_pattern": {
3272
+ "type": "SEQ",
3273
+ "members": [
3274
+ {
3275
+ "type": "STRING",
3276
+ "value": "{"
3277
+ },
3278
+ {
3279
+ "type": "REPEAT",
3280
+ "content": {
3281
+ "type": "SEQ",
3282
+ "members": [
3283
+ {
3284
+ "type": "FIELD",
3285
+ "name": "field",
3286
+ "content": {
3287
+ "type": "SYMBOL",
3288
+ "name": "event_pattern_field"
3289
+ }
3290
+ },
3291
+ {
3292
+ "type": "STRING",
3293
+ "value": ","
3294
+ }
3295
+ ]
3296
+ }
3297
+ },
3298
+ {
3299
+ "type": "STRING",
3300
+ "value": ".."
3301
+ },
3302
+ {
3303
+ "type": "STRING",
3304
+ "value": "}"
3305
+ }
3306
+ ]
3307
+ },
3308
+ "event_pattern_field": {
3309
+ "type": "SEQ",
3310
+ "members": [
3311
+ {
3312
+ "type": "FIELD",
3313
+ "name": "name",
3314
+ "content": {
3315
+ "type": "SYMBOL",
3316
+ "name": "identifier"
3317
+ }
3318
+ },
3319
+ {
3320
+ "type": "STRING",
3321
+ "value": ":"
3322
+ },
3323
+ {
3324
+ "type": "FIELD",
3325
+ "name": "value",
3326
+ "content": {
3327
+ "type": "SYMBOL",
3328
+ "name": "event_pattern_value"
3329
+ }
3330
+ }
3331
+ ]
3332
+ },
3333
+ "event_pattern_value": {
3334
+ "type": "CHOICE",
3335
+ "members": [
3336
+ {
3337
+ "type": "SEQ",
3338
+ "members": [
3339
+ {
3340
+ "type": "CHOICE",
3341
+ "members": [
3342
+ {
3343
+ "type": "STRING",
3344
+ "value": "-"
3345
+ },
3346
+ {
3347
+ "type": "BLANK"
3348
+ }
3349
+ ]
3350
+ },
3351
+ {
3352
+ "type": "SYMBOL",
3353
+ "name": "number_literal"
3354
+ }
3355
+ ]
3356
+ },
3357
+ {
3358
+ "type": "SYMBOL",
3359
+ "name": "string_literal"
3360
+ },
3361
+ {
3362
+ "type": "SYMBOL",
3363
+ "name": "boolean_literal"
3364
+ },
3365
+ {
3366
+ "type": "SEQ",
3367
+ "members": [
3368
+ {
3369
+ "type": "CHOICE",
3370
+ "members": [
3371
+ {
3372
+ "type": "SEQ",
3373
+ "members": [
3374
+ {
3375
+ "type": "FIELD",
3376
+ "name": "type",
3377
+ "content": {
3378
+ "type": "SYMBOL",
3379
+ "name": "identifier"
3380
+ }
3381
+ },
3382
+ {
3383
+ "type": "STRING",
3384
+ "value": "."
3385
+ }
3386
+ ]
3387
+ },
3388
+ {
3389
+ "type": "BLANK"
3390
+ }
3391
+ ]
3392
+ },
3393
+ {
3394
+ "type": "FIELD",
3395
+ "name": "variant",
3396
+ "content": {
3397
+ "type": "SYMBOL",
3398
+ "name": "identifier"
3399
+ }
3173
3400
  }
3174
3401
  ]
3175
3402
  }
@@ -3596,6 +3823,128 @@
3596
3823
  {
3597
3824
  "type": "SYMBOL",
3598
3825
  "name": "ws_close_handler"
3826
+ },
3827
+ {
3828
+ "type": "SYMBOL",
3829
+ "name": "event_handler"
3830
+ }
3831
+ ]
3832
+ },
3833
+ "event_handler": {
3834
+ "type": "SEQ",
3835
+ "members": [
3836
+ {
3837
+ "type": "STRING",
3838
+ "value": "on"
3839
+ },
3840
+ {
3841
+ "type": "STRING",
3842
+ "value": "event"
3843
+ },
3844
+ {
3845
+ "type": "STRING",
3846
+ "value": "("
3847
+ },
3848
+ {
3849
+ "type": "CHOICE",
3850
+ "members": [
3851
+ {
3852
+ "type": "SEQ",
3853
+ "members": [
3854
+ {
3855
+ "type": "SYMBOL",
3856
+ "name": "param"
3857
+ },
3858
+ {
3859
+ "type": "REPEAT",
3860
+ "content": {
3861
+ "type": "SEQ",
3862
+ "members": [
3863
+ {
3864
+ "type": "STRING",
3865
+ "value": ","
3866
+ },
3867
+ {
3868
+ "type": "SYMBOL",
3869
+ "name": "param"
3870
+ }
3871
+ ]
3872
+ }
3873
+ }
3874
+ ]
3875
+ },
3876
+ {
3877
+ "type": "BLANK"
3878
+ }
3879
+ ]
3880
+ },
3881
+ {
3882
+ "type": "CHOICE",
3883
+ "members": [
3884
+ {
3885
+ "type": "STRING",
3886
+ "value": ","
3887
+ },
3888
+ {
3889
+ "type": "BLANK"
3890
+ }
3891
+ ]
3892
+ },
3893
+ {
3894
+ "type": "STRING",
3895
+ "value": ")"
3896
+ },
3897
+ {
3898
+ "type": "STRING",
3899
+ "value": "->"
3900
+ },
3901
+ {
3902
+ "type": "FIELD",
3903
+ "name": "return_type",
3904
+ "content": {
3905
+ "type": "SYMBOL",
3906
+ "name": "_type_ref"
3907
+ }
3908
+ },
3909
+ {
3910
+ "type": "CHOICE",
3911
+ "members": [
3912
+ {
3913
+ "type": "FIELD",
3914
+ "name": "by",
3915
+ "content": {
3916
+ "type": "SYMBOL",
3917
+ "name": "by_clause"
3918
+ }
3919
+ },
3920
+ {
3921
+ "type": "BLANK"
3922
+ }
3923
+ ]
3924
+ },
3925
+ {
3926
+ "type": "CHOICE",
3927
+ "members": [
3928
+ {
3929
+ "type": "FIELD",
3930
+ "name": "given",
3931
+ "content": {
3932
+ "type": "SYMBOL",
3933
+ "name": "given_clause"
3934
+ }
3935
+ },
3936
+ {
3937
+ "type": "BLANK"
3938
+ }
3939
+ ]
3940
+ },
3941
+ {
3942
+ "type": "FIELD",
3943
+ "name": "body",
3944
+ "content": {
3945
+ "type": "SYMBOL",
3946
+ "name": "block"
3947
+ }
3599
3948
  }
3600
3949
  ]
3601
3950
  },