jaclang 0.8.7__py3-none-any.whl → 0.8.9__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 +77 -29
- jaclang/cli/cmdreg.py +44 -0
- jaclang/compiler/constant.py +6 -2
- jaclang/compiler/jac.lark +37 -47
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +356 -61
- jaclang/compiler/passes/main/__init__.py +2 -4
- jaclang/compiler/passes/main/def_use_pass.py +1 -4
- jaclang/compiler/passes/main/predynamo_pass.py +221 -0
- jaclang/compiler/passes/main/pyast_gen_pass.py +221 -135
- jaclang/compiler/passes/main/pyast_load_pass.py +54 -20
- jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -1
- jaclang/compiler/passes/main/tests/fixtures/checker/import_sym.jac +2 -0
- jaclang/compiler/passes/main/tests/fixtures/checker/import_sym_test.jac +6 -0
- jaclang/compiler/passes/main/tests/fixtures/checker/imported_sym.jac +5 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_arg_param_match.jac +37 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_arity.jac +18 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_cat_is_animal.jac +18 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_float.jac +7 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_param_types.jac +11 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_self_type.jac +9 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_sym_inherit.jac +42 -0
- jaclang/compiler/passes/main/tests/fixtures/predynamo_fix3.jac +43 -0
- jaclang/compiler/passes/main/tests/fixtures/predynamo_where_assign.jac +13 -0
- jaclang/compiler/passes/main/tests/fixtures/predynamo_where_return.jac +11 -0
- jaclang/compiler/passes/main/tests/test_checker_pass.py +190 -0
- jaclang/compiler/passes/main/tests/test_predynamo_pass.py +56 -0
- jaclang/compiler/passes/main/type_checker_pass.py +29 -73
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +302 -58
- jaclang/compiler/passes/tool/jac_formatter_pass.py +119 -69
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +3 -3
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +4 -5
- jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +7 -1
- jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +276 -10
- jaclang/compiler/passes/transform.py +12 -8
- jaclang/compiler/program.py +19 -7
- jaclang/compiler/tests/fixtures/jac_import_py_files.py +4 -0
- jaclang/compiler/tests/fixtures/jac_module.jac +3 -0
- jaclang/compiler/tests/fixtures/multiple_syntax_errors.jac +10 -0
- jaclang/compiler/tests/fixtures/python_module.py +1 -0
- jaclang/compiler/tests/test_importer.py +39 -0
- jaclang/compiler/tests/test_parser.py +49 -0
- jaclang/compiler/type_system/type_evaluator.jac +959 -0
- jaclang/compiler/type_system/type_utils.py +246 -0
- jaclang/compiler/type_system/types.py +58 -2
- jaclang/compiler/unitree.py +102 -107
- jaclang/langserve/engine.jac +138 -159
- jaclang/langserve/server.jac +25 -1
- jaclang/langserve/tests/fixtures/circle.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_pure.test.jac +3 -3
- jaclang/langserve/tests/fixtures/completion_test_err.jac +10 -0
- jaclang/langserve/tests/server_test/circle_template.jac +80 -0
- jaclang/langserve/tests/server_test/glob_template.jac +4 -0
- jaclang/langserve/tests/server_test/test_lang_serve.py +154 -309
- jaclang/langserve/tests/server_test/utils.py +153 -116
- jaclang/langserve/tests/test_server.py +21 -84
- jaclang/langserve/utils.jac +12 -15
- jaclang/lib.py +17 -0
- jaclang/runtimelib/archetype.py +25 -25
- jaclang/runtimelib/constructs.py +2 -2
- jaclang/runtimelib/machine.py +63 -46
- jaclang/runtimelib/meta_importer.py +27 -1
- jaclang/runtimelib/tests/fixtures/custom_access_validation.jac +1 -1
- jaclang/runtimelib/tests/fixtures/savable_object.jac +2 -2
- jaclang/settings.py +19 -16
- jaclang/tests/fixtures/abc_check.jac +3 -3
- jaclang/tests/fixtures/arch_rel_import_creation.jac +12 -12
- jaclang/tests/fixtures/attr_pattern_case.jac +18 -0
- jaclang/tests/fixtures/chandra_bugs2.jac +3 -3
- jaclang/tests/fixtures/create_dynamic_archetype.jac +13 -13
- jaclang/tests/fixtures/funccall_genexpr.jac +7 -0
- jaclang/tests/fixtures/funccall_genexpr.py +5 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
- jaclang/tests/fixtures/params/param_syntax_err.jac +9 -0
- jaclang/tests/fixtures/params/test_complex_params.jac +42 -0
- jaclang/tests/fixtures/params/test_failing_kwonly.jac +207 -0
- jaclang/tests/fixtures/params/test_failing_posonly.jac +116 -0
- jaclang/tests/fixtures/params/test_failing_varargs.jac +300 -0
- jaclang/tests/fixtures/params/test_kwonly_params.jac +29 -0
- jaclang/tests/fixtures/py2jac_params.py +8 -0
- jaclang/tests/fixtures/run_test.jac +4 -4
- jaclang/tests/test_cli.py +159 -7
- jaclang/tests/test_language.py +213 -38
- jaclang/tests/test_reference.py +3 -1
- jaclang/utils/helpers.py +67 -6
- jaclang/utils/module_resolver.py +10 -0
- jaclang/utils/test.py +8 -0
- jaclang/utils/tests/test_lang_tools.py +4 -15
- jaclang/utils/treeprinter.py +0 -18
- {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/METADATA +1 -2
- {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/RECORD +95 -65
- {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/WHEEL +1 -1
- jaclang/compiler/passes/main/inheritance_pass.py +0 -131
- jaclang/compiler/type_system/type_evaluator.py +0 -560
- jaclang/langserve/dev_engine.jac +0 -645
- jaclang/langserve/dev_server.jac +0 -201
- /jaclang/{langserve/tests/server_test/code_test.py → tests/fixtures/py2jac_empty.py} +0 -0
- {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/entry_points.txt +0 -0
|
@@ -64,7 +64,6 @@ TOKEN_AST_MAP: dict[Tok, type[ast3.AST]] = {
|
|
|
64
64
|
Tok.MINUS: ast3.Sub,
|
|
65
65
|
Tok.SUB_EQ: ast3.Sub,
|
|
66
66
|
Tok.BW_NOT: ast3.Invert,
|
|
67
|
-
Tok.BW_NOT_EQ: ast3.Invert,
|
|
68
67
|
Tok.NOT: ast3.Not,
|
|
69
68
|
Tok.EQ: ast3.NotEq,
|
|
70
69
|
Tok.EE: ast3.Eq,
|
|
@@ -92,11 +91,34 @@ UNARY_OP_MAP: dict[Tok, type[ast3.unaryop]] = {
|
|
|
92
91
|
class PyastGenPass(UniPass):
|
|
93
92
|
"""Jac blue transpilation to python pass."""
|
|
94
93
|
|
|
94
|
+
# Builtins that should be imported from jaclang.runtimelib.builtin
|
|
95
|
+
KNOWN_BUILTINS = {
|
|
96
|
+
"abstractmethod",
|
|
97
|
+
"ClassVar",
|
|
98
|
+
"override",
|
|
99
|
+
"printgraph",
|
|
100
|
+
"jid",
|
|
101
|
+
"jobj",
|
|
102
|
+
"grant",
|
|
103
|
+
"revoke",
|
|
104
|
+
"allroots",
|
|
105
|
+
"save",
|
|
106
|
+
"commit",
|
|
107
|
+
"NoPerm",
|
|
108
|
+
"ReadPerm",
|
|
109
|
+
"ConnectPerm",
|
|
110
|
+
"WritePerm",
|
|
111
|
+
}
|
|
112
|
+
|
|
95
113
|
def before_pass(self) -> None:
|
|
114
|
+
self.child_passes: list[PyastGenPass] = []
|
|
96
115
|
for i in self.ir_in.impl_mod + self.ir_in.test_mod:
|
|
97
|
-
PyastGenPass(ir_in=i, prog=self.prog)
|
|
116
|
+
child_pass = PyastGenPass(ir_in=i, prog=self.prog)
|
|
117
|
+
self.child_passes.append(child_pass)
|
|
98
118
|
self.debuginfo: dict[str, list[str]] = {"jac_mods": []}
|
|
99
119
|
self.already_added: list[str] = []
|
|
120
|
+
self.jaclib_imports: set[str] = set() # Track individual jaclib imports
|
|
121
|
+
self.builtin_imports: set[str] = set() # Track individual builtin imports
|
|
100
122
|
self.preamble: list[ast3.AST] = [
|
|
101
123
|
self.sync(
|
|
102
124
|
ast3.ImportFrom(
|
|
@@ -106,40 +128,6 @@ class PyastGenPass(UniPass):
|
|
|
106
128
|
),
|
|
107
129
|
jac_node=self.ir_out,
|
|
108
130
|
),
|
|
109
|
-
(
|
|
110
|
-
self.sync(
|
|
111
|
-
ast3.ImportFrom(
|
|
112
|
-
module="jaclang.runtimelib.builtin",
|
|
113
|
-
names=[
|
|
114
|
-
self.sync(
|
|
115
|
-
ast3.alias(
|
|
116
|
-
name="*",
|
|
117
|
-
asname=None,
|
|
118
|
-
)
|
|
119
|
-
)
|
|
120
|
-
],
|
|
121
|
-
level=0,
|
|
122
|
-
),
|
|
123
|
-
jac_node=self.ir_out,
|
|
124
|
-
)
|
|
125
|
-
),
|
|
126
|
-
(
|
|
127
|
-
self.sync(
|
|
128
|
-
ast3.ImportFrom(
|
|
129
|
-
module="jaclang",
|
|
130
|
-
names=[
|
|
131
|
-
self.sync(
|
|
132
|
-
ast3.alias(
|
|
133
|
-
name="JacMachineInterface",
|
|
134
|
-
asname=settings.pyout_jaclib_alias,
|
|
135
|
-
)
|
|
136
|
-
),
|
|
137
|
-
],
|
|
138
|
-
level=0,
|
|
139
|
-
),
|
|
140
|
-
jac_node=self.ir_out,
|
|
141
|
-
)
|
|
142
|
-
),
|
|
143
131
|
]
|
|
144
132
|
|
|
145
133
|
def enter_node(self, node: uni.UniNode) -> None:
|
|
@@ -161,15 +149,31 @@ class PyastGenPass(UniPass):
|
|
|
161
149
|
|
|
162
150
|
def jaclib_obj(self, obj_name: str) -> ast3.Name | ast3.Attribute:
|
|
163
151
|
"""Return the object from jaclib as ast node based on the import config."""
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
152
|
+
if settings.library_mode:
|
|
153
|
+
self.jaclib_imports.add(obj_name)
|
|
154
|
+
return self.sync(ast3.Name(id=obj_name, ctx=ast3.Load()))
|
|
155
|
+
else:
|
|
156
|
+
self.needs_jaclib()
|
|
157
|
+
return self.sync(
|
|
158
|
+
ast3.Attribute(
|
|
159
|
+
value=self.sync(
|
|
160
|
+
ast3.Name(id=settings.pyout_jaclib_alias, ctx=ast3.Load())
|
|
161
|
+
),
|
|
162
|
+
attr=obj_name,
|
|
163
|
+
ctx=ast3.Load(),
|
|
164
|
+
)
|
|
171
165
|
)
|
|
172
|
-
|
|
166
|
+
|
|
167
|
+
def builtin_name(self, name: str) -> ast3.Name:
|
|
168
|
+
"""Return a builtin name and track it for importing.
|
|
169
|
+
|
|
170
|
+
Note: Some names like 'Enum' are provided by other imports (e.g., needs_enum)
|
|
171
|
+
and should not be added to builtin_imports.
|
|
172
|
+
"""
|
|
173
|
+
# Enum is imported via needs_enum, not from builtins
|
|
174
|
+
if name not in ["Enum"]:
|
|
175
|
+
self.builtin_imports.add(name)
|
|
176
|
+
return self.sync(ast3.Name(id=name, ctx=ast3.Load()))
|
|
173
177
|
|
|
174
178
|
def _add_preamble_once(self, key: str, node: ast3.AST) -> None:
|
|
175
179
|
"""Append an import statement to the preamble once."""
|
|
@@ -187,15 +191,6 @@ class PyastGenPass(UniPass):
|
|
|
187
191
|
),
|
|
188
192
|
)
|
|
189
193
|
|
|
190
|
-
def needs_mtllm(self) -> None:
|
|
191
|
-
"""Ensure byLLM is imported only once."""
|
|
192
|
-
self._add_preamble_once(
|
|
193
|
-
self.needs_mtllm.__name__,
|
|
194
|
-
ast3.Import(
|
|
195
|
-
names=[self.sync(ast3.alias(name="byllm"), jac_node=self.ir_out)]
|
|
196
|
-
),
|
|
197
|
-
)
|
|
198
|
-
|
|
199
194
|
def needs_enum(self) -> None:
|
|
200
195
|
"""Ensure Enum utilities are imported only once."""
|
|
201
196
|
self._add_preamble_once(
|
|
@@ -221,6 +216,24 @@ class PyastGenPass(UniPass):
|
|
|
221
216
|
),
|
|
222
217
|
)
|
|
223
218
|
|
|
219
|
+
def needs_jaclib(self) -> None:
|
|
220
|
+
"""Ensure JacMachineInterface is imported only once."""
|
|
221
|
+
self._add_preamble_once(
|
|
222
|
+
self.needs_jaclib.__name__,
|
|
223
|
+
ast3.ImportFrom(
|
|
224
|
+
module="jaclang",
|
|
225
|
+
names=[
|
|
226
|
+
self.sync(
|
|
227
|
+
ast3.alias(
|
|
228
|
+
name="JacMachineInterface",
|
|
229
|
+
asname=settings.pyout_jaclib_alias,
|
|
230
|
+
)
|
|
231
|
+
)
|
|
232
|
+
],
|
|
233
|
+
level=0,
|
|
234
|
+
),
|
|
235
|
+
)
|
|
236
|
+
|
|
224
237
|
def _get_sem_decorator(self, node: uni.UniNode) -> ast3.Call | None:
|
|
225
238
|
"""Create a semstring decorator for the given semantic strings.
|
|
226
239
|
|
|
@@ -283,7 +296,10 @@ class PyastGenPass(UniPass):
|
|
|
283
296
|
else {}
|
|
284
297
|
)
|
|
285
298
|
|
|
286
|
-
if
|
|
299
|
+
# Only add sem decorator if there's actual semantic content
|
|
300
|
+
if not semstr and (
|
|
301
|
+
not inner_semstr or all(not v for v in inner_semstr.values())
|
|
302
|
+
):
|
|
287
303
|
return None
|
|
288
304
|
|
|
289
305
|
return self.sync(
|
|
@@ -417,6 +433,48 @@ class PyastGenPass(UniPass):
|
|
|
417
433
|
node.gen.py_ast = node.tag.gen.py_ast
|
|
418
434
|
|
|
419
435
|
def exit_module(self, node: uni.Module) -> None:
|
|
436
|
+
# Check if any child passes (impl_mod or test_mod) needed jaclib
|
|
437
|
+
for child_pass in self.child_passes:
|
|
438
|
+
if "needs_jaclib" in child_pass.already_added:
|
|
439
|
+
self.needs_jaclib()
|
|
440
|
+
break
|
|
441
|
+
# Merge jaclib and builtin imports from child passes
|
|
442
|
+
if settings.library_mode:
|
|
443
|
+
self.jaclib_imports.update(child_pass.jaclib_imports)
|
|
444
|
+
self.builtin_imports.update(child_pass.builtin_imports)
|
|
445
|
+
|
|
446
|
+
# Add builtin imports if any were used
|
|
447
|
+
if self.builtin_imports:
|
|
448
|
+
self.preamble.append(
|
|
449
|
+
self.sync(
|
|
450
|
+
ast3.ImportFrom(
|
|
451
|
+
module="jaclang.runtimelib.builtin",
|
|
452
|
+
names=[
|
|
453
|
+
self.sync(ast3.alias(name=name, asname=None))
|
|
454
|
+
for name in sorted(self.builtin_imports)
|
|
455
|
+
],
|
|
456
|
+
level=0,
|
|
457
|
+
),
|
|
458
|
+
jac_node=self.ir_out,
|
|
459
|
+
)
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
# Add library mode imports at the end of preamble
|
|
463
|
+
if settings.library_mode and self.jaclib_imports:
|
|
464
|
+
self.preamble.append(
|
|
465
|
+
self.sync(
|
|
466
|
+
ast3.ImportFrom(
|
|
467
|
+
module="jaclang.lib",
|
|
468
|
+
names=[
|
|
469
|
+
self.sync(ast3.alias(name=name, asname=None))
|
|
470
|
+
for name in sorted(self.jaclib_imports)
|
|
471
|
+
],
|
|
472
|
+
level=0,
|
|
473
|
+
),
|
|
474
|
+
jac_node=self.ir_out,
|
|
475
|
+
)
|
|
476
|
+
)
|
|
477
|
+
|
|
420
478
|
clean_body = [i for i in node.body if not isinstance(i, uni.ImplDef)]
|
|
421
479
|
pre_body: list[uni.UniNode] = []
|
|
422
480
|
for pbody in node.impl_mod:
|
|
@@ -722,7 +780,7 @@ class PyastGenPass(UniPass):
|
|
|
722
780
|
decorators.append(sem_decorator)
|
|
723
781
|
|
|
724
782
|
base_classes = [cast(ast3.expr, i.gen.py_ast[0]) for i in node.base_classes]
|
|
725
|
-
base_classes.append(self.
|
|
783
|
+
base_classes.append(self.builtin_name("Enum"))
|
|
726
784
|
node.gen.py_ast = [
|
|
727
785
|
self.sync(
|
|
728
786
|
ast3.ClassDef(
|
|
@@ -744,23 +802,9 @@ class PyastGenPass(UniPass):
|
|
|
744
802
|
self, model: ast3.expr, caller: ast3.expr, args: ast3.Dict
|
|
745
803
|
) -> ast3.Call:
|
|
746
804
|
"""Reusable method to codegen call_llm(model, caller, args)."""
|
|
747
|
-
self.needs_mtllm()
|
|
748
|
-
mtir_cls_ast = self.sync(
|
|
749
|
-
ast3.Attribute(
|
|
750
|
-
value=self.sync(ast3.Name(id="byllm", ctx=ast3.Load())),
|
|
751
|
-
attr="MTIR",
|
|
752
|
-
ctx=ast3.Load(),
|
|
753
|
-
)
|
|
754
|
-
)
|
|
755
805
|
mtir_ast = self.sync(
|
|
756
806
|
ast3.Call(
|
|
757
|
-
func=self.
|
|
758
|
-
ast3.Attribute(
|
|
759
|
-
value=mtir_cls_ast,
|
|
760
|
-
attr="factory",
|
|
761
|
-
ctx=ast3.Load(),
|
|
762
|
-
)
|
|
763
|
-
),
|
|
807
|
+
func=self.jaclib_obj("get_mtir"),
|
|
764
808
|
args=[],
|
|
765
809
|
keywords=[
|
|
766
810
|
self.sync(
|
|
@@ -928,7 +972,9 @@ class PyastGenPass(UniPass):
|
|
|
928
972
|
if isinstance(node.signature, uni.EventSignature):
|
|
929
973
|
decorator_list.append(
|
|
930
974
|
self.jaclib_obj(
|
|
931
|
-
"
|
|
975
|
+
"on_entry"
|
|
976
|
+
if node.signature.event.name == Tok.KW_ENTRY
|
|
977
|
+
else "on_exit"
|
|
932
978
|
)
|
|
933
979
|
)
|
|
934
980
|
|
|
@@ -943,11 +989,9 @@ class PyastGenPass(UniPass):
|
|
|
943
989
|
)
|
|
944
990
|
)
|
|
945
991
|
if node.is_abstract:
|
|
946
|
-
decorator_list.append(
|
|
947
|
-
self.sync(ast3.Name(id="abstractmethod", ctx=ast3.Load()))
|
|
948
|
-
)
|
|
992
|
+
decorator_list.append(self.builtin_name("abstractmethod"))
|
|
949
993
|
if node.is_override:
|
|
950
|
-
decorator_list.append(self.
|
|
994
|
+
decorator_list.append(self.builtin_name("override"))
|
|
951
995
|
if node.is_static:
|
|
952
996
|
decorator_list.insert(
|
|
953
997
|
0, self.sync(ast3.Name(id="staticmethod", ctx=ast3.Load()))
|
|
@@ -1000,6 +1044,9 @@ class PyastGenPass(UniPass):
|
|
|
1000
1044
|
pass
|
|
1001
1045
|
|
|
1002
1046
|
def exit_func_signature(self, node: uni.FuncSignature) -> None:
|
|
1047
|
+
posonlyargs = [i.gen.py_ast[0] for i in node.posonly_params]
|
|
1048
|
+
vararg = node.varargs.gen.py_ast[0] if node.varargs else None
|
|
1049
|
+
kwarg = node.kwargs.gen.py_ast[0] if node.kwargs else None
|
|
1003
1050
|
params = (
|
|
1004
1051
|
[self.sync(ast3.arg(arg="self", annotation=None))]
|
|
1005
1052
|
if (abl := node.parent)
|
|
@@ -1009,29 +1056,33 @@ class PyastGenPass(UniPass):
|
|
|
1009
1056
|
and not node.is_in_py_class
|
|
1010
1057
|
else []
|
|
1011
1058
|
)
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1059
|
+
if posonlyargs:
|
|
1060
|
+
posonlyargs = params + posonlyargs
|
|
1061
|
+
params = [i.gen.py_ast[0] for i in node.params]
|
|
1062
|
+
else:
|
|
1063
|
+
params = params + [i.gen.py_ast[0] for i in node.params]
|
|
1064
|
+
defaults = []
|
|
1065
|
+
for i in [*node.posonly_params, *node.params]:
|
|
1066
|
+
if i.value:
|
|
1067
|
+
defaults.append(cast(ast3.expr, i.value.gen.py_ast[0]))
|
|
1068
|
+
kwonly_args = [i.gen.py_ast[0] for i in node.kwonlyargs]
|
|
1069
|
+
# kw_defaults must be the same length as kwonlyargs
|
|
1070
|
+
# it will have None for args that don't have defaults
|
|
1071
|
+
kw_defaults: list[ast3.expr | None] = []
|
|
1072
|
+
for i in node.kwonlyargs:
|
|
1073
|
+
if i.value:
|
|
1074
|
+
kw_defaults.append(cast(ast3.expr, i.value.gen.py_ast[0]))
|
|
1019
1075
|
else:
|
|
1020
|
-
(
|
|
1021
|
-
params.append(i.gen.py_ast[0])
|
|
1022
|
-
if isinstance(i.gen.py_ast[0], ast3.arg)
|
|
1023
|
-
else self.ice("This list should only be Args")
|
|
1024
|
-
)
|
|
1025
|
-
defaults = [x.value.gen.py_ast[0] for x in node.params if x.value]
|
|
1076
|
+
kw_defaults.append(None)
|
|
1026
1077
|
node.gen.py_ast = [
|
|
1027
1078
|
self.sync(
|
|
1028
1079
|
ast3.arguments(
|
|
1029
|
-
posonlyargs=[],
|
|
1080
|
+
posonlyargs=[cast(ast3.arg, param) for param in posonlyargs],
|
|
1030
1081
|
args=[cast(ast3.arg, param) for param in params],
|
|
1031
|
-
kwonlyargs=
|
|
1082
|
+
kwonlyargs=kwonly_args,
|
|
1032
1083
|
vararg=cast(ast3.arg, vararg) if vararg else None,
|
|
1033
1084
|
kwarg=cast(ast3.arg, kwarg) if kwarg else None,
|
|
1034
|
-
kw_defaults=
|
|
1085
|
+
kw_defaults=kw_defaults,
|
|
1035
1086
|
defaults=[cast(ast3.expr, default) for default in defaults],
|
|
1036
1087
|
)
|
|
1037
1088
|
)
|
|
@@ -1138,7 +1189,7 @@ class PyastGenPass(UniPass):
|
|
|
1138
1189
|
elif is_static_var:
|
|
1139
1190
|
annotation = self.sync(
|
|
1140
1191
|
ast3.Subscript(
|
|
1141
|
-
value=self.
|
|
1192
|
+
value=self.builtin_name("ClassVar"),
|
|
1142
1193
|
slice=cast(ast3.expr, annotation),
|
|
1143
1194
|
ctx=ast3.Load(),
|
|
1144
1195
|
)
|
|
@@ -1215,8 +1266,29 @@ class PyastGenPass(UniPass):
|
|
|
1215
1266
|
]
|
|
1216
1267
|
|
|
1217
1268
|
def exit_typed_ctx_block(self, node: uni.TypedCtxBlock) -> None:
|
|
1218
|
-
|
|
1219
|
-
|
|
1269
|
+
loc = self.sync(
|
|
1270
|
+
ast3.Name(id=Con.HERE.value, ctx=ast3.Load())
|
|
1271
|
+
if node.from_walker
|
|
1272
|
+
else ast3.Name(id=Con.VISITOR.value, ctx=ast3.Load())
|
|
1273
|
+
)
|
|
1274
|
+
node.gen.py_ast = [
|
|
1275
|
+
self.sync(
|
|
1276
|
+
ast3.If(
|
|
1277
|
+
test=self.sync(
|
|
1278
|
+
ast3.Call(
|
|
1279
|
+
func=self.sync(ast3.Name(id="isinstance", ctx=ast3.Load())),
|
|
1280
|
+
args=[
|
|
1281
|
+
loc,
|
|
1282
|
+
cast(ast3.expr, node.type_ctx.gen.py_ast[0]),
|
|
1283
|
+
],
|
|
1284
|
+
keywords=[],
|
|
1285
|
+
)
|
|
1286
|
+
),
|
|
1287
|
+
body=cast(list[ast3.stmt], self.resolve_stmt_block(node.body)),
|
|
1288
|
+
orelse=[],
|
|
1289
|
+
)
|
|
1290
|
+
)
|
|
1291
|
+
]
|
|
1220
1292
|
|
|
1221
1293
|
def exit_if_stmt(self, node: uni.IfStmt) -> None:
|
|
1222
1294
|
node.gen.py_ast = [
|
|
@@ -1467,20 +1539,23 @@ class PyastGenPass(UniPass):
|
|
|
1467
1539
|
]
|
|
1468
1540
|
|
|
1469
1541
|
def exit_assert_stmt(self, node: uni.AssertStmt) -> None:
|
|
1470
|
-
node.
|
|
1471
|
-
self.
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1542
|
+
if isinstance(node.parent, uni.Test):
|
|
1543
|
+
self.assert_helper(node)
|
|
1544
|
+
else:
|
|
1545
|
+
node.gen.py_ast = [
|
|
1546
|
+
self.sync(
|
|
1547
|
+
ast3.Assert(
|
|
1548
|
+
test=cast(ast3.expr, node.condition.gen.py_ast[0]),
|
|
1549
|
+
msg=(
|
|
1550
|
+
cast(ast3.expr, node.error_msg.gen.py_ast[0])
|
|
1551
|
+
if node.error_msg
|
|
1552
|
+
else None
|
|
1553
|
+
),
|
|
1554
|
+
)
|
|
1479
1555
|
)
|
|
1480
|
-
|
|
1481
|
-
]
|
|
1556
|
+
]
|
|
1482
1557
|
|
|
1483
|
-
def
|
|
1558
|
+
def assert_helper(self, node: uni.AssertStmt) -> None:
|
|
1484
1559
|
"""Sub objects.
|
|
1485
1560
|
|
|
1486
1561
|
target: ExprType,
|
|
@@ -1536,16 +1611,16 @@ class PyastGenPass(UniPass):
|
|
|
1536
1611
|
|
|
1537
1612
|
# By default the check expression will become assertTrue(<expr>), unless any pattern detected.
|
|
1538
1613
|
assert_func_name = "assertTrue"
|
|
1539
|
-
assert_args_list = node.
|
|
1614
|
+
assert_args_list = node.condition.gen.py_ast
|
|
1540
1615
|
|
|
1541
1616
|
# Compare operations. Note that We're only considering the compare
|
|
1542
1617
|
# operation with a single operation ie. a < b < c is ignored here.
|
|
1543
1618
|
if (
|
|
1544
|
-
isinstance(node.
|
|
1545
|
-
and isinstance(node.
|
|
1546
|
-
and len(node.
|
|
1619
|
+
isinstance(node.condition, uni.CompareExpr)
|
|
1620
|
+
and isinstance(node.condition.gen.py_ast[0], ast3.Compare)
|
|
1621
|
+
and len(node.condition.ops) == 1
|
|
1547
1622
|
):
|
|
1548
|
-
expr: uni.CompareExpr = node.
|
|
1623
|
+
expr: uni.CompareExpr = node.condition
|
|
1549
1624
|
opty: uni.Token = expr.ops[0]
|
|
1550
1625
|
|
|
1551
1626
|
optype2fn = {
|
|
@@ -1579,10 +1654,10 @@ class PyastGenPass(UniPass):
|
|
|
1579
1654
|
assert_args_list.pop()
|
|
1580
1655
|
|
|
1581
1656
|
# Check if 'isinstance' is called.
|
|
1582
|
-
elif isinstance(node.
|
|
1583
|
-
node.
|
|
1657
|
+
elif isinstance(node.condition, uni.FuncCall) and isinstance(
|
|
1658
|
+
node.condition.gen.py_ast[0], ast3.Call
|
|
1584
1659
|
):
|
|
1585
|
-
res = check_node_isinstance_call(node.
|
|
1660
|
+
res = check_node_isinstance_call(node.condition)
|
|
1586
1661
|
if res.isit:
|
|
1587
1662
|
# These assertions will make mypy happy.
|
|
1588
1663
|
assert isinstance(res.inst, ast3.AST)
|
|
@@ -1592,12 +1667,12 @@ class PyastGenPass(UniPass):
|
|
|
1592
1667
|
|
|
1593
1668
|
# Check if 'not isinstance(<expr>, <expr>)' is called.
|
|
1594
1669
|
elif (
|
|
1595
|
-
isinstance(node.
|
|
1596
|
-
and isinstance(node.
|
|
1597
|
-
and isinstance(node.
|
|
1598
|
-
and isinstance(node.
|
|
1670
|
+
isinstance(node.condition, uni.UnaryExpr)
|
|
1671
|
+
and isinstance(node.condition, uni.UnaryExpr)
|
|
1672
|
+
and isinstance(node.condition.operand, uni.FuncCall)
|
|
1673
|
+
and isinstance(node.condition.operand, uni.UnaryExpr)
|
|
1599
1674
|
):
|
|
1600
|
-
res = check_node_isinstance_call(node.
|
|
1675
|
+
res = check_node_isinstance_call(node.condition.operand)
|
|
1601
1676
|
if res.isit:
|
|
1602
1677
|
# These assertions will make mypy happy.
|
|
1603
1678
|
assert isinstance(res.inst, ast3.AST)
|
|
@@ -1610,14 +1685,14 @@ class PyastGenPass(UniPass):
|
|
|
1610
1685
|
# the almost equal functionality (snice there is no almost equal operator in jac and never needed ig.).
|
|
1611
1686
|
|
|
1612
1687
|
# Check if 'almostEqual' is called.
|
|
1613
|
-
if isinstance(node.
|
|
1614
|
-
node.
|
|
1688
|
+
if isinstance(node.condition, uni.FuncCall) and isinstance(
|
|
1689
|
+
node.condition.gen.py_ast[0], ast3.Call
|
|
1615
1690
|
):
|
|
1616
|
-
func = node.
|
|
1691
|
+
func = node.condition.target
|
|
1617
1692
|
if isinstance(func, uni.Name) and func.value == "almostEqual":
|
|
1618
1693
|
assert_func_name = "assertAlmostEqual"
|
|
1619
1694
|
assert_args_list = []
|
|
1620
|
-
for param in node.
|
|
1695
|
+
for param in node.condition.params:
|
|
1621
1696
|
assert_args_list.append(param.gen.py_ast[0])
|
|
1622
1697
|
|
|
1623
1698
|
# assert_func_expr = "Con.JAC_CHECK.value.assertXXX"
|
|
@@ -1989,7 +2064,7 @@ class PyastGenPass(UniPass):
|
|
|
1989
2064
|
keywords.append(
|
|
1990
2065
|
self.sync(
|
|
1991
2066
|
ast3.keyword(
|
|
1992
|
-
arg="
|
|
2067
|
+
arg="filter_on",
|
|
1993
2068
|
value=cast(
|
|
1994
2069
|
ast3.expr,
|
|
1995
2070
|
node.op.edge_spec.filter_cond.gen.py_ast[0],
|
|
@@ -2196,7 +2271,7 @@ class PyastGenPass(UniPass):
|
|
|
2196
2271
|
node.gen.py_ast = [
|
|
2197
2272
|
self.sync(
|
|
2198
2273
|
ast3.Call(
|
|
2199
|
-
func=self.
|
|
2274
|
+
func=self.builtin_name("jobj"),
|
|
2200
2275
|
args=[],
|
|
2201
2276
|
keywords=[
|
|
2202
2277
|
self.sync(
|
|
@@ -2421,7 +2496,7 @@ class PyastGenPass(UniPass):
|
|
|
2421
2496
|
node.gen.py_ast = [
|
|
2422
2497
|
self.sync(
|
|
2423
2498
|
ast3.Call(
|
|
2424
|
-
func=self.jaclib_obj("
|
|
2499
|
+
func=self.jaclib_obj("filter_on"),
|
|
2425
2500
|
args=[],
|
|
2426
2501
|
keywords=[
|
|
2427
2502
|
self.sync(
|
|
@@ -2444,7 +2519,7 @@ class PyastGenPass(UniPass):
|
|
|
2444
2519
|
node.gen.py_ast = [
|
|
2445
2520
|
self.sync(
|
|
2446
2521
|
ast3.Call(
|
|
2447
|
-
func=self.jaclib_obj("
|
|
2522
|
+
func=self.jaclib_obj("assign_all"),
|
|
2448
2523
|
args=cast(
|
|
2449
2524
|
list[ast3.expr],
|
|
2450
2525
|
[node.target.gen.py_ast[0], node.right.gen.py_ast[0]],
|
|
@@ -2675,7 +2750,7 @@ class PyastGenPass(UniPass):
|
|
|
2675
2750
|
func=self.sync(
|
|
2676
2751
|
ast3.Attribute(
|
|
2677
2752
|
value=pynode,
|
|
2678
|
-
attr=f"
|
|
2753
|
+
attr=f"edge_{cur.edge_dir.name.lower()}",
|
|
2679
2754
|
ctx=ast3.Load(),
|
|
2680
2755
|
)
|
|
2681
2756
|
),
|
|
@@ -2718,14 +2793,22 @@ class PyastGenPass(UniPass):
|
|
|
2718
2793
|
keywords=[],
|
|
2719
2794
|
)
|
|
2720
2795
|
)
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2796
|
+
if node.is_async:
|
|
2797
|
+
pynode = self.sync(
|
|
2798
|
+
ast3.Call(
|
|
2799
|
+
func=self.jaclib_obj("arefs"),
|
|
2800
|
+
args=[pynode],
|
|
2801
|
+
keywords=[],
|
|
2802
|
+
)
|
|
2803
|
+
)
|
|
2804
|
+
else:
|
|
2805
|
+
pynode = self.sync(
|
|
2806
|
+
ast3.Call(
|
|
2807
|
+
func=self.jaclib_obj("refs"),
|
|
2808
|
+
args=[pynode],
|
|
2809
|
+
keywords=[],
|
|
2810
|
+
)
|
|
2727
2811
|
)
|
|
2728
|
-
)
|
|
2729
2812
|
|
|
2730
2813
|
node.gen.py_ast = [pynode]
|
|
2731
2814
|
|
|
@@ -3008,6 +3091,9 @@ class PyastGenPass(UniPass):
|
|
|
3008
3091
|
|
|
3009
3092
|
def exit_name(self, node: uni.Name) -> None:
|
|
3010
3093
|
name = node.sym_name
|
|
3094
|
+
# Track if this name is a known builtin
|
|
3095
|
+
if name in self.KNOWN_BUILTINS:
|
|
3096
|
+
self.builtin_imports.add(name)
|
|
3011
3097
|
node.gen.py_ast = [self.sync(ast3.Name(id=name, ctx=node.py_ctx_func()))]
|
|
3012
3098
|
|
|
3013
3099
|
def exit_float(self, node: uni.Float) -> None:
|