tree-sitter-ucode 0.5.0 → 0.6.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.
@@ -38,3 +38,9 @@
38
38
  (for_alt_statement open: (_) increment: (_) @injection.content (#set! injection.language "ucode"))
39
39
 
40
40
  (for_in_alt_statement open: (_) right: (_) @injection.content (#set! injection.language "ucode"))
41
+
42
+ ; Inject ucdocs into JSDoc block comments (/** ... */).
43
+ ; The [^*/] guard excludes /*** section dividers (≥3 stars) and /**/ (empty, non-JSDoc).
44
+ ((comment) @injection.content
45
+ (#match? @injection.content "^/\\*\\*[^*/]")
46
+ (#set! injection.language "ucdocs"))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-sitter-ucode",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Ucode grammar for tree-sitter",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,5 @@
1
+ ; Inject ucdocs into JSDoc block comments (/** ... */).
2
+ ; The [^*/] guard excludes /*** section dividers (≥3 stars) and /**/ (empty, non-JSDoc).
3
+ ((comment) @injection.content
4
+ (#match? @injection.content "^/\\*\\*[^*/]")
5
+ (#set! injection.language "ucdocs"))
@@ -400,9 +400,7 @@ static bool scan_automatic_semicolon(TSLexer *lexer) {
400
400
  }
401
401
 
402
402
  static bool scan_ternary_qmark(TSLexer *lexer) {
403
- while (lexer->lookahead != '\r' && lexer->lookahead != '\n' &&
404
- lexer->lookahead != 0x2028 && lexer->lookahead != 0x2029 &&
405
- iswspace(lexer->lookahead))
403
+ while (iswspace(lexer->lookahead))
406
404
  skip(lexer);
407
405
 
408
406
  if (lexer->lookahead != '?') return false;
Binary file
Binary file
package/tree-sitter.json CHANGED
@@ -14,9 +14,21 @@
14
14
  "locals": [
15
15
  "queries/locals.scm"
16
16
  ],
17
+ "injections": [
18
+ "queries/injections.scm"
19
+ ],
17
20
  "tags": [
18
21
  "queries/tags.scm"
19
22
  ],
23
+ "folds": [
24
+ "queries/folds.scm"
25
+ ],
26
+ "indents": [
27
+ "queries/indents.scm"
28
+ ],
29
+ "textobjects": [
30
+ "queries/textobjects.scm"
31
+ ],
20
32
  "injection-regex": "^ucode$"
21
33
  },
22
34
  {
package/ucdocs/grammar.js CHANGED
@@ -33,28 +33,24 @@ module.exports = grammar({
33
33
  $.see_tag,
34
34
  $.example_tag,
35
35
  $.default_tag,
36
+ $.function_tag,
37
+ $.module_tag,
36
38
  $.unknown_tag,
37
39
  )),
38
40
  $._end,
39
41
  ),
40
42
 
41
- _begin: _ => seq('/', repeat('*')),
42
- _end: _ => '/',
43
+ _begin: _ => token(seq('/', /\*+/)),
44
+ _end: _ => token(seq(/\**/, '/')),
43
45
 
44
46
  // Used after a type_expression/rest_type_expression has already claimed `{` at
45
47
  // this position (param_tag, returns_tag, throws_tag) — excludes _brace_text so
46
48
  // it never competes with a legitimate {type} for the leading `{`.
47
- _typed_description: $ => prec.right(seq(
48
- choice($._text, $.inline_tag),
49
- repeat(choice($._text, $.inline_tag)),
50
- )),
49
+ _typed_description: $ => repeat1(choice($._text, $.inline_tag)),
51
50
 
52
51
  // Used wherever no type_expression can appear at the same position, so a bare
53
52
  // `{` can only be an inline tag or arbitrary brace-text (e.g. @example code).
54
- _free_description: $ => prec.right(seq(
55
- choice($._text, $.inline_tag, $._brace_text),
56
- repeat(choice($._text, $.inline_tag, $._brace_text)),
57
- )),
53
+ _free_description: $ => repeat1(choice($._text, $.inline_tag, $._brace_text)),
58
54
 
59
55
  // {@link target text} and similar inline JSDoc tags embedded in description text.
60
56
  inline_tag: $ => seq(
@@ -159,6 +155,29 @@ module.exports = grammar({
159
155
  optional(field('description', alias($._free_description, $.description))),
160
156
  ),
161
157
 
158
+ // @function module:X.Y#Z — identifies the qualified name of the documented function.
159
+ function_tag: $ => seq(
160
+ '@function',
161
+ optional(field('namepath', $.namepath)),
162
+ ),
163
+
164
+ // @module name — identifies the module this file documents.
165
+ module_tag: $ => seq(
166
+ '@module',
167
+ field('name', $.member_name),
168
+ ),
169
+
170
+ // module:X.Y#Z — a namepath referencing a specific member within a module.
171
+ // The #member suffix distinguishes instance methods from the module path itself.
172
+ namepath: $ => seq(
173
+ 'module:',
174
+ field('path', $.module_path),
175
+ optional(seq('#', field('member', $.member_name))),
176
+ ),
177
+
178
+ // Member names cover lowercase (error), uppercase (ERR), and underscored (ulog_open).
179
+ member_name: _ => /[a-zA-Z_$][a-zA-Z0-9_$]*/,
180
+
162
181
  unknown_tag: $ => seq(
163
182
  $.tag_name,
164
183
  optional(field('description', alias($._free_description, $.description))),
@@ -185,9 +204,11 @@ module.exports = grammar({
185
204
  $.union_type,
186
205
  $.nullable_type,
187
206
  $.any_type,
207
+ $.parenthesized_type,
208
+ $.array_type,
188
209
  ),
189
210
 
190
- primitive_type: _ => choice('int', 'float', 'string', 'boolean', 'null', 'void'),
211
+ primitive_type: _ => choice('int', 'float', 'string', 'boolean', 'null', 'void', 'function'),
191
212
 
192
213
  any_type: _ => choice('*', 'any'),
193
214
 
@@ -259,6 +280,14 @@ module.exports = grammar({
259
280
  optional(seq(':', field('return', $._type))),
260
281
  ),
261
282
 
283
+ // Explicit grouping: (T|U) to override default union associativity or
284
+ // for clarity in complex expressions like ?(T|U).
285
+ parenthesized_type: $ => seq('(', $._type, ')'),
286
+
287
+ // T[] postfix array notation. Precedence 3 > nullable (2) > union (1)
288
+ // so ?T[] == ?(T[]) and T[]|U[] == (T[])|(U[]).
289
+ array_type: $ => prec(3, seq($._type, '[]')),
290
+
262
291
  // Left-associative so T | U | V parses as (T | U) | V.
263
292
  union_type: $ => prec.left(1, seq($._type, '|', $._type)),
264
293
 
@@ -271,7 +300,7 @@ module.exports = grammar({
271
300
  // Lowercase-starting names: parameter names and function param names.
272
301
  identifier: _ => /[a-z_$][a-zA-Z_$0-9]*/,
273
302
 
274
- _text: _ => token(prec(-1, /[^*{}@\s][^*{}@\n]*/)),
303
+ _text: _ => token(prec(-1, /[^*{}@\s][^*{}@\n\r]*/)),
275
304
  },
276
305
  });
277
306
 
@@ -1,4 +1,7 @@
1
+ ; ── Tag keywords ──────────────────────────────────────────────────────────────
2
+
1
3
  (tag_name) @keyword
4
+
2
5
  (param_tag "@param" @keyword)
3
6
  (returns_tag ["@returns" "@return"] @keyword)
4
7
  (template_tag "@template" @keyword)
@@ -10,16 +13,72 @@
10
13
  (see_tag "@see" @keyword)
11
14
  (example_tag "@example" @keyword)
12
15
  (default_tag "@default" @keyword)
16
+ (function_tag "@function" @keyword)
17
+ (module_tag "@module" @keyword)
18
+
19
+ ; ── Names ──────────────────────────────────────────────────────────────────
13
20
 
14
21
  (type_param) @type.parameter
15
22
  (type_identifier) @type
16
23
  (primitive_type) @type.builtin
17
24
  (any_type) @type.builtin
18
- (module_type "module:" @module)
19
- (module_path) @module
20
25
 
21
26
  (identifier) @variable.parameter
27
+ (record_field name: (identifier) @variable.member)
28
+ (member_name) @variable.member
29
+
22
30
  (default_value) @constant
23
- (description) @comment
31
+
32
+ ; ── Module paths ────────────────────────────────────────────────────────────
33
+
34
+ (module_type "module:" @module)
35
+ (module_type path: (module_path) @module)
36
+ (namepath "module:" @module)
37
+ (namepath path: (module_path) @module)
38
+
39
+ ; ── Operators ───────────────────────────────────────────────────────────────
40
+
41
+ (union_type "|" @operator)
42
+ (nullable_type "?" @operator)
43
+ (function_type "=>" @operator)
44
+ (optional_param "=" @operator)
45
+
46
+ ; ── Punctuation: brackets ────────────────────────────────────────────────────
47
+
48
+ (type_expression "{" @punctuation.bracket "}" @punctuation.bracket)
49
+ (rest_type_expression "{" @punctuation.bracket "}" @punctuation.bracket)
50
+ (record_type "{" @punctuation.bracket "}" @punctuation.bracket)
51
+ (parenthesized_type "(" @punctuation.bracket ")" @punctuation.bracket)
52
+ (function_type "(" @punctuation.bracket ")" @punctuation.bracket)
53
+ (anon_function_type "(" @punctuation.bracket ")" @punctuation.bracket)
54
+ (named_type "<" @punctuation.bracket ">" @punctuation.bracket)
55
+ (list_type "<" @punctuation.bracket ">" @punctuation.bracket)
56
+ (dict_type "<" @punctuation.bracket ">" @punctuation.bracket)
57
+ (optional_param "[" @punctuation.bracket "]" @punctuation.bracket)
58
+ (array_type "[]" @punctuation.bracket)
24
59
  (inline_tag "{" @punctuation.bracket "}" @punctuation.bracket)
25
- (inline_tag (tag_name) @keyword)
60
+
61
+ ; ── Punctuation: delimiters ──────────────────────────────────────────────────
62
+
63
+ (record_type "," @punctuation.delimiter)
64
+ (record_field ":" @punctuation.delimiter)
65
+ (function_param ":" @punctuation.delimiter)
66
+ (anon_function_type ":" @punctuation.delimiter)
67
+ (namepath "#" @punctuation.delimiter)
68
+
69
+ ; ── Punctuation: special ─────────────────────────────────────────────────────
70
+
71
+ (rest_type_expression "..." @punctuation.special)
72
+
73
+ ; ── Descriptions ─────────────────────────────────────────────────────────────
74
+
75
+ (description) @comment
76
+
77
+ ; @spell only on prose-bearing tags; @example descriptions contain code.
78
+ (document (description) @spell)
79
+ (param_tag description: (description) @spell)
80
+ (returns_tag description: (description) @spell)
81
+ (throws_tag description: (description) @spell)
82
+ (deprecated_tag description: (description) @spell)
83
+ (since_tag description: (description) @spell)
84
+ (see_tag description: (description) @spell)
@@ -75,6 +75,14 @@
75
75
  "type": "SYMBOL",
76
76
  "name": "default_tag"
77
77
  },
78
+ {
79
+ "type": "SYMBOL",
80
+ "name": "function_tag"
81
+ },
82
+ {
83
+ "type": "SYMBOL",
84
+ "name": "module_tag"
85
+ },
78
86
  {
79
87
  "type": "SYMBOL",
80
88
  "name": "unknown_tag"
@@ -89,105 +97,69 @@
89
97
  ]
90
98
  },
91
99
  "_begin": {
92
- "type": "SEQ",
93
- "members": [
94
- {
95
- "type": "STRING",
96
- "value": "/"
97
- },
98
- {
99
- "type": "REPEAT",
100
- "content": {
100
+ "type": "TOKEN",
101
+ "content": {
102
+ "type": "SEQ",
103
+ "members": [
104
+ {
101
105
  "type": "STRING",
102
- "value": "*"
106
+ "value": "/"
107
+ },
108
+ {
109
+ "type": "PATTERN",
110
+ "value": "\\*+"
103
111
  }
104
- }
105
- ]
112
+ ]
113
+ }
106
114
  },
107
115
  "_end": {
108
- "type": "STRING",
109
- "value": "/"
116
+ "type": "TOKEN",
117
+ "content": {
118
+ "type": "SEQ",
119
+ "members": [
120
+ {
121
+ "type": "PATTERN",
122
+ "value": "\\**"
123
+ },
124
+ {
125
+ "type": "STRING",
126
+ "value": "/"
127
+ }
128
+ ]
129
+ }
110
130
  },
111
131
  "_typed_description": {
112
- "type": "PREC_RIGHT",
113
- "value": 0,
132
+ "type": "REPEAT1",
114
133
  "content": {
115
- "type": "SEQ",
134
+ "type": "CHOICE",
116
135
  "members": [
117
136
  {
118
- "type": "CHOICE",
119
- "members": [
120
- {
121
- "type": "SYMBOL",
122
- "name": "_text"
123
- },
124
- {
125
- "type": "SYMBOL",
126
- "name": "inline_tag"
127
- }
128
- ]
137
+ "type": "SYMBOL",
138
+ "name": "_text"
129
139
  },
130
140
  {
131
- "type": "REPEAT",
132
- "content": {
133
- "type": "CHOICE",
134
- "members": [
135
- {
136
- "type": "SYMBOL",
137
- "name": "_text"
138
- },
139
- {
140
- "type": "SYMBOL",
141
- "name": "inline_tag"
142
- }
143
- ]
144
- }
141
+ "type": "SYMBOL",
142
+ "name": "inline_tag"
145
143
  }
146
144
  ]
147
145
  }
148
146
  },
149
147
  "_free_description": {
150
- "type": "PREC_RIGHT",
151
- "value": 0,
148
+ "type": "REPEAT1",
152
149
  "content": {
153
- "type": "SEQ",
150
+ "type": "CHOICE",
154
151
  "members": [
155
152
  {
156
- "type": "CHOICE",
157
- "members": [
158
- {
159
- "type": "SYMBOL",
160
- "name": "_text"
161
- },
162
- {
163
- "type": "SYMBOL",
164
- "name": "inline_tag"
165
- },
166
- {
167
- "type": "SYMBOL",
168
- "name": "_brace_text"
169
- }
170
- ]
153
+ "type": "SYMBOL",
154
+ "name": "_text"
171
155
  },
172
156
  {
173
- "type": "REPEAT",
174
- "content": {
175
- "type": "CHOICE",
176
- "members": [
177
- {
178
- "type": "SYMBOL",
179
- "name": "_text"
180
- },
181
- {
182
- "type": "SYMBOL",
183
- "name": "inline_tag"
184
- },
185
- {
186
- "type": "SYMBOL",
187
- "name": "_brace_text"
188
- }
189
- ]
190
- }
157
+ "type": "SYMBOL",
158
+ "name": "inline_tag"
159
+ },
160
+ {
161
+ "type": "SYMBOL",
162
+ "name": "_brace_text"
191
163
  }
192
164
  ]
193
165
  }
@@ -793,6 +765,94 @@
793
765
  }
794
766
  ]
795
767
  },
768
+ "function_tag": {
769
+ "type": "SEQ",
770
+ "members": [
771
+ {
772
+ "type": "STRING",
773
+ "value": "@function"
774
+ },
775
+ {
776
+ "type": "CHOICE",
777
+ "members": [
778
+ {
779
+ "type": "FIELD",
780
+ "name": "namepath",
781
+ "content": {
782
+ "type": "SYMBOL",
783
+ "name": "namepath"
784
+ }
785
+ },
786
+ {
787
+ "type": "BLANK"
788
+ }
789
+ ]
790
+ }
791
+ ]
792
+ },
793
+ "module_tag": {
794
+ "type": "SEQ",
795
+ "members": [
796
+ {
797
+ "type": "STRING",
798
+ "value": "@module"
799
+ },
800
+ {
801
+ "type": "FIELD",
802
+ "name": "name",
803
+ "content": {
804
+ "type": "SYMBOL",
805
+ "name": "member_name"
806
+ }
807
+ }
808
+ ]
809
+ },
810
+ "namepath": {
811
+ "type": "SEQ",
812
+ "members": [
813
+ {
814
+ "type": "STRING",
815
+ "value": "module:"
816
+ },
817
+ {
818
+ "type": "FIELD",
819
+ "name": "path",
820
+ "content": {
821
+ "type": "SYMBOL",
822
+ "name": "module_path"
823
+ }
824
+ },
825
+ {
826
+ "type": "CHOICE",
827
+ "members": [
828
+ {
829
+ "type": "SEQ",
830
+ "members": [
831
+ {
832
+ "type": "STRING",
833
+ "value": "#"
834
+ },
835
+ {
836
+ "type": "FIELD",
837
+ "name": "member",
838
+ "content": {
839
+ "type": "SYMBOL",
840
+ "name": "member_name"
841
+ }
842
+ }
843
+ ]
844
+ },
845
+ {
846
+ "type": "BLANK"
847
+ }
848
+ ]
849
+ }
850
+ ]
851
+ },
852
+ "member_name": {
853
+ "type": "PATTERN",
854
+ "value": "[a-zA-Z_$][a-zA-Z0-9_$]*"
855
+ },
796
856
  "unknown_tag": {
797
857
  "type": "SEQ",
798
858
  "members": [
@@ -911,6 +971,14 @@
911
971
  {
912
972
  "type": "SYMBOL",
913
973
  "name": "any_type"
974
+ },
975
+ {
976
+ "type": "SYMBOL",
977
+ "name": "parenthesized_type"
978
+ },
979
+ {
980
+ "type": "SYMBOL",
981
+ "name": "array_type"
914
982
  }
915
983
  ]
916
984
  },
@@ -940,6 +1008,10 @@
940
1008
  {
941
1009
  "type": "STRING",
942
1010
  "value": "void"
1011
+ },
1012
+ {
1013
+ "type": "STRING",
1014
+ "value": "function"
943
1015
  }
944
1016
  ]
945
1017
  },
@@ -1327,6 +1399,40 @@
1327
1399
  }
1328
1400
  ]
1329
1401
  },
1402
+ "parenthesized_type": {
1403
+ "type": "SEQ",
1404
+ "members": [
1405
+ {
1406
+ "type": "STRING",
1407
+ "value": "("
1408
+ },
1409
+ {
1410
+ "type": "SYMBOL",
1411
+ "name": "_type"
1412
+ },
1413
+ {
1414
+ "type": "STRING",
1415
+ "value": ")"
1416
+ }
1417
+ ]
1418
+ },
1419
+ "array_type": {
1420
+ "type": "PREC",
1421
+ "value": 3,
1422
+ "content": {
1423
+ "type": "SEQ",
1424
+ "members": [
1425
+ {
1426
+ "type": "SYMBOL",
1427
+ "name": "_type"
1428
+ },
1429
+ {
1430
+ "type": "STRING",
1431
+ "value": "[]"
1432
+ }
1433
+ ]
1434
+ }
1435
+ },
1330
1436
  "union_type": {
1331
1437
  "type": "PREC_LEFT",
1332
1438
  "value": 1,
@@ -1380,7 +1486,7 @@
1380
1486
  "value": -1,
1381
1487
  "content": {
1382
1488
  "type": "PATTERN",
1383
- "value": "[^*{}@\\s][^*{}@\\n]*"
1489
+ "value": "[^*{}@\\s][^*{}@\\n\\r]*"
1384
1490
  }
1385
1491
  }
1386
1492
  }