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.
- agent_codinglanguage_mapper/__init__.py +20 -0
- agent_codinglanguage_mapper/__main__.py +4 -0
- agent_codinglanguage_mapper/_version.py +2 -0
- agent_codinglanguage_mapper/adapters/__init__.py +4 -0
- agent_codinglanguage_mapper/adapters/delphi.py +822 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/__init__.py +6 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/comment_builder.py +29 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/consts.py +345 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/grammar.py +460 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/lark_builder.py +2674 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/lark_tokens.py +237 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/lsp_server.py +1832 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/nodes.py +371 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/parser.py +193 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/preprocessor.py +997 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/project_discovery.py +518 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/project_indexer.py +319 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/semantic.py +375 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/semantic_builder.py +1384 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/source_reader.py +17 -0
- agent_codinglanguage_mapper/adapters/delphi_frontend/workspace.py +67 -0
- agent_codinglanguage_mapper/adapters/tree_sitter.py +1722 -0
- agent_codinglanguage_mapper/cli.py +138 -0
- agent_codinglanguage_mapper/discovery.py +1328 -0
- agent_codinglanguage_mapper/indexer.py +1102 -0
- agent_codinglanguage_mapper/integration.py +186 -0
- agent_codinglanguage_mapper/lsp_server.py +413 -0
- agent_codinglanguage_mapper/lsp_service.py +447 -0
- agent_codinglanguage_mapper/mapper.py +596 -0
- agent_codinglanguage_mapper/models.py +101 -0
- agent_codinglanguage_mapper/protocol.py +152 -0
- agent_codinglanguage_mapper/rendering.py +153 -0
- agent_codinglanguage_mapper/templates/opencode/plugins/codebase_map.ts +191 -0
- agent_codinglanguage_mapper/templates/skill/SKILL.md +52 -0
- agent_codinglanguage_mapper/worker.py +29 -0
- agent_codinglanguage_mapper/workspace.py +114 -0
- agent_codinglanguage_mapper-1.0.0.dist-info/METADATA +383 -0
- agent_codinglanguage_mapper-1.0.0.dist-info/RECORD +42 -0
- agent_codinglanguage_mapper-1.0.0.dist-info/WHEEL +5 -0
- agent_codinglanguage_mapper-1.0.0.dist-info/entry_points.txt +2 -0
- agent_codinglanguage_mapper-1.0.0.dist-info/licenses/LICENSE +373 -0
- 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)
|