jaclang 0.8.0__py3-none-any.whl → 0.8.2__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.
Potentially problematic release.
This version of jaclang might be problematic. Click here for more details.
- jaclang/__init__.py +6 -0
- jaclang/cli/cli.py +23 -50
- jaclang/compiler/codeinfo.py +0 -1
- jaclang/compiler/jac.lark +14 -22
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +378 -531
- jaclang/compiler/passes/main/__init__.py +0 -14
- jaclang/compiler/passes/main/annex_pass.py +2 -8
- jaclang/compiler/passes/main/cfg_build_pass.py +39 -13
- jaclang/compiler/passes/main/def_impl_match_pass.py +14 -13
- jaclang/compiler/passes/main/def_use_pass.py +4 -7
- jaclang/compiler/passes/main/import_pass.py +6 -14
- jaclang/compiler/passes/main/inheritance_pass.py +2 -2
- jaclang/compiler/passes/main/pyast_gen_pass.py +428 -799
- jaclang/compiler/passes/main/pyast_load_pass.py +115 -311
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +8 -7
- jaclang/compiler/passes/main/sym_tab_build_pass.py +3 -3
- jaclang/compiler/passes/main/sym_tab_link_pass.py +6 -9
- jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/action/actions.jac +1 -5
- jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/main.jac +1 -8
- jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +5 -9
- jaclang/compiler/passes/main/tests/test_decl_impl_match_pass.py +7 -8
- jaclang/compiler/passes/main/tests/test_import_pass.py +5 -18
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -6
- jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -3
- jaclang/compiler/passes/main/tests/test_sym_tab_link_pass.py +20 -17
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +425 -216
- jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -0
- jaclang/compiler/passes/tool/tests/fixtures/archetype_frmt.jac +14 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +5 -4
- jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +6 -0
- jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +3 -3
- jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +9 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +18 -3
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
- jaclang/compiler/program.py +22 -66
- jaclang/compiler/tests/fixtures/fam.jac +2 -2
- jaclang/compiler/tests/fixtures/pkg_import_lib/__init__.jac +1 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/sub/__init__.jac +1 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/sub/helper.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/tools.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +5 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/helper.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/tools.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_main.jac +10 -0
- jaclang/compiler/tests/fixtures/pkg_import_main_py.jac +11 -0
- jaclang/compiler/tests/test_importer.py +30 -13
- jaclang/compiler/tests/test_parser.py +1 -0
- jaclang/compiler/unitree.py +488 -320
- jaclang/langserve/__init__.jac +1 -0
- jaclang/langserve/engine.jac +503 -0
- jaclang/langserve/sem_manager.jac +309 -0
- jaclang/langserve/server.jac +201 -0
- jaclang/langserve/tests/server_test/test_lang_serve.py +139 -48
- jaclang/langserve/tests/server_test/utils.py +35 -6
- jaclang/langserve/tests/session.jac +294 -0
- jaclang/langserve/tests/test_sem_tokens.py +2 -2
- jaclang/langserve/tests/test_server.py +8 -7
- jaclang/langserve/utils.jac +51 -30
- jaclang/runtimelib/archetype.py +128 -6
- jaclang/runtimelib/builtin.py +17 -14
- jaclang/runtimelib/importer.py +51 -76
- jaclang/runtimelib/machine.py +469 -305
- jaclang/runtimelib/meta_importer.py +86 -0
- jaclang/runtimelib/tests/fixtures/graph_purger.jac +24 -26
- jaclang/runtimelib/tests/fixtures/other_root_access.jac +25 -16
- jaclang/runtimelib/tests/fixtures/traversing_save.jac +7 -5
- jaclang/runtimelib/tests/test_jaseci.py +3 -1
- jaclang/runtimelib/utils.py +3 -3
- jaclang/tests/fixtures/arch_rel_import_creation.jac +23 -23
- jaclang/tests/fixtures/async_ability.jac +43 -10
- jaclang/tests/fixtures/async_function.jac +18 -0
- jaclang/tests/fixtures/async_walker.jac +17 -12
- jaclang/tests/fixtures/backward_edge_visit.jac +31 -0
- jaclang/tests/fixtures/builtin_printgraph.jac +85 -0
- jaclang/tests/fixtures/builtin_printgraph_json.jac +21 -0
- jaclang/tests/fixtures/builtin_printgraph_mermaid.jac +16 -0
- jaclang/tests/fixtures/chandra_bugs2.jac +20 -13
- jaclang/tests/fixtures/concurrency.jac +1 -1
- jaclang/tests/fixtures/create_dynamic_archetype.jac +25 -28
- jaclang/tests/fixtures/deep/deeper/deep_outer_import.jac +7 -4
- jaclang/tests/fixtures/deep/deeper/snd_lev.jac +2 -2
- jaclang/tests/fixtures/deep/deeper/snd_lev_dup.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +2 -2
- jaclang/tests/fixtures/deep/one_lev_dup.jac +4 -3
- jaclang/tests/fixtures/dynamic_archetype.jac +19 -12
- jaclang/tests/fixtures/edge_ability.jac +49 -0
- jaclang/tests/fixtures/foo.jac +14 -22
- jaclang/tests/fixtures/guess_game.jac +1 -1
- jaclang/tests/fixtures/here_usage_error.jac +21 -0
- jaclang/tests/fixtures/here_visitor_usage.jac +21 -0
- jaclang/tests/fixtures/jac_from_py.py +1 -1
- jaclang/tests/fixtures/jp_importer.jac +6 -6
- jaclang/tests/fixtures/jp_importer_auto.jac +5 -3
- jaclang/tests/fixtures/node_del.jac +30 -36
- jaclang/tests/fixtures/unicode_strings.jac +24 -0
- jaclang/tests/fixtures/visit_traversal.jac +47 -0
- jaclang/tests/fixtures/walker_update.jac +5 -7
- jaclang/tests/test_cli.py +12 -7
- jaclang/tests/test_language.py +218 -145
- jaclang/tests/test_reference.py +9 -4
- jaclang/tests/test_typecheck.py +13 -26
- jaclang/utils/helpers.py +14 -6
- jaclang/utils/lang_tools.py +9 -8
- jaclang/utils/module_resolver.py +23 -0
- jaclang/utils/tests/test_lang_tools.py +2 -1
- jaclang/utils/treeprinter.py +3 -4
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/METADATA +4 -3
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/RECORD +112 -94
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/WHEEL +1 -1
- jaclang/compiler/passes/main/tests/fixtures/main_err.jac +0 -6
- jaclang/compiler/passes/main/tests/fixtures/second_err.jac +0 -4
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +0 -644
- jaclang/compiler/passes/tool/tests/test_doc_ir_gen_pass.py +0 -29
- jaclang/langserve/__init__.py +0 -1
- jaclang/langserve/engine.py +0 -553
- jaclang/langserve/sem_manager.py +0 -383
- jaclang/langserve/server.py +0 -167
- jaclang/langserve/tests/session.py +0 -255
- jaclang/tests/fixtures/builtin_dotgen.jac +0 -42
- jaclang/tests/fixtures/builtin_dotgen_json.jac +0 -21
- jaclang/tests/fixtures/deep/deeper/__init__.jac +0 -1
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/entry_points.txt +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
This is a pass for generating DocIr for Jac code.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from typing import List, Optional
|
|
6
|
+
from typing import List, Optional, Sequence
|
|
7
7
|
|
|
8
8
|
import jaclang.compiler.passes.tool.doc_ir as doc
|
|
9
9
|
import jaclang.compiler.unitree as uni
|
|
@@ -78,26 +78,6 @@ class DocIRGenPass(UniPass):
|
|
|
78
78
|
|
|
79
79
|
return self.concat(result)
|
|
80
80
|
|
|
81
|
-
def _strip_trailing_ws(self, part: doc.DocType) -> doc.DocType:
|
|
82
|
-
"""Recursively strip trailing whitespace from a Doc node."""
|
|
83
|
-
if isinstance(part, doc.Concat) and part.parts:
|
|
84
|
-
while (
|
|
85
|
-
part.parts
|
|
86
|
-
and isinstance(part.parts[-1], doc.Text)
|
|
87
|
-
and getattr(part.parts[-1], "text", "") == " "
|
|
88
|
-
):
|
|
89
|
-
part.parts.pop()
|
|
90
|
-
if part.parts:
|
|
91
|
-
part.parts[-1] = self._strip_trailing_ws(part.parts[-1])
|
|
92
|
-
elif isinstance(part, (doc.Group, doc.Indent, doc.Align)):
|
|
93
|
-
part.contents = self._strip_trailing_ws(part.contents)
|
|
94
|
-
return part
|
|
95
|
-
|
|
96
|
-
def finalize(self, parts: List[doc.DocType], group: bool = True) -> doc.DocType:
|
|
97
|
-
"""Concat parts and remove trailing whitespace before grouping."""
|
|
98
|
-
result = self._strip_trailing_ws(self.concat(parts))
|
|
99
|
-
return self.group(result) if group else result
|
|
100
|
-
|
|
101
81
|
def is_one_line(self, node: uni.UniNode) -> bool:
|
|
102
82
|
"""Check if the node is a one line node."""
|
|
103
83
|
kid = [i for i in node.kid if not isinstance(i, uni.CommentToken)]
|
|
@@ -139,14 +119,15 @@ class DocIRGenPass(UniPass):
|
|
|
139
119
|
"""Exit import node."""
|
|
140
120
|
parts: list[doc.DocType] = []
|
|
141
121
|
for i in node.kid:
|
|
142
|
-
if isinstance(i, uni.
|
|
143
|
-
parts.
|
|
144
|
-
|
|
145
|
-
)
|
|
146
|
-
parts.append(self.line())
|
|
122
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
123
|
+
parts.pop()
|
|
124
|
+
parts.append(i.gen.doc_ir)
|
|
125
|
+
parts.append(self.space())
|
|
147
126
|
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
148
127
|
parts.pop()
|
|
149
128
|
parts.append(i.gen.doc_ir)
|
|
129
|
+
elif isinstance(i, uni.Token) and i.name == Tok.RBRACE:
|
|
130
|
+
parts.append(i.gen.doc_ir)
|
|
150
131
|
else:
|
|
151
132
|
parts.append(i.gen.doc_ir)
|
|
152
133
|
parts.append(self.space())
|
|
@@ -179,13 +160,45 @@ class DocIRGenPass(UniPass):
|
|
|
179
160
|
def exit_archetype(self, node: uni.Archetype) -> None:
|
|
180
161
|
"""Generate DocIR for archetypes."""
|
|
181
162
|
parts: list[doc.DocType] = []
|
|
163
|
+
body_parts: list[doc.DocType] = []
|
|
164
|
+
prev_item = None
|
|
165
|
+
in_body = False
|
|
182
166
|
for i in node.kid:
|
|
183
|
-
if i
|
|
167
|
+
if (node.doc and i is node.doc) or (
|
|
168
|
+
node.decorators and i in node.decorators
|
|
169
|
+
):
|
|
184
170
|
parts.append(i.gen.doc_ir)
|
|
185
171
|
parts.append(self.hard_line())
|
|
186
172
|
elif i == node.name:
|
|
187
173
|
parts.append(i.gen.doc_ir)
|
|
188
174
|
parts.append(self.space())
|
|
175
|
+
elif isinstance(i, uni.Token) and i.name == Tok.LBRACE:
|
|
176
|
+
parts.append(i.gen.doc_ir)
|
|
177
|
+
elif isinstance(i, uni.Token) and i.name == Tok.LPAREN:
|
|
178
|
+
parts.pop()
|
|
179
|
+
parts.append(i.gen.doc_ir)
|
|
180
|
+
elif isinstance(i, uni.Token) and i.name == Tok.RPAREN:
|
|
181
|
+
parts.pop()
|
|
182
|
+
parts.append(i.gen.doc_ir)
|
|
183
|
+
parts.append(self.space())
|
|
184
|
+
elif isinstance(node.body, Sequence) and i in node.body:
|
|
185
|
+
if not in_body:
|
|
186
|
+
body_parts.append(self.hard_line())
|
|
187
|
+
if (prev_item and type(prev_item) is not type(i)) or (
|
|
188
|
+
prev_item and not self.is_one_line(prev_item)
|
|
189
|
+
):
|
|
190
|
+
body_parts.append(self.hard_line())
|
|
191
|
+
body_parts.append(i.gen.doc_ir)
|
|
192
|
+
body_parts.append(self.hard_line())
|
|
193
|
+
prev_item = i
|
|
194
|
+
in_body = True
|
|
195
|
+
elif in_body:
|
|
196
|
+
in_body = False
|
|
197
|
+
body_parts.pop()
|
|
198
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
199
|
+
parts.append(self.hard_line())
|
|
200
|
+
parts.append(i.gen.doc_ir)
|
|
201
|
+
parts.append(self.space())
|
|
189
202
|
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
190
203
|
parts.pop()
|
|
191
204
|
parts.append(i.gen.doc_ir)
|
|
@@ -193,43 +206,85 @@ class DocIRGenPass(UniPass):
|
|
|
193
206
|
else:
|
|
194
207
|
parts.append(i.gen.doc_ir)
|
|
195
208
|
parts.append(self.space())
|
|
196
|
-
|
|
209
|
+
|
|
210
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
197
211
|
|
|
198
212
|
def exit_ability(self, node: uni.Ability) -> None:
|
|
199
213
|
"""Generate DocIR for abilities."""
|
|
200
214
|
parts: list[doc.DocType] = []
|
|
215
|
+
body_parts: list[doc.DocType] = []
|
|
216
|
+
in_body = False
|
|
201
217
|
for i in node.kid:
|
|
202
|
-
if i
|
|
218
|
+
if i == node.doc or (node.decorators and i in node.decorators):
|
|
203
219
|
parts.append(i.gen.doc_ir)
|
|
204
220
|
parts.append(self.hard_line())
|
|
205
221
|
elif i == node.name_ref:
|
|
206
222
|
parts.append(i.gen.doc_ir)
|
|
207
223
|
if not isinstance(node.signature, uni.FuncSignature):
|
|
208
224
|
parts.append(self.space())
|
|
225
|
+
elif isinstance(node.body, Sequence) and i in node.body:
|
|
226
|
+
if not in_body:
|
|
227
|
+
parts.pop()
|
|
228
|
+
body_parts.append(self.hard_line())
|
|
229
|
+
body_parts.append(i.gen.doc_ir)
|
|
230
|
+
body_parts.append(self.hard_line())
|
|
231
|
+
in_body = True
|
|
232
|
+
elif in_body:
|
|
233
|
+
in_body = False
|
|
234
|
+
body_parts.pop()
|
|
235
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
236
|
+
parts.append(self.hard_line())
|
|
237
|
+
parts.append(i.gen.doc_ir)
|
|
238
|
+
parts.append(self.space())
|
|
209
239
|
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
210
240
|
parts.pop()
|
|
211
241
|
parts.append(i.gen.doc_ir)
|
|
242
|
+
parts.append(self.space())
|
|
212
243
|
else:
|
|
213
244
|
parts.append(i.gen.doc_ir)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
node.gen.doc_ir = self.finalize(parts)
|
|
245
|
+
parts.append(self.space())
|
|
246
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
217
247
|
|
|
218
248
|
def exit_func_signature(self, node: uni.FuncSignature) -> None:
|
|
219
249
|
"""Generate DocIR for function signatures."""
|
|
220
250
|
parts: list[doc.DocType] = []
|
|
251
|
+
indent_parts: list[doc.DocType] = []
|
|
252
|
+
in_params = False
|
|
253
|
+
has_parens = False
|
|
221
254
|
for i in node.kid:
|
|
222
|
-
if isinstance(i, uni.Token) and i.name == Tok.LPAREN:
|
|
255
|
+
if isinstance(i, uni.Token) and i.name == Tok.LPAREN and node.params:
|
|
256
|
+
in_params = True
|
|
223
257
|
parts.append(i.gen.doc_ir)
|
|
224
|
-
elif i == node.params:
|
|
258
|
+
elif isinstance(i, uni.Token) and i.name == Tok.RPAREN and node.params:
|
|
259
|
+
in_params = False
|
|
260
|
+
has_parens = True
|
|
225
261
|
parts.append(
|
|
226
|
-
self.indent(self.concat([self.tight_line(),
|
|
262
|
+
self.indent(self.concat([self.tight_line(), *indent_parts]))
|
|
227
263
|
)
|
|
228
264
|
parts.append(self.tight_line())
|
|
265
|
+
parts.append(i.gen.doc_ir)
|
|
266
|
+
parts.append(self.space())
|
|
267
|
+
elif isinstance(i, uni.Token) and i.name == Tok.RPAREN:
|
|
268
|
+
parts.pop()
|
|
269
|
+
parts.append(i.gen.doc_ir)
|
|
270
|
+
parts.append(self.space())
|
|
271
|
+
elif in_params:
|
|
272
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
273
|
+
indent_parts.append(i.gen.doc_ir)
|
|
274
|
+
indent_parts.append(self.space())
|
|
275
|
+
else:
|
|
276
|
+
indent_parts.append(i.gen.doc_ir)
|
|
229
277
|
else:
|
|
278
|
+
if (
|
|
279
|
+
isinstance(i, uni.Token)
|
|
280
|
+
and i.name == Tok.RETURN_HINT
|
|
281
|
+
and not has_parens
|
|
282
|
+
):
|
|
283
|
+
parts.append(self.space())
|
|
230
284
|
parts.append(i.gen.doc_ir)
|
|
231
285
|
parts.append(self.space())
|
|
232
|
-
|
|
286
|
+
parts.pop()
|
|
287
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
233
288
|
|
|
234
289
|
def exit_param_var(self, node: uni.ParamVar) -> None:
|
|
235
290
|
"""Generate DocIR for parameter variables."""
|
|
@@ -241,51 +296,140 @@ class DocIRGenPass(UniPass):
|
|
|
241
296
|
parts.append(self.space())
|
|
242
297
|
else:
|
|
243
298
|
parts.append(i.gen.doc_ir)
|
|
244
|
-
node.gen.doc_ir = self.
|
|
299
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
245
300
|
|
|
246
301
|
def exit_type_ref(self, node: uni.TypeRef) -> None:
|
|
247
302
|
"""Generate DocIR for type references."""
|
|
248
303
|
parts: list[doc.DocType] = []
|
|
249
304
|
for i in node.kid:
|
|
250
305
|
parts.append(i.gen.doc_ir)
|
|
251
|
-
node.gen.doc_ir = self.
|
|
306
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
252
307
|
|
|
253
308
|
def exit_assignment(self, node: uni.Assignment) -> None:
|
|
254
309
|
"""Generate DocIR for assignments."""
|
|
310
|
+
lhs_parts: list[doc.DocType] = []
|
|
311
|
+
rhs_parts: list[doc.DocType] = []
|
|
312
|
+
eq_tok: Optional[doc.DocType] = None
|
|
313
|
+
seen_eq = False
|
|
314
|
+
|
|
315
|
+
for i in node.kid:
|
|
316
|
+
if isinstance(i, uni.Token) and i.name == Tok.KW_LET:
|
|
317
|
+
lhs_parts.append(i.gen.doc_ir)
|
|
318
|
+
lhs_parts.append(self.space())
|
|
319
|
+
elif isinstance(i, uni.Token) and i.name == Tok.EQ and not seen_eq:
|
|
320
|
+
eq_tok = i.gen.doc_ir
|
|
321
|
+
seen_eq = True
|
|
322
|
+
elif seen_eq:
|
|
323
|
+
rhs_parts.append(i.gen.doc_ir)
|
|
324
|
+
else:
|
|
325
|
+
if i == node.aug_op:
|
|
326
|
+
lhs_parts.append(self.space())
|
|
327
|
+
lhs_parts.append(i.gen.doc_ir)
|
|
328
|
+
if i == node.aug_op:
|
|
329
|
+
lhs_parts.append(self.space())
|
|
330
|
+
|
|
331
|
+
if eq_tok is not None:
|
|
332
|
+
rhs_concat = self.concat(rhs_parts)
|
|
333
|
+
node.gen.doc_ir = self.group(
|
|
334
|
+
self.concat(
|
|
335
|
+
[
|
|
336
|
+
*lhs_parts,
|
|
337
|
+
self.space(),
|
|
338
|
+
eq_tok,
|
|
339
|
+
self.indent(self.concat([self.line(), rhs_concat])),
|
|
340
|
+
]
|
|
341
|
+
)
|
|
342
|
+
)
|
|
343
|
+
else:
|
|
344
|
+
node.gen.doc_ir = self.group(self.concat(lhs_parts + rhs_parts))
|
|
345
|
+
|
|
346
|
+
def exit_if_stmt(self, node: uni.IfStmt) -> None:
|
|
347
|
+
"""Generate DocIR for if statements."""
|
|
255
348
|
parts: list[doc.DocType] = []
|
|
349
|
+
body_parts: list[doc.DocType] = []
|
|
350
|
+
in_body = False
|
|
256
351
|
for i in node.kid:
|
|
257
|
-
if isinstance(
|
|
352
|
+
if isinstance(node.body, Sequence) and i in node.body:
|
|
353
|
+
if not in_body:
|
|
354
|
+
parts.pop()
|
|
355
|
+
body_parts.append(self.hard_line())
|
|
356
|
+
body_parts.append(i.gen.doc_ir)
|
|
357
|
+
body_parts.append(self.hard_line())
|
|
358
|
+
in_body = True
|
|
359
|
+
elif in_body:
|
|
360
|
+
in_body = False
|
|
361
|
+
body_parts.pop()
|
|
362
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
363
|
+
parts.append(self.hard_line())
|
|
364
|
+
parts.append(i.gen.doc_ir)
|
|
365
|
+
parts.append(self.space())
|
|
366
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
258
367
|
parts.pop()
|
|
259
368
|
parts.append(i.gen.doc_ir)
|
|
260
369
|
parts.append(self.space())
|
|
261
370
|
else:
|
|
262
371
|
parts.append(i.gen.doc_ir)
|
|
263
372
|
parts.append(self.space())
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
def exit_if_stmt(self, node: uni.IfStmt) -> None:
|
|
267
|
-
"""Generate DocIR for if statements."""
|
|
268
|
-
parts: list[doc.DocType] = []
|
|
269
|
-
for i in node.kid:
|
|
270
|
-
parts.append(i.gen.doc_ir)
|
|
271
|
-
parts.append(self.space())
|
|
272
|
-
node.gen.doc_ir = self.finalize(parts)
|
|
373
|
+
parts.pop()
|
|
374
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
273
375
|
|
|
274
376
|
def exit_else_if(self, node: uni.ElseIf) -> None:
|
|
275
377
|
"""Generate DocIR for else if statements."""
|
|
276
378
|
parts: list[doc.DocType] = []
|
|
379
|
+
body_parts: list[doc.DocType] = []
|
|
380
|
+
in_body = False
|
|
277
381
|
for i in node.kid:
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
382
|
+
if isinstance(node.body, Sequence) and i in node.body:
|
|
383
|
+
if not in_body:
|
|
384
|
+
parts.pop()
|
|
385
|
+
body_parts.append(self.hard_line())
|
|
386
|
+
body_parts.append(i.gen.doc_ir)
|
|
387
|
+
body_parts.append(self.hard_line())
|
|
388
|
+
in_body = True
|
|
389
|
+
elif in_body:
|
|
390
|
+
in_body = False
|
|
391
|
+
body_parts.pop()
|
|
392
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
393
|
+
parts.append(self.hard_line())
|
|
394
|
+
parts.append(i.gen.doc_ir)
|
|
395
|
+
parts.append(self.space())
|
|
396
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
397
|
+
parts.pop()
|
|
398
|
+
parts.append(i.gen.doc_ir)
|
|
399
|
+
parts.append(self.space())
|
|
400
|
+
else:
|
|
401
|
+
parts.append(i.gen.doc_ir)
|
|
402
|
+
parts.append(self.space())
|
|
403
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
281
404
|
|
|
282
405
|
def exit_else_stmt(self, node: uni.ElseStmt) -> None:
|
|
283
406
|
"""Generate DocIR for else statements."""
|
|
284
407
|
parts: list[doc.DocType] = []
|
|
408
|
+
body_parts: list[doc.DocType] = []
|
|
409
|
+
in_body = False
|
|
285
410
|
for i in node.kid:
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
411
|
+
if isinstance(node.body, Sequence) and i in node.body:
|
|
412
|
+
if not in_body:
|
|
413
|
+
parts.pop()
|
|
414
|
+
body_parts.append(self.hard_line())
|
|
415
|
+
body_parts.append(i.gen.doc_ir)
|
|
416
|
+
body_parts.append(self.hard_line())
|
|
417
|
+
in_body = True
|
|
418
|
+
elif in_body:
|
|
419
|
+
in_body = False
|
|
420
|
+
body_parts.pop()
|
|
421
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
422
|
+
parts.append(self.hard_line())
|
|
423
|
+
parts.append(i.gen.doc_ir)
|
|
424
|
+
parts.append(self.space())
|
|
425
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
426
|
+
parts.pop()
|
|
427
|
+
parts.append(i.gen.doc_ir)
|
|
428
|
+
parts.append(self.space())
|
|
429
|
+
else:
|
|
430
|
+
parts.append(i.gen.doc_ir)
|
|
431
|
+
parts.append(self.space())
|
|
432
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
289
433
|
|
|
290
434
|
def exit_binary_expr(self, node: uni.BinaryExpr) -> None:
|
|
291
435
|
"""Generate DocIR for binary expressions."""
|
|
@@ -293,23 +437,14 @@ class DocIRGenPass(UniPass):
|
|
|
293
437
|
for i in node.kid:
|
|
294
438
|
parts.append(i.gen.doc_ir)
|
|
295
439
|
parts.append(self.space())
|
|
296
|
-
|
|
440
|
+
parts.pop()
|
|
441
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
297
442
|
|
|
298
443
|
def exit_expr_stmt(self, node: uni.ExprStmt) -> None:
|
|
299
444
|
"""Generate DocIR for expression statements."""
|
|
300
445
|
parts: list[doc.DocType] = []
|
|
301
|
-
is_fstring = (
|
|
302
|
-
node.parent
|
|
303
|
-
and isinstance(node.parent, uni.SubNodeList)
|
|
304
|
-
and node.parent.parent
|
|
305
|
-
and isinstance(node.parent.parent, uni.FString)
|
|
306
|
-
)
|
|
307
446
|
for i in node.kid:
|
|
308
|
-
if is_fstring:
|
|
309
|
-
parts.append(self.text("{"))
|
|
310
447
|
parts.append(i.gen.doc_ir)
|
|
311
|
-
if is_fstring:
|
|
312
|
-
parts.append(self.text("}"))
|
|
313
448
|
node.gen.doc_ir = self.group(self.concat(parts))
|
|
314
449
|
|
|
315
450
|
def exit_concurrent_expr(self, node: uni.ConcurrentExpr) -> None:
|
|
@@ -318,7 +453,7 @@ class DocIRGenPass(UniPass):
|
|
|
318
453
|
for i in node.kid:
|
|
319
454
|
parts.append(i.gen.doc_ir)
|
|
320
455
|
parts.append(self.space())
|
|
321
|
-
node.gen.doc_ir = self.
|
|
456
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
322
457
|
|
|
323
458
|
def exit_return_stmt(self, node: uni.ReturnStmt) -> None:
|
|
324
459
|
"""Generate DocIR for return statements."""
|
|
@@ -330,13 +465,32 @@ class DocIRGenPass(UniPass):
|
|
|
330
465
|
else:
|
|
331
466
|
parts.append(i.gen.doc_ir)
|
|
332
467
|
parts.append(self.space())
|
|
333
|
-
node.gen.doc_ir = self.
|
|
468
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
334
469
|
|
|
335
470
|
def exit_func_call(self, node: uni.FuncCall) -> None:
|
|
336
471
|
"""Generate DocIR for function calls."""
|
|
337
472
|
parts: list[doc.DocType] = []
|
|
473
|
+
indent_parts: list[doc.DocType] = []
|
|
474
|
+
in_params = False
|
|
338
475
|
for i in node.kid:
|
|
339
|
-
|
|
476
|
+
if isinstance(i, uni.Token) and i.name == Tok.LPAREN and node.params:
|
|
477
|
+
in_params = True
|
|
478
|
+
parts.append(i.gen.doc_ir)
|
|
479
|
+
elif isinstance(i, uni.Token) and i.name == Tok.RPAREN and node.params:
|
|
480
|
+
in_params = False
|
|
481
|
+
parts.append(
|
|
482
|
+
self.indent(self.concat([self.tight_line(), *indent_parts]))
|
|
483
|
+
)
|
|
484
|
+
parts.append(self.tight_line())
|
|
485
|
+
parts.append(i.gen.doc_ir)
|
|
486
|
+
elif in_params:
|
|
487
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
488
|
+
indent_parts.append(i.gen.doc_ir)
|
|
489
|
+
indent_parts.append(self.space())
|
|
490
|
+
else:
|
|
491
|
+
indent_parts.append(i.gen.doc_ir)
|
|
492
|
+
else:
|
|
493
|
+
parts.append(i.gen.doc_ir)
|
|
340
494
|
node.gen.doc_ir = self.group(self.concat(parts))
|
|
341
495
|
|
|
342
496
|
def exit_atom_trailer(self, node: uni.AtomTrailer) -> None:
|
|
@@ -350,8 +504,24 @@ class DocIRGenPass(UniPass):
|
|
|
350
504
|
"""Generate DocIR for list values."""
|
|
351
505
|
parts: list[doc.DocType] = []
|
|
352
506
|
for i in node.kid:
|
|
353
|
-
|
|
354
|
-
|
|
507
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
508
|
+
parts.append(i.gen.doc_ir)
|
|
509
|
+
parts.append(self.space())
|
|
510
|
+
else:
|
|
511
|
+
parts.append(i.gen.doc_ir)
|
|
512
|
+
not_broke = self.concat(parts)
|
|
513
|
+
parts = []
|
|
514
|
+
for i in node.kid:
|
|
515
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
516
|
+
parts.append(i.gen.doc_ir)
|
|
517
|
+
parts.append(self.hard_line())
|
|
518
|
+
elif isinstance(i, uni.Token) and i.name == Tok.LSQUARE:
|
|
519
|
+
parts.append(self.hard_line())
|
|
520
|
+
parts.append(i.gen.doc_ir)
|
|
521
|
+
else:
|
|
522
|
+
parts.append(i.gen.doc_ir)
|
|
523
|
+
broke = self.concat(parts)
|
|
524
|
+
node.gen.doc_ir = self.group(self.if_break(broke, not_broke))
|
|
355
525
|
|
|
356
526
|
def exit_dict_val(self, node: uni.DictVal) -> None:
|
|
357
527
|
"""Generate DocIR for dictionary values."""
|
|
@@ -363,7 +533,7 @@ class DocIRGenPass(UniPass):
|
|
|
363
533
|
else:
|
|
364
534
|
parts.append(i.gen.doc_ir)
|
|
365
535
|
parts.append(self.space())
|
|
366
|
-
node.gen.doc_ir = self.
|
|
536
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
367
537
|
|
|
368
538
|
def exit_k_v_pair(self, node: uni.KVPair) -> None:
|
|
369
539
|
"""Generate DocIR for key-value pairs."""
|
|
@@ -371,7 +541,8 @@ class DocIRGenPass(UniPass):
|
|
|
371
541
|
for i in node.kid:
|
|
372
542
|
parts.append(i.gen.doc_ir)
|
|
373
543
|
parts.append(self.space())
|
|
374
|
-
|
|
544
|
+
parts.pop()
|
|
545
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
375
546
|
|
|
376
547
|
def exit_has_var(self, node: uni.HasVar) -> None:
|
|
377
548
|
"""Generate DocIR for has variable declarations."""
|
|
@@ -395,16 +566,14 @@ class DocIRGenPass(UniPass):
|
|
|
395
566
|
if i == node.doc:
|
|
396
567
|
parts.append(i.gen.doc_ir)
|
|
397
568
|
parts.append(self.hard_line())
|
|
398
|
-
elif (
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
):
|
|
403
|
-
parts.append(self.align(i.gen.doc_ir))
|
|
569
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
570
|
+
parts.pop()
|
|
571
|
+
parts.append(i.gen.doc_ir)
|
|
572
|
+
parts.append(self.space())
|
|
404
573
|
else:
|
|
405
574
|
parts.append(i.gen.doc_ir)
|
|
406
575
|
parts.append(self.space())
|
|
407
|
-
node.gen.doc_ir = self.
|
|
576
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
408
577
|
|
|
409
578
|
def exit_while_stmt(self, node: uni.WhileStmt) -> None:
|
|
410
579
|
"""Generate DocIR for while statements."""
|
|
@@ -412,7 +581,7 @@ class DocIRGenPass(UniPass):
|
|
|
412
581
|
for i in node.kid:
|
|
413
582
|
parts.append(i.gen.doc_ir)
|
|
414
583
|
parts.append(self.space())
|
|
415
|
-
node.gen.doc_ir = self.
|
|
584
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
416
585
|
|
|
417
586
|
def exit_in_for_stmt(self, node: uni.InForStmt) -> None:
|
|
418
587
|
"""Generate DocIR for for-in statements."""
|
|
@@ -420,7 +589,7 @@ class DocIRGenPass(UniPass):
|
|
|
420
589
|
for i in node.kid:
|
|
421
590
|
parts.append(i.gen.doc_ir)
|
|
422
591
|
parts.append(self.space())
|
|
423
|
-
node.gen.doc_ir = self.
|
|
592
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
424
593
|
|
|
425
594
|
def exit_iter_for_stmt(self, node: uni.IterForStmt) -> None:
|
|
426
595
|
"""Generate DocIR for iterative for statements."""
|
|
@@ -428,7 +597,7 @@ class DocIRGenPass(UniPass):
|
|
|
428
597
|
for i in node.kid:
|
|
429
598
|
parts.append(i.gen.doc_ir)
|
|
430
599
|
parts.append(self.space())
|
|
431
|
-
node.gen.doc_ir = self.
|
|
600
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
432
601
|
|
|
433
602
|
def exit_try_stmt(self, node: uni.TryStmt) -> None:
|
|
434
603
|
"""Generate DocIR for try statements."""
|
|
@@ -436,7 +605,7 @@ class DocIRGenPass(UniPass):
|
|
|
436
605
|
for i in node.kid:
|
|
437
606
|
parts.append(i.gen.doc_ir)
|
|
438
607
|
parts.append(self.space())
|
|
439
|
-
node.gen.doc_ir = self.
|
|
608
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
440
609
|
|
|
441
610
|
def exit_except(self, node: uni.Except) -> None:
|
|
442
611
|
"""Generate DocIR for except clauses."""
|
|
@@ -444,7 +613,7 @@ class DocIRGenPass(UniPass):
|
|
|
444
613
|
for i in node.kid:
|
|
445
614
|
parts.append(i.gen.doc_ir)
|
|
446
615
|
parts.append(self.space())
|
|
447
|
-
node.gen.doc_ir = self.
|
|
616
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
448
617
|
|
|
449
618
|
def exit_finally_stmt(self, node: uni.FinallyStmt) -> None:
|
|
450
619
|
"""Generate DocIR for finally statements."""
|
|
@@ -452,14 +621,30 @@ class DocIRGenPass(UniPass):
|
|
|
452
621
|
for i in node.kid:
|
|
453
622
|
parts.append(i.gen.doc_ir)
|
|
454
623
|
parts.append(self.space())
|
|
455
|
-
node.gen.doc_ir = self.
|
|
624
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
456
625
|
|
|
457
626
|
def exit_tuple_val(self, node: uni.TupleVal) -> None:
|
|
458
627
|
"""Generate DocIR for tuple values."""
|
|
459
628
|
parts: list[doc.DocType] = []
|
|
460
629
|
for i in node.kid:
|
|
461
|
-
|
|
462
|
-
|
|
630
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
631
|
+
parts.append(i.gen.doc_ir)
|
|
632
|
+
parts.append(self.space())
|
|
633
|
+
else:
|
|
634
|
+
parts.append(i.gen.doc_ir)
|
|
635
|
+
not_broke = self.concat(parts)
|
|
636
|
+
parts = []
|
|
637
|
+
for i in node.kid:
|
|
638
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
639
|
+
parts.append(i.gen.doc_ir)
|
|
640
|
+
parts.append(self.hard_line())
|
|
641
|
+
elif isinstance(i, uni.Token) and i.name == Tok.LPAREN:
|
|
642
|
+
parts.append(self.hard_line())
|
|
643
|
+
parts.append(i.gen.doc_ir)
|
|
644
|
+
else:
|
|
645
|
+
parts.append(i.gen.doc_ir)
|
|
646
|
+
broke = self.concat(parts)
|
|
647
|
+
node.gen.doc_ir = self.group(self.if_break(broke, not_broke))
|
|
463
648
|
|
|
464
649
|
def exit_multi_string(self, node: uni.MultiString) -> None:
|
|
465
650
|
"""Generate DocIR for multiline strings."""
|
|
@@ -472,12 +657,7 @@ class DocIRGenPass(UniPass):
|
|
|
472
657
|
"""Generate DocIR for set values."""
|
|
473
658
|
parts: list[doc.DocType] = []
|
|
474
659
|
for i in node.kid:
|
|
475
|
-
|
|
476
|
-
parts.append(i.gen.doc_ir)
|
|
477
|
-
elif isinstance(i, uni.SubNodeList):
|
|
478
|
-
parts.append(self.if_break(self.line(), self.space()))
|
|
479
|
-
parts.append(i.gen.doc_ir)
|
|
480
|
-
parts.append(self.if_break(self.line(), self.space()))
|
|
660
|
+
parts.append(i.gen.doc_ir)
|
|
481
661
|
|
|
482
662
|
node.gen.doc_ir = self.group(self.concat(parts))
|
|
483
663
|
|
|
@@ -487,7 +667,8 @@ class DocIRGenPass(UniPass):
|
|
|
487
667
|
for i in node.kid:
|
|
488
668
|
parts.append(i.gen.doc_ir)
|
|
489
669
|
parts.append(self.space())
|
|
490
|
-
|
|
670
|
+
parts.pop()
|
|
671
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
491
672
|
|
|
492
673
|
def exit_list_compr(self, node: uni.ListCompr) -> None:
|
|
493
674
|
"""Generate DocIR for list comprehensions."""
|
|
@@ -495,7 +676,8 @@ class DocIRGenPass(UniPass):
|
|
|
495
676
|
for i in node.kid:
|
|
496
677
|
parts.append(i.gen.doc_ir)
|
|
497
678
|
parts.append(self.space())
|
|
498
|
-
|
|
679
|
+
parts.pop()
|
|
680
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
499
681
|
|
|
500
682
|
def exit_inner_compr(self, node: uni.InnerCompr) -> None:
|
|
501
683
|
"""Generate DocIR for inner comprehension clauses."""
|
|
@@ -503,7 +685,8 @@ class DocIRGenPass(UniPass):
|
|
|
503
685
|
for i in node.kid:
|
|
504
686
|
parts.append(i.gen.doc_ir)
|
|
505
687
|
parts.append(self.space())
|
|
506
|
-
|
|
688
|
+
parts.pop()
|
|
689
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
507
690
|
|
|
508
691
|
def exit_f_string(self, node: uni.FString) -> None:
|
|
509
692
|
"""Generate DocIR for formatted strings."""
|
|
@@ -526,7 +709,7 @@ class DocIRGenPass(UniPass):
|
|
|
526
709
|
else:
|
|
527
710
|
parts.append(i.gen.doc_ir)
|
|
528
711
|
parts.append(self.space())
|
|
529
|
-
|
|
712
|
+
parts.pop()
|
|
530
713
|
node.gen.doc_ir = self.group(self.concat(parts))
|
|
531
714
|
|
|
532
715
|
def exit_bool_expr(self, node: uni.BoolExpr) -> None:
|
|
@@ -539,7 +722,6 @@ class DocIRGenPass(UniPass):
|
|
|
539
722
|
else:
|
|
540
723
|
parts.append(i.gen.doc_ir)
|
|
541
724
|
parts.append(self.line()) # Potential break
|
|
542
|
-
|
|
543
725
|
node.gen.doc_ir = self.group(self.concat(parts))
|
|
544
726
|
|
|
545
727
|
def exit_unary_expr(self, node: uni.UnaryExpr) -> None:
|
|
@@ -605,7 +787,8 @@ class DocIRGenPass(UniPass):
|
|
|
605
787
|
for i in node.kid:
|
|
606
788
|
parts.append(i.gen.doc_ir)
|
|
607
789
|
parts.append(self.space())
|
|
608
|
-
|
|
790
|
+
parts.pop()
|
|
791
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
609
792
|
|
|
610
793
|
def exit_gen_compr(self, node: uni.GenCompr) -> None:
|
|
611
794
|
"""Generate DocIR for generator comprehensions."""
|
|
@@ -613,7 +796,8 @@ class DocIRGenPass(UniPass):
|
|
|
613
796
|
for i in node.kid:
|
|
614
797
|
parts.append(i.gen.doc_ir)
|
|
615
798
|
parts.append(self.space())
|
|
616
|
-
|
|
799
|
+
parts.pop()
|
|
800
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
617
801
|
|
|
618
802
|
def exit_set_compr(self, node: uni.SetCompr) -> None:
|
|
619
803
|
"""Generate DocIR for set comprehensions."""
|
|
@@ -621,7 +805,8 @@ class DocIRGenPass(UniPass):
|
|
|
621
805
|
for i in node.kid:
|
|
622
806
|
parts.append(i.gen.doc_ir)
|
|
623
807
|
parts.append(self.space())
|
|
624
|
-
|
|
808
|
+
parts.pop()
|
|
809
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
625
810
|
|
|
626
811
|
def exit_dict_compr(self, node: uni.DictCompr) -> None:
|
|
627
812
|
"""Generate DocIR for dictionary comprehensions."""
|
|
@@ -632,14 +817,15 @@ class DocIRGenPass(UniPass):
|
|
|
632
817
|
else:
|
|
633
818
|
parts.append(i.gen.doc_ir)
|
|
634
819
|
parts.append(self.space())
|
|
635
|
-
|
|
820
|
+
parts.pop()
|
|
821
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
636
822
|
|
|
637
823
|
def exit_k_w_pair(self, node: uni.KWPair) -> None:
|
|
638
824
|
"""Generate DocIR for keyword arguments."""
|
|
639
825
|
parts: list[doc.DocType] = []
|
|
640
826
|
for i in node.kid:
|
|
641
827
|
parts.append(i.gen.doc_ir)
|
|
642
|
-
node.gen.doc_ir = self.
|
|
828
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
643
829
|
|
|
644
830
|
def exit_await_expr(self, node: uni.AwaitExpr) -> None:
|
|
645
831
|
"""Generate DocIR for await expressions."""
|
|
@@ -647,7 +833,8 @@ class DocIRGenPass(UniPass):
|
|
|
647
833
|
for i in node.kid:
|
|
648
834
|
parts.append(i.gen.doc_ir)
|
|
649
835
|
parts.append(self.space())
|
|
650
|
-
|
|
836
|
+
parts.pop()
|
|
837
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
651
838
|
|
|
652
839
|
def exit_yield_expr(self, node: uni.YieldExpr) -> None:
|
|
653
840
|
"""Generate DocIR for yield expressions."""
|
|
@@ -655,7 +842,8 @@ class DocIRGenPass(UniPass):
|
|
|
655
842
|
for i in node.kid:
|
|
656
843
|
parts.append(i.gen.doc_ir)
|
|
657
844
|
parts.append(self.space())
|
|
658
|
-
|
|
845
|
+
parts.pop()
|
|
846
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
659
847
|
|
|
660
848
|
def exit_ctrl_stmt(self, node: uni.CtrlStmt) -> None:
|
|
661
849
|
"""Generate DocIR for control statements (break, continue, skip)."""
|
|
@@ -670,7 +858,8 @@ class DocIRGenPass(UniPass):
|
|
|
670
858
|
for i in node.kid:
|
|
671
859
|
parts.append(i.gen.doc_ir)
|
|
672
860
|
parts.append(self.space())
|
|
673
|
-
|
|
861
|
+
parts.pop()
|
|
862
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
674
863
|
|
|
675
864
|
def exit_disengage_stmt(self, node: uni.DisengageStmt) -> None:
|
|
676
865
|
"""Generate DocIR for disengage statements."""
|
|
@@ -685,7 +874,8 @@ class DocIRGenPass(UniPass):
|
|
|
685
874
|
for i in node.kid:
|
|
686
875
|
parts.append(i.gen.doc_ir)
|
|
687
876
|
parts.append(self.space())
|
|
688
|
-
|
|
877
|
+
parts.pop()
|
|
878
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
689
879
|
|
|
690
880
|
def exit_assert_stmt(self, node: uni.AssertStmt) -> None:
|
|
691
881
|
"""Generate DocIR for assert statements."""
|
|
@@ -693,7 +883,8 @@ class DocIRGenPass(UniPass):
|
|
|
693
883
|
for i in node.kid:
|
|
694
884
|
parts.append(i.gen.doc_ir)
|
|
695
885
|
parts.append(self.space())
|
|
696
|
-
|
|
886
|
+
parts.pop()
|
|
887
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
697
888
|
|
|
698
889
|
def exit_raise_stmt(self, node: uni.RaiseStmt) -> None:
|
|
699
890
|
"""Generate DocIR for raise statements."""
|
|
@@ -701,7 +892,8 @@ class DocIRGenPass(UniPass):
|
|
|
701
892
|
for i in node.kid:
|
|
702
893
|
parts.append(i.gen.doc_ir)
|
|
703
894
|
parts.append(self.space())
|
|
704
|
-
|
|
895
|
+
parts.pop()
|
|
896
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
705
897
|
|
|
706
898
|
def exit_global_vars(self, node: uni.GlobalVars) -> None:
|
|
707
899
|
"""Generate DocIR for global variables."""
|
|
@@ -717,26 +909,45 @@ class DocIRGenPass(UniPass):
|
|
|
717
909
|
else:
|
|
718
910
|
parts.append(i.gen.doc_ir)
|
|
719
911
|
parts.append(self.space())
|
|
720
|
-
node.gen.doc_ir = self.
|
|
912
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
721
913
|
|
|
722
914
|
def exit_module_code(self, node: uni.ModuleCode) -> None:
|
|
723
915
|
"""Generate DocIR for module code."""
|
|
724
916
|
parts: list[doc.DocType] = []
|
|
917
|
+
body_parts: list[doc.DocType] = []
|
|
918
|
+
in_body = False
|
|
725
919
|
for i in node.kid:
|
|
726
|
-
if i
|
|
920
|
+
if node.doc and i is node.doc:
|
|
727
921
|
parts.append(i.gen.doc_ir)
|
|
728
922
|
parts.append(self.hard_line())
|
|
729
|
-
elif
|
|
923
|
+
elif i == node.name:
|
|
924
|
+
parts.append(i.gen.doc_ir)
|
|
925
|
+
parts.append(self.space())
|
|
926
|
+
elif isinstance(node.body, Sequence) and i in node.body:
|
|
927
|
+
if not in_body:
|
|
928
|
+
parts.pop()
|
|
929
|
+
body_parts.append(self.hard_line())
|
|
930
|
+
body_parts.append(i.gen.doc_ir)
|
|
931
|
+
body_parts.append(self.hard_line())
|
|
932
|
+
in_body = True
|
|
933
|
+
elif in_body:
|
|
934
|
+
in_body = False
|
|
935
|
+
body_parts.pop()
|
|
936
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
937
|
+
parts.append(self.hard_line())
|
|
938
|
+
parts.append(i.gen.doc_ir)
|
|
939
|
+
parts.append(self.space())
|
|
940
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
941
|
+
parts.pop()
|
|
730
942
|
parts.append(i.gen.doc_ir)
|
|
731
943
|
parts.append(self.space())
|
|
732
944
|
else:
|
|
733
|
-
parts.append(
|
|
734
|
-
|
|
945
|
+
parts.append(i.gen.doc_ir)
|
|
946
|
+
parts.append(self.space())
|
|
735
947
|
node.gen.doc_ir = self.group(self.concat(parts))
|
|
736
948
|
|
|
737
949
|
def exit_global_stmt(self, node: uni.GlobalStmt) -> None:
|
|
738
950
|
"""Generate DocIR for global statements."""
|
|
739
|
-
# node.kid is [GLOBAL_OP_token, name_list_SubNodeList, SEMI_token]
|
|
740
951
|
parts: list[doc.DocType] = []
|
|
741
952
|
for i in node.kid:
|
|
742
953
|
parts.append(i.gen.doc_ir)
|
|
@@ -748,7 +959,7 @@ class DocIRGenPass(UniPass):
|
|
|
748
959
|
for i in node.kid:
|
|
749
960
|
parts.append(i.gen.doc_ir)
|
|
750
961
|
parts.append(self.space())
|
|
751
|
-
node.gen.doc_ir = self.
|
|
962
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
752
963
|
|
|
753
964
|
def exit_visit_stmt(self, node: uni.VisitStmt) -> None:
|
|
754
965
|
"""Generate DocIR for visit statements."""
|
|
@@ -761,7 +972,7 @@ class DocIRGenPass(UniPass):
|
|
|
761
972
|
else:
|
|
762
973
|
parts.append(i.gen.doc_ir)
|
|
763
974
|
parts.append(self.space())
|
|
764
|
-
node.gen.doc_ir = self.
|
|
975
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
765
976
|
|
|
766
977
|
def exit_ignore_stmt(self, node: uni.IgnoreStmt) -> None:
|
|
767
978
|
"""Generate DocIR for ignore statements."""
|
|
@@ -769,7 +980,7 @@ class DocIRGenPass(UniPass):
|
|
|
769
980
|
for i in node.kid:
|
|
770
981
|
parts.append(i.gen.doc_ir)
|
|
771
982
|
parts.append(self.space())
|
|
772
|
-
node.gen.doc_ir = self.
|
|
983
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
773
984
|
|
|
774
985
|
def exit_connect_op(self, node: uni.ConnectOp) -> None:
|
|
775
986
|
"""Generate DocIR for connect operator."""
|
|
@@ -777,7 +988,8 @@ class DocIRGenPass(UniPass):
|
|
|
777
988
|
for i in node.kid:
|
|
778
989
|
parts.append(i.gen.doc_ir)
|
|
779
990
|
parts.append(self.space())
|
|
780
|
-
|
|
991
|
+
parts.pop()
|
|
992
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
781
993
|
|
|
782
994
|
def exit_disconnect_op(self, node: uni.DisconnectOp) -> None:
|
|
783
995
|
"""Generate DocIR for disconnect operator."""
|
|
@@ -785,7 +997,8 @@ class DocIRGenPass(UniPass):
|
|
|
785
997
|
for i in node.kid:
|
|
786
998
|
parts.append(i.gen.doc_ir)
|
|
787
999
|
parts.append(self.space())
|
|
788
|
-
|
|
1000
|
+
parts.pop()
|
|
1001
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
789
1002
|
|
|
790
1003
|
def exit_compare_expr(self, node: uni.CompareExpr) -> None:
|
|
791
1004
|
"""Generate DocIR for comparison expressions."""
|
|
@@ -793,7 +1006,8 @@ class DocIRGenPass(UniPass):
|
|
|
793
1006
|
for i in node.kid:
|
|
794
1007
|
parts.append(i.gen.doc_ir)
|
|
795
1008
|
parts.append(self.space())
|
|
796
|
-
|
|
1009
|
+
parts.pop()
|
|
1010
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
797
1011
|
|
|
798
1012
|
def exit_atom_unit(self, node: uni.AtomUnit) -> None:
|
|
799
1013
|
"""Generate DocIR for atom units (parenthesized expressions)."""
|
|
@@ -815,7 +1029,8 @@ class DocIRGenPass(UniPass):
|
|
|
815
1029
|
parts.append(i.gen.doc_ir)
|
|
816
1030
|
parts.append(self.space())
|
|
817
1031
|
prev_item = i
|
|
818
|
-
|
|
1032
|
+
parts.pop()
|
|
1033
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
819
1034
|
|
|
820
1035
|
def exit_expr_as_item(self, node: uni.ExprAsItem) -> None:
|
|
821
1036
|
"""Generate DocIR for expression as item nodes."""
|
|
@@ -823,7 +1038,7 @@ class DocIRGenPass(UniPass):
|
|
|
823
1038
|
for i in node.kid:
|
|
824
1039
|
parts.append(i.gen.doc_ir)
|
|
825
1040
|
parts.append(self.space())
|
|
826
|
-
node.gen.doc_ir = self.
|
|
1041
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
827
1042
|
|
|
828
1043
|
def exit_filter_compr(self, node: uni.FilterCompr) -> None:
|
|
829
1044
|
"""Generate DocIR for filter comprehensions."""
|
|
@@ -831,7 +1046,7 @@ class DocIRGenPass(UniPass):
|
|
|
831
1046
|
for i in node.kid:
|
|
832
1047
|
parts.append(i.gen.doc_ir)
|
|
833
1048
|
parts.append(self.space())
|
|
834
|
-
node.gen.doc_ir = self.
|
|
1049
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
835
1050
|
|
|
836
1051
|
def exit_assign_compr(self, node: uni.AssignCompr) -> None:
|
|
837
1052
|
"""Generate DocIR for assignment comprehensions."""
|
|
@@ -839,7 +1054,7 @@ class DocIRGenPass(UniPass):
|
|
|
839
1054
|
for i in node.kid:
|
|
840
1055
|
parts.append(i.gen.doc_ir)
|
|
841
1056
|
parts.append(self.space())
|
|
842
|
-
node.gen.doc_ir = self.
|
|
1057
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
843
1058
|
|
|
844
1059
|
def exit_py_inline_code(self, node: uni.PyInlineCode) -> None:
|
|
845
1060
|
"""Generate DocIR for Python inline code blocks."""
|
|
@@ -856,7 +1071,7 @@ class DocIRGenPass(UniPass):
|
|
|
856
1071
|
else:
|
|
857
1072
|
parts.append(i.gen.doc_ir)
|
|
858
1073
|
parts.append(self.space())
|
|
859
|
-
node.gen.doc_ir = self.
|
|
1074
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
860
1075
|
|
|
861
1076
|
def exit_test(self, node: uni.Test) -> None:
|
|
862
1077
|
"""Generate DocIR for test nodes."""
|
|
@@ -872,7 +1087,7 @@ class DocIRGenPass(UniPass):
|
|
|
872
1087
|
else:
|
|
873
1088
|
parts.append(i.gen.doc_ir)
|
|
874
1089
|
parts.append(self.space())
|
|
875
|
-
node.gen.doc_ir = self.
|
|
1090
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
876
1091
|
|
|
877
1092
|
def exit_check_stmt(self, node: uni.CheckStmt) -> None:
|
|
878
1093
|
"""Generate DocIR for check statements."""
|
|
@@ -882,7 +1097,7 @@ class DocIRGenPass(UniPass):
|
|
|
882
1097
|
parts.pop()
|
|
883
1098
|
parts.append(i.gen.doc_ir)
|
|
884
1099
|
parts.append(self.space())
|
|
885
|
-
node.gen.doc_ir = self.
|
|
1100
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
886
1101
|
|
|
887
1102
|
def exit_match_stmt(self, node: uni.MatchStmt) -> None:
|
|
888
1103
|
"""Generate DocIR for match statements."""
|
|
@@ -902,7 +1117,7 @@ class DocIRGenPass(UniPass):
|
|
|
902
1117
|
else:
|
|
903
1118
|
parts.append(i.gen.doc_ir)
|
|
904
1119
|
parts.append(self.space())
|
|
905
|
-
node.gen.doc_ir = self.
|
|
1120
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
906
1121
|
|
|
907
1122
|
def exit_match_case(self, node: uni.MatchCase) -> None:
|
|
908
1123
|
"""Generate DocIR for match cases."""
|
|
@@ -919,7 +1134,7 @@ class DocIRGenPass(UniPass):
|
|
|
919
1134
|
parts.append(i.gen.doc_ir)
|
|
920
1135
|
parts.append(self.space())
|
|
921
1136
|
parts.append(self.indent(self.concat([self.hard_line()] + indent_parts)))
|
|
922
|
-
node.gen.doc_ir = self.
|
|
1137
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
923
1138
|
|
|
924
1139
|
def exit_match_value(self, node: uni.MatchValue) -> None:
|
|
925
1140
|
"""Generate DocIR for match value patterns."""
|
|
@@ -927,7 +1142,8 @@ class DocIRGenPass(UniPass):
|
|
|
927
1142
|
for i in node.kid:
|
|
928
1143
|
parts.append(i.gen.doc_ir)
|
|
929
1144
|
parts.append(self.space())
|
|
930
|
-
|
|
1145
|
+
parts.pop()
|
|
1146
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
931
1147
|
|
|
932
1148
|
def exit_match_singleton(self, node: uni.MatchSingleton) -> None:
|
|
933
1149
|
"""Generate DocIR for match singleton patterns."""
|
|
@@ -935,7 +1151,8 @@ class DocIRGenPass(UniPass):
|
|
|
935
1151
|
for i in node.kid:
|
|
936
1152
|
parts.append(i.gen.doc_ir)
|
|
937
1153
|
parts.append(self.space())
|
|
938
|
-
|
|
1154
|
+
parts.pop()
|
|
1155
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
939
1156
|
|
|
940
1157
|
def exit_match_sequence(self, node: uni.MatchSequence) -> None:
|
|
941
1158
|
"""Generate DocIR for match sequence patterns."""
|
|
@@ -943,7 +1160,8 @@ class DocIRGenPass(UniPass):
|
|
|
943
1160
|
for i in node.kid:
|
|
944
1161
|
parts.append(i.gen.doc_ir)
|
|
945
1162
|
parts.append(self.space())
|
|
946
|
-
|
|
1163
|
+
parts.pop()
|
|
1164
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
947
1165
|
|
|
948
1166
|
def exit_match_mapping(self, node: uni.MatchMapping) -> None:
|
|
949
1167
|
"""Generate DocIR for match mapping patterns."""
|
|
@@ -951,7 +1169,8 @@ class DocIRGenPass(UniPass):
|
|
|
951
1169
|
for i in node.kid:
|
|
952
1170
|
parts.append(i.gen.doc_ir)
|
|
953
1171
|
parts.append(self.space())
|
|
954
|
-
|
|
1172
|
+
parts.pop()
|
|
1173
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
955
1174
|
|
|
956
1175
|
def exit_match_or(self, node: uni.MatchOr) -> None:
|
|
957
1176
|
"""Generate DocIR for match OR patterns."""
|
|
@@ -959,7 +1178,8 @@ class DocIRGenPass(UniPass):
|
|
|
959
1178
|
for i in node.kid:
|
|
960
1179
|
parts.append(i.gen.doc_ir)
|
|
961
1180
|
parts.append(self.space())
|
|
962
|
-
|
|
1181
|
+
parts.pop()
|
|
1182
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
963
1183
|
|
|
964
1184
|
def exit_match_as(self, node: uni.MatchAs) -> None:
|
|
965
1185
|
"""Generate DocIR for match AS patterns."""
|
|
@@ -967,7 +1187,8 @@ class DocIRGenPass(UniPass):
|
|
|
967
1187
|
for i in node.kid:
|
|
968
1188
|
parts.append(i.gen.doc_ir)
|
|
969
1189
|
parts.append(self.space())
|
|
970
|
-
|
|
1190
|
+
parts.pop()
|
|
1191
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
971
1192
|
|
|
972
1193
|
def exit_match_wild(self, node: uni.MatchWild) -> None:
|
|
973
1194
|
"""Generate DocIR for match wildcard patterns."""
|
|
@@ -975,7 +1196,8 @@ class DocIRGenPass(UniPass):
|
|
|
975
1196
|
for i in node.kid:
|
|
976
1197
|
parts.append(i.gen.doc_ir)
|
|
977
1198
|
parts.append(self.space())
|
|
978
|
-
|
|
1199
|
+
parts.pop()
|
|
1200
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
979
1201
|
|
|
980
1202
|
def exit_match_star(self, node: uni.MatchStar) -> None:
|
|
981
1203
|
"""Generate DocIR for match star patterns (e.g., *args, **kwargs)."""
|
|
@@ -983,7 +1205,8 @@ class DocIRGenPass(UniPass):
|
|
|
983
1205
|
for i in node.kid:
|
|
984
1206
|
parts.append(i.gen.doc_ir)
|
|
985
1207
|
parts.append(self.space())
|
|
986
|
-
|
|
1208
|
+
parts.pop()
|
|
1209
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
987
1210
|
|
|
988
1211
|
def exit_match_k_v_pair(self, node: uni.MatchKVPair) -> None:
|
|
989
1212
|
"""Generate DocIR for match key-value pairs."""
|
|
@@ -994,21 +1217,27 @@ class DocIRGenPass(UniPass):
|
|
|
994
1217
|
else:
|
|
995
1218
|
parts.append(i.gen.doc_ir)
|
|
996
1219
|
parts.append(self.space())
|
|
997
|
-
|
|
1220
|
+
parts.pop()
|
|
1221
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
998
1222
|
|
|
999
1223
|
def exit_match_arch(self, node: uni.MatchArch) -> None:
|
|
1000
1224
|
"""Generate DocIR for match architecture patterns."""
|
|
1001
1225
|
parts: list[doc.DocType] = []
|
|
1002
1226
|
for i in node.kid:
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1227
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
1228
|
+
parts.append(i.gen.doc_ir)
|
|
1229
|
+
parts.append(self.space())
|
|
1230
|
+
else:
|
|
1231
|
+
parts.append(i.gen.doc_ir)
|
|
1232
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
1006
1233
|
|
|
1007
1234
|
def exit_enum(self, node: uni.Enum) -> None:
|
|
1008
1235
|
"""Generate DocIR for enum declarations."""
|
|
1009
1236
|
parts: list[doc.DocType] = []
|
|
1010
1237
|
for i in node.kid:
|
|
1011
|
-
if i
|
|
1238
|
+
if (node.doc and i is node.doc) or (
|
|
1239
|
+
node.decorators and i in node.decorators
|
|
1240
|
+
):
|
|
1012
1241
|
parts.append(i.gen.doc_ir)
|
|
1013
1242
|
parts.append(self.hard_line())
|
|
1014
1243
|
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
@@ -1018,93 +1247,74 @@ class DocIRGenPass(UniPass):
|
|
|
1018
1247
|
else:
|
|
1019
1248
|
parts.append(i.gen.doc_ir)
|
|
1020
1249
|
parts.append(self.space())
|
|
1021
|
-
node.gen.doc_ir = self.
|
|
1250
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
1022
1251
|
|
|
1023
1252
|
def exit_sub_tag(self, node: uni.SubTag) -> None:
|
|
1024
1253
|
"""Generate DocIR for sub-tag nodes."""
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
parts.append(self.space())
|
|
1029
|
-
node.gen.doc_ir = self.finalize(parts)
|
|
1254
|
+
before_colon: list[doc.DocType] = []
|
|
1255
|
+
after_colon: list[doc.DocType] = []
|
|
1256
|
+
seen_colon = False
|
|
1030
1257
|
|
|
1031
|
-
def exit_sub_node_list(self, node: uni.SubNodeList) -> None:
|
|
1032
|
-
"""Generate DocIR for a SubNodeList."""
|
|
1033
|
-
parts: list[doc.DocType] = []
|
|
1034
|
-
indent_parts: list[doc.DocType] = []
|
|
1035
|
-
prev_item: Optional[uni.UniNode] = None
|
|
1036
|
-
in_codeblock = node.delim and node.delim.name == Tok.WS
|
|
1037
|
-
in_archetype = (
|
|
1038
|
-
node.parent
|
|
1039
|
-
and isinstance(node.parent, (uni.Archetype, uni.Enum))
|
|
1040
|
-
and node == node.parent.body
|
|
1041
|
-
)
|
|
1042
|
-
is_assignment = node.delim and node.delim.name == Tok.EQ
|
|
1043
1258
|
for i in node.kid:
|
|
1044
|
-
if i ==
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
elif
|
|
1048
|
-
|
|
1049
|
-
indent_parts.pop()
|
|
1050
|
-
parts.append(self.indent(self.concat(indent_parts)))
|
|
1051
|
-
if prev_item != node.left_enc:
|
|
1052
|
-
parts.append(self.line())
|
|
1053
|
-
parts.append(i.gen.doc_ir)
|
|
1054
|
-
elif (
|
|
1055
|
-
isinstance(i, uni.Token)
|
|
1056
|
-
and node.delim
|
|
1057
|
-
and i.name == node.delim.name
|
|
1058
|
-
and i.name not in [Tok.DOT, Tok.DECOR_OP]
|
|
1059
|
-
):
|
|
1060
|
-
indent_parts.append(i.gen.doc_ir)
|
|
1061
|
-
indent_parts.append(self.line())
|
|
1259
|
+
if isinstance(i, uni.Token) and i.name == Tok.COLON and not seen_colon:
|
|
1260
|
+
colon_tok = i.gen.doc_ir
|
|
1261
|
+
seen_colon = True
|
|
1262
|
+
elif seen_colon:
|
|
1263
|
+
after_colon.append(i.gen.doc_ir)
|
|
1062
1264
|
else:
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
and prev_item not in [None, node.left_enc, node.right_enc]
|
|
1078
|
-
and (
|
|
1079
|
-
type(prev_item) is not type(i)
|
|
1080
|
-
or (prev_item and not self.is_one_line(prev_item))
|
|
1081
|
-
)
|
|
1082
|
-
):
|
|
1083
|
-
indent_parts.append(self.hard_line())
|
|
1084
|
-
indent_parts.append(i.gen.doc_ir)
|
|
1085
|
-
if in_codeblock:
|
|
1086
|
-
indent_parts.append(self.hard_line())
|
|
1087
|
-
elif is_assignment:
|
|
1088
|
-
indent_parts.append(self.space())
|
|
1089
|
-
prev_item = i
|
|
1090
|
-
if is_assignment:
|
|
1091
|
-
indent_parts.pop()
|
|
1092
|
-
node.gen.doc_ir = self.concat(parts) if parts else self.concat(indent_parts)
|
|
1265
|
+
before_colon.append(i.gen.doc_ir)
|
|
1266
|
+
|
|
1267
|
+
if seen_colon:
|
|
1268
|
+
flat = self.concat([*before_colon, colon_tok, self.space(), *after_colon])
|
|
1269
|
+
broke = self.concat(
|
|
1270
|
+
[
|
|
1271
|
+
*before_colon,
|
|
1272
|
+
colon_tok,
|
|
1273
|
+
self.indent(self.concat([self.line(), *after_colon])),
|
|
1274
|
+
]
|
|
1275
|
+
)
|
|
1276
|
+
node.gen.doc_ir = self.group(self.if_break(broke, flat))
|
|
1277
|
+
else:
|
|
1278
|
+
node.gen.doc_ir = self.concat(before_colon + after_colon)
|
|
1093
1279
|
|
|
1094
1280
|
def exit_impl_def(self, node: uni.ImplDef) -> None:
|
|
1095
1281
|
"""Generate DocIR for implementation definitions."""
|
|
1096
1282
|
parts: list[doc.DocType] = []
|
|
1283
|
+
body_parts: list[doc.DocType] = []
|
|
1284
|
+
in_body = False
|
|
1097
1285
|
for i in node.kid:
|
|
1098
|
-
if i
|
|
1286
|
+
if i == node.doc or (node.decorators and i in node.decorators):
|
|
1099
1287
|
parts.append(i.gen.doc_ir)
|
|
1100
1288
|
parts.append(self.hard_line())
|
|
1101
|
-
elif i
|
|
1289
|
+
elif i in node.target:
|
|
1290
|
+
parts.append(i.gen.doc_ir)
|
|
1291
|
+
elif (
|
|
1292
|
+
in_body
|
|
1293
|
+
or isinstance(node.body, Sequence)
|
|
1294
|
+
and node.body
|
|
1295
|
+
and i == node.body[0]
|
|
1296
|
+
):
|
|
1297
|
+
if not in_body:
|
|
1298
|
+
parts.pop()
|
|
1299
|
+
body_parts.append(self.hard_line())
|
|
1300
|
+
if isinstance(i, uni.Token) and i.name == Tok.COMMA:
|
|
1301
|
+
body_parts.pop()
|
|
1302
|
+
body_parts.append(i.gen.doc_ir)
|
|
1303
|
+
body_parts.append(self.hard_line())
|
|
1304
|
+
in_body = True
|
|
1305
|
+
if in_body and isinstance(node.body, Sequence) and i == node.body[-1]:
|
|
1306
|
+
in_body = False
|
|
1307
|
+
body_parts.pop()
|
|
1308
|
+
parts.append(self.indent(self.concat(body_parts)))
|
|
1309
|
+
parts.append(self.hard_line())
|
|
1310
|
+
elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
|
|
1311
|
+
parts.pop()
|
|
1102
1312
|
parts.append(i.gen.doc_ir)
|
|
1103
1313
|
parts.append(self.space())
|
|
1104
1314
|
else:
|
|
1105
1315
|
parts.append(i.gen.doc_ir)
|
|
1106
1316
|
parts.append(self.space())
|
|
1107
|
-
node.gen.doc_ir = self.
|
|
1317
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
1108
1318
|
|
|
1109
1319
|
def exit_event_signature(self, node: uni.EventSignature) -> None:
|
|
1110
1320
|
"""Generate DocIR for event signatures."""
|
|
@@ -1112,7 +1322,8 @@ class DocIRGenPass(UniPass):
|
|
|
1112
1322
|
for i in node.kid:
|
|
1113
1323
|
parts.append(i.gen.doc_ir)
|
|
1114
1324
|
parts.append(self.space())
|
|
1115
|
-
|
|
1325
|
+
parts.pop()
|
|
1326
|
+
node.gen.doc_ir = self.group(self.concat(parts))
|
|
1116
1327
|
|
|
1117
1328
|
def exit_typed_ctx_block(self, node: uni.TypedCtxBlock) -> None:
|
|
1118
1329
|
"""Generate DocIR for typed context blocks."""
|
|
@@ -1154,9 +1365,7 @@ class DocIRGenPass(UniPass):
|
|
|
1154
1365
|
is_escaped_curly = (
|
|
1155
1366
|
node.lit_value in ["{", "}"]
|
|
1156
1367
|
and node.parent
|
|
1157
|
-
and isinstance(node.parent, uni.
|
|
1158
|
-
and node.parent.parent
|
|
1159
|
-
and isinstance(node.parent.parent, uni.FString)
|
|
1368
|
+
and isinstance(node.parent, uni.FString)
|
|
1160
1369
|
)
|
|
1161
1370
|
|
|
1162
1371
|
if "\n" in node.value:
|