jaclang 0.7.14__py3-none-any.whl → 0.7.16__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 +15 -10
- jaclang/cli/cmdreg.py +9 -12
- jaclang/compiler/__init__.py +19 -53
- jaclang/compiler/absyntree.py +86 -13
- jaclang/compiler/jac.lark +4 -3
- jaclang/compiler/parser.py +31 -23
- jaclang/compiler/passes/ir_pass.py +4 -13
- jaclang/compiler/passes/main/access_modifier_pass.py +1 -1
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +4 -5
- jaclang/compiler/passes/main/import_pass.py +18 -23
- jaclang/compiler/passes/main/pyast_gen_pass.py +307 -559
- jaclang/compiler/passes/main/pyast_load_pass.py +32 -6
- jaclang/compiler/passes/main/registry_pass.py +37 -3
- jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -1
- jaclang/compiler/passes/main/tests/__init__.py +1 -1
- jaclang/compiler/passes/main/type_check_pass.py +7 -0
- jaclang/compiler/passes/tool/jac_formatter_pass.py +124 -86
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +0 -1
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/architype_test.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comment_alignment.jac +11 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comments.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/decorator_stack.jac +37 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/esc_keywords.jac +5 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/long_names.jac +19 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +6 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -0
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +33 -39
- jaclang/compiler/passes/transform.py +4 -0
- jaclang/compiler/semtable.py +31 -7
- jaclang/compiler/tests/test_importer.py +12 -5
- jaclang/langserve/engine.py +65 -118
- jaclang/langserve/sem_manager.py +379 -0
- jaclang/langserve/server.py +8 -10
- jaclang/langserve/tests/fixtures/base_module_structure.jac +27 -6
- 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/import_include_statements.jac +1 -1
- jaclang/langserve/tests/test_sem_tokens.py +277 -0
- jaclang/langserve/tests/test_server.py +72 -16
- jaclang/langserve/utils.py +163 -96
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +212 -24
- jaclang/plugin/feature.py +59 -11
- jaclang/plugin/spec.py +58 -6
- jaclang/{core → runtimelib}/architype.py +1 -1
- jaclang/{core → runtimelib}/context.py +8 -1
- jaclang/runtimelib/importer.py +361 -0
- jaclang/runtimelib/machine.py +94 -0
- jaclang/{core → runtimelib}/utils.py +13 -5
- jaclang/settings.py +4 -1
- jaclang/tests/fixtures/abc.jac +3 -3
- jaclang/tests/fixtures/byllmissue.jac +1 -5
- jaclang/tests/fixtures/chandra_bugs2.jac +11 -10
- jaclang/tests/fixtures/cls_method.jac +41 -0
- jaclang/tests/fixtures/dblhello.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +3 -3
- jaclang/tests/fixtures/deep/one_lev_dup.jac +2 -3
- jaclang/tests/fixtures/deep_import_mods.jac +13 -0
- jaclang/tests/fixtures/err.impl.jac +3 -0
- jaclang/tests/fixtures/err.jac +4 -2
- jaclang/tests/fixtures/err.test.jac +3 -0
- jaclang/tests/fixtures/err_runtime.jac +15 -0
- jaclang/tests/fixtures/game1.jac +1 -1
- jaclang/tests/fixtures/hello.jac +4 -0
- jaclang/tests/fixtures/impl_grab.impl.jac +2 -1
- jaclang/tests/fixtures/impl_grab.jac +4 -1
- jaclang/tests/fixtures/jp_importer_auto.jac +14 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
- jaclang/tests/fixtures/needs_import.jac +2 -2
- jaclang/tests/fixtures/pyfunc_2.py +3 -0
- jaclang/tests/fixtures/registry.jac +9 -0
- jaclang/tests/fixtures/run_test.jac +4 -4
- jaclang/tests/fixtures/semstr.jac +1 -4
- jaclang/tests/fixtures/simple_archs.jac +1 -1
- jaclang/tests/test_cli.py +65 -2
- jaclang/tests/test_language.py +74 -7
- jaclang/tests/test_reference.py +6 -0
- jaclang/utils/helpers.py +45 -21
- jaclang/utils/test.py +9 -0
- jaclang/utils/treeprinter.py +0 -4
- {jaclang-0.7.14.dist-info → jaclang-0.7.16.dist-info}/METADATA +3 -2
- {jaclang-0.7.14.dist-info → jaclang-0.7.16.dist-info}/RECORD +89 -74
- jaclang/core/importer.py +0 -344
- jaclang/tests/fixtures/aott_raise.jac +0 -25
- jaclang/tests/fixtures/package_import.jac +0 -6
- /jaclang/{core → runtimelib}/__init__.py +0 -0
- /jaclang/{core → runtimelib}/constructs.py +0 -0
- /jaclang/{core → runtimelib}/memory.py +0 -0
- /jaclang/{core → runtimelib}/test.py +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.16.dist-info}/WHEEL +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.16.dist-info}/entry_points.txt +0 -0
|
@@ -6,12 +6,12 @@ in each node. Module nodes contain the entire module code.
|
|
|
6
6
|
|
|
7
7
|
import ast as ast3
|
|
8
8
|
import textwrap
|
|
9
|
+
from dataclasses import dataclass
|
|
9
10
|
from typing import Optional, Sequence, TypeVar
|
|
10
11
|
|
|
11
12
|
import jaclang.compiler.absyntree as ast
|
|
12
13
|
from jaclang.compiler.constant import Constants as Con, EdgeDir, Tokens as Tok
|
|
13
14
|
from jaclang.compiler.passes import Pass
|
|
14
|
-
from jaclang.core.utils import extract_params, extract_type, get_sem_scope
|
|
15
15
|
|
|
16
16
|
T = TypeVar("T", bound=ast3.AST)
|
|
17
17
|
|
|
@@ -19,24 +19,25 @@ T = TypeVar("T", bound=ast3.AST)
|
|
|
19
19
|
class PyastGenPass(Pass):
|
|
20
20
|
"""Jac blue transpilation to python pass."""
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
# TODO: This should live in utils and perhaps a test added using it
|
|
23
|
+
# @staticmethod
|
|
24
|
+
# def node_compilable_test(node: ast3.AST) -> None:
|
|
25
|
+
# """Convert any AST node to a compilable module node."""
|
|
26
|
+
# if isinstance(node, ast3.Module):
|
|
27
|
+
# pass
|
|
28
|
+
# elif isinstance(node, (ast3.Expr, ast3.stmt)):
|
|
29
|
+
# node = ast3.Module(body=[node], type_ignores=[])
|
|
30
|
+
# elif isinstance(node, list) and all(isinstance(n, ast3.stmt) for n in node):
|
|
31
|
+
# node = ast3.Module(body=node, type_ignores=[])
|
|
32
|
+
# else:
|
|
33
|
+
# node = ast3.Module(body=[], type_ignores=[])
|
|
34
|
+
# try:
|
|
35
|
+
# compile(node, "<ast>", "exec")
|
|
36
|
+
# except TypeError as e:
|
|
37
|
+
# print(ast3.dump(node, indent=2))
|
|
38
|
+
# raise e
|
|
39
|
+
# except Exception:
|
|
40
|
+
# pass
|
|
40
41
|
|
|
41
42
|
def before_pass(self) -> None:
|
|
42
43
|
"""Initialize pass."""
|
|
@@ -51,14 +52,6 @@ class PyastGenPass(Pass):
|
|
|
51
52
|
),
|
|
52
53
|
jac_node=self.ir,
|
|
53
54
|
),
|
|
54
|
-
self.sync(
|
|
55
|
-
ast3.ImportFrom(
|
|
56
|
-
module="typing",
|
|
57
|
-
names=[self.sync(ast3.alias(name="TYPE_CHECKING", asname=None))],
|
|
58
|
-
level=0,
|
|
59
|
-
),
|
|
60
|
-
jac_node=self.ir,
|
|
61
|
-
),
|
|
62
55
|
]
|
|
63
56
|
|
|
64
57
|
def enter_node(self, node: ast.AstNode) -> None:
|
|
@@ -80,7 +73,7 @@ class PyastGenPass(Pass):
|
|
|
80
73
|
|
|
81
74
|
def needs_jac_import(self) -> None:
|
|
82
75
|
"""Check if import is needed."""
|
|
83
|
-
if
|
|
76
|
+
if self.needs_jac_import.__name__ in self.already_added:
|
|
84
77
|
return
|
|
85
78
|
self.preamble.append(
|
|
86
79
|
self.sync(
|
|
@@ -96,11 +89,11 @@ class PyastGenPass(Pass):
|
|
|
96
89
|
jac_node=self.ir,
|
|
97
90
|
)
|
|
98
91
|
)
|
|
99
|
-
self.already_added.append(
|
|
92
|
+
self.already_added.append(self.needs_jac_import.__name__)
|
|
100
93
|
|
|
101
94
|
def needs_typing(self) -> None:
|
|
102
95
|
"""Check if enum is needed."""
|
|
103
|
-
if
|
|
96
|
+
if self.needs_typing.__name__ in self.already_added:
|
|
104
97
|
return
|
|
105
98
|
self.preamble.append(
|
|
106
99
|
self.sync(
|
|
@@ -115,11 +108,30 @@ class PyastGenPass(Pass):
|
|
|
115
108
|
jac_node=self.ir,
|
|
116
109
|
)
|
|
117
110
|
)
|
|
118
|
-
self.already_added.append(
|
|
111
|
+
self.already_added.append(self.needs_typing.__name__)
|
|
112
|
+
|
|
113
|
+
def needs_abc(self) -> None:
|
|
114
|
+
"""Check if enum is needed."""
|
|
115
|
+
if self.needs_abc.__name__ in self.already_added:
|
|
116
|
+
return
|
|
117
|
+
self.preamble.append(
|
|
118
|
+
self.sync(
|
|
119
|
+
ast3.Import(
|
|
120
|
+
names=[
|
|
121
|
+
self.sync(
|
|
122
|
+
ast3.alias(name="abc", asname="_jac_abc"),
|
|
123
|
+
jac_node=self.ir,
|
|
124
|
+
),
|
|
125
|
+
]
|
|
126
|
+
),
|
|
127
|
+
jac_node=self.ir,
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
self.already_added.append(self.needs_abc.__name__)
|
|
119
131
|
|
|
120
132
|
def needs_enum(self) -> None:
|
|
121
133
|
"""Check if enum is needed."""
|
|
122
|
-
if
|
|
134
|
+
if self.needs_enum.__name__ in self.already_added:
|
|
123
135
|
return
|
|
124
136
|
self.preamble.append(
|
|
125
137
|
self.sync(
|
|
@@ -134,11 +146,11 @@ class PyastGenPass(Pass):
|
|
|
134
146
|
jac_node=self.ir,
|
|
135
147
|
)
|
|
136
148
|
)
|
|
137
|
-
self.already_added.append(
|
|
149
|
+
self.already_added.append(self.needs_enum.__name__)
|
|
138
150
|
|
|
139
151
|
def needs_jac_feature(self) -> None:
|
|
140
152
|
"""Check if enum is needed."""
|
|
141
|
-
if
|
|
153
|
+
if self.needs_jac_feature.__name__ in self.already_added:
|
|
142
154
|
return
|
|
143
155
|
self.preamble.append(
|
|
144
156
|
self.sync(
|
|
@@ -164,11 +176,11 @@ class PyastGenPass(Pass):
|
|
|
164
176
|
jac_node=self.ir,
|
|
165
177
|
)
|
|
166
178
|
)
|
|
167
|
-
self.already_added.append(
|
|
179
|
+
self.already_added.append(self.needs_jac_feature.__name__)
|
|
168
180
|
|
|
169
181
|
def needs_dataclass(self) -> None:
|
|
170
182
|
"""Check if enum is needed."""
|
|
171
|
-
if
|
|
183
|
+
if self.needs_dataclass.__name__ in self.already_added:
|
|
172
184
|
return
|
|
173
185
|
self.preamble.append(
|
|
174
186
|
self.sync(
|
|
@@ -184,11 +196,11 @@ class PyastGenPass(Pass):
|
|
|
184
196
|
jac_node=self.ir,
|
|
185
197
|
)
|
|
186
198
|
)
|
|
187
|
-
self.already_added.append(
|
|
199
|
+
self.already_added.append(self.needs_dataclass.__name__)
|
|
188
200
|
|
|
189
201
|
def needs_dataclass_field(self) -> None:
|
|
190
202
|
"""Check if enum is needed."""
|
|
191
|
-
if
|
|
203
|
+
if self.needs_dataclass_field.__name__ in self.already_added:
|
|
192
204
|
return
|
|
193
205
|
self.preamble.append(
|
|
194
206
|
self.sync(
|
|
@@ -202,7 +214,7 @@ class PyastGenPass(Pass):
|
|
|
202
214
|
jac_node=self.ir,
|
|
203
215
|
)
|
|
204
216
|
)
|
|
205
|
-
self.already_added.append(
|
|
217
|
+
self.already_added.append(self.needs_dataclass_field.__name__)
|
|
206
218
|
|
|
207
219
|
def flatten(self, body: list[T | list[T] | None]) -> list[T]:
|
|
208
220
|
"""Flatten ast list."""
|
|
@@ -425,6 +437,33 @@ class PyastGenPass(Pass):
|
|
|
425
437
|
type_params=[],
|
|
426
438
|
),
|
|
427
439
|
)
|
|
440
|
+
if node.loc.mod_path != self.ir.loc.mod_path:
|
|
441
|
+
func.decorator_list.append(
|
|
442
|
+
self.sync(
|
|
443
|
+
ast3.Call(
|
|
444
|
+
func=self.sync(
|
|
445
|
+
ast3.Attribute(
|
|
446
|
+
value=self.sync(
|
|
447
|
+
ast3.Name(id=Con.JAC_FEATURE.value, ctx=ast3.Load())
|
|
448
|
+
),
|
|
449
|
+
attr="impl_patch_filename",
|
|
450
|
+
ctx=ast3.Load(),
|
|
451
|
+
)
|
|
452
|
+
),
|
|
453
|
+
args=[],
|
|
454
|
+
keywords=[
|
|
455
|
+
self.sync(
|
|
456
|
+
ast3.keyword(
|
|
457
|
+
arg="file_loc",
|
|
458
|
+
value=self.sync(
|
|
459
|
+
ast3.Constant(value=node.body.loc.mod_path)
|
|
460
|
+
),
|
|
461
|
+
)
|
|
462
|
+
),
|
|
463
|
+
],
|
|
464
|
+
)
|
|
465
|
+
)
|
|
466
|
+
)
|
|
428
467
|
node.gen.py_ast = [func]
|
|
429
468
|
|
|
430
469
|
def exit_module_code(self, node: ast.ModuleCode) -> None:
|
|
@@ -592,23 +631,12 @@ class PyastGenPass(Pass):
|
|
|
592
631
|
),
|
|
593
632
|
)
|
|
594
633
|
),
|
|
595
|
-
self.sync(
|
|
596
|
-
ast3.keyword(
|
|
597
|
-
arg="mod_bundle",
|
|
598
|
-
value=self.sync(
|
|
599
|
-
ast3.Name(
|
|
600
|
-
id="__name__",
|
|
601
|
-
ctx=ast3.Load(),
|
|
602
|
-
)
|
|
603
|
-
),
|
|
604
|
-
)
|
|
605
|
-
),
|
|
606
634
|
self.sync(
|
|
607
635
|
ast3.keyword(
|
|
608
636
|
arg="lng",
|
|
609
637
|
value=self.sync(
|
|
610
638
|
ast3.Constant(
|
|
611
|
-
value=node.
|
|
639
|
+
value="py" if node.is_py else "jac"
|
|
612
640
|
),
|
|
613
641
|
node.hint,
|
|
614
642
|
),
|
|
@@ -823,10 +851,17 @@ class PyastGenPass(Pass):
|
|
|
823
851
|
)
|
|
824
852
|
)
|
|
825
853
|
)
|
|
854
|
+
self.needs_typing()
|
|
826
855
|
py_nodes.append(
|
|
827
856
|
self.sync(
|
|
828
857
|
ast3.If(
|
|
829
|
-
test=self.sync(
|
|
858
|
+
test=self.sync(
|
|
859
|
+
ast3.Attribute(
|
|
860
|
+
value=self.sync(ast3.Name(id="_jac_typ", ctx=ast3.Load())),
|
|
861
|
+
attr="TYPE_CHECKING",
|
|
862
|
+
ctx=ast3.Load(),
|
|
863
|
+
)
|
|
864
|
+
),
|
|
830
865
|
body=typecheck_nodes,
|
|
831
866
|
orelse=runtime_nodes,
|
|
832
867
|
)
|
|
@@ -899,6 +934,7 @@ class PyastGenPass(Pass):
|
|
|
899
934
|
if isinstance(node.decorators, ast.SubNodeList)
|
|
900
935
|
else []
|
|
901
936
|
)
|
|
937
|
+
|
|
902
938
|
ds_on_entry, ds_on_exit = self.collect_events(node)
|
|
903
939
|
if node.arch_type.name != Tok.KW_CLASS:
|
|
904
940
|
self.needs_jac_feature()
|
|
@@ -971,19 +1007,11 @@ class PyastGenPass(Pass):
|
|
|
971
1007
|
)
|
|
972
1008
|
)
|
|
973
1009
|
if node.is_abstract:
|
|
974
|
-
self.
|
|
1010
|
+
self.needs_abc()
|
|
975
1011
|
base_classes.append(
|
|
976
1012
|
self.sync(
|
|
977
1013
|
ast3.Attribute(
|
|
978
|
-
value=self.sync(
|
|
979
|
-
ast3.Attribute(
|
|
980
|
-
value=self.sync(
|
|
981
|
-
ast3.Name(id=Con.JAC_FEATURE.value, ctx=ast3.Load())
|
|
982
|
-
),
|
|
983
|
-
attr="abc",
|
|
984
|
-
ctx=ast3.Load(),
|
|
985
|
-
)
|
|
986
|
-
),
|
|
1014
|
+
value=self.sync(ast3.Name(id="_jac_abc", ctx=ast3.Load())),
|
|
987
1015
|
attr="ABC",
|
|
988
1016
|
ctx=ast3.Load(),
|
|
989
1017
|
)
|
|
@@ -1133,6 +1161,13 @@ class PyastGenPass(Pass):
|
|
|
1133
1161
|
if isinstance(node.body, ast.AstImplOnlyNode):
|
|
1134
1162
|
self.traverse(node.body)
|
|
1135
1163
|
|
|
1164
|
+
def gen_llm_body(self, node: ast.Ability) -> list[ast3.AST]:
|
|
1165
|
+
"""Generate the by LLM body."""
|
|
1166
|
+
# to Avoid circular import
|
|
1167
|
+
from jaclang.plugin.feature import JacFeature
|
|
1168
|
+
|
|
1169
|
+
return JacFeature.gen_llm_body(self, node)
|
|
1170
|
+
|
|
1136
1171
|
def exit_ability(self, node: ast.Ability) -> None:
|
|
1137
1172
|
"""Sub objects.
|
|
1138
1173
|
|
|
@@ -1179,20 +1214,40 @@ class PyastGenPass(Pass):
|
|
|
1179
1214
|
node,
|
|
1180
1215
|
)
|
|
1181
1216
|
decorator_list = node.decorators.gen.py_ast if node.decorators else []
|
|
1182
|
-
if node.
|
|
1217
|
+
if isinstance(node.body, ast.AstImplOnlyNode):
|
|
1183
1218
|
self.needs_jac_feature()
|
|
1184
1219
|
decorator_list.append(
|
|
1185
1220
|
self.sync(
|
|
1186
|
-
ast3.
|
|
1187
|
-
|
|
1221
|
+
ast3.Call(
|
|
1222
|
+
func=self.sync(
|
|
1188
1223
|
ast3.Attribute(
|
|
1189
1224
|
value=self.sync(
|
|
1190
1225
|
ast3.Name(id=Con.JAC_FEATURE.value, ctx=ast3.Load())
|
|
1191
1226
|
),
|
|
1192
|
-
attr="
|
|
1227
|
+
attr="impl_patch_filename",
|
|
1193
1228
|
ctx=ast3.Load(),
|
|
1194
1229
|
)
|
|
1195
1230
|
),
|
|
1231
|
+
args=[],
|
|
1232
|
+
keywords=[
|
|
1233
|
+
self.sync(
|
|
1234
|
+
ast3.keyword(
|
|
1235
|
+
arg="file_loc",
|
|
1236
|
+
value=self.sync(
|
|
1237
|
+
ast3.Constant(value=node.body.loc.mod_path)
|
|
1238
|
+
),
|
|
1239
|
+
)
|
|
1240
|
+
),
|
|
1241
|
+
],
|
|
1242
|
+
)
|
|
1243
|
+
)
|
|
1244
|
+
)
|
|
1245
|
+
if node.is_abstract:
|
|
1246
|
+
self.needs_abc()
|
|
1247
|
+
decorator_list.append(
|
|
1248
|
+
self.sync(
|
|
1249
|
+
ast3.Attribute(
|
|
1250
|
+
value=self.sync(ast3.Name(id="_jac_abc", ctx=ast3.Load())),
|
|
1196
1251
|
attr="abstractmethod",
|
|
1197
1252
|
ctx=ast3.Load(),
|
|
1198
1253
|
)
|
|
@@ -1234,289 +1289,6 @@ class PyastGenPass(Pass):
|
|
|
1234
1289
|
)
|
|
1235
1290
|
]
|
|
1236
1291
|
|
|
1237
|
-
def gen_llm_body(self, node: ast.Ability) -> list[ast3.AST]:
|
|
1238
|
-
"""Generate llm body."""
|
|
1239
|
-
self.needs_jac_feature()
|
|
1240
|
-
if isinstance(node.body, ast.FuncCall):
|
|
1241
|
-
model = node.body.target.gen.py_ast[0]
|
|
1242
|
-
extracted_type = (
|
|
1243
|
-
"".join(extract_type(node.signature.return_type))
|
|
1244
|
-
if isinstance(node.signature, ast.FuncSignature)
|
|
1245
|
-
and node.signature.return_type
|
|
1246
|
-
else None
|
|
1247
|
-
)
|
|
1248
|
-
scope = self.sync(ast3.Constant(value=str(get_sem_scope(node))))
|
|
1249
|
-
model_params, include_info, exclude_info = extract_params(node.body)
|
|
1250
|
-
inputs = (
|
|
1251
|
-
[
|
|
1252
|
-
self.sync(
|
|
1253
|
-
ast3.Tuple(
|
|
1254
|
-
elts=[
|
|
1255
|
-
(
|
|
1256
|
-
self.sync(
|
|
1257
|
-
ast3.Constant(
|
|
1258
|
-
value=(
|
|
1259
|
-
param.semstr.lit_value
|
|
1260
|
-
if param.semstr
|
|
1261
|
-
else None
|
|
1262
|
-
)
|
|
1263
|
-
)
|
|
1264
|
-
)
|
|
1265
|
-
),
|
|
1266
|
-
(
|
|
1267
|
-
param.type_tag.tag.gen.py_ast[0]
|
|
1268
|
-
if param.type_tag
|
|
1269
|
-
else None
|
|
1270
|
-
),
|
|
1271
|
-
self.sync(ast3.Constant(value=param.name.value)),
|
|
1272
|
-
self.sync(
|
|
1273
|
-
ast3.Name(
|
|
1274
|
-
id=param.name.value,
|
|
1275
|
-
ctx=ast3.Load(),
|
|
1276
|
-
)
|
|
1277
|
-
),
|
|
1278
|
-
],
|
|
1279
|
-
ctx=ast3.Load(),
|
|
1280
|
-
)
|
|
1281
|
-
)
|
|
1282
|
-
for param in node.signature.params.items
|
|
1283
|
-
]
|
|
1284
|
-
if isinstance(node.signature, ast.FuncSignature)
|
|
1285
|
-
and node.signature.params
|
|
1286
|
-
else []
|
|
1287
|
-
)
|
|
1288
|
-
outputs = (
|
|
1289
|
-
[
|
|
1290
|
-
(
|
|
1291
|
-
self.sync(
|
|
1292
|
-
ast3.Constant(
|
|
1293
|
-
value=(
|
|
1294
|
-
node.signature.semstr.lit_value
|
|
1295
|
-
if node.signature.semstr
|
|
1296
|
-
else ""
|
|
1297
|
-
)
|
|
1298
|
-
)
|
|
1299
|
-
)
|
|
1300
|
-
),
|
|
1301
|
-
(self.sync(ast3.Constant(value=(extracted_type)))),
|
|
1302
|
-
]
|
|
1303
|
-
if isinstance(node.signature, ast.FuncSignature)
|
|
1304
|
-
else []
|
|
1305
|
-
)
|
|
1306
|
-
action = (
|
|
1307
|
-
node.semstr.gen.py_ast[0]
|
|
1308
|
-
if node.semstr
|
|
1309
|
-
else self.sync(ast3.Constant(value=node.name_ref.sym_name))
|
|
1310
|
-
)
|
|
1311
|
-
return [
|
|
1312
|
-
self.sync(
|
|
1313
|
-
ast3.Assign(
|
|
1314
|
-
targets=[self.sync(ast3.Name(id="output", ctx=ast3.Store()))],
|
|
1315
|
-
value=self.by_llm_call(
|
|
1316
|
-
model,
|
|
1317
|
-
model_params,
|
|
1318
|
-
scope,
|
|
1319
|
-
inputs,
|
|
1320
|
-
outputs,
|
|
1321
|
-
action,
|
|
1322
|
-
include_info,
|
|
1323
|
-
exclude_info,
|
|
1324
|
-
),
|
|
1325
|
-
)
|
|
1326
|
-
),
|
|
1327
|
-
self.sync(
|
|
1328
|
-
ast3.Try(
|
|
1329
|
-
body=[
|
|
1330
|
-
self.sync(
|
|
1331
|
-
ast3.Return(
|
|
1332
|
-
value=self.sync(
|
|
1333
|
-
ast3.Call(
|
|
1334
|
-
func=self.sync(
|
|
1335
|
-
ast3.Name(id="eval", ctx=ast3.Load())
|
|
1336
|
-
),
|
|
1337
|
-
args=[
|
|
1338
|
-
self.sync(
|
|
1339
|
-
ast3.Name(
|
|
1340
|
-
id="output", ctx=ast3.Load()
|
|
1341
|
-
)
|
|
1342
|
-
)
|
|
1343
|
-
],
|
|
1344
|
-
keywords=[],
|
|
1345
|
-
)
|
|
1346
|
-
)
|
|
1347
|
-
)
|
|
1348
|
-
)
|
|
1349
|
-
],
|
|
1350
|
-
handlers=[
|
|
1351
|
-
self.sync(
|
|
1352
|
-
ast3.ExceptHandler(
|
|
1353
|
-
type=None,
|
|
1354
|
-
name=None,
|
|
1355
|
-
body=[
|
|
1356
|
-
self.sync(
|
|
1357
|
-
ast3.Return(
|
|
1358
|
-
value=self.sync(
|
|
1359
|
-
ast3.Name(
|
|
1360
|
-
id="output", ctx=ast3.Load()
|
|
1361
|
-
)
|
|
1362
|
-
)
|
|
1363
|
-
)
|
|
1364
|
-
)
|
|
1365
|
-
],
|
|
1366
|
-
)
|
|
1367
|
-
)
|
|
1368
|
-
],
|
|
1369
|
-
orelse=[],
|
|
1370
|
-
finalbody=[],
|
|
1371
|
-
)
|
|
1372
|
-
),
|
|
1373
|
-
]
|
|
1374
|
-
else:
|
|
1375
|
-
return []
|
|
1376
|
-
|
|
1377
|
-
def by_llm_call(
|
|
1378
|
-
self,
|
|
1379
|
-
model: ast3.AST,
|
|
1380
|
-
model_params: dict[str, ast.Expr],
|
|
1381
|
-
scope: ast3.AST,
|
|
1382
|
-
inputs: Sequence[Optional[ast3.AST]],
|
|
1383
|
-
outputs: Sequence[Optional[ast3.AST]] | ast3.Call,
|
|
1384
|
-
action: Optional[ast3.AST],
|
|
1385
|
-
include_info: list[tuple[str, ast3.AST]],
|
|
1386
|
-
exclude_info: list[tuple[str, ast3.AST]],
|
|
1387
|
-
) -> ast3.Call:
|
|
1388
|
-
"""Return the LLM Call, e.g. _Jac.with_llm()."""
|
|
1389
|
-
return self.sync(
|
|
1390
|
-
ast3.Call(
|
|
1391
|
-
func=self.sync(
|
|
1392
|
-
ast3.Attribute(
|
|
1393
|
-
value=self.sync(
|
|
1394
|
-
ast3.Name(
|
|
1395
|
-
id=Con.JAC_FEATURE.value,
|
|
1396
|
-
ctx=ast3.Load(),
|
|
1397
|
-
)
|
|
1398
|
-
),
|
|
1399
|
-
attr="with_llm",
|
|
1400
|
-
ctx=ast3.Load(),
|
|
1401
|
-
)
|
|
1402
|
-
),
|
|
1403
|
-
args=[],
|
|
1404
|
-
keywords=[
|
|
1405
|
-
self.sync(
|
|
1406
|
-
ast3.keyword(
|
|
1407
|
-
arg="file_loc",
|
|
1408
|
-
value=self.sync(ast3.Name(id="__file__", ctx=ast3.Load())),
|
|
1409
|
-
)
|
|
1410
|
-
),
|
|
1411
|
-
self.sync(
|
|
1412
|
-
ast3.keyword(
|
|
1413
|
-
arg="model",
|
|
1414
|
-
value=model,
|
|
1415
|
-
)
|
|
1416
|
-
),
|
|
1417
|
-
self.sync(
|
|
1418
|
-
ast3.keyword(
|
|
1419
|
-
arg="model_params",
|
|
1420
|
-
value=self.sync(
|
|
1421
|
-
ast3.Dict(
|
|
1422
|
-
keys=[
|
|
1423
|
-
self.sync(ast3.Constant(value=key))
|
|
1424
|
-
for key in model_params.keys()
|
|
1425
|
-
],
|
|
1426
|
-
values=[
|
|
1427
|
-
value.gen.py_ast[0]
|
|
1428
|
-
for value in model_params.values()
|
|
1429
|
-
],
|
|
1430
|
-
)
|
|
1431
|
-
),
|
|
1432
|
-
)
|
|
1433
|
-
),
|
|
1434
|
-
self.sync(
|
|
1435
|
-
ast3.keyword(
|
|
1436
|
-
arg="scope",
|
|
1437
|
-
value=scope,
|
|
1438
|
-
)
|
|
1439
|
-
),
|
|
1440
|
-
self.sync(
|
|
1441
|
-
ast3.keyword(
|
|
1442
|
-
arg="incl_info",
|
|
1443
|
-
value=self.sync(
|
|
1444
|
-
ast3.List(
|
|
1445
|
-
elts=[
|
|
1446
|
-
self.sync(
|
|
1447
|
-
ast3.Tuple(
|
|
1448
|
-
elts=[
|
|
1449
|
-
self.sync(ast3.Constant(value=key)),
|
|
1450
|
-
value,
|
|
1451
|
-
],
|
|
1452
|
-
ctx=ast3.Load(),
|
|
1453
|
-
)
|
|
1454
|
-
)
|
|
1455
|
-
for key, value in include_info
|
|
1456
|
-
],
|
|
1457
|
-
ctx=ast3.Load(),
|
|
1458
|
-
)
|
|
1459
|
-
),
|
|
1460
|
-
)
|
|
1461
|
-
),
|
|
1462
|
-
self.sync(
|
|
1463
|
-
ast3.keyword(
|
|
1464
|
-
arg="excl_info",
|
|
1465
|
-
value=self.sync(
|
|
1466
|
-
ast3.List(
|
|
1467
|
-
elts=[
|
|
1468
|
-
self.sync(
|
|
1469
|
-
ast3.Tuple(
|
|
1470
|
-
elts=[
|
|
1471
|
-
self.sync(ast3.Constant(value=key)),
|
|
1472
|
-
value,
|
|
1473
|
-
],
|
|
1474
|
-
ctx=ast3.Load(),
|
|
1475
|
-
)
|
|
1476
|
-
)
|
|
1477
|
-
for key, value in exclude_info
|
|
1478
|
-
],
|
|
1479
|
-
ctx=ast3.Load(),
|
|
1480
|
-
)
|
|
1481
|
-
),
|
|
1482
|
-
),
|
|
1483
|
-
),
|
|
1484
|
-
self.sync(
|
|
1485
|
-
ast3.keyword(
|
|
1486
|
-
arg="inputs",
|
|
1487
|
-
value=self.sync(
|
|
1488
|
-
ast3.List(
|
|
1489
|
-
elts=inputs,
|
|
1490
|
-
ctx=ast3.Load(),
|
|
1491
|
-
)
|
|
1492
|
-
),
|
|
1493
|
-
)
|
|
1494
|
-
),
|
|
1495
|
-
self.sync(
|
|
1496
|
-
ast3.keyword(
|
|
1497
|
-
arg="outputs",
|
|
1498
|
-
value=(
|
|
1499
|
-
self.sync(
|
|
1500
|
-
ast3.Tuple(
|
|
1501
|
-
elts=outputs,
|
|
1502
|
-
ctx=ast3.Load(),
|
|
1503
|
-
)
|
|
1504
|
-
)
|
|
1505
|
-
if not isinstance(outputs, ast3.Call)
|
|
1506
|
-
else outputs
|
|
1507
|
-
),
|
|
1508
|
-
)
|
|
1509
|
-
),
|
|
1510
|
-
self.sync(
|
|
1511
|
-
ast3.keyword(
|
|
1512
|
-
arg="action",
|
|
1513
|
-
value=action,
|
|
1514
|
-
)
|
|
1515
|
-
),
|
|
1516
|
-
],
|
|
1517
|
-
)
|
|
1518
|
-
)
|
|
1519
|
-
|
|
1520
1292
|
def exit_ability_def(self, node: ast.AbilityDef) -> None:
|
|
1521
1293
|
"""Sub objects.
|
|
1522
1294
|
|
|
@@ -1535,7 +1307,7 @@ class PyastGenPass(Pass):
|
|
|
1535
1307
|
"""
|
|
1536
1308
|
params = (
|
|
1537
1309
|
[self.sync(ast3.arg(arg="self", annotation=None))]
|
|
1538
|
-
if node.is_method and not node.is_static
|
|
1310
|
+
if node.is_method and not node.is_static and not node.is_in_py_class
|
|
1539
1311
|
else []
|
|
1540
1312
|
)
|
|
1541
1313
|
vararg = None
|
|
@@ -2080,33 +1852,160 @@ class PyastGenPass(Pass):
|
|
|
2080
1852
|
|
|
2081
1853
|
target: ExprType,
|
|
2082
1854
|
"""
|
|
1855
|
+
# TODO: Here is the list of assertions which are not implemented instead a simpler version of them will work.
|
|
1856
|
+
# ie. [] == [] will be assertEqual instead of assertListEqual. However I don't think this is needed since it can
|
|
1857
|
+
# only detected if both operand are compile time literal list or type inferable.
|
|
1858
|
+
#
|
|
1859
|
+
# assertAlmostEqual
|
|
1860
|
+
# assertNotAlmostEqual
|
|
1861
|
+
# assertSequenceEqual
|
|
1862
|
+
# assertListEqual
|
|
1863
|
+
# assertTupleEqual
|
|
1864
|
+
# assertSetEqual
|
|
1865
|
+
# assertDictEqual
|
|
1866
|
+
# assertCountEqual
|
|
1867
|
+
# assertMultiLineEqual
|
|
1868
|
+
# assertRaisesRegex
|
|
1869
|
+
# assertWarnsRegex
|
|
1870
|
+
# assertRegex
|
|
1871
|
+
# assertNotRegex
|
|
1872
|
+
|
|
1873
|
+
# The return type "struct" for the bellow check_node_isinstance_call.
|
|
1874
|
+
@dataclass
|
|
1875
|
+
class CheckNodeIsinstanceCallResult:
|
|
1876
|
+
isit: bool = False
|
|
1877
|
+
inst: ast3.AST | None = None
|
|
1878
|
+
clss: ast3.AST | None = None
|
|
1879
|
+
|
|
1880
|
+
# This will check if a node is `isinstance(<expr>, <expr>)`, we're
|
|
1881
|
+
# using a function because it's reusable to check not isinstance(<expr>, <expr>).
|
|
1882
|
+
def check_node_isinstance_call(
|
|
1883
|
+
node: ast.FuncCall,
|
|
1884
|
+
) -> CheckNodeIsinstanceCallResult:
|
|
1885
|
+
|
|
1886
|
+
# Ensure the type of the FuncCall node is SubNodeList[Expr]
|
|
1887
|
+
# since the type can be: Optional[SubNodeList[Expr | KWPair]].
|
|
1888
|
+
if not (
|
|
1889
|
+
node.params is not None
|
|
1890
|
+
and len(node.params.items) == 2
|
|
1891
|
+
and isinstance(node.params.items[0], ast.Expr)
|
|
1892
|
+
and isinstance(node.params.items[1], ast.Expr)
|
|
1893
|
+
):
|
|
1894
|
+
return CheckNodeIsinstanceCallResult()
|
|
1895
|
+
|
|
1896
|
+
func = node.target.gen.py_ast[0]
|
|
1897
|
+
if not (isinstance(func, ast3.Name) and func.id == "isinstance"):
|
|
1898
|
+
return CheckNodeIsinstanceCallResult()
|
|
1899
|
+
|
|
1900
|
+
return CheckNodeIsinstanceCallResult(
|
|
1901
|
+
True,
|
|
1902
|
+
node.params.items[0].gen.py_ast[0],
|
|
1903
|
+
node.params.items[1].gen.py_ast[0],
|
|
1904
|
+
)
|
|
1905
|
+
|
|
1906
|
+
# By default the check expression will become assertTrue(<expr>), unless any pattern detected.
|
|
1907
|
+
assert_func_name = "assertTrue"
|
|
1908
|
+
assert_args_list = node.target.gen.py_ast
|
|
1909
|
+
|
|
1910
|
+
# Compare operations. Note that We're only considering the compare
|
|
1911
|
+
# operation with a single operation ie. a < b < c is ignored here.
|
|
1912
|
+
if (
|
|
1913
|
+
isinstance(node.target, ast.CompareExpr)
|
|
1914
|
+
and isinstance(node.target.gen.py_ast[0], ast3.Compare)
|
|
1915
|
+
and len(node.target.ops) == 1
|
|
1916
|
+
):
|
|
1917
|
+
expr: ast.CompareExpr = node.target
|
|
1918
|
+
opty: ast.Token = expr.ops[0]
|
|
1919
|
+
|
|
1920
|
+
optype2fn = {
|
|
1921
|
+
Tok.EE.name: "assertEqual",
|
|
1922
|
+
Tok.NE.name: "assertNotEqual",
|
|
1923
|
+
Tok.LT.name: "assertLess",
|
|
1924
|
+
Tok.LTE.name: "assertLessEqual",
|
|
1925
|
+
Tok.GT.name: "assertGreater",
|
|
1926
|
+
Tok.GTE.name: "assertGreaterEqual",
|
|
1927
|
+
Tok.KW_IN.name: "assertIn",
|
|
1928
|
+
Tok.KW_NIN.name: "assertNotIn",
|
|
1929
|
+
Tok.KW_IS.name: "assertIs",
|
|
1930
|
+
Tok.KW_ISN.name: "assertIsNot",
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
if opty.name in optype2fn:
|
|
1934
|
+
assert_func_name = optype2fn[opty.name]
|
|
1935
|
+
assert_args_list = [
|
|
1936
|
+
expr.left.gen.py_ast[0],
|
|
1937
|
+
expr.rights[0].gen.py_ast[0],
|
|
1938
|
+
]
|
|
1939
|
+
|
|
1940
|
+
# Override for <expr> is None.
|
|
1941
|
+
if opty.name == Tok.KW_IS and isinstance(expr.rights[0], ast.Null):
|
|
1942
|
+
assert_func_name = "assertIsNone"
|
|
1943
|
+
assert_args_list.pop()
|
|
1944
|
+
|
|
1945
|
+
# Override for <expr> is not None.
|
|
1946
|
+
elif opty.name == Tok.KW_ISN and isinstance(expr.rights[0], ast.Null):
|
|
1947
|
+
assert_func_name = "assertIsNotNone"
|
|
1948
|
+
assert_args_list.pop()
|
|
1949
|
+
|
|
1950
|
+
# Check if 'isinstance' is called.
|
|
1951
|
+
elif isinstance(node.target, ast.FuncCall) and isinstance(
|
|
1952
|
+
node.target.gen.py_ast[0], ast3.Call
|
|
1953
|
+
):
|
|
1954
|
+
res = check_node_isinstance_call(node.target)
|
|
1955
|
+
if res.isit:
|
|
1956
|
+
# These assertions will make mypy happy.
|
|
1957
|
+
assert isinstance(res.inst, ast3.AST)
|
|
1958
|
+
assert isinstance(res.clss, ast3.AST)
|
|
1959
|
+
assert_func_name = "assertIsInstance"
|
|
1960
|
+
assert_args_list = [res.inst, res.clss]
|
|
1961
|
+
|
|
1962
|
+
# Check if 'not isinstance(<expr>, <expr>)' is called.
|
|
1963
|
+
elif (
|
|
1964
|
+
isinstance(node.target, ast.UnaryExpr)
|
|
1965
|
+
and isinstance(node.target, ast.UnaryExpr)
|
|
1966
|
+
and isinstance(node.target.operand, ast.FuncCall)
|
|
1967
|
+
and isinstance(node.target.operand, ast.UnaryExpr)
|
|
1968
|
+
):
|
|
1969
|
+
res = check_node_isinstance_call(node.target.operand)
|
|
1970
|
+
if res.isit:
|
|
1971
|
+
# These assertions will make mypy happy.
|
|
1972
|
+
assert isinstance(res.inst, ast3.AST)
|
|
1973
|
+
assert isinstance(res.clss, ast3.AST)
|
|
1974
|
+
assert_func_name = "assertIsNotInstance"
|
|
1975
|
+
assert_args_list = [res.inst, res.clss]
|
|
1976
|
+
|
|
1977
|
+
# NOTE That the almost equal is NOT a builtin function of jaclang and won't work outside of the
|
|
1978
|
+
# check statement. And we're hacking the node here. Not sure if this is a hacky workaround to support
|
|
1979
|
+
# the almost equal functionality (snice there is no almost equal operator in jac and never needed ig.).
|
|
1980
|
+
|
|
1981
|
+
# Check if 'almostEqual' is called.
|
|
2083
1982
|
if isinstance(node.target, ast.FuncCall) and isinstance(
|
|
2084
1983
|
node.target.gen.py_ast[0], ast3.Call
|
|
2085
1984
|
):
|
|
2086
|
-
func = node.target.target
|
|
2087
|
-
if isinstance(func,
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
self.
|
|
2105
|
-
|
|
2106
|
-
"in the style of assertTrue(), assertEqual(), etc.",
|
|
2107
|
-
node,
|
|
1985
|
+
func = node.target.target
|
|
1986
|
+
if isinstance(func, ast.Name) and func.value == "almostEqual":
|
|
1987
|
+
assert_func_name = "assertAlmostEqual"
|
|
1988
|
+
assert_args_list = []
|
|
1989
|
+
if node.target.params is not None:
|
|
1990
|
+
for param in node.target.params.items:
|
|
1991
|
+
assert_args_list.append(param.gen.py_ast[0])
|
|
1992
|
+
|
|
1993
|
+
# assert_func_expr = "_jac_check.assertXXX"
|
|
1994
|
+
assert_func_expr: ast3.Attribute = self.sync(
|
|
1995
|
+
ast3.Attribute(
|
|
1996
|
+
value=self.sync(ast3.Name(id="_jac_check", ctx=ast3.Load())),
|
|
1997
|
+
attr=assert_func_name,
|
|
1998
|
+
ctx=ast3.Load(),
|
|
1999
|
+
)
|
|
2000
|
+
)
|
|
2001
|
+
|
|
2002
|
+
# assert_call_expr = "(_jac_check.assertXXX)(args)"
|
|
2003
|
+
assert_call_expr: ast3.Call = self.sync(
|
|
2004
|
+
ast3.Call(func=assert_func_expr, args=assert_args_list, keywords=[])
|
|
2108
2005
|
)
|
|
2109
2006
|
|
|
2007
|
+
node.gen.py_ast = [self.sync(ast3.Expr(assert_call_expr))]
|
|
2008
|
+
|
|
2110
2009
|
def exit_ctrl_stmt(self, node: ast.CtrlStmt) -> None:
|
|
2111
2010
|
"""Sub objects.
|
|
2112
2011
|
|
|
@@ -3073,6 +2972,40 @@ class PyastGenPass(Pass):
|
|
|
3073
2972
|
"""
|
|
3074
2973
|
node.gen.py_ast = node.value.gen.py_ast
|
|
3075
2974
|
|
|
2975
|
+
def by_llm_call(
|
|
2976
|
+
self,
|
|
2977
|
+
model: ast3.AST,
|
|
2978
|
+
model_params: dict[str, ast.Expr],
|
|
2979
|
+
scope: ast3.AST,
|
|
2980
|
+
inputs: Sequence[Optional[ast3.AST]],
|
|
2981
|
+
outputs: Sequence[Optional[ast3.AST]] | ast3.Call,
|
|
2982
|
+
action: Optional[ast3.AST],
|
|
2983
|
+
include_info: list[tuple[str, ast3.AST]],
|
|
2984
|
+
exclude_info: list[tuple[str, ast3.AST]],
|
|
2985
|
+
) -> ast3.Call:
|
|
2986
|
+
"""Return the LLM Call, e.g. _Jac.with_llm()."""
|
|
2987
|
+
# to avoid circular import
|
|
2988
|
+
from jaclang.plugin.feature import JacFeature
|
|
2989
|
+
|
|
2990
|
+
return JacFeature.by_llm_call(
|
|
2991
|
+
self,
|
|
2992
|
+
model,
|
|
2993
|
+
model_params,
|
|
2994
|
+
scope,
|
|
2995
|
+
inputs,
|
|
2996
|
+
outputs,
|
|
2997
|
+
action,
|
|
2998
|
+
include_info,
|
|
2999
|
+
exclude_info,
|
|
3000
|
+
)
|
|
3001
|
+
|
|
3002
|
+
def get_by_llm_call_args(self, node: ast.FuncCall) -> dict:
|
|
3003
|
+
"""Get the arguments for the by_llm_call."""
|
|
3004
|
+
# to avoid circular import
|
|
3005
|
+
from jaclang.plugin.feature import JacFeature
|
|
3006
|
+
|
|
3007
|
+
return JacFeature.get_by_llm_call_args(self, node)
|
|
3008
|
+
|
|
3076
3009
|
def exit_func_call(self, node: ast.FuncCall) -> None:
|
|
3077
3010
|
"""Sub objects.
|
|
3078
3011
|
|
|
@@ -3098,193 +3031,8 @@ class PyastGenPass(Pass):
|
|
|
3098
3031
|
self.ice("Invalid Parameter")
|
|
3099
3032
|
if node.genai_call:
|
|
3100
3033
|
self.needs_jac_feature()
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
action = self.sync(
|
|
3104
|
-
ast3.Constant(
|
|
3105
|
-
value="Create an object of the specified type, using the specifically "
|
|
3106
|
-
" provided input value(s) and look up any missing attributes from reliable"
|
|
3107
|
-
" online sources to fill them in accurately."
|
|
3108
|
-
)
|
|
3109
|
-
)
|
|
3110
|
-
_output_ = "".join(extract_type(node.target))
|
|
3111
|
-
include_info.append(
|
|
3112
|
-
(
|
|
3113
|
-
_output_.split(".")[0],
|
|
3114
|
-
self.sync(ast3.Name(id=_output_.split(".")[0], ctx=ast3.Load())),
|
|
3115
|
-
)
|
|
3116
|
-
)
|
|
3117
|
-
scope = self.sync(
|
|
3118
|
-
ast3.Call(
|
|
3119
|
-
func=self.sync(
|
|
3120
|
-
ast3.Attribute(
|
|
3121
|
-
value=self.sync(
|
|
3122
|
-
ast3.Name(
|
|
3123
|
-
id=Con.JAC_FEATURE.value,
|
|
3124
|
-
ctx=ast3.Load(),
|
|
3125
|
-
)
|
|
3126
|
-
),
|
|
3127
|
-
attr="obj_scope",
|
|
3128
|
-
ctx=ast3.Load(),
|
|
3129
|
-
)
|
|
3130
|
-
),
|
|
3131
|
-
args=[
|
|
3132
|
-
self.sync(
|
|
3133
|
-
ast3.Name(
|
|
3134
|
-
id="__file__",
|
|
3135
|
-
ctx=ast3.Load(),
|
|
3136
|
-
)
|
|
3137
|
-
),
|
|
3138
|
-
self.sync(ast3.Constant(value=_output_)),
|
|
3139
|
-
],
|
|
3140
|
-
keywords=[],
|
|
3141
|
-
)
|
|
3142
|
-
)
|
|
3143
|
-
outputs = self.sync(
|
|
3144
|
-
ast3.Call(
|
|
3145
|
-
func=self.sync(
|
|
3146
|
-
ast3.Attribute(
|
|
3147
|
-
value=self.sync(
|
|
3148
|
-
ast3.Name(
|
|
3149
|
-
id=Con.JAC_FEATURE.value,
|
|
3150
|
-
ctx=ast3.Load(),
|
|
3151
|
-
)
|
|
3152
|
-
),
|
|
3153
|
-
attr="get_sem_type",
|
|
3154
|
-
ctx=ast3.Load(),
|
|
3155
|
-
)
|
|
3156
|
-
),
|
|
3157
|
-
args=[
|
|
3158
|
-
self.sync(
|
|
3159
|
-
ast3.Name(
|
|
3160
|
-
id="__file__",
|
|
3161
|
-
ctx=ast3.Load(),
|
|
3162
|
-
)
|
|
3163
|
-
),
|
|
3164
|
-
self.sync(ast3.Constant(value=str(_output_))),
|
|
3165
|
-
],
|
|
3166
|
-
keywords=[],
|
|
3167
|
-
)
|
|
3168
|
-
)
|
|
3169
|
-
if node.params and node.params.items:
|
|
3170
|
-
inputs = [
|
|
3171
|
-
self.sync(
|
|
3172
|
-
ast3.Tuple(
|
|
3173
|
-
elts=[
|
|
3174
|
-
self.sync(
|
|
3175
|
-
ast3.Call(
|
|
3176
|
-
func=self.sync(
|
|
3177
|
-
ast3.Attribute(
|
|
3178
|
-
value=self.sync(
|
|
3179
|
-
ast3.Name(
|
|
3180
|
-
id=Con.JAC_FEATURE.value,
|
|
3181
|
-
ctx=ast3.Load(),
|
|
3182
|
-
)
|
|
3183
|
-
),
|
|
3184
|
-
attr="get_semstr_type",
|
|
3185
|
-
ctx=ast3.Load(),
|
|
3186
|
-
)
|
|
3187
|
-
),
|
|
3188
|
-
args=[
|
|
3189
|
-
self.sync(
|
|
3190
|
-
ast3.Name(
|
|
3191
|
-
id="__file__", ctx=ast3.Load()
|
|
3192
|
-
)
|
|
3193
|
-
),
|
|
3194
|
-
scope,
|
|
3195
|
-
self.sync(
|
|
3196
|
-
ast3.Constant(
|
|
3197
|
-
value=(
|
|
3198
|
-
kw_pair.key.value
|
|
3199
|
-
if isinstance(
|
|
3200
|
-
kw_pair.key, ast.Name
|
|
3201
|
-
)
|
|
3202
|
-
else None
|
|
3203
|
-
)
|
|
3204
|
-
)
|
|
3205
|
-
),
|
|
3206
|
-
self.sync(ast3.Constant(value=True)),
|
|
3207
|
-
],
|
|
3208
|
-
keywords=[],
|
|
3209
|
-
)
|
|
3210
|
-
),
|
|
3211
|
-
self.sync(
|
|
3212
|
-
ast3.Call(
|
|
3213
|
-
func=self.sync(
|
|
3214
|
-
ast3.Attribute(
|
|
3215
|
-
value=self.sync(
|
|
3216
|
-
ast3.Name(
|
|
3217
|
-
id=Con.JAC_FEATURE.value,
|
|
3218
|
-
ctx=ast3.Load(),
|
|
3219
|
-
)
|
|
3220
|
-
),
|
|
3221
|
-
attr="get_semstr_type",
|
|
3222
|
-
ctx=ast3.Load(),
|
|
3223
|
-
)
|
|
3224
|
-
),
|
|
3225
|
-
args=[
|
|
3226
|
-
self.sync(
|
|
3227
|
-
ast3.Name(
|
|
3228
|
-
id="__file__", ctx=ast3.Load()
|
|
3229
|
-
)
|
|
3230
|
-
),
|
|
3231
|
-
scope,
|
|
3232
|
-
self.sync(
|
|
3233
|
-
ast3.Constant(
|
|
3234
|
-
value=(
|
|
3235
|
-
kw_pair.key.value
|
|
3236
|
-
if isinstance(
|
|
3237
|
-
kw_pair.key, ast.Name
|
|
3238
|
-
)
|
|
3239
|
-
else None
|
|
3240
|
-
)
|
|
3241
|
-
)
|
|
3242
|
-
),
|
|
3243
|
-
self.sync(ast3.Constant(value=False)),
|
|
3244
|
-
],
|
|
3245
|
-
keywords=[],
|
|
3246
|
-
)
|
|
3247
|
-
),
|
|
3248
|
-
self.sync(
|
|
3249
|
-
ast3.Constant(
|
|
3250
|
-
value=(
|
|
3251
|
-
kw_pair.key.value
|
|
3252
|
-
if isinstance(kw_pair.key, ast.Name)
|
|
3253
|
-
else None
|
|
3254
|
-
)
|
|
3255
|
-
)
|
|
3256
|
-
),
|
|
3257
|
-
kw_pair.value.gen.py_ast[0],
|
|
3258
|
-
],
|
|
3259
|
-
ctx=ast3.Load(),
|
|
3260
|
-
)
|
|
3261
|
-
)
|
|
3262
|
-
for kw_pair in node.params.items
|
|
3263
|
-
if isinstance(kw_pair, ast.KWPair)
|
|
3264
|
-
]
|
|
3265
|
-
else:
|
|
3266
|
-
inputs = []
|
|
3267
|
-
|
|
3268
|
-
node.gen.py_ast = [
|
|
3269
|
-
self.sync(
|
|
3270
|
-
ast3.Call(
|
|
3271
|
-
func=self.sync(ast3.Name(id="eval", ctx=ast3.Load())),
|
|
3272
|
-
args=[
|
|
3273
|
-
self.by_llm_call(
|
|
3274
|
-
model,
|
|
3275
|
-
model_params,
|
|
3276
|
-
scope,
|
|
3277
|
-
inputs,
|
|
3278
|
-
outputs,
|
|
3279
|
-
action,
|
|
3280
|
-
include_info,
|
|
3281
|
-
exclude_info,
|
|
3282
|
-
),
|
|
3283
|
-
],
|
|
3284
|
-
keywords=[],
|
|
3285
|
-
)
|
|
3286
|
-
)
|
|
3287
|
-
]
|
|
3034
|
+
by_llm_call_args = self.get_by_llm_call_args(node)
|
|
3035
|
+
node.gen.py_ast = [self.sync(self.by_llm_call(**by_llm_call_args))]
|
|
3288
3036
|
else:
|
|
3289
3037
|
node.gen.py_ast = [
|
|
3290
3038
|
self.sync(ast3.Call(func=func, args=args, keywords=keywords))
|