agent-codinglanguage-mapper 1.0.0__py3-none-any.whl

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.
Files changed (42) hide show
  1. agent_codinglanguage_mapper/__init__.py +20 -0
  2. agent_codinglanguage_mapper/__main__.py +4 -0
  3. agent_codinglanguage_mapper/_version.py +2 -0
  4. agent_codinglanguage_mapper/adapters/__init__.py +4 -0
  5. agent_codinglanguage_mapper/adapters/delphi.py +822 -0
  6. agent_codinglanguage_mapper/adapters/delphi_frontend/__init__.py +6 -0
  7. agent_codinglanguage_mapper/adapters/delphi_frontend/comment_builder.py +29 -0
  8. agent_codinglanguage_mapper/adapters/delphi_frontend/consts.py +345 -0
  9. agent_codinglanguage_mapper/adapters/delphi_frontend/grammar.py +460 -0
  10. agent_codinglanguage_mapper/adapters/delphi_frontend/lark_builder.py +2674 -0
  11. agent_codinglanguage_mapper/adapters/delphi_frontend/lark_tokens.py +237 -0
  12. agent_codinglanguage_mapper/adapters/delphi_frontend/lsp_server.py +1832 -0
  13. agent_codinglanguage_mapper/adapters/delphi_frontend/nodes.py +371 -0
  14. agent_codinglanguage_mapper/adapters/delphi_frontend/parser.py +193 -0
  15. agent_codinglanguage_mapper/adapters/delphi_frontend/preprocessor.py +997 -0
  16. agent_codinglanguage_mapper/adapters/delphi_frontend/project_discovery.py +518 -0
  17. agent_codinglanguage_mapper/adapters/delphi_frontend/project_indexer.py +319 -0
  18. agent_codinglanguage_mapper/adapters/delphi_frontend/semantic.py +375 -0
  19. agent_codinglanguage_mapper/adapters/delphi_frontend/semantic_builder.py +1384 -0
  20. agent_codinglanguage_mapper/adapters/delphi_frontend/source_reader.py +17 -0
  21. agent_codinglanguage_mapper/adapters/delphi_frontend/workspace.py +67 -0
  22. agent_codinglanguage_mapper/adapters/tree_sitter.py +1722 -0
  23. agent_codinglanguage_mapper/cli.py +138 -0
  24. agent_codinglanguage_mapper/discovery.py +1328 -0
  25. agent_codinglanguage_mapper/indexer.py +1102 -0
  26. agent_codinglanguage_mapper/integration.py +186 -0
  27. agent_codinglanguage_mapper/lsp_server.py +413 -0
  28. agent_codinglanguage_mapper/lsp_service.py +447 -0
  29. agent_codinglanguage_mapper/mapper.py +596 -0
  30. agent_codinglanguage_mapper/models.py +101 -0
  31. agent_codinglanguage_mapper/protocol.py +152 -0
  32. agent_codinglanguage_mapper/rendering.py +153 -0
  33. agent_codinglanguage_mapper/templates/opencode/plugins/codebase_map.ts +191 -0
  34. agent_codinglanguage_mapper/templates/skill/SKILL.md +52 -0
  35. agent_codinglanguage_mapper/worker.py +29 -0
  36. agent_codinglanguage_mapper/workspace.py +114 -0
  37. agent_codinglanguage_mapper-1.0.0.dist-info/METADATA +383 -0
  38. agent_codinglanguage_mapper-1.0.0.dist-info/RECORD +42 -0
  39. agent_codinglanguage_mapper-1.0.0.dist-info/WHEEL +5 -0
  40. agent_codinglanguage_mapper-1.0.0.dist-info/entry_points.txt +2 -0
  41. agent_codinglanguage_mapper-1.0.0.dist-info/licenses/LICENSE +373 -0
  42. agent_codinglanguage_mapper-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2674 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Callable, Iterable
4
+
5
+ from .consts import AttributeName, SyntaxNodeType
6
+ from .nodes import CompoundSyntaxNode, SyntaxNode, ValuedSyntaxNode
7
+
8
+
9
+ def build_syntax_tree(
10
+ tree: Any,
11
+ file_name: str,
12
+ *,
13
+ string_transform: Callable[[str], str] | None = None,
14
+ ) -> SyntaxNode:
15
+ try:
16
+ from lark import Transformer, v_args
17
+ from lark.lexer import Token
18
+ except ImportError as exc: # pragma: no cover - runtime dependency
19
+ raise RuntimeError('lark is required to build the syntax tree') from exc
20
+
21
+ def is_token(value: Any) -> bool:
22
+ return isinstance(value, Token)
23
+
24
+ def apply_string(value: str, token_type: str | None = None) -> str:
25
+ if string_transform is None:
26
+ return value
27
+ if token_type is None or token_type in {
28
+ 'NAME',
29
+ 'GENERIC_NAME',
30
+ 'SPACED_GENERIC_NAME',
31
+ 'STRICT_NAME',
32
+ 'STRING_LITERAL',
33
+ 'STRING_BLOCK3',
34
+ 'STRING_BLOCK5',
35
+ }:
36
+ return string_transform(value)
37
+ return value
38
+
39
+ def token_value(value: Any) -> str:
40
+ if is_token(value):
41
+ return apply_string(value.value, value.type)
42
+ return apply_string(str(value))
43
+
44
+ @v_args(meta=True, inline=True)
45
+ class Builder(Transformer):
46
+ def __init__(self) -> None:
47
+ super().__init__()
48
+ self.file_name = file_name
49
+
50
+ def __default__(self, data: str, children: list[Any], meta: Any) -> Any:
51
+ items: list[Any] = []
52
+ for child in children:
53
+ items.extend(self._flatten(child))
54
+ nodes = [child for child in items if isinstance(child, SyntaxNode)]
55
+ if not nodes:
56
+ return None
57
+ if len(nodes) == 1:
58
+ return nodes[0]
59
+ return nodes
60
+
61
+ def __default_token__(self, token: Any) -> Any:
62
+ return token
63
+
64
+ def unit_file(self, meta: Any, *children: Any) -> SyntaxNode:
65
+ unit_name = 'unit'
66
+ directives: dict[str, str] = {}
67
+ for item in self._flatten(children):
68
+ if self._is_text(item):
69
+ unit_name = item
70
+ break
71
+ for item in self._flatten(children):
72
+ if isinstance(item, dict):
73
+ directives.update(item)
74
+ root = self._make_node(SyntaxNodeType.ntUnit, meta)
75
+ root.set_attribute(AttributeName.anName, unit_name)
76
+ self._apply_decl_directives(root, directives)
77
+ for child in children:
78
+ if isinstance(child, SyntaxNode):
79
+ root.add_child(child)
80
+ return root
81
+
82
+ def include_file(self, meta: Any, *children: Any) -> SyntaxNode:
83
+ name = file_name.replace('\\', '/').rsplit('/', 1)[-1].rsplit('.', 1)[0] or 'include'
84
+ root = self._make_node(SyntaxNodeType.ntUnit, meta)
85
+ root.set_attribute(AttributeName.anName, name)
86
+ for child in self._flatten(children):
87
+ if isinstance(child, SyntaxNode):
88
+ root.add_child(child)
89
+ return root
90
+
91
+ def program_file(self, meta: Any, *children: Any) -> SyntaxNode:
92
+ return self._build_program_root(meta, 'program', children)
93
+
94
+ def library_file(self, meta: Any, *children: Any) -> SyntaxNode:
95
+ return self._build_program_root(meta, 'library', children)
96
+
97
+ def package_file(self, meta: Any, *children: Any) -> SyntaxNode:
98
+ unit_name = self._extract_name(children, default='package')
99
+ root = self._make_node(SyntaxNodeType.ntPackage, meta)
100
+ root.set_attribute(AttributeName.anName, unit_name)
101
+ for child in children:
102
+ if isinstance(child, SyntaxNode):
103
+ root.add_child(child)
104
+ elif isinstance(child, list):
105
+ for item in child:
106
+ if isinstance(item, SyntaxNode):
107
+ root.add_child(item)
108
+ return root
109
+
110
+ def unit_header(self, meta: Any, *children: Any) -> list[Any]:
111
+ name = 'unit'
112
+ directives: dict[str, str] = {}
113
+ for child in children:
114
+ if self._is_text(child):
115
+ name = child
116
+ break
117
+ for child in children:
118
+ if isinstance(child, dict):
119
+ directives.update(child)
120
+ return [name, directives]
121
+
122
+ def program_header(self, meta: Any, *children: Any) -> list[Any]:
123
+ name = self._extract_name(children, default='program')
124
+ nodes = [child for child in children if isinstance(child, SyntaxNode)]
125
+ return [name, *nodes]
126
+
127
+ def library_header(self, meta: Any, *children: Any) -> list[Any]:
128
+ name = self._extract_name(children, default='library')
129
+ nodes = [child for child in children if isinstance(child, SyntaxNode)]
130
+ return [name, *nodes]
131
+
132
+ def package_header(self, meta: Any, *children: Any) -> str:
133
+ return self._extract_name(children, default='package')
134
+
135
+ def unit_directive_list(self, meta: Any, *children: Any) -> dict[str, str]:
136
+ attrs: dict[str, str] = {}
137
+ for child in children:
138
+ if isinstance(child, tuple):
139
+ key, value = child
140
+ attrs[key] = value
141
+ return attrs
142
+
143
+ def unit_directive(self, meta: Any, *children: Any) -> tuple[str, str]:
144
+ return self.decl_directive(meta, *children)
145
+
146
+ def program_body(self, meta: Any, *children: Any) -> list[SyntaxNode]:
147
+ return [child for child in self._flatten(children) if isinstance(child, SyntaxNode)]
148
+
149
+ def package_body(self, meta: Any, *children: Any) -> list[SyntaxNode]:
150
+ return [child for child in self._flatten(children) if isinstance(child, SyntaxNode)]
151
+
152
+ def interface_section(self, meta: Any, *children: Any) -> SyntaxNode:
153
+ node = self._make_compound(SyntaxNodeType.ntInterface, meta)
154
+ for child in children:
155
+ if isinstance(child, SyntaxNode):
156
+ node.add_child(child)
157
+ elif isinstance(child, list):
158
+ for item in child:
159
+ if isinstance(item, SyntaxNode):
160
+ node.add_child(item)
161
+ return node
162
+
163
+ def interface_preamble(self, meta: Any, *_: Any) -> None:
164
+ return None
165
+
166
+ def implementation_section(self, meta: Any, *children: Any) -> SyntaxNode:
167
+ node = self._make_compound(SyntaxNodeType.ntImplementation, meta)
168
+ for child in children:
169
+ if isinstance(child, SyntaxNode):
170
+ node.add_child(child)
171
+ elif isinstance(child, list):
172
+ for item in child:
173
+ if isinstance(item, SyntaxNode):
174
+ node.add_child(item)
175
+ return node
176
+
177
+ def initialization_section(self, meta: Any, *children: Any) -> SyntaxNode:
178
+ node = self._make_compound(SyntaxNodeType.ntInitialization, meta)
179
+ for child in children:
180
+ if isinstance(child, SyntaxNode):
181
+ node.add_child(child)
182
+ elif isinstance(child, list):
183
+ for item in child:
184
+ if isinstance(item, SyntaxNode):
185
+ node.add_child(item)
186
+ return node
187
+
188
+ def bare_initialization_section(self, meta: Any, *children: Any) -> SyntaxNode:
189
+ return self.initialization_section(meta, *children)
190
+
191
+ def finalization_section(self, meta: Any, *children: Any) -> SyntaxNode:
192
+ node = self._make_compound(SyntaxNodeType.ntFinalization, meta)
193
+ for child in children:
194
+ if isinstance(child, SyntaxNode):
195
+ node.add_child(child)
196
+ elif isinstance(child, list):
197
+ for item in child:
198
+ if isinstance(item, SyntaxNode):
199
+ node.add_child(item)
200
+ return node
201
+
202
+ def decl_sections(self, meta: Any, *children: Any) -> list[SyntaxNode]:
203
+ nodes: list[SyntaxNode] = []
204
+ for child in children:
205
+ if isinstance(child, list):
206
+ for item in child:
207
+ if isinstance(item, SyntaxNode):
208
+ nodes.append(item)
209
+ elif isinstance(child, SyntaxNode):
210
+ nodes.append(child)
211
+ return nodes
212
+
213
+ def interface_decl_sections(self, meta: Any, *children: Any) -> list[SyntaxNode]:
214
+ return self.decl_sections(meta, *children)
215
+
216
+ def implementation_decl_sections(self, meta: Any, *children: Any) -> list[SyntaxNode]:
217
+ return self.decl_sections(meta, *children)
218
+
219
+ def ignored_proc_type_directive(self, meta: Any, *_: Any) -> None:
220
+ return None
221
+
222
+ def ignored_compiler_error_line(self, meta: Any, *_: Any) -> None:
223
+ return None
224
+
225
+ def block_decl_sections(self, meta: Any, *children: Any) -> list[SyntaxNode]:
226
+ return self.decl_sections(meta, *children)
227
+
228
+ def uses_clause(self, meta: Any, *children: Any) -> SyntaxNode:
229
+ node = self._make_compound(SyntaxNodeType.ntUses, meta)
230
+ for child in children:
231
+ if isinstance(child, SyntaxNode):
232
+ node.add_child(child)
233
+ return node
234
+
235
+ def uses_item(self, meta: Any, *children: Any) -> SyntaxNode:
236
+ name = None
237
+ path = None
238
+ for child in children:
239
+ if self._is_text(child):
240
+ name = child
241
+ elif is_token(child) and child.type == 'STRING_LITERAL':
242
+ path = self._dequote_string(child.value)
243
+ elif isinstance(child, ValuedSyntaxNode):
244
+ path = child.value
245
+ if name is None:
246
+ name = 'unit'
247
+ node = self._make_node(SyntaxNodeType.ntUnit, meta)
248
+ node.set_attribute(AttributeName.anName, name)
249
+ if path:
250
+ node.set_attribute(AttributeName.anPath, path)
251
+ return node
252
+
253
+ def label_section(self, meta: Any, *children: Any) -> list[SyntaxNode]:
254
+ labels: list[SyntaxNode] = []
255
+ for child in self._flatten(children):
256
+ if isinstance(child, str):
257
+ node = self._make_node(SyntaxNodeType.ntLabel, meta)
258
+ node.set_attribute(AttributeName.anName, child)
259
+ labels.append(node)
260
+ return labels
261
+
262
+ def label_list(self, meta: Any, *children: Any) -> list[str]:
263
+ values: list[str] = []
264
+ for child in children:
265
+ if self._is_text(child):
266
+ values.append(child)
267
+ elif is_token(child):
268
+ values.append(child.value)
269
+ return values
270
+
271
+ def label(self, meta: Any, token: Any) -> str:
272
+ return token_value(token)
273
+
274
+ def const_section(self, meta: Any, *children: Any) -> SyntaxNode:
275
+ node = self._make_node(SyntaxNodeType.ntConstants, meta)
276
+ for child in children:
277
+ if isinstance(child, SyntaxNode):
278
+ node.add_child(child)
279
+ return node
280
+
281
+ def resourcestring_section(self, meta: Any, *children: Any) -> SyntaxNode:
282
+ node = self._make_node(SyntaxNodeType.ntResourceString, meta)
283
+ for child in children:
284
+ if isinstance(child, SyntaxNode):
285
+ node.add_child(child)
286
+ return node
287
+
288
+ def const_decl(self, meta: Any, *children: Any) -> SyntaxNode:
289
+ name = None
290
+ attributes: list[SyntaxNode] = []
291
+ directives: dict[str, str] = {}
292
+ for child in children:
293
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAttributes:
294
+ attributes.append(child)
295
+ elif isinstance(child, dict):
296
+ directives.update(child)
297
+ elif self._is_text(child):
298
+ name = child
299
+ elif is_token(child) and child.type == 'NAME':
300
+ name = child.value
301
+ if name is None:
302
+ name = 'const'
303
+ node = self._make_node(SyntaxNodeType.ntConstant, meta)
304
+ node.add_child(self._make_valued(SyntaxNodeType.ntName, name, meta))
305
+ for attr in attributes:
306
+ node.add_child(attr)
307
+ for child in children:
308
+ if isinstance(child, SyntaxNode):
309
+ if child.typ == SyntaxNodeType.ntType:
310
+ node.add_child(child)
311
+ else:
312
+ value_node = self._make_node(SyntaxNodeType.ntValue, meta)
313
+ value_node.add_child(child)
314
+ node.add_child(value_node)
315
+ self._apply_decl_directives(node, directives)
316
+ return node
317
+
318
+ def var_section(self, meta: Any, *children: Any) -> SyntaxNode:
319
+ node = self._make_node(SyntaxNodeType.ntVariables, meta)
320
+ for child in children:
321
+ if isinstance(child, list):
322
+ for var_node in child:
323
+ node.add_child(var_node)
324
+ elif isinstance(child, SyntaxNode):
325
+ node.add_child(child)
326
+ return node
327
+
328
+ def threadvar_section(self, meta: Any, *children: Any) -> SyntaxNode:
329
+ node = self.var_section(meta, *children)
330
+ node.set_attribute(AttributeName.anKind, 'threadvar')
331
+ return node
332
+
333
+ def class_var_section(self, meta: Any, *children: Any) -> SyntaxNode:
334
+ node = self.var_section(meta, *children)
335
+ node.set_attribute(AttributeName.anKind, 'class var')
336
+ return node
337
+
338
+ def class_threadvar_section(self, meta: Any, *children: Any) -> SyntaxNode:
339
+ node = self.var_section(meta, *children)
340
+ node.set_attribute(AttributeName.anKind, 'class threadvar')
341
+ return node
342
+
343
+ def var_decl(self, meta: Any, *children: Any) -> list[SyntaxNode]:
344
+ names: list[str] = []
345
+ type_node = None
346
+ value_expr = None
347
+ absolute_expr = None
348
+ attributes: list[SyntaxNode] = []
349
+ directives: dict[str, str] = {}
350
+ for child in children:
351
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAttributes:
352
+ attributes.append(child)
353
+ elif isinstance(child, list):
354
+ names = child
355
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
356
+ type_node = child
357
+ elif isinstance(child, dict):
358
+ directives.update(child)
359
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAbsolute:
360
+ absolute_expr = child
361
+ elif isinstance(child, SyntaxNode):
362
+ value_expr = child
363
+ variables: list[SyntaxNode] = []
364
+ if type_node is None:
365
+ return variables
366
+ if directives:
367
+ self._apply_directives(type_node, directives)
368
+ for name in names:
369
+ node = self._make_node(SyntaxNodeType.ntVariable, meta)
370
+ node.add_child(self._make_valued(SyntaxNodeType.ntName, name, meta))
371
+ node.add_child(type_node.clone())
372
+ for attr in attributes:
373
+ node.add_child(attr)
374
+ if absolute_expr is not None:
375
+ node.add_child(absolute_expr.clone())
376
+ if value_expr is not None:
377
+ value_node = self._make_node(SyntaxNodeType.ntValue, meta)
378
+ value_node.add_child(value_expr)
379
+ node.add_child(value_node)
380
+ variables.append(node)
381
+ return variables
382
+
383
+ def absolute_spec(self, meta: Any, *children: Any) -> SyntaxNode:
384
+ node = self._make_node(SyntaxNodeType.ntAbsolute, meta)
385
+ for child in children:
386
+ if isinstance(child, SyntaxNode):
387
+ node.add_child(child)
388
+ return node
389
+
390
+ def type_section(self, meta: Any, *children: Any) -> SyntaxNode:
391
+ node = self._make_node(SyntaxNodeType.ntTypeSection, meta)
392
+ for child in children:
393
+ if isinstance(child, SyntaxNode):
394
+ node.add_child(child)
395
+ return node
396
+
397
+ def type_decl(self, meta: Any, *children: Any) -> SyntaxNode:
398
+ name = None
399
+ type_node = None
400
+ type_params = None
401
+ attributes: list[SyntaxNode] = []
402
+ directives: dict[str, str] = {}
403
+ for child in children:
404
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAttributes:
405
+ attributes.append(child)
406
+ elif isinstance(child, dict):
407
+ directives.update(child)
408
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntTypeParams:
409
+ type_params = child
410
+ elif self._is_text(child):
411
+ name = child
412
+ elif is_token(child) and child.type in {'NAME', 'GENERIC_NAME'}:
413
+ name = child.value
414
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
415
+ type_node = child
416
+ if name is None or type_node is None:
417
+ return self._make_compound(SyntaxNodeType.ntTypeDecl, meta)
418
+ if '<' in name:
419
+ base_name, generic_args = self._split_generic_name(name)
420
+ name = base_name
421
+ if type_params is None and generic_args:
422
+ type_params = self._type_params_from_generic_name(meta, generic_args)
423
+ node = self._make_compound(SyntaxNodeType.ntTypeDecl, meta)
424
+ node.set_attribute(AttributeName.anName, name)
425
+ for attr in attributes:
426
+ node.add_child(attr)
427
+ if type_params is not None:
428
+ node.add_child(type_params)
429
+ if directives:
430
+ self._apply_directives(type_node, directives)
431
+ node.add_child(type_node)
432
+ self._apply_decl_directives(node, directives)
433
+ return node
434
+
435
+ def incomplete_type_decl(self, meta: Any, *children: Any) -> SyntaxNode:
436
+ name = None
437
+ type_params = None
438
+ attributes: list[SyntaxNode] = []
439
+ for child in children:
440
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAttributes:
441
+ attributes.append(child)
442
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntTypeParams:
443
+ type_params = child
444
+ elif self._is_text(child):
445
+ name = child
446
+ elif is_token(child) and child.type in {'NAME', 'GENERIC_NAME'}:
447
+ name = child.value
448
+ node = self._make_compound(SyntaxNodeType.ntTypeDecl, meta)
449
+ if name is not None:
450
+ node.set_attribute(AttributeName.anName, name)
451
+ for attr in attributes:
452
+ node.add_child(attr)
453
+ if type_params is not None:
454
+ node.add_child(type_params)
455
+ unknown = self._make_node(SyntaxNodeType.ntType, meta)
456
+ unknown.set_attribute(AttributeName.anType, 'unknown')
457
+ node.add_child(unknown)
458
+ return node
459
+
460
+ def type_decl_name(self, meta: Any, token: Any) -> str:
461
+ return token_value(token)
462
+
463
+ def decl_directive_list(self, meta: Any, *children: Any) -> dict[str, str]:
464
+ attrs: dict[str, str] = {}
465
+ for child in children:
466
+ if isinstance(child, tuple):
467
+ key, value = child
468
+ attrs[key] = value
469
+ return attrs
470
+
471
+ def decl_directive(self, meta: Any, *children: Any) -> tuple[str, str]:
472
+ token = None
473
+ str_token = None
474
+ for child in children:
475
+ if is_token(child) and child.type in {'DEPRECATED', 'PLATFORM', 'EXPERIMENTAL', 'LIBRARY'}:
476
+ token = child
477
+ elif is_token(child) and child.type == 'STRING_LITERAL':
478
+ str_token = child
479
+ if token is None:
480
+ return ('', '')
481
+ key = token.type.lower()
482
+ if key == 'deprecated' and str_token is not None:
483
+ return ('deprecated', self._dequote_string(str_token.value))
484
+ return (key, 'true')
485
+
486
+ def simple_type(self, meta: Any, *children: Any) -> SyntaxNode:
487
+ for child in children:
488
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
489
+ return child
490
+ if self._is_text(child):
491
+ node = self._make_node(SyntaxNodeType.ntType, meta)
492
+ node.set_attribute(AttributeName.anName, child)
493
+ return node
494
+ return self._make_node(SyntaxNodeType.ntType, meta)
495
+
496
+ def type_name(self, meta: Any, *children: Any) -> SyntaxNode:
497
+ name = None
498
+ type_args = None
499
+ for child in children:
500
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntTypeArgs:
501
+ type_args = child
502
+ elif self._is_text(child):
503
+ name = child
504
+ node = self._make_node(SyntaxNodeType.ntType, meta)
505
+ if name is not None:
506
+ node.set_attribute(AttributeName.anName, name)
507
+ if type_args is not None:
508
+ node.add_child(type_args)
509
+ return node
510
+
511
+ def pointer_type(self, meta: Any, *children: Any) -> SyntaxNode:
512
+ node = self._make_node(SyntaxNodeType.ntType, meta)
513
+ node.set_attribute(AttributeName.anType, 'pointer')
514
+ for child in children:
515
+ if isinstance(child, SyntaxNode):
516
+ node.add_child(child)
517
+ elif is_token(child) and child.type == 'POINTER_CHAR':
518
+ target = self._make_node(SyntaxNodeType.ntType, meta)
519
+ target.set_attribute(AttributeName.anName, child.value[1:])
520
+ node.add_child(target)
521
+ return node
522
+
523
+ def distinct_type(self, meta: Any, *children: Any) -> SyntaxNode:
524
+ node = self._make_node(SyntaxNodeType.ntType, meta)
525
+ node.set_attribute(AttributeName.anType, 'distinct')
526
+ for child in children:
527
+ if isinstance(child, SyntaxNode):
528
+ node.add_child(child)
529
+ return node
530
+
531
+ def array_type(self, meta: Any, *children: Any) -> SyntaxNode:
532
+ node = self._make_node(SyntaxNodeType.ntType, meta)
533
+ node.set_attribute(AttributeName.anType, 'array')
534
+ for child in children:
535
+ if isinstance(child, SyntaxNode):
536
+ node.add_child(child)
537
+ return node
538
+
539
+ def array_of_const_type(self, meta: Any, *_: Any) -> SyntaxNode:
540
+ node = self._make_node(SyntaxNodeType.ntType, meta)
541
+ node.set_attribute(AttributeName.anType, 'array')
542
+ const_node = self._make_node(SyntaxNodeType.ntType, meta)
543
+ const_node.set_attribute(AttributeName.anName, 'const')
544
+ node.add_child(const_node)
545
+ return node
546
+
547
+ def array_bounds(self, meta: Any, *children: Any) -> SyntaxNode:
548
+ node = self._make_node(SyntaxNodeType.ntBounds, meta)
549
+ for child in children:
550
+ if isinstance(child, SyntaxNode):
551
+ node.add_child(child)
552
+ return node
553
+
554
+ def array_bound(self, meta: Any, *children: Any) -> SyntaxNode:
555
+ nodes = [child for child in children if isinstance(child, SyntaxNode)]
556
+ if len(nodes) == 2:
557
+ subrange = self._make_node(SyntaxNodeType.ntSubrange, meta)
558
+ subrange.add_child(nodes[0])
559
+ subrange.add_child(nodes[1])
560
+ return subrange
561
+ if nodes:
562
+ return nodes[0]
563
+ return self._make_node(SyntaxNodeType.ntExpression, meta)
564
+
565
+ def set_type(self, meta: Any, *children: Any) -> SyntaxNode:
566
+ node = self._make_node(SyntaxNodeType.ntType, meta)
567
+ node.set_attribute(AttributeName.anType, 'set')
568
+ for child in children:
569
+ if isinstance(child, SyntaxNode):
570
+ node.add_child(child)
571
+ return node
572
+
573
+ def enum_type(self, meta: Any, *children: Any) -> SyntaxNode:
574
+ node = self._make_node(SyntaxNodeType.ntType, meta)
575
+ node.set_attribute(AttributeName.anName, 'enum')
576
+ for child in children:
577
+ if isinstance(child, SyntaxNode):
578
+ node.add_child(child)
579
+ return node
580
+
581
+ def enum_item(self, meta: Any, *children: Any) -> SyntaxNode:
582
+ name = None
583
+ value_expr = None
584
+ for child in children:
585
+ if self._is_text(child):
586
+ name = child
587
+ elif isinstance(child, SyntaxNode):
588
+ value_expr = child
589
+ node = self._make_node(SyntaxNodeType.ntEnum, meta)
590
+ if name:
591
+ node.add_child(self._make_valued(SyntaxNodeType.ntName, name, meta))
592
+ if value_expr is not None:
593
+ value_node = self._make_node(SyntaxNodeType.ntValue, meta)
594
+ value_node.add_child(value_expr)
595
+ node.add_child(value_node)
596
+ return node
597
+
598
+ def string_type(self, meta: Any, *children: Any) -> SyntaxNode:
599
+ node = self._make_node(SyntaxNodeType.ntType, meta)
600
+ node.set_attribute(AttributeName.anName, 'string')
601
+ for child in children:
602
+ if isinstance(child, SyntaxNode):
603
+ node.add_child(child)
604
+ return node
605
+
606
+ def file_type(self, meta: Any, *children: Any) -> SyntaxNode:
607
+ node = self._make_node(SyntaxNodeType.ntType, meta)
608
+ node.set_attribute(AttributeName.anType, 'file')
609
+ for child in children:
610
+ if isinstance(child, SyntaxNode):
611
+ node.add_child(child)
612
+ return node
613
+
614
+ def class_of_type(self, meta: Any, *children: Any) -> SyntaxNode:
615
+ node = self._make_node(SyntaxNodeType.ntType, meta)
616
+ node.set_attribute(AttributeName.anType, 'class of')
617
+ for child in children:
618
+ if isinstance(child, SyntaxNode):
619
+ node.add_child(child)
620
+ return node
621
+
622
+ def reference_type(self, meta: Any, *children: Any) -> SyntaxNode:
623
+ node = self._make_node(SyntaxNodeType.ntType, meta)
624
+ node.set_attribute(AttributeName.anType, 'reference')
625
+ for child in children:
626
+ if isinstance(child, SyntaxNode):
627
+ node.add_child(child)
628
+ return node
629
+
630
+ def packed_type(self, meta: Any, *children: Any) -> SyntaxNode:
631
+ node = self._make_node(SyntaxNodeType.ntType, meta)
632
+ node.set_attribute(AttributeName.anType, 'packed')
633
+ for child in children:
634
+ if isinstance(child, SyntaxNode):
635
+ node.add_child(child)
636
+ return node
637
+
638
+ def subrange_type(self, meta: Any, lower: Any, upper: Any) -> SyntaxNode:
639
+ node = self._make_node(SyntaxNodeType.ntType, meta)
640
+ node.set_attribute(AttributeName.anName, 'subrange')
641
+ bounds = self._make_node(SyntaxNodeType.ntBounds, meta)
642
+ bounds.add_child(self._ensure_expr_node(meta, lower))
643
+ bounds.add_child(self._ensure_expr_node(meta, upper))
644
+ node.add_child(bounds)
645
+ return node
646
+
647
+ def class_type(self, meta: Any, *children: Any) -> SyntaxNode:
648
+ node = self._make_node(SyntaxNodeType.ntType, meta)
649
+ node.set_attribute(AttributeName.anType, 'class')
650
+ for child in children:
651
+ if isinstance(child, SyntaxNode):
652
+ node.add_child(child)
653
+ elif isinstance(child, list):
654
+ for item in child:
655
+ if isinstance(item, SyntaxNode):
656
+ node.add_child(item)
657
+ return node
658
+
659
+ def forward_class_decl(self, meta: Any, *children: Any) -> SyntaxNode:
660
+ node = self._make_node(SyntaxNodeType.ntType, meta)
661
+ node.set_attribute(AttributeName.anType, 'class')
662
+ for child in children:
663
+ if isinstance(child, SyntaxNode):
664
+ node.add_child(child)
665
+ elif isinstance(child, list):
666
+ for item in child:
667
+ if isinstance(item, SyntaxNode):
668
+ node.add_child(item)
669
+ return node
670
+
671
+ def forward_interface_decl(self, meta: Any, *children: Any) -> SyntaxNode:
672
+ node = self._make_node(SyntaxNodeType.ntType, meta)
673
+ node.set_attribute(AttributeName.anType, 'interface')
674
+ for child in children:
675
+ if isinstance(child, SyntaxNode):
676
+ node.add_child(child)
677
+ elif isinstance(child, list):
678
+ for item in child:
679
+ if isinstance(item, SyntaxNode):
680
+ node.add_child(item)
681
+ return node
682
+
683
+ def forward_dispinterface_decl(self, meta: Any, *children: Any) -> SyntaxNode:
684
+ node = self._make_node(SyntaxNodeType.ntType, meta)
685
+ node.set_attribute(AttributeName.anType, 'dispinterface')
686
+ for child in children:
687
+ if isinstance(child, SyntaxNode):
688
+ node.add_child(child)
689
+ elif isinstance(child, list):
690
+ for item in child:
691
+ if isinstance(item, SyntaxNode):
692
+ node.add_child(item)
693
+ return node
694
+
695
+ def record_type(self, meta: Any, *children: Any) -> SyntaxNode:
696
+ node = self._make_node(SyntaxNodeType.ntType, meta)
697
+ node.set_attribute(AttributeName.anType, 'record')
698
+ for child in children:
699
+ if isinstance(child, list):
700
+ for item in child:
701
+ if isinstance(item, tuple) and item and item[0] == 'align':
702
+ node.set_attribute(AttributeName.anAlign, item[1])
703
+ else:
704
+ node.add_child(item)
705
+ elif isinstance(child, tuple) and child and child[0] == 'align':
706
+ node.set_attribute(AttributeName.anAlign, child[1])
707
+ elif isinstance(child, SyntaxNode):
708
+ node.add_child(child)
709
+ return node
710
+
711
+ def record_align(self, meta: Any, *children: Any) -> tuple[str, str]:
712
+ for child in children:
713
+ if isinstance(child, SyntaxNode):
714
+ value = self._expr_to_text(child)
715
+ if value:
716
+ return ('align', value)
717
+ if self._is_text(child) or is_token(child):
718
+ return ('align', token_value(child))
719
+ return ('align', 'true')
720
+
721
+ def object_type(self, meta: Any, *children: Any) -> SyntaxNode:
722
+ node = self._make_node(SyntaxNodeType.ntType, meta)
723
+ node.set_attribute(AttributeName.anType, 'object')
724
+ for child in children:
725
+ if isinstance(child, SyntaxNode):
726
+ node.add_child(child)
727
+ elif isinstance(child, list):
728
+ for item in child:
729
+ node.add_child(item)
730
+ return node
731
+
732
+ def interface_type(self, meta: Any, *children: Any) -> SyntaxNode:
733
+ node = self._make_node(SyntaxNodeType.ntType, meta)
734
+ token = children[0] if children else None
735
+ if is_token(token) and token.type == 'DISPINTERFACE':
736
+ node.set_attribute(AttributeName.anType, 'dispinterface')
737
+ start_index = 1
738
+ else:
739
+ node.set_attribute(AttributeName.anType, 'interface')
740
+ start_index = 0
741
+ for child in children[start_index:]:
742
+ if isinstance(child, SyntaxNode):
743
+ node.add_child(child)
744
+ elif isinstance(child, list):
745
+ for item in child:
746
+ node.add_child(item)
747
+ return node
748
+
749
+ def helper_type(self, meta: Any, *children: Any) -> SyntaxNode:
750
+ node = self._make_node(SyntaxNodeType.ntType, meta)
751
+ node.set_attribute(AttributeName.anType, 'helper')
752
+ for child in children:
753
+ if isinstance(child, SyntaxNode):
754
+ node.add_child(child)
755
+ elif isinstance(child, list):
756
+ for item in child:
757
+ node.add_child(item)
758
+ return node
759
+
760
+ def interface_guid(self, meta: Any, token: Any) -> SyntaxNode:
761
+ node = self._make_node(SyntaxNodeType.ntGuid, meta)
762
+ if is_token(token) and token.type == 'STRING_LITERAL':
763
+ node.set_attribute(AttributeName.anName, self._dequote_string(token.value))
764
+ return node
765
+
766
+ def type_heritage(self, meta: Any, *children: Any) -> list[SyntaxNode]:
767
+ bases = []
768
+ for name in children:
769
+ if isinstance(name, SyntaxNode) and name.typ == SyntaxNodeType.ntType:
770
+ bases.append(name)
771
+ elif self._is_text(name):
772
+ base = self._make_node(SyntaxNodeType.ntType, meta)
773
+ base.set_attribute(AttributeName.anName, name)
774
+ bases.append(base)
775
+ return bases
776
+
777
+ def type_params(self, meta: Any, *children: Any) -> SyntaxNode:
778
+ node = self._make_node(SyntaxNodeType.ntTypeParams, meta)
779
+ for child in children:
780
+ if isinstance(child, list):
781
+ for item in child:
782
+ if isinstance(item, SyntaxNode):
783
+ node.add_child(item)
784
+ elif isinstance(child, SyntaxNode):
785
+ node.add_child(child)
786
+ return node
787
+
788
+ def type_param(self, meta: Any, *children: Any) -> list[SyntaxNode]:
789
+ names: list[str] = []
790
+ constraints = None
791
+ for child in children:
792
+ if isinstance(child, tuple):
793
+ tuple_names, tuple_constraints = child
794
+ names = list(tuple_names)
795
+ constraints = tuple_constraints
796
+ elif isinstance(child, list):
797
+ names = [token_value(item) for item in child]
798
+ elif self._is_text(child):
799
+ names.append(child)
800
+ elif is_token(child) and child.type == 'NAME':
801
+ names.append(token_value(child))
802
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntConstraints:
803
+ constraints = child
804
+ params: list[SyntaxNode] = []
805
+ for name in names:
806
+ node = self._make_node(SyntaxNodeType.ntTypeParam, meta)
807
+ node.add_child(self._make_valued(SyntaxNodeType.ntName, name, meta))
808
+ if constraints is not None:
809
+ node.add_child(constraints.clone())
810
+ params.append(node)
811
+ return params
812
+
813
+ def constrained_name_list(self, meta: Any, *children: Any) -> list[str]:
814
+ return [token_value(child) for child in children]
815
+
816
+ def constrained_type_param(self, meta: Any, names: Any, constraints: Any) -> tuple[list[str], SyntaxNode | None]:
817
+ resolved_names: list[str] = []
818
+ if isinstance(names, list):
819
+ resolved_names = [token_value(name) for name in names]
820
+ elif self._is_text(names):
821
+ resolved_names = [names]
822
+ elif is_token(names):
823
+ resolved_names = [token_value(names)]
824
+ constraint_node = constraints if isinstance(constraints, SyntaxNode) else None
825
+ return (resolved_names, constraint_node)
826
+
827
+ def type_constraints(self, meta: Any, *children: Any) -> SyntaxNode:
828
+ node = self._make_node(SyntaxNodeType.ntConstraints, meta)
829
+ for child in children:
830
+ if isinstance(child, SyntaxNode):
831
+ node.add_child(child)
832
+ return node
833
+
834
+ def type_constraint(self, meta: Any, *children: Any) -> SyntaxNode:
835
+ for child in children:
836
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
837
+ return child
838
+ if is_token(child):
839
+ if child.type == 'CLASS':
840
+ return self._make_node(SyntaxNodeType.ntClassConstraint, meta)
841
+ if child.type == 'RECORD':
842
+ return self._make_node(SyntaxNodeType.ntRecordConstraint, meta)
843
+ if child.type == 'CONSTRUCTOR':
844
+ return self._make_node(SyntaxNodeType.ntConstructorConstraint, meta)
845
+ if child.type == 'INTERFACE':
846
+ return self._make_node(SyntaxNodeType.ntInterfaceConstraint, meta)
847
+ if child.type == 'UNMANAGED':
848
+ return self._make_node(SyntaxNodeType.ntUnmanagedConstraint, meta)
849
+ return self._make_node(SyntaxNodeType.ntUnknown, meta)
850
+
851
+ def type_args(self, meta: Any, *children: Any) -> SyntaxNode:
852
+ node = self._make_node(SyntaxNodeType.ntTypeArgs, meta)
853
+ for child in children:
854
+ if isinstance(child, SyntaxNode):
855
+ node.add_child(child)
856
+ return node
857
+
858
+ def field_list(self, meta: Any, *children: Any) -> list[SyntaxNode]:
859
+ fields: list[SyntaxNode] = []
860
+ for child in children:
861
+ if isinstance(child, list):
862
+ fields.extend(child)
863
+ return fields
864
+
865
+ def field_decl(self, meta: Any, *children: Any) -> list[SyntaxNode]:
866
+ names: list[str] = []
867
+ type_node = None
868
+ attributes: list[SyntaxNode] = []
869
+ directives: dict[str, str] = {}
870
+ for child in children:
871
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAttributes:
872
+ attributes.append(child)
873
+ elif isinstance(child, list):
874
+ names = child
875
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
876
+ type_node = child
877
+ elif isinstance(child, dict):
878
+ directives.update(child)
879
+ fields: list[SyntaxNode] = []
880
+ if type_node is None:
881
+ return fields
882
+ if directives:
883
+ self._apply_directives(type_node, directives)
884
+ for name in names:
885
+ field = self._make_node(SyntaxNodeType.ntField, meta)
886
+ field.add_child(self._make_valued(SyntaxNodeType.ntName, name, meta))
887
+ field.add_child(type_node.clone())
888
+ for attr in attributes:
889
+ field.add_child(attr)
890
+ fields.append(field)
891
+ return fields
892
+
893
+ def proc_type(self, meta: Any, *children: Any) -> SyntaxNode:
894
+ kind = 'procedure'
895
+ params = None
896
+ return_type = None
897
+ for child in children:
898
+ if is_token(child) and child.type == 'FUNCTION':
899
+ kind = 'function'
900
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntParameters:
901
+ params = child
902
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
903
+ return_type = child
904
+ node = self._make_node(SyntaxNodeType.ntType, meta)
905
+ node.set_attribute(AttributeName.anType, kind)
906
+ if params is not None:
907
+ node.add_child(params)
908
+ if return_type is not None:
909
+ return_node = self._make_node(SyntaxNodeType.ntReturnType, meta)
910
+ return_node.add_child(return_type)
911
+ node.add_child(return_node)
912
+ return node
913
+
914
+ def proc_type_decl_directive(self, meta: Any, *children: Any) -> dict[str, str]:
915
+ for child in children:
916
+ if is_token(child):
917
+ values = child.value.lstrip(';').strip().casefold().split()
918
+ return self._proc_type_directive_attrs(values)
919
+ return {}
920
+
921
+ def visibility_spec(self, meta: Any, *children: Any) -> SyntaxNode:
922
+ token = None
923
+ for child in children:
924
+ if is_token(child):
925
+ token = child
926
+ if token is None:
927
+ return self._make_node(SyntaxNodeType.ntPublic, meta)
928
+ mapping = {
929
+ 'PRIVATE': SyntaxNodeType.ntPrivate,
930
+ 'PROTECTED': SyntaxNodeType.ntProtected,
931
+ 'PUBLIC': SyntaxNodeType.ntPublic,
932
+ 'PUBLISHED': SyntaxNodeType.ntPublished,
933
+ 'AUTOMATED': SyntaxNodeType.ntPublished,
934
+ }
935
+ if token.type == 'PRIVATE' and any(is_token(c) and c.type == 'STRICT' for c in children):
936
+ node = self._make_node(SyntaxNodeType.ntStrictPrivate, meta)
937
+ elif token.type == 'PROTECTED' and any(is_token(c) and c.type == 'STRICT' for c in children):
938
+ node = self._make_node(SyntaxNodeType.ntStrictProtected, meta)
939
+ else:
940
+ node = self._make_node(mapping.get(token.type, SyntaxNodeType.ntPublic), meta)
941
+ node.set_attribute(AttributeName.anVisibility, 'true')
942
+ return node
943
+
944
+ def class_member(self, meta: Any, *children: Any) -> list[SyntaxNode]:
945
+ visibility = None
946
+ members: list[SyntaxNode] = []
947
+ for child in children:
948
+ if isinstance(child, SyntaxNode) and child.typ in {
949
+ SyntaxNodeType.ntPrivate,
950
+ SyntaxNodeType.ntProtected,
951
+ SyntaxNodeType.ntPublic,
952
+ SyntaxNodeType.ntPublished,
953
+ SyntaxNodeType.ntStrictPrivate,
954
+ SyntaxNodeType.ntStrictProtected,
955
+ }:
956
+ visibility = child
957
+ elif isinstance(child, list):
958
+ for item in child:
959
+ if isinstance(item, SyntaxNode):
960
+ members.append(item)
961
+ elif isinstance(child, SyntaxNode):
962
+ members.append(child)
963
+ if visibility is None:
964
+ return members
965
+ return [visibility] + members
966
+
967
+ def class_body(self, meta: Any, *children: Any) -> list[SyntaxNode]:
968
+ members: list[SyntaxNode] = []
969
+ current_visibility: SyntaxNode | None = None
970
+ for child in children:
971
+ for item in self._flatten(child):
972
+ if isinstance(item, SyntaxNode) and item.typ in {
973
+ SyntaxNodeType.ntPrivate,
974
+ SyntaxNodeType.ntProtected,
975
+ SyntaxNodeType.ntPublic,
976
+ SyntaxNodeType.ntPublished,
977
+ SyntaxNodeType.ntStrictPrivate,
978
+ SyntaxNodeType.ntStrictProtected,
979
+ }:
980
+ current_visibility = item
981
+ continue
982
+ if isinstance(item, SyntaxNode):
983
+ if current_visibility is not None:
984
+ vis_node = current_visibility.clone()
985
+ vis_node.add_child(item)
986
+ members.append(vis_node)
987
+ else:
988
+ members.append(item)
989
+ return members
990
+
991
+ def record_body(self, meta: Any, *children: Any) -> list[SyntaxNode]:
992
+ return self.class_body(meta, *children)
993
+
994
+ def interface_body(self, meta: Any, *children: Any) -> list[SyntaxNode]:
995
+ return [child for child in children if isinstance(child, SyntaxNode)]
996
+
997
+ def interface_member(self, meta: Any, *children: Any) -> SyntaxNode | None:
998
+ for child in children:
999
+ if isinstance(child, SyntaxNode):
1000
+ return child
1001
+ return None
1002
+
1003
+ def property_decl(self, meta: Any, *children: Any) -> SyntaxNode:
1004
+ name = None
1005
+ attributes: list[SyntaxNode] = []
1006
+ for child in children:
1007
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAttributes:
1008
+ attributes.append(child)
1009
+ elif self._is_text(child):
1010
+ name = child
1011
+ elif is_token(child) and child.type == 'NAME':
1012
+ name = child.value
1013
+ if name is None:
1014
+ name = 'property'
1015
+ node = self._make_node(SyntaxNodeType.ntProperty, meta)
1016
+ node.set_attribute(AttributeName.anName, token_value(name))
1017
+ for attr in attributes:
1018
+ node.add_child(attr)
1019
+ for child in children:
1020
+ if isinstance(child, list):
1021
+ for item in child:
1022
+ if isinstance(item, SyntaxNode):
1023
+ node.add_child(item)
1024
+ elif isinstance(child, SyntaxNode):
1025
+ node.add_child(child)
1026
+ return node
1027
+
1028
+ def property_directive_block(self, meta: Any, *children: Any) -> list[SyntaxNode]:
1029
+ nodes: list[SyntaxNode] = []
1030
+ for child in children:
1031
+ if isinstance(child, SyntaxNode):
1032
+ nodes.append(child)
1033
+ elif isinstance(child, list):
1034
+ for item in child:
1035
+ if isinstance(item, SyntaxNode):
1036
+ nodes.append(item)
1037
+ return nodes
1038
+
1039
+ def property_directive(self, meta: Any, *children: Any) -> SyntaxNode:
1040
+ token = None
1041
+ expr = None
1042
+ for child in children:
1043
+ if is_token(child):
1044
+ token = child
1045
+ elif isinstance(child, SyntaxNode):
1046
+ expr = child
1047
+ if token is None:
1048
+ return self._make_node(SyntaxNodeType.ntUnknown, meta)
1049
+ mapping = {
1050
+ 'READ': SyntaxNodeType.ntRead,
1051
+ 'WRITE': SyntaxNodeType.ntWrite,
1052
+ 'ADD': SyntaxNodeType.ntUnknown,
1053
+ 'REMOVE': SyntaxNodeType.ntUnknown,
1054
+ 'DEFAULT': SyntaxNodeType.ntDefault,
1055
+ 'STORED': SyntaxNodeType.ntUnknown,
1056
+ 'IMPLEMENTS': SyntaxNodeType.ntImplements,
1057
+ }
1058
+ node = self._make_node(mapping.get(token.type, SyntaxNodeType.ntUnknown), meta)
1059
+ if token.type in {'ADD', 'REMOVE', 'STORED'}:
1060
+ node.set_attribute(AttributeName.anKind, token.type.lower())
1061
+ if expr is not None:
1062
+ node.add_child(expr)
1063
+ return node
1064
+
1065
+ def property_specifier(self, meta: Any, *children: Any) -> SyntaxNode:
1066
+ return self._make_node(SyntaxNodeType.ntUnknown, meta)
1067
+
1068
+ def routine_decl(self, meta: Any, *children: Any) -> SyntaxNode:
1069
+ heading = None
1070
+ body = None
1071
+ directives = None
1072
+ for child in children:
1073
+ if isinstance(child, SyntaxNode):
1074
+ if heading is None:
1075
+ heading = child
1076
+ else:
1077
+ body = child
1078
+ elif isinstance(child, list):
1079
+ body = child
1080
+ elif isinstance(child, dict):
1081
+ directives = child
1082
+ if heading is None:
1083
+ return self._make_node(SyntaxNodeType.ntMethod, meta)
1084
+ if directives:
1085
+ self._apply_directives(heading, directives)
1086
+ if body is not None:
1087
+ if isinstance(body, list):
1088
+ for item in body:
1089
+ if isinstance(item, SyntaxNode):
1090
+ heading.add_child(item)
1091
+ elif isinstance(body, SyntaxNode):
1092
+ heading.add_child(body)
1093
+ return heading
1094
+
1095
+ def resolution_decl(self, meta: Any, *children: Any) -> SyntaxNode:
1096
+ method = None
1097
+ source_name = None
1098
+ target_name = None
1099
+ for child in children:
1100
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntMethod:
1101
+ method = child
1102
+ elif self._is_text(child) or is_token(child):
1103
+ text = token_value(child)
1104
+ if source_name is None:
1105
+ source_name = text
1106
+ else:
1107
+ target_name = text
1108
+ if method is None:
1109
+ method = self._make_node(SyntaxNodeType.ntMethod, meta)
1110
+ if source_name:
1111
+ method.set_attribute(AttributeName.anName, source_name)
1112
+ method.set_attribute(AttributeName.anKind, 'resolution')
1113
+ if target_name:
1114
+ resolution = self._make_node(SyntaxNodeType.ntResolutionClause, meta)
1115
+ resolution.set_attribute(AttributeName.anName, target_name)
1116
+ method.add_child(resolution)
1117
+ return method
1118
+
1119
+ def routine_impl(self, meta: Any, *children: Any) -> SyntaxNode:
1120
+ heading = None
1121
+ body = None
1122
+ directives: dict[str, str] = {}
1123
+ for child in children:
1124
+ if isinstance(child, SyntaxNode):
1125
+ if heading is None:
1126
+ heading = child
1127
+ else:
1128
+ body = child
1129
+ elif isinstance(child, list):
1130
+ body = child
1131
+ elif isinstance(child, dict):
1132
+ directives.update(child)
1133
+ elif isinstance(child, tuple):
1134
+ key, value = child
1135
+ if key:
1136
+ directives[key] = value
1137
+ elif is_token(child):
1138
+ if child.type == 'FORWARD':
1139
+ directives['forwarded'] = 'true'
1140
+ elif child.type == 'EXTERNAL':
1141
+ directives['external'] = 'true'
1142
+ if heading is None:
1143
+ return self._make_node(SyntaxNodeType.ntMethod, meta)
1144
+ if directives:
1145
+ self._apply_directives(heading, directives)
1146
+ if body is not None:
1147
+ if isinstance(body, list):
1148
+ for item in body:
1149
+ if isinstance(item, SyntaxNode):
1150
+ heading.add_child(item)
1151
+ elif isinstance(body, SyntaxNode):
1152
+ heading.add_child(body)
1153
+ return heading
1154
+
1155
+ def procedure_decl(self, meta: Any, *children: Any) -> SyntaxNode:
1156
+ return self._build_routine_from_children(meta, 'procedure', children)
1157
+
1158
+ def function_decl(self, meta: Any, *children: Any) -> SyntaxNode:
1159
+ return self._build_routine_from_children(meta, 'function', children)
1160
+
1161
+ def constructor_decl(self, meta: Any, *children: Any) -> SyntaxNode:
1162
+ return self._build_routine_from_children(meta, 'constructor', children)
1163
+
1164
+ def destructor_decl(self, meta: Any, *children: Any) -> SyntaxNode:
1165
+ return self._build_routine_from_children(meta, 'destructor', children)
1166
+
1167
+ def operator_decl(self, meta: Any, *children: Any) -> SyntaxNode:
1168
+ return self._build_routine_from_children(meta, 'operator', children)
1169
+
1170
+ def routine_body(self, meta: Any, *children: Any) -> SyntaxNode | None:
1171
+ for child in children:
1172
+ if isinstance(child, SyntaxNode):
1173
+ return child
1174
+ if isinstance(child, list):
1175
+ return child
1176
+ if is_token(child) and child.type == 'FORWARD':
1177
+ node = self._make_node(SyntaxNodeType.ntUnknown, meta)
1178
+ node.set_attribute(AttributeName.anForwarded, 'true')
1179
+ return node
1180
+ return None
1181
+
1182
+ def block(self, meta: Any, *children: Any) -> list[SyntaxNode]:
1183
+ nodes: list[SyntaxNode] = []
1184
+ for child in children:
1185
+ if isinstance(child, list):
1186
+ for item in child:
1187
+ if isinstance(item, SyntaxNode):
1188
+ nodes.append(item)
1189
+ elif isinstance(child, SyntaxNode):
1190
+ nodes.append(child)
1191
+ return nodes
1192
+
1193
+ def asm_block(self, meta: Any, *children: Any) -> list[SyntaxNode]:
1194
+ return self.block(meta, *children)
1195
+
1196
+ def directive_list(self, meta: Any, *children: Any) -> dict[str, str]:
1197
+ attrs: dict[str, str] = {}
1198
+ for child in children:
1199
+ if isinstance(child, tuple):
1200
+ key, value = child
1201
+ attrs[key] = value
1202
+ elif isinstance(child, dict):
1203
+ attrs.update(child)
1204
+ return attrs
1205
+
1206
+ def body_directive_list(self, meta: Any, *children: Any) -> dict[str, str]:
1207
+ return self.directive_list(meta, *children)
1208
+
1209
+ def body_directive(self, meta: Any, *children: Any) -> tuple[str, str]:
1210
+ return self.directive(meta, *children)
1211
+
1212
+ def routine_heading_directive_list(self, meta: Any, *children: Any) -> dict[str, str]:
1213
+ attrs: dict[str, str] = {}
1214
+ for child in children:
1215
+ if isinstance(child, tuple):
1216
+ key, value = child
1217
+ if key:
1218
+ attrs[key] = value
1219
+ return attrs
1220
+
1221
+ def routine_heading_directive(self, meta: Any, *children: Any) -> tuple[str, str]:
1222
+ return self.directive(meta, *children)
1223
+
1224
+ def directive(self, meta: Any, *children: Any) -> tuple[str, str]:
1225
+ token = None
1226
+ expr = None
1227
+ directive_tokens = {
1228
+ 'OVERLOAD',
1229
+ 'OVERRIDE',
1230
+ 'VIRTUAL',
1231
+ 'DYNAMIC',
1232
+ 'ABSTRACT',
1233
+ 'INLINE',
1234
+ 'REINTRODUCE',
1235
+ 'STATIC',
1236
+ 'FINAL',
1237
+ 'SEALED',
1238
+ 'STDCALL',
1239
+ 'CDECL',
1240
+ 'PASCAL',
1241
+ 'REGISTER',
1242
+ 'SAFECALL',
1243
+ 'WINAPI',
1244
+ 'MESSAGE',
1245
+ 'EXTERNAL',
1246
+ 'FORWARD',
1247
+ 'DEPRECATED',
1248
+ 'PLATFORM',
1249
+ 'EXPERIMENTAL',
1250
+ 'NORETURN',
1251
+ 'VARARGS',
1252
+ 'LOCAL',
1253
+ 'LIBRARY',
1254
+ 'DELAYED',
1255
+ 'EXPORT',
1256
+ 'FAR',
1257
+ 'NEAR',
1258
+ 'ASSEMBLER',
1259
+ 'UNSAFE',
1260
+ 'DISPID',
1261
+ }
1262
+ for child in children:
1263
+ if is_token(child) and token is None and child.type in directive_tokens:
1264
+ token = child
1265
+ elif isinstance(child, SyntaxNode):
1266
+ expr = child
1267
+ if token is None:
1268
+ return ('', '')
1269
+ name = token.type.lower()
1270
+ if name in {'override', 'virtual', 'dynamic'}:
1271
+ return ('methodbinding', name)
1272
+ if name in {'reintroduce', 'overload', 'abstract', 'inline'}:
1273
+ return (name, 'true')
1274
+ if name in {'stdcall', 'cdecl', 'pascal', 'register', 'safecall'}:
1275
+ return ('callingconvention', name)
1276
+ if name == 'winapi':
1277
+ return ('callingconvention', 'winapi')
1278
+ if name == 'message' and expr is not None:
1279
+ return ('message', self._expr_to_text(expr))
1280
+ if name == 'external':
1281
+ return ('external', 'true')
1282
+ if name == 'forward':
1283
+ return ('forwarded', 'true')
1284
+ if name == 'deprecated':
1285
+ return ('deprecated', self._expr_to_text(expr) if expr is not None else 'true')
1286
+ if name in {
1287
+ 'platform',
1288
+ 'experimental',
1289
+ 'varargs',
1290
+ 'local',
1291
+ 'library',
1292
+ 'delayed',
1293
+ 'static',
1294
+ 'final',
1295
+ 'sealed',
1296
+ 'export',
1297
+ 'far',
1298
+ 'near',
1299
+ 'assembler',
1300
+ 'unsafe',
1301
+ 'noreturn',
1302
+ }:
1303
+ return (name, 'true')
1304
+ if name == 'dispid' and expr is not None:
1305
+ return ('dispid', self._expr_to_text(expr))
1306
+ return ('', '')
1307
+
1308
+ def formal_parameters(self, meta: Any, *children: Any) -> SyntaxNode:
1309
+ node = self._make_node(SyntaxNodeType.ntParameters, meta)
1310
+ for child in children:
1311
+ for param in self._flatten(child):
1312
+ if isinstance(param, SyntaxNode):
1313
+ node.add_child(param)
1314
+ return node
1315
+
1316
+ def param_list(self, meta: Any, *children: Any) -> list[SyntaxNode]:
1317
+ params: list[SyntaxNode] = []
1318
+ for child in children:
1319
+ if isinstance(child, list):
1320
+ params.extend(child)
1321
+ return params
1322
+
1323
+ def param(self, meta: Any, *children: Any) -> list[SyntaxNode]:
1324
+ modifier = None
1325
+ names: list[str] = []
1326
+ type_node = None
1327
+ default_expr = None
1328
+ attributes: list[SyntaxNode] = []
1329
+ for child in children:
1330
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAttributes:
1331
+ attributes.append(child)
1332
+ elif self._is_text(child):
1333
+ names.append(child)
1334
+ elif isinstance(child, list):
1335
+ names = child
1336
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
1337
+ type_node = child
1338
+ elif is_token(child):
1339
+ modifier = child
1340
+ elif isinstance(child, SyntaxNode):
1341
+ default_expr = child
1342
+ params: list[SyntaxNode] = []
1343
+ for name in names:
1344
+ node = self._make_node(SyntaxNodeType.ntParameter, meta)
1345
+ if modifier is not None:
1346
+ node.set_attribute(AttributeName.anKind, modifier.value.lower())
1347
+ node.add_child(self._make_valued(SyntaxNodeType.ntName, name, meta))
1348
+ if type_node is not None:
1349
+ node.add_child(type_node.clone())
1350
+ for attr in attributes:
1351
+ node.add_child(attr)
1352
+ if default_expr is not None:
1353
+ value_node = self._make_node(SyntaxNodeType.ntValue, meta)
1354
+ value_node.add_child(default_expr)
1355
+ node.add_child(value_node)
1356
+ params.append(node)
1357
+ return params
1358
+
1359
+ def param_modifier(self, meta: Any, token: Any) -> Any:
1360
+ return token
1361
+
1362
+ def name_list(self, meta: Any, *children: Any) -> list[str]:
1363
+ return [token_value(child) for child in children]
1364
+
1365
+ def qualified_name(self, meta: Any, *children: Any) -> str:
1366
+ return '.'.join(token_value(child) for child in children)
1367
+
1368
+ def qualified_name_part(self, meta: Any, token: Any) -> str:
1369
+ return token_value(token)
1370
+
1371
+ def expr_identifier(self, meta: Any, token: Any) -> SyntaxNode:
1372
+ name = token_value(token)
1373
+ return self._make_expr_identifier(meta, name)
1374
+
1375
+ def expr_qualified_name(self, meta: Any, *children: Any) -> SyntaxNode:
1376
+ nodes: list[SyntaxNode] = []
1377
+ for child in children:
1378
+ if isinstance(child, list):
1379
+ for item in child:
1380
+ if isinstance(item, SyntaxNode):
1381
+ nodes.append(item)
1382
+ elif self._is_text(item) or is_token(item):
1383
+ nodes.append(self._make_expr_identifier(meta, token_value(item)))
1384
+ elif isinstance(child, SyntaxNode):
1385
+ nodes.append(child)
1386
+ elif self._is_text(child) or is_token(child):
1387
+ nodes.append(self._make_expr_identifier(meta, token_value(child)))
1388
+ if not nodes:
1389
+ return self._make_node(SyntaxNodeType.ntExpression, meta)
1390
+ node = nodes[0]
1391
+ for part in nodes[1:]:
1392
+ dot = self._make_node(SyntaxNodeType.ntDot, meta)
1393
+ dot.add_child(node)
1394
+ dot.add_child(part)
1395
+ node = dot
1396
+ return node
1397
+
1398
+ def literal(self, meta: Any, token: Any) -> SyntaxNode:
1399
+ if isinstance(token, SyntaxNode):
1400
+ return token
1401
+ value = token_value(token)
1402
+ node = self._make_valued(SyntaxNodeType.ntLiteral, value, meta)
1403
+ if is_token(token):
1404
+ if token.type in {'STRING_LITERAL', 'STRING_BLOCK3', 'STRING_BLOCK5'}:
1405
+ node.value = self._dequote_string(value)
1406
+ node.set_attribute(AttributeName.anType, 'string')
1407
+ elif token.type == 'POINTER_CHAR':
1408
+ node.set_attribute(AttributeName.anType, 'char')
1409
+ else:
1410
+ node.set_attribute(AttributeName.anType, 'numeric')
1411
+ return node
1412
+
1413
+ def string_literal_sequence(self, meta: Any, *children: Any) -> SyntaxNode:
1414
+ parts: list[str] = []
1415
+ for child in children:
1416
+ if not is_token(child):
1417
+ continue
1418
+ value = token_value(child)
1419
+ if child.type in {'STRING_LITERAL', 'STRING_BLOCK3', 'STRING_BLOCK5'}:
1420
+ parts.append(self._dequote_string(value))
1421
+ else:
1422
+ parts.append(value)
1423
+ node = self._make_valued(SyntaxNodeType.ntLiteral, ''.join(parts), meta)
1424
+ node.set_attribute(AttributeName.anType, 'string')
1425
+ return node
1426
+
1427
+ def string_literal_part(self, meta: Any, token: Any) -> Any:
1428
+ return token
1429
+
1430
+ def numeric_literal(self, meta: Any, token: Any) -> SyntaxNode:
1431
+ value = token_value(token)
1432
+ node = self._make_valued(SyntaxNodeType.ntLiteral, value, meta)
1433
+ node.set_attribute(AttributeName.anType, 'numeric')
1434
+ return node
1435
+
1436
+ def anonymous_method(self, meta: Any, *children: Any) -> SyntaxNode:
1437
+ kind = None
1438
+ params = None
1439
+ return_type = None
1440
+ body = None
1441
+ for child in children:
1442
+ if is_token(child) and child.type in {'PROCEDURE', 'FUNCTION'}:
1443
+ kind = child.type.lower()
1444
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntParameters:
1445
+ params = child
1446
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
1447
+ return_type = child
1448
+ elif isinstance(child, list):
1449
+ body = child
1450
+ elif isinstance(child, SyntaxNode):
1451
+ body = child
1452
+ node = self._make_node(SyntaxNodeType.ntAnonymousMethod, meta)
1453
+ if kind:
1454
+ node.set_attribute(AttributeName.anKind, kind)
1455
+ if params is not None:
1456
+ node.add_child(params)
1457
+ if return_type is not None:
1458
+ return_node = self._make_node(SyntaxNodeType.ntReturnType, meta)
1459
+ return_node.add_child(return_type)
1460
+ node.add_child(return_node)
1461
+ if body is not None:
1462
+ if isinstance(body, list):
1463
+ for item in body:
1464
+ if isinstance(item, SyntaxNode):
1465
+ node.add_child(item)
1466
+ elif isinstance(body, SyntaxNode):
1467
+ node.add_child(body)
1468
+ return node
1469
+
1470
+ def primary(self, meta: Any, child: Any) -> SyntaxNode:
1471
+ if isinstance(child, SyntaxNode):
1472
+ return child
1473
+ if is_token(child) and child.type == 'NIL':
1474
+ node = self._make_valued(SyntaxNodeType.ntLiteral, 'nil', meta)
1475
+ node.set_attribute(AttributeName.anType, 'nil')
1476
+ return node
1477
+ if is_token(child) and child.type in {'TRUE', 'FALSE'}:
1478
+ node = self._make_valued(SyntaxNodeType.ntLiteral, child.value.lower(), meta)
1479
+ node.set_attribute(AttributeName.anType, 'boolean')
1480
+ return node
1481
+ if is_token(child) and child.type == 'SELF':
1482
+ node = self._make_node(SyntaxNodeType.ntIdentifier, meta)
1483
+ node.set_attribute(AttributeName.anName, 'self')
1484
+ return node
1485
+ name = token_value(child)
1486
+ node = self._make_node(SyntaxNodeType.ntIdentifier, meta)
1487
+ node.set_attribute(AttributeName.anName, name)
1488
+ return node
1489
+
1490
+ def expr_list(self, meta: Any, *children: Any) -> list[SyntaxNode]:
1491
+ return [child for child in self._flatten(children) if isinstance(child, SyntaxNode)]
1492
+
1493
+ def if_expr(self, meta: Any, *children: Any) -> SyntaxNode:
1494
+ node = self._make_node(SyntaxNodeType.ntIf, meta)
1495
+ for child in children:
1496
+ if isinstance(child, SyntaxNode):
1497
+ node.add_child(child)
1498
+ return node
1499
+
1500
+ def or_expr(self, meta: Any, *children: Any) -> SyntaxNode:
1501
+ return self._binary_chain(meta, children, {'OR': SyntaxNodeType.ntOr})
1502
+
1503
+ def xor_expr(self, meta: Any, *children: Any) -> SyntaxNode:
1504
+ return self._binary_chain(meta, children, {'XOR': SyntaxNodeType.ntXor})
1505
+
1506
+ def and_expr(self, meta: Any, *children: Any) -> SyntaxNode:
1507
+ return self._binary_chain(meta, children, {'AND': SyntaxNodeType.ntAnd})
1508
+
1509
+ def rel_expr(self, meta: Any, *children: Any) -> SyntaxNode:
1510
+ return self._binary_chain(
1511
+ meta,
1512
+ children,
1513
+ {
1514
+ '=': SyntaxNodeType.ntEqual,
1515
+ '<>': SyntaxNodeType.ntNotEqual,
1516
+ '<': SyntaxNodeType.ntLower,
1517
+ '<=': SyntaxNodeType.ntLowerEqual,
1518
+ '>': SyntaxNodeType.ntGreater,
1519
+ '>=': SyntaxNodeType.ntGreaterEqual,
1520
+ 'IN': SyntaxNodeType.ntIn,
1521
+ 'IS': SyntaxNodeType.ntIs,
1522
+ 'NOT IN': SyntaxNodeType.ntNotIn,
1523
+ 'IS NOT': SyntaxNodeType.ntIsNot,
1524
+ 'AS': SyntaxNodeType.ntAs,
1525
+ },
1526
+ )
1527
+
1528
+ def rel_op(self, meta: Any, *children: Any) -> Any:
1529
+ if children:
1530
+ return children[0]
1531
+ return ''
1532
+
1533
+ def not_in_op(self, meta: Any, *_: Any) -> str:
1534
+ return 'NOT IN'
1535
+
1536
+ def is_not_op(self, meta: Any, *_: Any) -> str:
1537
+ return 'IS NOT'
1538
+
1539
+ def add_expr(self, meta: Any, *children: Any) -> SyntaxNode:
1540
+ return self._binary_chain(
1541
+ meta,
1542
+ children,
1543
+ {'+': SyntaxNodeType.ntAdd, '-': SyntaxNodeType.ntSub},
1544
+ )
1545
+
1546
+ def mul_expr(self, meta: Any, *children: Any) -> SyntaxNode:
1547
+ return self._binary_chain(
1548
+ meta,
1549
+ children,
1550
+ {
1551
+ '*': SyntaxNodeType.ntMul,
1552
+ '/': SyntaxNodeType.ntFDiv,
1553
+ 'DIV': SyntaxNodeType.ntDiv,
1554
+ 'MOD': SyntaxNodeType.ntMod,
1555
+ 'SHL': SyntaxNodeType.ntShl,
1556
+ 'SHR': SyntaxNodeType.ntShr,
1557
+ },
1558
+ )
1559
+
1560
+ def unary_expr(self, meta: Any, *children: Any) -> SyntaxNode:
1561
+ if len(children) == 2 and is_token(children[0]):
1562
+ token = children[0]
1563
+ expr = children[1]
1564
+ if token.type == 'NOT':
1565
+ node = self._make_node(SyntaxNodeType.ntNot, meta)
1566
+ node.add_child(expr)
1567
+ return node
1568
+ if token.value == '@':
1569
+ node = self._make_node(SyntaxNodeType.ntAddr, meta)
1570
+ node.add_child(expr)
1571
+ return node
1572
+ if token.value == '^':
1573
+ node = self._make_node(SyntaxNodeType.ntDeref, meta)
1574
+ node.add_child(expr)
1575
+ return node
1576
+ if token.value == '-':
1577
+ node = self._make_node(SyntaxNodeType.ntUnaryMinus, meta)
1578
+ node.add_child(expr)
1579
+ return node
1580
+ return expr
1581
+ if children:
1582
+ return children[0]
1583
+ return self._make_node(SyntaxNodeType.ntExpression, meta)
1584
+
1585
+ def postfix_expr(self, meta: Any, *children: Any) -> SyntaxNode:
1586
+ if not children:
1587
+ return self._make_node(SyntaxNodeType.ntExpression, meta)
1588
+ node = children[0]
1589
+ if not isinstance(node, SyntaxNode):
1590
+ node = self._ensure_expr_node(meta, node)
1591
+ for suffix in children[1:]:
1592
+ if isinstance(suffix, tuple) and suffix[0] == 'call':
1593
+ call_node = self._make_node(SyntaxNodeType.ntCall, meta)
1594
+ call_node.add_child(node)
1595
+ args = self._make_node(SyntaxNodeType.ntArguments, meta)
1596
+ call_args = suffix[1] if isinstance(suffix[1], list) else [suffix[1]]
1597
+ for arg in call_args:
1598
+ if isinstance(arg, SyntaxNode):
1599
+ args.add_child(arg)
1600
+ call_node.add_child(args)
1601
+ node = call_node
1602
+ elif isinstance(suffix, tuple) and suffix[0] == 'index':
1603
+ idx_node = self._make_node(SyntaxNodeType.ntIndexed, meta)
1604
+ idx_node.add_child(node)
1605
+ exprs = self._make_node(SyntaxNodeType.ntExpressions, meta)
1606
+ index_exprs = suffix[1] if isinstance(suffix[1], list) else [suffix[1]]
1607
+ for expr in index_exprs:
1608
+ if isinstance(expr, SyntaxNode):
1609
+ exprs.add_child(expr)
1610
+ idx_node.add_child(exprs)
1611
+ node = idx_node
1612
+ elif isinstance(suffix, tuple) and suffix[0] == 'field':
1613
+ dot_node = self._make_node(SyntaxNodeType.ntDot, meta)
1614
+ dot_node.add_child(node)
1615
+ name_node = self._make_expr_identifier(meta, suffix[1])
1616
+ dot_node.add_child(name_node)
1617
+ node = dot_node
1618
+ elif isinstance(suffix, tuple) and suffix[0] == 'deref':
1619
+ deref_node = self._make_node(SyntaxNodeType.ntDeref, meta)
1620
+ deref_node.add_child(node)
1621
+ node = deref_node
1622
+ return node
1623
+
1624
+ def call_suffix(self, meta: Any, *children: Any) -> tuple[str, list[SyntaxNode]]:
1625
+ args: list[SyntaxNode] = []
1626
+ for child in children:
1627
+ if isinstance(child, list):
1628
+ args.extend(child)
1629
+ return ('call', args)
1630
+
1631
+ def range_postfix(self, meta: Any, *children: Any) -> SyntaxNode:
1632
+ return self.postfix_expr(meta, *children)
1633
+
1634
+ def range_call_suffix(self, meta: Any, *children: Any) -> tuple[str, list[SyntaxNode]]:
1635
+ args: list[SyntaxNode] = []
1636
+ for child in children:
1637
+ if isinstance(child, list):
1638
+ args.extend(child)
1639
+ return ('call', args)
1640
+
1641
+ def range_arg_list(self, meta: Any, *children: Any) -> list[SyntaxNode]:
1642
+ return [child for child in children if isinstance(child, SyntaxNode)]
1643
+
1644
+ def range_primary(self, meta: Any, child: Any) -> SyntaxNode:
1645
+ if isinstance(child, SyntaxNode):
1646
+ return child
1647
+ if self._is_text(child):
1648
+ parts = [self._make_expr_identifier(meta, part) for part in child.split('.')]
1649
+ return self.expr_qualified_name(meta, *parts)
1650
+ return self._ensure_expr_node(meta, child)
1651
+
1652
+ def op_add(self, meta: Any) -> str:
1653
+ return '+'
1654
+
1655
+ def op_sub(self, meta: Any) -> str:
1656
+ return '-'
1657
+
1658
+ def op_mul(self, meta: Any) -> str:
1659
+ return '*'
1660
+
1661
+ def op_fdiv(self, meta: Any) -> str:
1662
+ return '/'
1663
+
1664
+ def op_div(self, meta: Any, *_: Any) -> str:
1665
+ return 'DIV'
1666
+
1667
+ def op_mod(self, meta: Any, *_: Any) -> str:
1668
+ return 'MOD'
1669
+
1670
+ def op_shl(self, meta: Any, *_: Any) -> str:
1671
+ return 'SHL'
1672
+
1673
+ def op_shr(self, meta: Any, *_: Any) -> str:
1674
+ return 'SHR'
1675
+
1676
+ def index_suffix(self, meta: Any, exprs: list[SyntaxNode]) -> tuple[str, list[SyntaxNode]]:
1677
+ return ('index', exprs)
1678
+
1679
+ def field_suffix(self, meta: Any, name: Any) -> tuple[str, str]:
1680
+ return ('field', token_value(name))
1681
+
1682
+ def deref_suffix(self, meta: Any, *_: Any) -> tuple[str, None]:
1683
+ return ('deref', None)
1684
+
1685
+ def variable_ref(self, meta: Any, name: str) -> SyntaxNode:
1686
+ return self._make_expr_identifier(meta, name)
1687
+
1688
+ def assignment(self, meta: Any, *children: Any) -> SyntaxNode:
1689
+ nodes: list[SyntaxNode] = []
1690
+ for child in children:
1691
+ if isinstance(child, SyntaxNode):
1692
+ nodes.append(child)
1693
+ continue
1694
+ if is_token(child) and child.type == 'ASSIGN':
1695
+ continue
1696
+ nodes.append(self._ensure_expr_node(meta, child))
1697
+ left = nodes[0] if len(nodes) > 0 else self._make_node(SyntaxNodeType.ntExpression, meta)
1698
+ right = nodes[1] if len(nodes) > 1 else self._make_node(SyntaxNodeType.ntExpression, meta)
1699
+ node = self._make_node(SyntaxNodeType.ntAssign, meta)
1700
+ lhs = self._make_node(SyntaxNodeType.ntLHS, meta)
1701
+ rhs = self._make_node(SyntaxNodeType.ntRHS, meta)
1702
+ lhs.add_child(left)
1703
+ rhs.add_child(right)
1704
+ node.add_child(lhs)
1705
+ node.add_child(rhs)
1706
+ return node
1707
+
1708
+ def address_assignment(self, meta: Any, *children: Any) -> SyntaxNode:
1709
+ nodes: list[SyntaxNode] = []
1710
+ for child in children:
1711
+ if is_token(child) and child.type == 'ASSIGN':
1712
+ continue
1713
+ if isinstance(child, SyntaxNode):
1714
+ nodes.append(child)
1715
+ elif is_token(child) and child.type in {'NIL', 'TRUE', 'FALSE', 'SELF'}:
1716
+ nodes.append(self.primary(meta, child))
1717
+ elif child is not None:
1718
+ nodes.append(self._ensure_expr_node(meta, child))
1719
+ target = nodes[0] if nodes else self._make_node(SyntaxNodeType.ntExpression, meta)
1720
+ value = nodes[1] if len(nodes) > 1 else self._make_node(SyntaxNodeType.ntExpression, meta)
1721
+ addr = self._make_node(SyntaxNodeType.ntAddr, meta)
1722
+ addr.add_child(target)
1723
+ return self.assignment(meta, addr, value)
1724
+
1725
+ def call_expr(self, meta: Any, name: str, *children: Any) -> SyntaxNode:
1726
+ node = self._make_node(SyntaxNodeType.ntCall, meta)
1727
+ target = self._make_node(SyntaxNodeType.ntIdentifier, meta)
1728
+ target.set_attribute(AttributeName.anName, name)
1729
+ node.add_child(target)
1730
+ args = self._make_node(SyntaxNodeType.ntArguments, meta)
1731
+ for child in children:
1732
+ if isinstance(child, list):
1733
+ for arg in child:
1734
+ args.add_child(arg)
1735
+ node.add_child(args)
1736
+ return node
1737
+
1738
+ def call_statement(self, meta: Any, node: SyntaxNode) -> SyntaxNode:
1739
+ return node
1740
+
1741
+ def inline_number(self, meta: Any, token: Any) -> SyntaxNode:
1742
+ return self.literal(meta, token)
1743
+
1744
+ def inline_statement(self, meta: Any, *children: Any) -> SyntaxNode:
1745
+ node = self._make_node(SyntaxNodeType.ntUnknown, meta)
1746
+ node.set_attribute(AttributeName.anKind, 'inline')
1747
+ for child in children:
1748
+ if isinstance(child, SyntaxNode):
1749
+ node.add_child(child)
1750
+ return node
1751
+
1752
+ def inline_const_section(self, meta: Any, *children: Any) -> SyntaxNode:
1753
+ node = self._make_node(SyntaxNodeType.ntConstants, meta)
1754
+ node.set_attribute(AttributeName.anKind, 'inline')
1755
+ for child in children:
1756
+ if isinstance(child, SyntaxNode):
1757
+ node.add_child(child)
1758
+ return node
1759
+
1760
+ def inline_const_decl(self, meta: Any, *children: Any) -> SyntaxNode:
1761
+ return self.const_decl(meta, *children)
1762
+
1763
+ def inline_var_section(self, meta: Any, *children: Any) -> SyntaxNode:
1764
+ node = self._make_node(SyntaxNodeType.ntVariables, meta)
1765
+ node.set_attribute(AttributeName.anKind, 'inline')
1766
+ for child in children:
1767
+ if isinstance(child, list):
1768
+ for item in child:
1769
+ if isinstance(item, SyntaxNode):
1770
+ node.add_child(item)
1771
+ elif isinstance(child, SyntaxNode):
1772
+ node.add_child(child)
1773
+ return node
1774
+
1775
+ def inline_var_decl(self, meta: Any, *children: Any) -> list[SyntaxNode]:
1776
+ names: list[str] = []
1777
+ type_node = None
1778
+ value_expr = None
1779
+ attributes: list[SyntaxNode] = []
1780
+ for child in children:
1781
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAttributes:
1782
+ attributes.append(child)
1783
+ elif isinstance(child, list):
1784
+ names = child
1785
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
1786
+ type_node = child
1787
+ elif isinstance(child, SyntaxNode):
1788
+ value_expr = child
1789
+ variables: list[SyntaxNode] = []
1790
+ for name in names:
1791
+ node = self._make_node(SyntaxNodeType.ntVariable, meta)
1792
+ node.add_child(self._make_valued(SyntaxNodeType.ntName, name, meta))
1793
+ if type_node is not None:
1794
+ node.add_child(type_node.clone())
1795
+ for attr in attributes:
1796
+ node.add_child(attr)
1797
+ if value_expr is not None:
1798
+ value_node = self._make_node(SyntaxNodeType.ntValue, meta)
1799
+ value_node.add_child(value_expr)
1800
+ node.add_child(value_node)
1801
+ variables.append(node)
1802
+ return variables
1803
+
1804
+ def argument(self, meta: Any, *children: Any) -> SyntaxNode:
1805
+ if children and (self._is_text(children[0]) or is_token(children[0])):
1806
+ name = token_value(children[0])
1807
+ expr = next((child for child in children[1:] if isinstance(child, SyntaxNode)), None)
1808
+ if expr is not None:
1809
+ node = self._make_node(SyntaxNodeType.ntNamedArgument, meta)
1810
+ node.set_attribute(AttributeName.anName, name)
1811
+ node.add_child(expr)
1812
+ return node
1813
+ node = self._make_node(SyntaxNodeType.ntPositionalArgument, meta)
1814
+ for child in children:
1815
+ if isinstance(child, SyntaxNode):
1816
+ node.add_child(child)
1817
+ return node
1818
+
1819
+ def formatted_argument(self, meta: Any, *children: Any) -> SyntaxNode:
1820
+ node = self._make_node(SyntaxNodeType.ntExpression, meta)
1821
+ node.set_attribute(AttributeName.anKind, 'format')
1822
+ for child in children:
1823
+ if isinstance(child, SyntaxNode):
1824
+ node.add_child(child)
1825
+ return node
1826
+
1827
+ def named_formatted_argument(self, meta: Any, name: Any, *children: Any) -> SyntaxNode:
1828
+ node = self._make_node(SyntaxNodeType.ntExpression, meta)
1829
+ node.set_attribute(AttributeName.anKind, 'format')
1830
+ node.add_child(self._make_expr_identifier(meta, token_value(name)))
1831
+ for child in children:
1832
+ if isinstance(child, SyntaxNode):
1833
+ node.add_child(child)
1834
+ return node
1835
+
1836
+ def statement_list(self, meta: Any, *children: Any) -> SyntaxNode:
1837
+ node = self._make_compound(SyntaxNodeType.ntStatements, meta)
1838
+ for child in children:
1839
+ if isinstance(child, SyntaxNode):
1840
+ node.add_child(child)
1841
+ elif isinstance(child, list):
1842
+ for item in child:
1843
+ if isinstance(item, SyntaxNode):
1844
+ node.add_child(item)
1845
+ return node
1846
+
1847
+ def compound_statement(self, meta: Any, *children: Any) -> SyntaxNode:
1848
+ node = self._make_compound(SyntaxNodeType.ntStatements, meta)
1849
+ for child in children:
1850
+ if isinstance(child, SyntaxNode):
1851
+ node.add_child(child)
1852
+ elif isinstance(child, list):
1853
+ for item in child:
1854
+ if isinstance(item, SyntaxNode):
1855
+ node.add_child(item)
1856
+ return node
1857
+
1858
+ def if_statement(self, meta: Any, *children: Any) -> SyntaxNode:
1859
+ node = self._make_node(SyntaxNodeType.ntIf, meta)
1860
+ for child in children:
1861
+ if isinstance(child, SyntaxNode):
1862
+ node.add_child(child)
1863
+ return node
1864
+
1865
+ def while_statement(self, meta: Any, *children: Any) -> SyntaxNode:
1866
+ node = self._make_node(SyntaxNodeType.ntWhile, meta)
1867
+ for child in children:
1868
+ if isinstance(child, SyntaxNode):
1869
+ node.add_child(child)
1870
+ return node
1871
+
1872
+ def for_statement(self, meta: Any, *children: Any) -> SyntaxNode:
1873
+ node = self._make_node(SyntaxNodeType.ntFor, meta)
1874
+ for child in children:
1875
+ if isinstance(child, SyntaxNode):
1876
+ node.add_child(child)
1877
+ return node
1878
+
1879
+ def for_init(self, meta: Any, *children: Any) -> SyntaxNode:
1880
+ name = None
1881
+ expr = None
1882
+ type_node = None
1883
+ is_var = any(is_token(child) and child.type == 'VAR' for child in children)
1884
+ for child in children:
1885
+ if self._is_text(child) or is_token(child):
1886
+ if is_token(child) and child.type == 'VAR':
1887
+ continue
1888
+ name = token_value(child)
1889
+ elif isinstance(child, SyntaxNode):
1890
+ if child.typ == SyntaxNodeType.ntType and type_node is None:
1891
+ type_node = child
1892
+ else:
1893
+ expr = child
1894
+ if is_var:
1895
+ node = self._make_node(SyntaxNodeType.ntVariable, meta)
1896
+ node.set_attribute(AttributeName.anKind, 'inline')
1897
+ if name is not None:
1898
+ node.add_child(self._make_valued(SyntaxNodeType.ntName, name, meta))
1899
+ if type_node is not None:
1900
+ node.add_child(type_node)
1901
+ if expr is not None:
1902
+ value_node = self._make_node(SyntaxNodeType.ntValue, meta)
1903
+ value_node.add_child(expr)
1904
+ node.add_child(value_node)
1905
+ return node
1906
+ assign = self._make_node(SyntaxNodeType.ntAssign, meta)
1907
+ lhs = self._make_node(SyntaxNodeType.ntLHS, meta)
1908
+ rhs = self._make_node(SyntaxNodeType.ntRHS, meta)
1909
+ if name is not None:
1910
+ ident = self._make_node(SyntaxNodeType.ntIdentifier, meta)
1911
+ ident.set_attribute(AttributeName.anName, name)
1912
+ lhs.add_child(ident)
1913
+ if expr is not None:
1914
+ rhs.add_child(expr)
1915
+ assign.add_child(lhs)
1916
+ assign.add_child(rhs)
1917
+ return assign
1918
+
1919
+ def for_in(self, meta: Any, *children: Any) -> SyntaxNode:
1920
+ name = None
1921
+ expr = None
1922
+ type_node = None
1923
+ is_var = any(is_token(child) and child.type == 'VAR' for child in children)
1924
+ for child in children:
1925
+ if self._is_text(child) or is_token(child):
1926
+ if is_token(child) and child.type == 'VAR':
1927
+ continue
1928
+ name = token_value(child)
1929
+ elif isinstance(child, SyntaxNode):
1930
+ if child.typ == SyntaxNodeType.ntType and type_node is None:
1931
+ type_node = child
1932
+ else:
1933
+ expr = child
1934
+ node = self._make_node(SyntaxNodeType.ntIn, meta)
1935
+ if is_var:
1936
+ var_node = self._make_node(SyntaxNodeType.ntVariable, meta)
1937
+ var_node.set_attribute(AttributeName.anKind, 'inline')
1938
+ if name is not None:
1939
+ var_node.add_child(self._make_valued(SyntaxNodeType.ntName, name, meta))
1940
+ if type_node is not None:
1941
+ var_node.add_child(type_node)
1942
+ node.add_child(var_node)
1943
+ elif name is not None:
1944
+ ident = self._make_node(SyntaxNodeType.ntIdentifier, meta)
1945
+ ident.set_attribute(AttributeName.anName, name)
1946
+ node.add_child(ident)
1947
+ if expr is not None:
1948
+ node.add_child(expr)
1949
+ return node
1950
+
1951
+ def repeat_statement(self, meta: Any, *children: Any) -> SyntaxNode:
1952
+ node = self._make_node(SyntaxNodeType.ntRepeat, meta)
1953
+ for child in children:
1954
+ if isinstance(child, SyntaxNode):
1955
+ node.add_child(child)
1956
+ return node
1957
+
1958
+ def case_statement(self, meta: Any, *children: Any) -> SyntaxNode:
1959
+ node = self._make_node(SyntaxNodeType.ntCase, meta)
1960
+ for child in children:
1961
+ if isinstance(child, SyntaxNode):
1962
+ node.add_child(child)
1963
+ return node
1964
+
1965
+ def case_selector_list(self, meta: Any, *children: Any) -> list[SyntaxNode]:
1966
+ return [child for child in self._flatten(children) if isinstance(child, SyntaxNode)]
1967
+
1968
+ def case_selector(self, meta: Any, *children: Any) -> SyntaxNode:
1969
+ node = self._make_node(SyntaxNodeType.ntCaseSelector, meta)
1970
+ for child in children:
1971
+ if isinstance(child, SyntaxNode):
1972
+ node.add_child(child)
1973
+ return node
1974
+
1975
+ def case_label_list(self, meta: Any, *children: Any) -> SyntaxNode:
1976
+ node = self._make_node(SyntaxNodeType.ntCaseLabels, meta)
1977
+ for child in children:
1978
+ if isinstance(child, SyntaxNode):
1979
+ node.add_child(child)
1980
+ return node
1981
+
1982
+ def case_label(self, meta: Any, *children: Any) -> SyntaxNode:
1983
+ node = self._make_node(SyntaxNodeType.ntCaseLabel, meta)
1984
+ for child in children:
1985
+ if isinstance(child, SyntaxNode):
1986
+ node.add_child(child)
1987
+ return node
1988
+
1989
+ def case_else(self, meta: Any, *children: Any) -> SyntaxNode:
1990
+ node = self._make_node(SyntaxNodeType.ntCaseElse, meta)
1991
+ for child in children:
1992
+ if isinstance(child, SyntaxNode):
1993
+ node.add_child(child)
1994
+ return node
1995
+
1996
+ def with_statement(self, meta: Any, *children: Any) -> SyntaxNode:
1997
+ node = self._make_node(SyntaxNodeType.ntWith, meta)
1998
+ exprs: list[SyntaxNode] = []
1999
+ statements: list[SyntaxNode] = []
2000
+ for child in children:
2001
+ if isinstance(child, list):
2002
+ for item in child:
2003
+ if isinstance(item, SyntaxNode):
2004
+ exprs.append(item)
2005
+ elif isinstance(child, SyntaxNode):
2006
+ statements.append(child)
2007
+ if statements and not exprs:
2008
+ exprs = statements[:-1]
2009
+ statements = statements[-1:]
2010
+ for stmt in statements:
2011
+ node.add_child(stmt)
2012
+ if exprs:
2013
+ exprs_node = self._make_node(SyntaxNodeType.ntExpressions, meta)
2014
+ for expr in exprs:
2015
+ exprs_node.add_child(expr)
2016
+ node.add_child(exprs_node)
2017
+ return node
2018
+
2019
+ def try_statement(self, meta: Any, *children: Any) -> SyntaxNode:
2020
+ node = self._make_node(SyntaxNodeType.ntTry, meta)
2021
+ for child in children:
2022
+ if isinstance(child, SyntaxNode):
2023
+ node.add_child(child)
2024
+ return node
2025
+
2026
+ def except_block(self, meta: Any, *children: Any) -> SyntaxNode:
2027
+ node = self._make_node(SyntaxNodeType.ntExcept, meta)
2028
+ for child in children:
2029
+ if isinstance(child, SyntaxNode):
2030
+ node.add_child(child)
2031
+ return node
2032
+
2033
+ def exception_handler(self, meta: Any, *children: Any) -> SyntaxNode:
2034
+ node = self._make_node(SyntaxNodeType.ntExceptionHandler, meta)
2035
+ for child in children:
2036
+ if isinstance(child, SyntaxNode):
2037
+ node.add_child(child)
2038
+ return node
2039
+
2040
+ def finally_block(self, meta: Any, *children: Any) -> SyntaxNode:
2041
+ node = self._make_node(SyntaxNodeType.ntFinally, meta)
2042
+ for child in children:
2043
+ if isinstance(child, SyntaxNode):
2044
+ node.add_child(child)
2045
+ return node
2046
+
2047
+ def raise_statement(self, meta: Any, *children: Any) -> SyntaxNode:
2048
+ node = self._make_node(SyntaxNodeType.ntRaise, meta)
2049
+ for child in children:
2050
+ if isinstance(child, SyntaxNode):
2051
+ node.add_child(child)
2052
+ return node
2053
+
2054
+ def goto_statement(self, meta: Any, *children: Any) -> SyntaxNode:
2055
+ node = self._make_node(SyntaxNodeType.ntGoto, meta)
2056
+ for child in children:
2057
+ if isinstance(child, SyntaxNode):
2058
+ node.add_child(child)
2059
+ elif self._is_text(child):
2060
+ node.set_attribute(AttributeName.anName, child)
2061
+ return node
2062
+
2063
+ def label_statement(self, meta: Any, *children: Any) -> SyntaxNode:
2064
+ node = self._make_node(SyntaxNodeType.ntStatement, meta)
2065
+ node.set_attribute(AttributeName.anKind, 'label')
2066
+ for child in children:
2067
+ if isinstance(child, SyntaxNode):
2068
+ node.add_child(child)
2069
+ elif self._is_text(child):
2070
+ name_node = self._make_node(SyntaxNodeType.ntLabel, meta)
2071
+ name_node.set_attribute(AttributeName.anName, child)
2072
+ node.add_child(name_node)
2073
+ return node
2074
+
2075
+ def inherited_statement(self, meta: Any, *children: Any) -> SyntaxNode:
2076
+ node = self._make_node(SyntaxNodeType.ntInherited, meta)
2077
+ for child in children:
2078
+ if isinstance(child, SyntaxNode):
2079
+ node.add_child(child)
2080
+ return node
2081
+
2082
+ def inherited_expr(self, meta: Any, *children: Any) -> SyntaxNode:
2083
+ return self.inherited_statement(meta, *children)
2084
+
2085
+ def break_statement(self, meta: Any, *_: Any) -> SyntaxNode:
2086
+ node = self._make_node(SyntaxNodeType.ntStatement, meta)
2087
+ node.set_attribute(AttributeName.anKind, 'break')
2088
+ return node
2089
+
2090
+ def continue_statement(self, meta: Any, *_: Any) -> SyntaxNode:
2091
+ node = self._make_node(SyntaxNodeType.ntStatement, meta)
2092
+ node.set_attribute(AttributeName.anKind, 'continue')
2093
+ return node
2094
+
2095
+ def exit_statement(self, meta: Any, *children: Any) -> SyntaxNode:
2096
+ node = self._make_node(SyntaxNodeType.ntStatement, meta)
2097
+ node.set_attribute(AttributeName.anKind, 'exit')
2098
+ for child in children:
2099
+ if isinstance(child, SyntaxNode):
2100
+ node.add_child(child)
2101
+ return node
2102
+
2103
+ def asm_statement(self, meta: Any, *children: Any) -> SyntaxNode:
2104
+ node = self._make_compound(SyntaxNodeType.ntStatements, meta)
2105
+ node.set_attribute(AttributeName.anType, 'asm')
2106
+ return node
2107
+
2108
+ def empty_statement(self, meta: Any) -> SyntaxNode:
2109
+ return self._make_node(SyntaxNodeType.ntEmptyStatement, meta)
2110
+
2111
+ def requires_clause(self, meta: Any, *children: Any) -> SyntaxNode:
2112
+ node = self._make_node(SyntaxNodeType.ntRequires, meta)
2113
+ for child in children:
2114
+ if isinstance(child, SyntaxNode):
2115
+ node.add_child(child)
2116
+ elif self._is_text(child):
2117
+ pkg = self._make_node(SyntaxNodeType.ntPackage, meta)
2118
+ pkg.set_attribute(AttributeName.anName, child)
2119
+ node.add_child(pkg)
2120
+ return node
2121
+
2122
+ def contains_clause(self, meta: Any, *children: Any) -> SyntaxNode:
2123
+ node = self._make_node(SyntaxNodeType.ntContains, meta)
2124
+ for child in children:
2125
+ if isinstance(child, SyntaxNode):
2126
+ node.add_child(child)
2127
+ return node
2128
+
2129
+ def contains_item(self, meta: Any, *children: Any) -> SyntaxNode:
2130
+ return self.uses_item(meta, *children)
2131
+
2132
+ def exports_section(self, meta: Any, *children: Any) -> SyntaxNode:
2133
+ node = self._make_node(SyntaxNodeType.ntExports, meta)
2134
+ for child in children:
2135
+ if isinstance(child, SyntaxNode):
2136
+ node.add_child(child)
2137
+ return node
2138
+
2139
+ def exports_item(self, meta: Any, *children: Any) -> SyntaxNode:
2140
+ node = self._make_node(SyntaxNodeType.ntElement, meta)
2141
+ for child in children:
2142
+ if isinstance(child, SyntaxNode):
2143
+ node.add_child(child)
2144
+ elif self._is_text(child):
2145
+ name_node = self._make_node(SyntaxNodeType.ntName, meta)
2146
+ name_node.set_attribute(AttributeName.anName, child)
2147
+ node.add_child(name_node)
2148
+ return node
2149
+
2150
+ def exports_specifier(self, meta: Any, *children: Any) -> SyntaxNode:
2151
+ node = self._make_node(SyntaxNodeType.ntUnknown, meta)
2152
+ for child in children:
2153
+ if isinstance(child, SyntaxNode):
2154
+ node.add_child(child)
2155
+ return node
2156
+
2157
+ def attribute_sections(self, meta: Any, *children: Any) -> SyntaxNode:
2158
+ node = self._make_node(SyntaxNodeType.ntAttributes, meta)
2159
+ for child in children:
2160
+ if isinstance(child, list):
2161
+ for item in child:
2162
+ if isinstance(item, SyntaxNode):
2163
+ node.add_child(item)
2164
+ elif isinstance(child, SyntaxNode):
2165
+ node.add_child(child)
2166
+ return node
2167
+
2168
+ def attribute_section(self, meta: Any, *children: Any) -> list[SyntaxNode]:
2169
+ return [child for child in children if isinstance(child, SyntaxNode)]
2170
+
2171
+ def attribute_name(self, meta: Any, *children: Any) -> str:
2172
+ for child in children:
2173
+ if self._is_text(child) or is_token(child):
2174
+ return token_value(child)
2175
+ return ''
2176
+
2177
+ def attribute_keyword(self, meta: Any, token: Any) -> str:
2178
+ return token_value(token)
2179
+
2180
+ def attribute(self, meta: Any, *children: Any) -> SyntaxNode:
2181
+ name = None
2182
+ args = None
2183
+ for child in children:
2184
+ if self._is_text(child) or is_token(child):
2185
+ name = token_value(child)
2186
+ elif isinstance(child, SyntaxNode):
2187
+ args = child
2188
+ node = self._make_node(SyntaxNodeType.ntAttribute, meta)
2189
+ if name is not None:
2190
+ node.set_attribute(AttributeName.anName, name)
2191
+ if args is not None:
2192
+ node.add_child(args)
2193
+ return node
2194
+
2195
+ def attribute_arguments(self, meta: Any, *children: Any) -> SyntaxNode:
2196
+ node = self._make_node(SyntaxNodeType.ntArguments, meta)
2197
+ for child in children:
2198
+ if isinstance(child, list):
2199
+ for arg in child:
2200
+ if isinstance(arg, SyntaxNode):
2201
+ node.add_child(arg)
2202
+ return node
2203
+
2204
+ def set_const(self, meta: Any, *children: Any) -> SyntaxNode:
2205
+ node = self._make_node(SyntaxNodeType.ntSet, meta)
2206
+ for child in children:
2207
+ if isinstance(child, list):
2208
+ for item in child:
2209
+ if isinstance(item, SyntaxNode):
2210
+ node.add_child(item)
2211
+ elif isinstance(child, SyntaxNode):
2212
+ node.add_child(child)
2213
+ return node
2214
+
2215
+ def set_element_list(self, meta: Any, *children: Any) -> list[SyntaxNode]:
2216
+ return [child for child in self._flatten(children) if isinstance(child, SyntaxNode)]
2217
+
2218
+ def set_element(self, meta: Any, *children: Any) -> SyntaxNode:
2219
+ nodes = [child for child in children if isinstance(child, SyntaxNode)]
2220
+ if len(nodes) == 2:
2221
+ subrange = self._make_node(SyntaxNodeType.ntSubrange, meta)
2222
+ subrange.add_child(nodes[0])
2223
+ subrange.add_child(nodes[1])
2224
+ return subrange
2225
+ if nodes:
2226
+ return nodes[0]
2227
+ return self._make_node(SyntaxNodeType.ntExpression, meta)
2228
+
2229
+ def array_const(self, meta: Any, *children: Any) -> SyntaxNode:
2230
+ node = self._make_node(SyntaxNodeType.ntExpressions, meta)
2231
+ for child in children:
2232
+ for item in self._flatten(child):
2233
+ if isinstance(item, SyntaxNode):
2234
+ node.add_child(item)
2235
+ return node
2236
+
2237
+ def const_value_list(self, meta: Any, *children: Any) -> list[SyntaxNode]:
2238
+ return [child for child in children if isinstance(child, SyntaxNode)]
2239
+
2240
+ def record_const(self, meta: Any, *children: Any) -> SyntaxNode:
2241
+ node = self._make_node(SyntaxNodeType.ntUnknown, meta)
2242
+ for child in children:
2243
+ if isinstance(child, SyntaxNode):
2244
+ node.add_child(child)
2245
+ return node
2246
+
2247
+ def record_const_item(self, meta: Any, *children: Any) -> SyntaxNode:
2248
+ node = self._make_node(SyntaxNodeType.ntValue, meta)
2249
+ for child in children:
2250
+ if isinstance(child, SyntaxNode):
2251
+ node.add_child(child)
2252
+ return node
2253
+
2254
+ def _build_routine(
2255
+ self,
2256
+ meta: Any,
2257
+ name: str,
2258
+ kind: str,
2259
+ return_type: SyntaxNode | None,
2260
+ children: Iterable[Any],
2261
+ ) -> SyntaxNode:
2262
+ node = self._make_compound(SyntaxNodeType.ntMethod, meta)
2263
+ node.set_attribute(AttributeName.anName, name)
2264
+ node.set_attribute(AttributeName.anKind, kind)
2265
+
2266
+ parameters = None
2267
+ directives = None
2268
+ body: Any = None
2269
+ for child in children:
2270
+ if isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntParameters:
2271
+ parameters = child
2272
+ elif isinstance(child, dict):
2273
+ directives = child
2274
+ elif isinstance(child, SyntaxNode):
2275
+ body = child
2276
+ elif isinstance(child, list):
2277
+ body = child
2278
+
2279
+ if parameters is not None:
2280
+ node.add_child(parameters)
2281
+ if return_type is not None:
2282
+ return_node = self._make_node(SyntaxNodeType.ntReturnType, meta)
2283
+ return_node.add_child(return_type)
2284
+ node.add_child(return_node)
2285
+ if directives:
2286
+ self._apply_directives(node, directives)
2287
+ if body is not None:
2288
+ if isinstance(body, list):
2289
+ for item in body:
2290
+ if isinstance(item, SyntaxNode):
2291
+ node.add_child(item)
2292
+ elif isinstance(body, SyntaxNode):
2293
+ node.add_child(body)
2294
+ return node
2295
+
2296
+ def _apply_directives(self, node: SyntaxNode, directives: dict[str, str]) -> None:
2297
+ for key, value in directives.items():
2298
+ attr = {
2299
+ 'methodbinding': AttributeName.anMethodBinding,
2300
+ 'reintroduce': AttributeName.anReintroduce,
2301
+ 'overload': AttributeName.anOverload,
2302
+ 'abstract': AttributeName.anAbstract,
2303
+ 'inline': AttributeName.anInline,
2304
+ 'callingconvention': AttributeName.anCallingConvention,
2305
+ 'forwarded': AttributeName.anForwarded,
2306
+ 'external': AttributeName.anExternal,
2307
+ 'deprecated': AttributeName.anDeprecated,
2308
+ 'static': AttributeName.anStatic,
2309
+ 'final': AttributeName.anFinal,
2310
+ 'sealed': AttributeName.anSealed,
2311
+ 'assembler': AttributeName.anAssembler,
2312
+ 'unsafe': AttributeName.anUnsafe,
2313
+ 'export': AttributeName.anExport,
2314
+ 'far': AttributeName.anFar,
2315
+ 'near': AttributeName.anNear,
2316
+ 'noreturn': AttributeName.anNoReturn,
2317
+ 'varargs': AttributeName.anVarArgs,
2318
+ }.get(key)
2319
+ if attr is not None:
2320
+ node.set_attribute(attr, value)
2321
+
2322
+ def _apply_decl_directives(self, node: SyntaxNode, directives: dict[str, str]) -> None:
2323
+ for key, value in directives.items():
2324
+ attr = {
2325
+ 'deprecated': AttributeName.anDeprecated,
2326
+ 'platform': AttributeName.anKind,
2327
+ 'experimental': AttributeName.anKind,
2328
+ 'library': AttributeName.anKind,
2329
+ }.get(key)
2330
+ if attr is None:
2331
+ continue
2332
+ if attr == AttributeName.anKind and value == 'true':
2333
+ node.set_attribute(attr, key)
2334
+ else:
2335
+ node.set_attribute(attr, value)
2336
+
2337
+ def _build_routine_from_children(
2338
+ self,
2339
+ meta: Any,
2340
+ kind: str,
2341
+ children: Iterable[Any],
2342
+ ) -> SyntaxNode:
2343
+ name = None
2344
+ params = None
2345
+ return_type = None
2346
+ type_params = None
2347
+ directives = None
2348
+ body = None
2349
+ attributes: list[SyntaxNode] = []
2350
+ is_class = False
2351
+ forwarded = False
2352
+ for child in children:
2353
+ if is_token(child) and child.type == 'CLASS':
2354
+ is_class = True
2355
+ elif is_token(child) and child.type == 'FORWARD':
2356
+ forwarded = True
2357
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntAttributes:
2358
+ attributes.append(child)
2359
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntTypeParams:
2360
+ type_params = child
2361
+ elif self._is_text(child):
2362
+ name = child
2363
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntParameters:
2364
+ params = child
2365
+ elif isinstance(child, SyntaxNode) and child.typ == SyntaxNodeType.ntType:
2366
+ return_type = child
2367
+ elif isinstance(child, dict):
2368
+ directives = child
2369
+ elif isinstance(child, SyntaxNode):
2370
+ body = child
2371
+ elif isinstance(child, list):
2372
+ body = child
2373
+ if name is None:
2374
+ name = kind
2375
+ if isinstance(name, str) and '<' in name:
2376
+ base_name, generic_args = self._split_generic_name(name)
2377
+ name = base_name
2378
+ if type_params is None and generic_args:
2379
+ type_params = self._type_params_from_generic_name(meta, generic_args)
2380
+ routine = self._build_routine(meta, name, kind, return_type, [params, directives, body])
2381
+ if is_class:
2382
+ routine.set_attribute(AttributeName.anClass, 'true')
2383
+ if forwarded:
2384
+ routine.set_attribute(AttributeName.anForwarded, 'true')
2385
+ for attr in attributes:
2386
+ routine.add_child(attr)
2387
+ if type_params is not None:
2388
+ routine.add_child(type_params)
2389
+ return routine
2390
+
2391
+ def _expr_to_text(self, node: SyntaxNode) -> str:
2392
+ if isinstance(node, ValuedSyntaxNode):
2393
+ return node.value
2394
+ name = node.get_attribute(AttributeName.anName)
2395
+ if name:
2396
+ return name
2397
+ return ''
2398
+
2399
+ def _split_generic_name(self, name: str) -> tuple[str, str]:
2400
+ if '<' in name:
2401
+ base, rest = name.split('<', 1)
2402
+ return base, f'<{rest}'
2403
+ return name, ''
2404
+
2405
+ def _type_params_from_generic_name(self, meta: Any, generic_args: str) -> SyntaxNode | None:
2406
+ if not generic_args.startswith('<') or not generic_args.endswith('>'):
2407
+ return None
2408
+ inner = generic_args[1:-1].strip()
2409
+ if not inner:
2410
+ return None
2411
+ parsed: list[dict[str, Any]] = []
2412
+ current_group_indices: list[int] = []
2413
+ for segment in self._split_top_level(inner, ';'):
2414
+ if not segment:
2415
+ continue
2416
+ left, right = self._split_first_top_level(segment, ':')
2417
+ if right:
2418
+ names = [part for part in self._split_top_level(left, ',') if part]
2419
+ constraints = [part for part in self._split_top_level(right, ',') if part]
2420
+ current_group_indices = []
2421
+ for name in names:
2422
+ entry = {'name': name, 'constraints': list(constraints)}
2423
+ parsed.append(entry)
2424
+ current_group_indices.append(len(parsed) - 1)
2425
+ continue
2426
+
2427
+ parts = [part for part in self._split_top_level(segment, ',') if part]
2428
+ if not parts:
2429
+ continue
2430
+ if parsed and all(self._looks_like_constraint_fragment(part) for part in parts):
2431
+ targets = current_group_indices if current_group_indices else [len(parsed) - 1]
2432
+ for index in targets:
2433
+ parsed[index]['constraints'].extend(parts)
2434
+ continue
2435
+
2436
+ current_group_indices = []
2437
+ for part in parts:
2438
+ parsed.append({'name': part, 'constraints': []})
2439
+ current_group_indices.append(len(parsed) - 1)
2440
+
2441
+ if not parsed:
2442
+ return None
2443
+ params = self._make_node(SyntaxNodeType.ntTypeParams, meta)
2444
+ for item in parsed:
2445
+ raw_name = item['name']
2446
+ type_param = self._make_node(SyntaxNodeType.ntTypeParam, meta)
2447
+ type_param.add_child(self._make_valued(SyntaxNodeType.ntName, raw_name, meta))
2448
+ constraints = item.get('constraints') or []
2449
+ if constraints:
2450
+ constraints_node = self._make_node(SyntaxNodeType.ntConstraints, meta)
2451
+ for constraint_text in constraints:
2452
+ constraints_node.add_child(self._constraint_node_from_text(meta, constraint_text))
2453
+ type_param.add_child(constraints_node)
2454
+ params.add_child(type_param)
2455
+ return params
2456
+
2457
+ def _split_first_top_level(self, text: str, delimiter: str) -> tuple[str, str]:
2458
+ angle = 0
2459
+ square = 0
2460
+ round_ = 0
2461
+ in_string = False
2462
+ i = 0
2463
+ while i < len(text):
2464
+ ch = text[i]
2465
+ if ch == "'":
2466
+ if in_string and i + 1 < len(text) and text[i + 1] == "'":
2467
+ i += 2
2468
+ continue
2469
+ in_string = not in_string
2470
+ i += 1
2471
+ continue
2472
+ if in_string:
2473
+ i += 1
2474
+ continue
2475
+ if ch == '<':
2476
+ angle += 1
2477
+ elif ch == '>':
2478
+ angle = max(0, angle - 1)
2479
+ elif ch == '[':
2480
+ square += 1
2481
+ elif ch == ']':
2482
+ square = max(0, square - 1)
2483
+ elif ch == '(':
2484
+ round_ += 1
2485
+ elif ch == ')':
2486
+ round_ = max(0, round_ - 1)
2487
+ elif ch == delimiter and angle == 0 and square == 0 and round_ == 0:
2488
+ return (text[:i].strip(), text[i + 1 :].strip())
2489
+ i += 1
2490
+ return (text.strip(), '')
2491
+
2492
+ def _split_top_level(self, text: str, delimiter: str) -> list[str]:
2493
+ parts: list[str] = []
2494
+ current: list[str] = []
2495
+ angle = 0
2496
+ square = 0
2497
+ round_ = 0
2498
+ in_string = False
2499
+ i = 0
2500
+ while i < len(text):
2501
+ ch = text[i]
2502
+ if ch == "'":
2503
+ current.append(ch)
2504
+ if in_string and i + 1 < len(text) and text[i + 1] == "'":
2505
+ current.append(text[i + 1])
2506
+ i += 2
2507
+ continue
2508
+ in_string = not in_string
2509
+ i += 1
2510
+ continue
2511
+ if not in_string:
2512
+ if ch == '<':
2513
+ angle += 1
2514
+ elif ch == '>':
2515
+ angle = max(0, angle - 1)
2516
+ elif ch == '[':
2517
+ square += 1
2518
+ elif ch == ']':
2519
+ square = max(0, square - 1)
2520
+ elif ch == '(':
2521
+ round_ += 1
2522
+ elif ch == ')':
2523
+ round_ = max(0, round_ - 1)
2524
+ elif ch == delimiter and angle == 0 and square == 0 and round_ == 0:
2525
+ part = ''.join(current).strip()
2526
+ if part:
2527
+ parts.append(part)
2528
+ current = []
2529
+ i += 1
2530
+ continue
2531
+ current.append(ch)
2532
+ i += 1
2533
+ part = ''.join(current).strip()
2534
+ if part:
2535
+ parts.append(part)
2536
+ return parts
2537
+
2538
+ def _looks_like_constraint_fragment(self, fragment: str) -> bool:
2539
+ token = fragment.strip().casefold()
2540
+ return token in {'class', 'record', 'constructor', 'interface', 'unmanaged'}
2541
+
2542
+ def _constraint_node_from_text(self, meta: Any, constraint_text: str) -> SyntaxNode:
2543
+ text = constraint_text.strip()
2544
+ lowered = text.casefold()
2545
+ if lowered == 'class':
2546
+ return self._make_node(SyntaxNodeType.ntClassConstraint, meta)
2547
+ if lowered == 'record':
2548
+ return self._make_node(SyntaxNodeType.ntRecordConstraint, meta)
2549
+ if lowered == 'constructor':
2550
+ return self._make_node(SyntaxNodeType.ntConstructorConstraint, meta)
2551
+ if lowered == 'interface':
2552
+ return self._make_node(SyntaxNodeType.ntInterfaceConstraint, meta)
2553
+ if lowered == 'unmanaged':
2554
+ return self._make_node(SyntaxNodeType.ntUnmanagedConstraint, meta)
2555
+ node = self._make_node(SyntaxNodeType.ntType, meta)
2556
+ node.set_attribute(AttributeName.anName, text)
2557
+ return node
2558
+
2559
+ def _dequote_string(self, value: str) -> str:
2560
+ if len(value) < 2:
2561
+ return value
2562
+ if value[0] != "'":
2563
+ return value
2564
+ if value[-1] == "'":
2565
+ inner = value[1:-1]
2566
+ else:
2567
+ inner = value[1:]
2568
+ return inner.replace("''", "'")
2569
+
2570
+ def _make_node(self, typ: SyntaxNodeType, meta: Any) -> SyntaxNode:
2571
+ node = SyntaxNode(typ)
2572
+ self._set_pos(node, meta)
2573
+ return node
2574
+
2575
+ def _make_compound(self, typ: SyntaxNodeType, meta: Any) -> CompoundSyntaxNode:
2576
+ node = CompoundSyntaxNode(typ)
2577
+ self._set_pos(node, meta)
2578
+ return node
2579
+
2580
+ def _make_valued(self, typ: SyntaxNodeType, value: str, meta: Any) -> ValuedSyntaxNode:
2581
+ node = ValuedSyntaxNode(typ)
2582
+ node.value = value
2583
+ self._set_pos(node, meta)
2584
+ return node
2585
+
2586
+ def _set_pos(self, node: SyntaxNode, meta: Any) -> None:
2587
+ if meta is None:
2588
+ return
2589
+ if getattr(meta, 'line', None) is not None:
2590
+ node.line = meta.line
2591
+ node.col = meta.column
2592
+ node.file_name = self.file_name
2593
+ if isinstance(node, CompoundSyntaxNode) and getattr(meta, 'end_line', None) is not None:
2594
+ node.end_line = meta.end_line
2595
+ node.end_col = meta.end_column
2596
+
2597
+ def _binary_chain(self, meta: Any, children: Any, mapping: dict[str, SyntaxNodeType]) -> SyntaxNode:
2598
+ items = list(children)
2599
+ if not items:
2600
+ return self._make_node(SyntaxNodeType.ntExpression, meta)
2601
+ node = items[0] if isinstance(items[0], SyntaxNode) else self._make_node(SyntaxNodeType.ntExpression, meta)
2602
+ idx = 1
2603
+ while idx < len(items):
2604
+ op = items[idx]
2605
+ rhs = items[idx + 1] if idx + 1 < len(items) else None
2606
+ op_key = op.value if is_token(op) else str(op)
2607
+ op_key = op_key.upper()
2608
+ op_type = mapping.get(op_key) or mapping.get(op_key.lower()) or mapping.get(op_key)
2609
+ if rhs is None or op_type is None or not isinstance(rhs, SyntaxNode):
2610
+ break
2611
+ op_node = self._make_node(op_type, meta)
2612
+ op_node.add_child(node)
2613
+ op_node.add_child(rhs)
2614
+ node = op_node
2615
+ idx += 2
2616
+ return node
2617
+
2618
+ def _ensure_expr_node(self, meta: Any, value: Any) -> SyntaxNode:
2619
+ if isinstance(value, SyntaxNode):
2620
+ return value
2621
+ name = token_value(value)
2622
+ return self._make_expr_identifier(meta, name)
2623
+
2624
+ def _make_expr_identifier(self, meta: Any, name: str) -> SyntaxNode:
2625
+ base, generic_args = self._split_generic_name(name)
2626
+ node = self._make_node(SyntaxNodeType.ntIdentifier, meta)
2627
+ node.set_attribute(AttributeName.anName, base)
2628
+ if generic_args:
2629
+ node.set_attribute(AttributeName.anGenericArgs, generic_args)
2630
+ return node
2631
+
2632
+ def _flatten(self, value: Any) -> Iterable[Any]:
2633
+ if isinstance(value, (list, tuple)):
2634
+ for item in value:
2635
+ yield from self._flatten(item)
2636
+ else:
2637
+ yield value
2638
+
2639
+ def _is_text(self, value: Any) -> bool:
2640
+ return isinstance(value, str) and not is_token(value)
2641
+
2642
+ def _proc_type_directive_attrs(self, values: Iterable[str]) -> dict[str, str]:
2643
+ attrs: dict[str, str] = {}
2644
+ for value in values:
2645
+ if value == 'winapi':
2646
+ attrs['callingconvention'] = 'winapi'
2647
+ elif value in {'cdecl', 'stdcall', 'pascal', 'register', 'safecall'}:
2648
+ attrs['callingconvention'] = value
2649
+ elif value == 'varargs':
2650
+ attrs['varargs'] = 'true'
2651
+ return attrs
2652
+
2653
+ def _extract_name(self, children: Iterable[Any], default: str) -> str:
2654
+ for child in self._flatten(children):
2655
+ if self._is_text(child):
2656
+ return child
2657
+ return default
2658
+
2659
+ def _build_program_root(self, meta: Any, kind: str, children: Iterable[Any]) -> SyntaxNode:
2660
+ name = self._extract_name(children, default=kind)
2661
+ root = self._make_node(SyntaxNodeType.ntUnit, meta)
2662
+ root.set_attribute(AttributeName.anName, name)
2663
+ root.set_attribute(AttributeName.anKind, kind)
2664
+ for child in children:
2665
+ if isinstance(child, SyntaxNode):
2666
+ root.add_child(child)
2667
+ elif isinstance(child, list):
2668
+ for item in child:
2669
+ if isinstance(item, SyntaxNode):
2670
+ root.add_child(item)
2671
+ return root
2672
+
2673
+ builder = Builder()
2674
+ return builder.transform(tree)