jaclang 0.8.0__py3-none-any.whl → 0.8.1__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/cli/cli.py +11 -9
- jaclang/compiler/jac.lark +2 -12
- jaclang/compiler/larkparse/jac_parser.py +1 -1
- jaclang/compiler/parser.py +360 -521
- jaclang/compiler/passes/main/cfg_build_pass.py +2 -2
- 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 +3 -3
- jaclang/compiler/passes/main/inheritance_pass.py +2 -2
- jaclang/compiler/passes/main/pyast_gen_pass.py +196 -218
- 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 +4 -4
- 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 +4 -2
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +197 -120
- jaclang/compiler/program.py +2 -7
- 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 +11 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +7 -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 +20 -0
- jaclang/compiler/tests/test_parser.py +1 -0
- jaclang/compiler/unitree.py +456 -304
- jaclang/langserve/engine.jac +498 -0
- jaclang/langserve/sem_manager.jac +309 -0
- jaclang/langserve/server.jac +186 -0
- jaclang/langserve/tests/server_test/test_lang_serve.py +6 -7
- jaclang/langserve/tests/server_test/utils.py +4 -1
- jaclang/langserve/tests/session.jac +294 -0
- jaclang/langserve/tests/test_sem_tokens.py +2 -2
- jaclang/langserve/tests/test_server.py +12 -7
- jaclang/langserve/utils.jac +51 -30
- jaclang/runtimelib/archetype.py +1 -1
- jaclang/runtimelib/builtin.py +17 -14
- jaclang/runtimelib/importer.py +26 -8
- jaclang/runtimelib/machine.py +96 -55
- jaclang/runtimelib/tests/fixtures/traversing_save.jac +7 -5
- jaclang/runtimelib/utils.py +3 -3
- 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/edge_ability.jac +49 -0
- 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/node_del.jac +30 -36
- jaclang/tests/fixtures/visit_traversal.jac +47 -0
- jaclang/tests/test_cli.py +12 -7
- jaclang/tests/test_language.py +91 -16
- jaclang/utils/helpers.py +14 -6
- jaclang/utils/lang_tools.py +2 -3
- jaclang/utils/tests/test_lang_tools.py +2 -1
- jaclang/utils/treeprinter.py +3 -4
- {jaclang-0.8.0.dist-info → jaclang-0.8.1.dist-info}/METADATA +4 -3
- {jaclang-0.8.0.dist-info → jaclang-0.8.1.dist-info}/RECORD +71 -55
- {jaclang-0.8.0.dist-info → jaclang-0.8.1.dist-info}/WHEEL +1 -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/langserve/{__init__.py → __init__.jac} +0 -0
- {jaclang-0.8.0.dist-info → jaclang-0.8.1.dist-info}/entry_points.txt +0 -0
|
@@ -224,21 +224,15 @@ class PyastGenPass(UniPass):
|
|
|
224
224
|
|
|
225
225
|
def resolve_stmt_block(
|
|
226
226
|
self,
|
|
227
|
-
node:
|
|
228
|
-
uni.SubNodeList[uni.CodeBlockStmt]
|
|
229
|
-
| uni.SubNodeList[uni.ArchBlockStmt]
|
|
230
|
-
| uni.SubNodeList[uni.EnumBlockStmt]
|
|
231
|
-
| None
|
|
232
|
-
),
|
|
227
|
+
node: Sequence[uni.CodeBlockStmt] | Sequence[uni.EnumBlockStmt] | None,
|
|
233
228
|
doc: Optional[uni.String] = None,
|
|
234
229
|
) -> list[ast3.AST]:
|
|
235
230
|
"""Unwind codeblock."""
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
)
|
|
231
|
+
items = list(node) if node else []
|
|
232
|
+
valid_stmts = [i for i in items if not isinstance(i, uni.Semi)]
|
|
239
233
|
ret: list[ast3.AST] = (
|
|
240
|
-
[self.sync(ast3.Pass()
|
|
241
|
-
if isinstance(node,
|
|
234
|
+
[self.sync(ast3.Pass())]
|
|
235
|
+
if isinstance(node, Sequence) and not valid_stmts
|
|
242
236
|
else (
|
|
243
237
|
self.flatten(
|
|
244
238
|
[
|
|
@@ -247,7 +241,7 @@ class PyastGenPass(UniPass):
|
|
|
247
241
|
if not isinstance(x, uni.ImplDef)
|
|
248
242
|
]
|
|
249
243
|
)
|
|
250
|
-
if node
|
|
244
|
+
if node is not None
|
|
251
245
|
else []
|
|
252
246
|
)
|
|
253
247
|
)
|
|
@@ -287,9 +281,6 @@ class PyastGenPass(UniPass):
|
|
|
287
281
|
def exit_sub_tag(self, node: uni.SubTag[uni.T]) -> None:
|
|
288
282
|
node.gen.py_ast = node.tag.gen.py_ast
|
|
289
283
|
|
|
290
|
-
def exit_sub_node_list(self, node: uni.SubNodeList[uni.T]) -> None:
|
|
291
|
-
node.gen.py_ast = self.flatten([i.gen.py_ast for i in node.items])
|
|
292
|
-
|
|
293
284
|
def exit_module(self, node: uni.Module) -> None:
|
|
294
285
|
clean_body = [i for i in node.body if not isinstance(i, uni.ImplDef)]
|
|
295
286
|
pre_body: list[uni.UniNode] = []
|
|
@@ -332,14 +323,15 @@ class PyastGenPass(UniPass):
|
|
|
332
323
|
ast3.Expr(value=cast(ast3.expr, node.doc.gen.py_ast[0])),
|
|
333
324
|
jac_node=node.doc,
|
|
334
325
|
)
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
)
|
|
338
|
-
|
|
326
|
+
assigns_ast: list[ast3.AST] = self.flatten(
|
|
327
|
+
[a.gen.py_ast for a in node.assignments]
|
|
328
|
+
)
|
|
329
|
+
if isinstance(doc, ast3.AST):
|
|
330
|
+
node.gen.py_ast = [doc] + assigns_ast
|
|
339
331
|
else:
|
|
340
332
|
raise self.ice()
|
|
341
333
|
else:
|
|
342
|
-
node.gen.py_ast =
|
|
334
|
+
node.gen.py_ast = self.flatten([a.gen.py_ast for a in node.assignments])
|
|
343
335
|
|
|
344
336
|
def exit_test(self, node: uni.Test) -> None:
|
|
345
337
|
test_name = node.name.sym_name
|
|
@@ -382,7 +374,7 @@ class PyastGenPass(UniPass):
|
|
|
382
374
|
ast3.keyword(
|
|
383
375
|
arg="file_loc",
|
|
384
376
|
value=self.sync(
|
|
385
|
-
ast3.Constant(value=node.
|
|
377
|
+
ast3.Constant(value=node.loc.mod_path)
|
|
386
378
|
),
|
|
387
379
|
)
|
|
388
380
|
),
|
|
@@ -439,7 +431,7 @@ class PyastGenPass(UniPass):
|
|
|
439
431
|
)
|
|
440
432
|
imp_from = {}
|
|
441
433
|
if node.items:
|
|
442
|
-
for item in node.items
|
|
434
|
+
for item in node.items:
|
|
443
435
|
if isinstance(item, uni.ModuleItem):
|
|
444
436
|
imp_from[item.name.sym_name] = (
|
|
445
437
|
item.alias.sym_name if item.alias else None
|
|
@@ -710,7 +702,7 @@ class PyastGenPass(UniPass):
|
|
|
710
702
|
)
|
|
711
703
|
)
|
|
712
704
|
if node.is_absorb:
|
|
713
|
-
source = node.items
|
|
705
|
+
source = node.items[0]
|
|
714
706
|
if not isinstance(source, uni.ModulePath):
|
|
715
707
|
raise self.ice()
|
|
716
708
|
typecheck_nodes.append(
|
|
@@ -727,7 +719,11 @@ class PyastGenPass(UniPass):
|
|
|
727
719
|
typecheck_nodes.append(
|
|
728
720
|
self.sync(
|
|
729
721
|
ast3.Import(
|
|
730
|
-
names=[
|
|
722
|
+
names=[
|
|
723
|
+
cast(ast3.alias, x)
|
|
724
|
+
for item in node.items
|
|
725
|
+
for x in item.gen.py_ast
|
|
726
|
+
]
|
|
731
727
|
)
|
|
732
728
|
)
|
|
733
729
|
)
|
|
@@ -740,7 +736,11 @@ class PyastGenPass(UniPass):
|
|
|
740
736
|
if node.from_loc
|
|
741
737
|
else None
|
|
742
738
|
),
|
|
743
|
-
names=[
|
|
739
|
+
names=[
|
|
740
|
+
cast(ast3.alias, i)
|
|
741
|
+
for item in node.items
|
|
742
|
+
for i in item.gen.py_ast
|
|
743
|
+
],
|
|
744
744
|
level=0,
|
|
745
745
|
)
|
|
746
746
|
)
|
|
@@ -781,16 +781,19 @@ class PyastGenPass(UniPass):
|
|
|
781
781
|
self.traverse(node.body)
|
|
782
782
|
|
|
783
783
|
def exit_archetype(self, node: uni.Archetype) -> None:
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
if isinstance(node.body, uni.
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
)
|
|
793
|
-
|
|
784
|
+
inner = None
|
|
785
|
+
if isinstance(node.body, uni.ImplDef):
|
|
786
|
+
inner = (
|
|
787
|
+
node.body.body if not isinstance(node.body.body, uni.FuncCall) else None
|
|
788
|
+
)
|
|
789
|
+
elif not isinstance(node.body, uni.FuncCall):
|
|
790
|
+
inner = node.body
|
|
791
|
+
body = self.resolve_stmt_block(inner, doc=node.doc)
|
|
792
|
+
if not body and not isinstance(node.body, uni.FuncCall):
|
|
793
|
+
self.log_error(
|
|
794
|
+
"Archetype has no body. Perhaps an impl must be imported.", node
|
|
795
|
+
)
|
|
796
|
+
body = [self.sync(ast3.Pass(), node)]
|
|
794
797
|
if node.is_async:
|
|
795
798
|
body.insert(
|
|
796
799
|
0,
|
|
@@ -805,12 +808,11 @@ class PyastGenPass(UniPass):
|
|
|
805
808
|
)
|
|
806
809
|
|
|
807
810
|
decorators = (
|
|
808
|
-
|
|
809
|
-
if
|
|
811
|
+
[cast(ast3.expr, i.gen.py_ast[0]) for i in node.decorators]
|
|
812
|
+
if node.decorators
|
|
810
813
|
else []
|
|
811
814
|
)
|
|
812
|
-
|
|
813
|
-
base_classes = node.base_classes.gen.py_ast if node.base_classes else []
|
|
815
|
+
base_classes = [cast(ast3.expr, i.gen.py_ast[0]) for i in node.base_classes]
|
|
814
816
|
if node.arch_type.name != Tok.KW_CLASS:
|
|
815
817
|
base_classes.append(self.jaclib_obj(node.arch_type.value.capitalize()))
|
|
816
818
|
|
|
@@ -833,25 +835,21 @@ class PyastGenPass(UniPass):
|
|
|
833
835
|
|
|
834
836
|
def exit_enum(self, node: uni.Enum) -> None:
|
|
835
837
|
self.needs_enum()
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
if isinstance(node.body, uni.
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
)
|
|
838
|
+
inner = None
|
|
839
|
+
if isinstance(node.body, uni.ImplDef):
|
|
840
|
+
inner = (
|
|
841
|
+
node.body.body if not isinstance(node.body.body, uni.FuncCall) else None
|
|
842
|
+
)
|
|
843
|
+
elif not isinstance(node.body, uni.FuncCall):
|
|
844
|
+
inner = node.body
|
|
845
|
+
body = self.resolve_stmt_block(inner, doc=node.doc)
|
|
845
846
|
decorators = (
|
|
846
|
-
|
|
847
|
-
if
|
|
847
|
+
[cast(ast3.expr, i.gen.py_ast[0]) for i in node.decorators]
|
|
848
|
+
if node.decorators
|
|
848
849
|
else []
|
|
849
850
|
)
|
|
850
|
-
base_classes =
|
|
851
|
-
|
|
852
|
-
base_classes.append(self.sync(ast3.Name(id="Enum", ctx=ast3.Load())))
|
|
853
|
-
else:
|
|
854
|
-
raise self.ice()
|
|
851
|
+
base_classes = [cast(ast3.expr, i.gen.py_ast[0]) for i in node.base_classes]
|
|
852
|
+
base_classes.append(self.sync(ast3.Name(id="Enum", ctx=ast3.Load())))
|
|
855
853
|
node.gen.py_ast = [
|
|
856
854
|
self.sync(
|
|
857
855
|
ast3.ClassDef(
|
|
@@ -874,15 +872,26 @@ class PyastGenPass(UniPass):
|
|
|
874
872
|
# to Avoid circular import
|
|
875
873
|
from jaclang.runtimelib.machine import JacMachineInterface
|
|
876
874
|
|
|
877
|
-
|
|
875
|
+
body: list[ast3.AST] = JacMachineInterface.gen_llm_body(self, node)
|
|
876
|
+
if node.doc:
|
|
877
|
+
body.insert(
|
|
878
|
+
0,
|
|
879
|
+
self.sync(
|
|
880
|
+
ast3.Expr(value=cast(ast3.expr, node.doc.gen.py_ast[0])),
|
|
881
|
+
jac_node=node.doc,
|
|
882
|
+
),
|
|
883
|
+
)
|
|
884
|
+
return body
|
|
878
885
|
|
|
879
886
|
def exit_ability(self, node: uni.Ability) -> None:
|
|
880
887
|
func_type = ast3.AsyncFunctionDef if node.is_async else ast3.FunctionDef
|
|
881
888
|
body = (
|
|
882
889
|
self.gen_llm_body(node)
|
|
883
890
|
if isinstance(node.body, uni.FuncCall)
|
|
884
|
-
or
|
|
885
|
-
|
|
891
|
+
or (
|
|
892
|
+
isinstance(node.body, uni.ImplDef)
|
|
893
|
+
and isinstance(node.body.body, uni.FuncCall)
|
|
894
|
+
)
|
|
886
895
|
else (
|
|
887
896
|
[
|
|
888
897
|
self.sync(
|
|
@@ -899,8 +908,12 @@ class PyastGenPass(UniPass):
|
|
|
899
908
|
(
|
|
900
909
|
node.body.body
|
|
901
910
|
if isinstance(node.body, uni.ImplDef)
|
|
902
|
-
and isinstance(node.body.body, uni.
|
|
903
|
-
else
|
|
911
|
+
and not isinstance(node.body.body, uni.FuncCall)
|
|
912
|
+
else (
|
|
913
|
+
node.body
|
|
914
|
+
if not isinstance(node.body, uni.FuncCall)
|
|
915
|
+
else None
|
|
916
|
+
)
|
|
904
917
|
),
|
|
905
918
|
doc=node.doc,
|
|
906
919
|
)
|
|
@@ -912,7 +925,11 @@ class PyastGenPass(UniPass):
|
|
|
912
925
|
f"Abstract ability {node.sym_name} should not have a body.",
|
|
913
926
|
node,
|
|
914
927
|
)
|
|
915
|
-
decorator_list =
|
|
928
|
+
decorator_list = (
|
|
929
|
+
[cast(ast3.expr, i.gen.py_ast[0]) for i in node.decorators]
|
|
930
|
+
if node.decorators
|
|
931
|
+
else []
|
|
932
|
+
)
|
|
916
933
|
if isinstance(node.signature, uni.EventSignature):
|
|
917
934
|
decorator_list.append(
|
|
918
935
|
self.jaclib_obj(
|
|
@@ -995,23 +1012,18 @@ class PyastGenPass(UniPass):
|
|
|
995
1012
|
)
|
|
996
1013
|
vararg = None
|
|
997
1014
|
kwarg = None
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
(
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
defaults = (
|
|
1011
|
-
[x.value.gen.py_ast[0] for x in node.params.items if x.value]
|
|
1012
|
-
if node.params
|
|
1013
|
-
else []
|
|
1014
|
-
)
|
|
1015
|
+
for i in node.params:
|
|
1016
|
+
if i.unpack and i.unpack.value == "*":
|
|
1017
|
+
vararg = i.gen.py_ast[0]
|
|
1018
|
+
elif i.unpack and i.unpack.value == "**":
|
|
1019
|
+
kwarg = i.gen.py_ast[0]
|
|
1020
|
+
else:
|
|
1021
|
+
(
|
|
1022
|
+
params.append(i.gen.py_ast[0])
|
|
1023
|
+
if isinstance(i.gen.py_ast[0], ast3.arg)
|
|
1024
|
+
else self.ice("This list should only be Args")
|
|
1025
|
+
)
|
|
1026
|
+
defaults = [x.value.gen.py_ast[0] for x in node.params if x.value]
|
|
1015
1027
|
node.gen.py_ast = [
|
|
1016
1028
|
self.sync(
|
|
1017
1029
|
ast3.arguments(
|
|
@@ -1027,9 +1039,10 @@ class PyastGenPass(UniPass):
|
|
|
1027
1039
|
]
|
|
1028
1040
|
|
|
1029
1041
|
def exit_event_signature(self, node: uni.EventSignature) -> None:
|
|
1030
|
-
|
|
1042
|
+
arch_kw = Con.HERE.value if node.from_walker else Con.VISITOR.value
|
|
1043
|
+
arch_arg = self.sync(
|
|
1031
1044
|
ast3.arg(
|
|
1032
|
-
arg=f"{
|
|
1045
|
+
arg=f"{arch_kw}",
|
|
1033
1046
|
annotation=(
|
|
1034
1047
|
cast(ast3.expr, node.arch_tag_info.gen.py_ast[0])
|
|
1035
1048
|
if node.arch_tag_info
|
|
@@ -1043,10 +1056,10 @@ class PyastGenPass(UniPass):
|
|
|
1043
1056
|
ast3.arguments(
|
|
1044
1057
|
posonlyargs=[],
|
|
1045
1058
|
args=(
|
|
1046
|
-
[self.sync(ast3.arg(arg="self", annotation=None)),
|
|
1059
|
+
[self.sync(ast3.arg(arg="self", annotation=None)), arch_arg]
|
|
1047
1060
|
if (abl := node.find_parent_of_type(uni.Ability))
|
|
1048
1061
|
and abl.is_method
|
|
1049
|
-
else [
|
|
1062
|
+
else [arch_arg]
|
|
1050
1063
|
),
|
|
1051
1064
|
kwonlyargs=[],
|
|
1052
1065
|
vararg=None,
|
|
@@ -1090,43 +1103,31 @@ class PyastGenPass(UniPass):
|
|
|
1090
1103
|
]
|
|
1091
1104
|
|
|
1092
1105
|
def exit_arch_has(self, node: uni.ArchHas) -> None:
|
|
1106
|
+
vars_py: list[ast3.AST] = self.flatten([v.gen.py_ast for v in node.vars])
|
|
1093
1107
|
if node.doc:
|
|
1094
1108
|
doc = self.sync(
|
|
1095
1109
|
ast3.Expr(value=cast(ast3.expr, node.doc.gen.py_ast[0])),
|
|
1096
1110
|
jac_node=node.doc,
|
|
1097
1111
|
)
|
|
1098
|
-
if isinstance(doc, ast3.AST)
|
|
1099
|
-
node.gen.py_ast = [doc] +
|
|
1112
|
+
if isinstance(doc, ast3.AST):
|
|
1113
|
+
node.gen.py_ast = [doc] + vars_py
|
|
1100
1114
|
else:
|
|
1101
1115
|
raise self.ice()
|
|
1102
1116
|
else:
|
|
1103
|
-
node.gen.py_ast =
|
|
1117
|
+
node.gen.py_ast = vars_py
|
|
1104
1118
|
|
|
1105
1119
|
def exit_has_var(self, node: uni.HasVar) -> None:
|
|
1106
1120
|
annotation = node.type_tag.gen.py_ast[0] if node.type_tag else None
|
|
1107
1121
|
|
|
1108
1122
|
is_static_var = (
|
|
1109
|
-
node.
|
|
1110
|
-
and
|
|
1111
|
-
and
|
|
1112
|
-
and node.parent.parent.is_static
|
|
1123
|
+
(haspar := node.find_parent_of_type(uni.ArchHas))
|
|
1124
|
+
and haspar
|
|
1125
|
+
and haspar.is_static
|
|
1113
1126
|
)
|
|
1114
|
-
|
|
1115
1127
|
is_in_class = (
|
|
1116
|
-
node.
|
|
1117
|
-
and
|
|
1118
|
-
and
|
|
1119
|
-
and (
|
|
1120
|
-
(
|
|
1121
|
-
isinstance(node.parent.parent.parent, uni.Archetype)
|
|
1122
|
-
and node.parent.parent.parent.arch_type.name == Tok.KW_CLASS
|
|
1123
|
-
)
|
|
1124
|
-
or (
|
|
1125
|
-
node.parent.parent.parent.parent
|
|
1126
|
-
and isinstance(node.parent.parent.parent.parent, uni.Archetype)
|
|
1127
|
-
and node.parent.parent.parent.parent.arch_type.name == Tok.KW_CLASS
|
|
1128
|
-
)
|
|
1129
|
-
)
|
|
1128
|
+
(archpar := node.find_parent_of_type(uni.Archetype))
|
|
1129
|
+
and archpar
|
|
1130
|
+
and archpar.arch_type.name == Tok.KW_CLASS
|
|
1130
1131
|
)
|
|
1131
1132
|
|
|
1132
1133
|
value = None
|
|
@@ -1313,11 +1314,9 @@ class PyastGenPass(UniPass):
|
|
|
1313
1314
|
self.sync(
|
|
1314
1315
|
ast3.Try(
|
|
1315
1316
|
body=cast(list[ast3.stmt], self.resolve_stmt_block(node.body)),
|
|
1316
|
-
handlers=
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
else []
|
|
1320
|
-
),
|
|
1317
|
+
handlers=[
|
|
1318
|
+
cast(ast3.ExceptHandler, i.gen.py_ast[0]) for i in node.excepts
|
|
1319
|
+
],
|
|
1321
1320
|
orelse=(
|
|
1322
1321
|
[cast(ast3.stmt, i) for i in node.else_body.gen.py_ast]
|
|
1323
1322
|
if node.else_body
|
|
@@ -1355,7 +1354,7 @@ class PyastGenPass(UniPass):
|
|
|
1355
1354
|
|
|
1356
1355
|
def exit_iter_for_stmt(self, node: uni.IterForStmt) -> None:
|
|
1357
1356
|
py_nodes: list[ast3.AST] = []
|
|
1358
|
-
body = node.body
|
|
1357
|
+
body = self.resolve_stmt_block(node.body)
|
|
1359
1358
|
if (
|
|
1360
1359
|
isinstance(body, list)
|
|
1361
1360
|
and isinstance(node.count_by.gen.py_ast[0], ast3.AST)
|
|
@@ -1419,7 +1418,9 @@ class PyastGenPass(UniPass):
|
|
|
1419
1418
|
node.gen.py_ast = [
|
|
1420
1419
|
self.sync(
|
|
1421
1420
|
with_node(
|
|
1422
|
-
items=[
|
|
1421
|
+
items=[
|
|
1422
|
+
cast(ast3.withitem, item.gen.py_ast[0]) for item in node.exprs
|
|
1423
|
+
],
|
|
1423
1424
|
body=[
|
|
1424
1425
|
cast(ast3.stmt, stmt)
|
|
1425
1426
|
for stmt in self.resolve_stmt_block(node.body)
|
|
@@ -1510,13 +1511,11 @@ class PyastGenPass(UniPass):
|
|
|
1510
1511
|
node: uni.FuncCall,
|
|
1511
1512
|
) -> CheckNodeIsinstanceCallResult:
|
|
1512
1513
|
|
|
1513
|
-
# Ensure the
|
|
1514
|
-
# since the type can be: Optional[SubNodeList[Expr | KWPair]].
|
|
1514
|
+
# Ensure the func call has exactly two expression parameters
|
|
1515
1515
|
if not (
|
|
1516
|
-
node.params
|
|
1517
|
-
and
|
|
1518
|
-
and isinstance(node.params
|
|
1519
|
-
and isinstance(node.params.items[1], uni.Expr)
|
|
1516
|
+
len(node.params) == 2
|
|
1517
|
+
and isinstance(node.params[0], uni.Expr)
|
|
1518
|
+
and isinstance(node.params[1], uni.Expr)
|
|
1520
1519
|
):
|
|
1521
1520
|
return CheckNodeIsinstanceCallResult()
|
|
1522
1521
|
|
|
@@ -1526,8 +1525,8 @@ class PyastGenPass(UniPass):
|
|
|
1526
1525
|
|
|
1527
1526
|
return CheckNodeIsinstanceCallResult(
|
|
1528
1527
|
True,
|
|
1529
|
-
node.params
|
|
1530
|
-
node.params
|
|
1528
|
+
node.params[0].gen.py_ast[0],
|
|
1529
|
+
node.params[1].gen.py_ast[0],
|
|
1531
1530
|
)
|
|
1532
1531
|
|
|
1533
1532
|
# By default the check expression will become assertTrue(<expr>), unless any pattern detected.
|
|
@@ -1613,9 +1612,8 @@ class PyastGenPass(UniPass):
|
|
|
1613
1612
|
if isinstance(func, uni.Name) and func.value == "almostEqual":
|
|
1614
1613
|
assert_func_name = "assertAlmostEqual"
|
|
1615
1614
|
assert_args_list = []
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
assert_args_list.append(param.gen.py_ast[0])
|
|
1615
|
+
for param in node.target.params:
|
|
1616
|
+
assert_args_list.append(param.gen.py_ast[0])
|
|
1619
1617
|
|
|
1620
1618
|
# assert_func_expr = "Con.JAC_CHECK.value.assertXXX"
|
|
1621
1619
|
assert_func_expr: ast3.Attribute = self.sync(
|
|
@@ -1746,7 +1744,7 @@ class PyastGenPass(UniPass):
|
|
|
1746
1744
|
walker = self.sync(
|
|
1747
1745
|
ast3.Name(id="self", ctx=ast3.Load())
|
|
1748
1746
|
if node.from_walker
|
|
1749
|
-
else ast3.Name(id=Con.
|
|
1747
|
+
else ast3.Name(id=Con.VISITOR.value, ctx=ast3.Load())
|
|
1750
1748
|
)
|
|
1751
1749
|
|
|
1752
1750
|
node.gen.py_ast = [
|
|
@@ -1769,7 +1767,7 @@ class PyastGenPass(UniPass):
|
|
|
1769
1767
|
loc = self.sync(
|
|
1770
1768
|
ast3.Name(id="self", ctx=ast3.Load())
|
|
1771
1769
|
if node.from_walker
|
|
1772
|
-
else ast3.Name(id=Con.
|
|
1770
|
+
else ast3.Name(id=Con.VISITOR.value, ctx=ast3.Load())
|
|
1773
1771
|
)
|
|
1774
1772
|
|
|
1775
1773
|
visit_call = self.sync(
|
|
@@ -1780,6 +1778,16 @@ class PyastGenPass(UniPass):
|
|
|
1780
1778
|
)
|
|
1781
1779
|
)
|
|
1782
1780
|
|
|
1781
|
+
if node.insert_loc is not None:
|
|
1782
|
+
visit_call.keywords.append(
|
|
1783
|
+
self.sync(
|
|
1784
|
+
ast3.keyword(
|
|
1785
|
+
arg="insert_loc",
|
|
1786
|
+
value=cast(ast3.expr, node.insert_loc.gen.py_ast[0]),
|
|
1787
|
+
)
|
|
1788
|
+
)
|
|
1789
|
+
)
|
|
1790
|
+
|
|
1783
1791
|
node.gen.py_ast = [
|
|
1784
1792
|
(
|
|
1785
1793
|
self.sync(
|
|
@@ -1803,7 +1811,7 @@ class PyastGenPass(UniPass):
|
|
|
1803
1811
|
loc = self.sync(
|
|
1804
1812
|
ast3.Name(id="self", ctx=ast3.Load())
|
|
1805
1813
|
if node.from_walker
|
|
1806
|
-
else ast3.Name(id=Con.
|
|
1814
|
+
else ast3.Name(id=Con.VISITOR.value, ctx=ast3.Load())
|
|
1807
1815
|
)
|
|
1808
1816
|
node.gen.py_ast = [
|
|
1809
1817
|
self.sync(
|
|
@@ -1843,7 +1851,7 @@ class PyastGenPass(UniPass):
|
|
|
1843
1851
|
|
|
1844
1852
|
def exit_global_stmt(self, node: uni.GlobalStmt) -> None:
|
|
1845
1853
|
py_nodes = []
|
|
1846
|
-
for x in node.target
|
|
1854
|
+
for x in node.target:
|
|
1847
1855
|
py_nodes.append(
|
|
1848
1856
|
self.sync(
|
|
1849
1857
|
ast3.Global(names=[x.sym_name]),
|
|
@@ -1854,7 +1862,7 @@ class PyastGenPass(UniPass):
|
|
|
1854
1862
|
|
|
1855
1863
|
def exit_non_local_stmt(self, node: uni.NonLocalStmt) -> None:
|
|
1856
1864
|
py_nodes = []
|
|
1857
|
-
for x in node.target
|
|
1865
|
+
for x in node.target:
|
|
1858
1866
|
py_nodes.append(
|
|
1859
1867
|
self.sync(
|
|
1860
1868
|
ast3.Nonlocal(names=[x.sym_name]),
|
|
@@ -1879,18 +1887,20 @@ class PyastGenPass(UniPass):
|
|
|
1879
1887
|
else None if node.type_tag else self.ice()
|
|
1880
1888
|
)
|
|
1881
1889
|
)
|
|
1890
|
+
targets_ast = [cast(ast3.expr, t.gen.py_ast[0]) for t in node.target]
|
|
1891
|
+
|
|
1882
1892
|
if node.type_tag:
|
|
1883
1893
|
node.gen.py_ast = [
|
|
1884
1894
|
self.sync(
|
|
1885
1895
|
ast3.AnnAssign(
|
|
1886
|
-
target=cast(ast3.Name,
|
|
1896
|
+
target=cast(ast3.Name, targets_ast[0]),
|
|
1887
1897
|
annotation=cast(ast3.expr, node.type_tag.gen.py_ast[0]),
|
|
1888
1898
|
value=(
|
|
1889
1899
|
cast(ast3.expr, node.value.gen.py_ast[0])
|
|
1890
1900
|
if node.value
|
|
1891
1901
|
else None
|
|
1892
1902
|
),
|
|
1893
|
-
simple=int(isinstance(
|
|
1903
|
+
simple=int(isinstance(targets_ast[0], ast3.Name)),
|
|
1894
1904
|
)
|
|
1895
1905
|
)
|
|
1896
1906
|
]
|
|
@@ -1898,7 +1908,7 @@ class PyastGenPass(UniPass):
|
|
|
1898
1908
|
node.gen.py_ast = [
|
|
1899
1909
|
self.sync(
|
|
1900
1910
|
ast3.AugAssign(
|
|
1901
|
-
target=cast(ast3.Name,
|
|
1911
|
+
target=cast(ast3.Name, targets_ast[0]),
|
|
1902
1912
|
op=cast(ast3.operator, node.aug_op.gen.py_ast[0]),
|
|
1903
1913
|
value=(
|
|
1904
1914
|
cast(ast3.expr, value)
|
|
@@ -1912,7 +1922,7 @@ class PyastGenPass(UniPass):
|
|
|
1912
1922
|
node.gen.py_ast = [
|
|
1913
1923
|
self.sync(
|
|
1914
1924
|
ast3.Assign(
|
|
1915
|
-
targets=cast(list[ast3.expr],
|
|
1925
|
+
targets=cast(list[ast3.expr], targets_ast),
|
|
1916
1926
|
value=(
|
|
1917
1927
|
cast(ast3.expr, value)
|
|
1918
1928
|
if isinstance(value, ast3.expr)
|
|
@@ -2078,11 +2088,9 @@ class PyastGenPass(UniPass):
|
|
|
2078
2088
|
func_node = uni.FuncCall(
|
|
2079
2089
|
target=node.right,
|
|
2080
2090
|
params=(
|
|
2081
|
-
node.left.values
|
|
2082
|
-
if isinstance(node.left, uni.TupleVal)
|
|
2083
|
-
else
|
|
2084
|
-
items=[node.left], delim=Tok.COMMA, kid=[node.left]
|
|
2085
|
-
)
|
|
2091
|
+
list(node.left.values)
|
|
2092
|
+
if isinstance(node.left, uni.TupleVal) and node.left.values
|
|
2093
|
+
else [node.left]
|
|
2086
2094
|
),
|
|
2087
2095
|
genai_call=None,
|
|
2088
2096
|
kid=node.kid,
|
|
@@ -2110,11 +2118,9 @@ class PyastGenPass(UniPass):
|
|
|
2110
2118
|
func_node = uni.FuncCall(
|
|
2111
2119
|
target=node.left,
|
|
2112
2120
|
params=(
|
|
2113
|
-
node.right.values
|
|
2114
|
-
if isinstance(node.right, uni.TupleVal)
|
|
2115
|
-
else
|
|
2116
|
-
items=[node.right], delim=Tok.COMMA, kid=[node.right]
|
|
2117
|
-
)
|
|
2121
|
+
list(node.right.values)
|
|
2122
|
+
if isinstance(node.right, uni.TupleVal) and node.right.values
|
|
2123
|
+
else [node.right]
|
|
2118
2124
|
),
|
|
2119
2125
|
genai_call=None,
|
|
2120
2126
|
kid=node.kid,
|
|
@@ -2274,9 +2280,11 @@ class PyastGenPass(UniPass):
|
|
|
2274
2280
|
if isinstance(i, uni.String):
|
|
2275
2281
|
pieces.append(i.lit_value)
|
|
2276
2282
|
elif isinstance(i, uni.FString):
|
|
2277
|
-
pieces.extend(get_pieces(i.parts
|
|
2283
|
+
pieces.extend(get_pieces(i.parts)) if i.parts else None
|
|
2278
2284
|
elif isinstance(i, uni.ExprStmt):
|
|
2279
2285
|
pieces.append(i.gen.py_ast[0])
|
|
2286
|
+
elif isinstance(i, uni.Token) and i.name in [Tok.LBRACE, Tok.RBRACE]:
|
|
2287
|
+
continue
|
|
2280
2288
|
else:
|
|
2281
2289
|
raise self.ice("Multi string made of something weird.")
|
|
2282
2290
|
return pieces
|
|
@@ -2313,62 +2321,30 @@ class PyastGenPass(UniPass):
|
|
|
2313
2321
|
node.gen.py_ast = [combined_multi[0]]
|
|
2314
2322
|
|
|
2315
2323
|
def exit_f_string(self, node: uni.FString) -> None:
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
)
|
|
2324
|
+
py_parts: list[list[ast3.AST]] = [
|
|
2325
|
+
cast(list[ast3.AST], p.gen.py_ast) for p in node.parts
|
|
2326
|
+
]
|
|
2327
|
+
parts = self.flatten(cast(list[list[ast3.AST] | ast3.AST | None], py_parts))
|
|
2328
|
+
node.gen.py_ast = parts if parts else [self.sync(ast3.Constant(value=""))]
|
|
2321
2329
|
|
|
2322
2330
|
def exit_list_val(self, node: uni.ListVal) -> None:
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
else []
|
|
2331
|
-
),
|
|
2332
|
-
ctx=ast3.Load(),
|
|
2333
|
-
)
|
|
2334
|
-
)
|
|
2335
|
-
]
|
|
2336
|
-
else:
|
|
2337
|
-
node.gen.py_ast = [
|
|
2338
|
-
self.sync(
|
|
2339
|
-
ast3.List(
|
|
2340
|
-
elts=(
|
|
2341
|
-
[cast(ast3.expr, item) for item in node.values.gen.py_ast]
|
|
2342
|
-
if node.values and node.values.gen.py_ast
|
|
2343
|
-
else []
|
|
2344
|
-
),
|
|
2345
|
-
ctx=cast(ast3.expr_context, node.py_ctx_func()),
|
|
2346
|
-
)
|
|
2347
|
-
)
|
|
2348
|
-
]
|
|
2331
|
+
elts = [cast(ast3.expr, v.gen.py_ast[0]) for v in node.values]
|
|
2332
|
+
ctx = (
|
|
2333
|
+
ast3.Load()
|
|
2334
|
+
if isinstance(node.py_ctx_func(), ast3.Load)
|
|
2335
|
+
else cast(ast3.expr_context, node.py_ctx_func())
|
|
2336
|
+
)
|
|
2337
|
+
node.gen.py_ast = [self.sync(ast3.List(elts=elts, ctx=ctx))]
|
|
2349
2338
|
|
|
2350
2339
|
def exit_set_val(self, node: uni.SetVal) -> None:
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
ast3.Set(
|
|
2354
|
-
elts=(
|
|
2355
|
-
[cast(ast3.expr, i) for i in node.values.gen.py_ast]
|
|
2356
|
-
if node.values
|
|
2357
|
-
else []
|
|
2358
|
-
),
|
|
2359
|
-
)
|
|
2360
|
-
)
|
|
2361
|
-
]
|
|
2340
|
+
elts = [cast(ast3.expr, i.gen.py_ast[0]) for i in node.values]
|
|
2341
|
+
node.gen.py_ast = [self.sync(ast3.Set(elts=elts))]
|
|
2362
2342
|
|
|
2363
2343
|
def exit_tuple_val(self, node: uni.TupleVal) -> None:
|
|
2364
2344
|
node.gen.py_ast = [
|
|
2365
2345
|
self.sync(
|
|
2366
2346
|
ast3.Tuple(
|
|
2367
|
-
elts=(
|
|
2368
|
-
cast(list[ast3.expr], node.values.gen.py_ast)
|
|
2369
|
-
if node.values
|
|
2370
|
-
else []
|
|
2371
|
-
),
|
|
2347
|
+
elts=[cast(ast3.expr, i.gen.py_ast[0]) for i in node.values],
|
|
2372
2348
|
ctx=cast(ast3.expr_context, node.py_ctx_func()),
|
|
2373
2349
|
)
|
|
2374
2350
|
)
|
|
@@ -2601,8 +2577,8 @@ class PyastGenPass(UniPass):
|
|
|
2601
2577
|
func = node.target.gen.py_ast[0]
|
|
2602
2578
|
args = []
|
|
2603
2579
|
keywords = []
|
|
2604
|
-
if node.params
|
|
2605
|
-
for x in node.params
|
|
2580
|
+
if node.params:
|
|
2581
|
+
for x in node.params:
|
|
2606
2582
|
if isinstance(x, uni.UnaryExpr) and x.op.name == Tok.STAR_POW:
|
|
2607
2583
|
keywords.append(
|
|
2608
2584
|
self.sync(
|
|
@@ -2726,6 +2702,7 @@ class PyastGenPass(UniPass):
|
|
|
2726
2702
|
pynode = node.chain[0].gen.py_ast[0]
|
|
2727
2703
|
chomp = [*node.chain]
|
|
2728
2704
|
last_edge = None
|
|
2705
|
+
from_visit = bool(isinstance(node.parent, uni.VisitStmt))
|
|
2729
2706
|
if node.edges_only:
|
|
2730
2707
|
for i in node.chain:
|
|
2731
2708
|
if isinstance(i, uni.EdgeOpRef):
|
|
@@ -2748,6 +2725,7 @@ class PyastGenPass(UniPass):
|
|
|
2748
2725
|
else None
|
|
2749
2726
|
),
|
|
2750
2727
|
edges_only=node.edges_only and cur == last_edge,
|
|
2728
|
+
from_visit=from_visit,
|
|
2751
2729
|
)
|
|
2752
2730
|
if next_i and isinstance(next_i, uni.FilterCompr):
|
|
2753
2731
|
pynode = self.sync(
|
|
@@ -2777,6 +2755,7 @@ class PyastGenPass(UniPass):
|
|
|
2777
2755
|
cur,
|
|
2778
2756
|
targ=None,
|
|
2779
2757
|
edges_only=node.edges_only and cur == last_edge,
|
|
2758
|
+
from_visit=from_visit,
|
|
2780
2759
|
)
|
|
2781
2760
|
else:
|
|
2782
2761
|
raise self.ice("Invalid edge ref trailer")
|
|
@@ -2797,6 +2776,7 @@ class PyastGenPass(UniPass):
|
|
|
2797
2776
|
node: uni.EdgeOpRef,
|
|
2798
2777
|
targ: ast3.AST | None,
|
|
2799
2778
|
edges_only: bool,
|
|
2779
|
+
from_visit: bool,
|
|
2800
2780
|
) -> ast3.AST:
|
|
2801
2781
|
"""Generate ast for edge op ref call."""
|
|
2802
2782
|
keywords = [self.sync(ast3.keyword(arg="sources", value=cast(ast3.expr, loc)))]
|
|
@@ -2844,6 +2824,16 @@ class PyastGenPass(UniPass):
|
|
|
2844
2824
|
)
|
|
2845
2825
|
)
|
|
2846
2826
|
|
|
2827
|
+
if from_visit:
|
|
2828
|
+
keywords.append(
|
|
2829
|
+
self.sync(
|
|
2830
|
+
ast3.keyword(
|
|
2831
|
+
arg="from_visit",
|
|
2832
|
+
value=self.sync(ast3.Constant(value=from_visit)),
|
|
2833
|
+
)
|
|
2834
|
+
)
|
|
2835
|
+
)
|
|
2836
|
+
|
|
2847
2837
|
return self.sync(
|
|
2848
2838
|
ast3.Call(
|
|
2849
2839
|
func=self.jaclib_obj("refs"),
|
|
@@ -2949,7 +2939,7 @@ class PyastGenPass(UniPass):
|
|
|
2949
2939
|
),
|
|
2950
2940
|
jac_node=x,
|
|
2951
2941
|
)
|
|
2952
|
-
for x in
|
|
2942
|
+
for x in node.compares
|
|
2953
2943
|
if isinstance(x.gen.py_ast[0], ast3.Compare)
|
|
2954
2944
|
and isinstance(x.gen.py_ast[0].left, ast3.Name)
|
|
2955
2945
|
)
|
|
@@ -2984,7 +2974,7 @@ class PyastGenPass(UniPass):
|
|
|
2984
2974
|
def exit_assign_compr(self, node: uni.AssignCompr) -> None:
|
|
2985
2975
|
keys = []
|
|
2986
2976
|
values = []
|
|
2987
|
-
for i in node.assigns
|
|
2977
|
+
for i in node.assigns:
|
|
2988
2978
|
if i.key: # TODO: add support for **kwargs in assign_compr
|
|
2989
2979
|
keys.append(self.sync(ast3.Constant(i.key.sym_name)))
|
|
2990
2980
|
values.append(i.value.gen.py_ast[0])
|
|
@@ -3099,31 +3089,19 @@ class PyastGenPass(UniPass):
|
|
|
3099
3089
|
self.sync(
|
|
3100
3090
|
ast3.MatchClass(
|
|
3101
3091
|
cls=cast(ast3.expr, node.name.gen.py_ast[0]),
|
|
3102
|
-
patterns=
|
|
3103
|
-
[
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
]
|
|
3116
|
-
if node.kw_patterns
|
|
3117
|
-
else []
|
|
3118
|
-
),
|
|
3119
|
-
kwd_patterns=(
|
|
3120
|
-
[
|
|
3121
|
-
cast(ast3.pattern, x.value.gen.py_ast[0])
|
|
3122
|
-
for x in node.kw_patterns.items
|
|
3123
|
-
]
|
|
3124
|
-
if node.kw_patterns
|
|
3125
|
-
else []
|
|
3126
|
-
),
|
|
3092
|
+
patterns=[
|
|
3093
|
+
cast(ast3.pattern, x.gen.py_ast[0])
|
|
3094
|
+
for x in (node.arg_patterns or [])
|
|
3095
|
+
],
|
|
3096
|
+
kwd_attrs=[
|
|
3097
|
+
x.key.sym_name
|
|
3098
|
+
for x in (node.kw_patterns or [])
|
|
3099
|
+
if isinstance(x.key, uni.NameAtom)
|
|
3100
|
+
],
|
|
3101
|
+
kwd_patterns=[
|
|
3102
|
+
cast(ast3.pattern, x.value.gen.py_ast[0])
|
|
3103
|
+
for x in (node.kw_patterns or [])
|
|
3104
|
+
],
|
|
3127
3105
|
)
|
|
3128
3106
|
)
|
|
3129
3107
|
]
|