jaclang 0.7.23__py3-none-any.whl → 0.7.26__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 +46 -29
- jaclang/compiler/__init__.py +2 -2
- jaclang/compiler/absyntree.py +114 -66
- jaclang/compiler/codeloc.py +7 -2
- jaclang/compiler/compile.py +10 -3
- jaclang/compiler/jac.lark +4 -1
- jaclang/compiler/parser.py +63 -43
- jaclang/compiler/passes/ir_pass.py +2 -2
- jaclang/compiler/passes/main/def_impl_match_pass.py +83 -0
- jaclang/compiler/passes/main/def_use_pass.py +1 -2
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +146 -123
- jaclang/compiler/passes/main/import_pass.py +6 -2
- jaclang/compiler/passes/main/pyast_gen_pass.py +46 -20
- jaclang/compiler/passes/main/pyast_load_pass.py +56 -41
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -7
- jaclang/compiler/passes/main/registry_pass.py +3 -12
- jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -2
- jaclang/compiler/passes/main/tests/fixtures/defn_decl_mismatch.jac +19 -0
- jaclang/compiler/passes/main/tests/fixtures/fstrings.jac +2 -0
- jaclang/compiler/passes/main/tests/fixtures/uninitialized_hasvars.jac +26 -0
- jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +66 -0
- jaclang/compiler/passes/main/tests/test_def_use_pass.py +3 -3
- jaclang/compiler/passes/main/tests/test_registry_pass.py +2 -10
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -2
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +3 -3
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +3 -3
- jaclang/compiler/passes/transform.py +27 -3
- jaclang/compiler/passes/utils/mypy_ast_build.py +246 -26
- jaclang/compiler/symtable.py +6 -0
- jaclang/compiler/tests/test_importer.py +2 -2
- jaclang/compiler/tests/test_parser.py +7 -1
- jaclang/langserve/engine.py +14 -12
- jaclang/langserve/server.py +7 -2
- jaclang/langserve/tests/test_server.py +1 -1
- jaclang/langserve/utils.py +17 -3
- jaclang/plugin/default.py +80 -43
- jaclang/plugin/feature.py +12 -2
- jaclang/plugin/plugin.md +471 -0
- jaclang/plugin/spec.py +14 -1
- jaclang/plugin/tests/fixtures/graph_purger.jac +101 -0
- jaclang/plugin/tests/fixtures/other_root_access.jac +9 -0
- jaclang/plugin/tests/test_jaseci.py +126 -6
- jaclang/runtimelib/architype.py +12 -1
- jaclang/runtimelib/context.py +2 -0
- jaclang/runtimelib/importer.py +7 -2
- jaclang/runtimelib/machine.py +21 -6
- jaclang/runtimelib/memory.py +5 -1
- jaclang/settings.py +3 -0
- jaclang/tests/fixtures/architype_def_bug.jac +17 -0
- jaclang/tests/fixtures/builtin_dotgen.jac +6 -6
- jaclang/tests/fixtures/decl_defn_param_name.jac +19 -0
- jaclang/tests/fixtures/enum_inside_archtype.jac +16 -11
- jaclang/tests/fixtures/expr_type.jac +54 -0
- jaclang/tests/fixtures/glob_multivar_statement.jac +15 -0
- jaclang/tests/fixtures/multi_dim_array_split.jac +19 -0
- jaclang/tests/fixtures/registry.jac +20 -8
- jaclang/tests/foo/__init__.jac +0 -0
- jaclang/tests/main.jac +2 -0
- jaclang/tests/test_cli.py +86 -4
- jaclang/tests/test_language.py +104 -27
- jaclang/utils/helpers.py +92 -14
- jaclang/utils/lang_tools.py +6 -2
- jaclang/utils/treeprinter.py +4 -2
- {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/METADATA +2 -1
- {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/RECORD +68 -57
- {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/WHEEL +1 -1
- {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/entry_points.txt +0 -0
|
@@ -30,33 +30,40 @@ class FuseTypeInfoPass(Pass):
|
|
|
30
30
|
|
|
31
31
|
node_type_hash: dict[MypyNodes.Node | VNode, MyType] = {}
|
|
32
32
|
|
|
33
|
+
# Override this to support enter expression.
|
|
34
|
+
def enter_node(self, node: ast.AstNode) -> None:
|
|
35
|
+
"""Run on entering node."""
|
|
36
|
+
super().enter_node(node)
|
|
37
|
+
|
|
38
|
+
if isinstance(node, ast.Expr):
|
|
39
|
+
self.enter_expr(node)
|
|
40
|
+
|
|
33
41
|
def __debug_print(self, msg: str) -> None:
|
|
34
42
|
if settings.fuse_type_info_debug:
|
|
35
43
|
self.log_info("FuseTypeInfo::" + msg)
|
|
36
44
|
|
|
37
|
-
def __call_type_handler(
|
|
38
|
-
self, node: ast.AstSymbolNode, mypy_type: MypyTypes.Type
|
|
39
|
-
) -> None:
|
|
45
|
+
def __call_type_handler(self, mypy_type: MypyTypes.Type) -> Optional[str]:
|
|
40
46
|
mypy_type_name = pascal_to_snake(mypy_type.__class__.__name__)
|
|
41
47
|
type_handler_name = f"get_type_from_{mypy_type_name}"
|
|
42
48
|
if hasattr(self, type_handler_name):
|
|
43
|
-
getattr(self, type_handler_name)(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def
|
|
49
|
+
return getattr(self, type_handler_name)(mypy_type)
|
|
50
|
+
self.__debug_print(
|
|
51
|
+
f'"MypyTypes::{mypy_type.__class__.__name__}" isn\'t supported yet'
|
|
52
|
+
)
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
def __set_type_sym_table_link(self, node: ast.AstSymbolNode) -> None:
|
|
56
|
+
typ = node.expr_type.split(".")
|
|
50
57
|
typ_sym_table = self.ir.sym_tab
|
|
51
58
|
assert isinstance(self.ir, ast.Module)
|
|
52
59
|
|
|
53
|
-
sym_type = node.
|
|
60
|
+
sym_type = node.expr_type
|
|
54
61
|
if re.match(r"builtins.(list|dict|tuple)", sym_type):
|
|
55
62
|
sym_type = re.sub(r"\[.*\]", "", sym_type)
|
|
56
63
|
|
|
57
64
|
typ = sym_type.split(".")
|
|
58
65
|
|
|
59
|
-
if node.
|
|
66
|
+
if node.expr_type == "types.ModuleType" and node.sym:
|
|
60
67
|
node.name_spec.type_sym_tab = node.sym.parent_tab.find_scope(node.sym_name)
|
|
61
68
|
|
|
62
69
|
for i in typ:
|
|
@@ -118,7 +125,7 @@ class FuseTypeInfoPass(Pass):
|
|
|
118
125
|
# Jac node has only one mypy node linked to it
|
|
119
126
|
if len(node.gen.mypy_ast) == 1:
|
|
120
127
|
func(self, node)
|
|
121
|
-
self.
|
|
128
|
+
self.__set_type_sym_table_link(node)
|
|
122
129
|
self.__collect_python_dependencies(node)
|
|
123
130
|
|
|
124
131
|
# Jac node has multiple mypy nodes linked to it
|
|
@@ -142,13 +149,13 @@ class FuseTypeInfoPass(Pass):
|
|
|
142
149
|
f"{jac_node_str} has duplicate mypy nodes associated to it"
|
|
143
150
|
)
|
|
144
151
|
func(self, node)
|
|
145
|
-
self.
|
|
152
|
+
self.__set_type_sym_table_link(node)
|
|
146
153
|
self.__collect_python_dependencies(node)
|
|
147
154
|
|
|
148
155
|
# Special handing for BuiltinType
|
|
149
156
|
elif isinstance(node, ast.BuiltinType):
|
|
150
157
|
func(self, node) # type: ignore
|
|
151
|
-
self.
|
|
158
|
+
self.__set_type_sym_table_link(node)
|
|
152
159
|
|
|
153
160
|
# Jac node doesn't have mypy nodes linked to it
|
|
154
161
|
else:
|
|
@@ -170,7 +177,10 @@ class FuseTypeInfoPass(Pass):
|
|
|
170
177
|
|
|
171
178
|
if isinstance(mypy_node, MypyNodes.MemberExpr):
|
|
172
179
|
if mypy_node in self.node_type_hash:
|
|
173
|
-
|
|
180
|
+
node.name_spec.expr_type = (
|
|
181
|
+
self.__call_type_handler(self.node_type_hash[mypy_node])
|
|
182
|
+
or node.name_spec.expr_type
|
|
183
|
+
)
|
|
174
184
|
else:
|
|
175
185
|
self.__debug_print(f"{node.loc} MemberExpr type is not found")
|
|
176
186
|
|
|
@@ -179,19 +189,24 @@ class FuseTypeInfoPass(Pass):
|
|
|
179
189
|
mypy_node = mypy_node.node
|
|
180
190
|
|
|
181
191
|
if isinstance(mypy_node, (MypyNodes.Var, MypyNodes.FuncDef)):
|
|
182
|
-
|
|
192
|
+
node.name_spec.expr_type = (
|
|
193
|
+
self.__call_type_handler(mypy_node.type) or node.name_spec.expr_type
|
|
194
|
+
)
|
|
183
195
|
|
|
184
196
|
elif isinstance(mypy_node, MypyNodes.MypyFile):
|
|
185
|
-
node.name_spec.
|
|
197
|
+
node.name_spec.expr_type = "types.ModuleType"
|
|
186
198
|
|
|
187
199
|
elif isinstance(mypy_node, MypyNodes.TypeInfo):
|
|
188
|
-
node.name_spec.
|
|
200
|
+
node.name_spec.expr_type = mypy_node.fullname
|
|
189
201
|
|
|
190
202
|
elif isinstance(mypy_node, MypyNodes.OverloadedFuncDef):
|
|
191
|
-
|
|
203
|
+
node.name_spec.expr_type = (
|
|
204
|
+
self.__call_type_handler(mypy_node.items[0].func.type)
|
|
205
|
+
or node.name_spec.expr_type
|
|
206
|
+
)
|
|
192
207
|
|
|
193
208
|
elif mypy_node is None:
|
|
194
|
-
node.name_spec.
|
|
209
|
+
node.name_spec.expr_type = "None"
|
|
195
210
|
|
|
196
211
|
else:
|
|
197
212
|
self.__debug_print(
|
|
@@ -201,14 +216,22 @@ class FuseTypeInfoPass(Pass):
|
|
|
201
216
|
|
|
202
217
|
else:
|
|
203
218
|
if isinstance(mypy_node, MypyNodes.ClassDef):
|
|
204
|
-
node.name_spec.
|
|
205
|
-
self.
|
|
219
|
+
node.name_spec.expr_type = mypy_node.fullname
|
|
220
|
+
self.__set_type_sym_table_link(node)
|
|
206
221
|
elif isinstance(mypy_node, MypyNodes.FuncDef):
|
|
207
|
-
|
|
222
|
+
node.name_spec.expr_type = (
|
|
223
|
+
self.__call_type_handler(mypy_node.type) or node.name_spec.expr_type
|
|
224
|
+
)
|
|
208
225
|
elif isinstance(mypy_node, MypyNodes.Argument):
|
|
209
|
-
|
|
226
|
+
node.name_spec.expr_type = (
|
|
227
|
+
self.__call_type_handler(mypy_node.variable.type)
|
|
228
|
+
or node.name_spec.expr_type
|
|
229
|
+
)
|
|
210
230
|
elif isinstance(mypy_node, MypyNodes.Decorator):
|
|
211
|
-
|
|
231
|
+
node.name_spec.expr_type = (
|
|
232
|
+
self.__call_type_handler(mypy_node.func.type.ret_type)
|
|
233
|
+
or node.name_spec.expr_type
|
|
234
|
+
)
|
|
212
235
|
else:
|
|
213
236
|
self.__debug_print(
|
|
214
237
|
f'"{node.loc}::{node.__class__.__name__}" mypy node isn\'t supported'
|
|
@@ -224,6 +247,45 @@ class FuseTypeInfoPass(Pass):
|
|
|
224
247
|
if builtins_sym:
|
|
225
248
|
node.name_spec._sym = builtins_sym
|
|
226
249
|
|
|
250
|
+
collection_types_map = {
|
|
251
|
+
ast.ListVal: "builtins.list",
|
|
252
|
+
ast.SetVal: "builtins.set",
|
|
253
|
+
ast.TupleVal: "builtins.tuple",
|
|
254
|
+
ast.DictVal: "builtins.dict",
|
|
255
|
+
ast.ListCompr: None,
|
|
256
|
+
ast.DictCompr: None,
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
# NOTE (Thakee): Since expression nodes are not AstSymbolNodes, I'm not decorating this with __handle_node
|
|
260
|
+
# and IMO instead of checking if it's a symbol node or an expression, we somehow mark expressions as
|
|
261
|
+
# valid nodes that can have symbols. At this point I'm leaving this like this and lemme know
|
|
262
|
+
# otherwise.
|
|
263
|
+
# NOTE (GAMAL): This will be fixed through the AstTypedNode
|
|
264
|
+
def enter_expr(self: FuseTypeInfoPass, node: ast.Expr) -> None:
|
|
265
|
+
"""Enter an expression node."""
|
|
266
|
+
if len(node.gen.mypy_ast) == 0:
|
|
267
|
+
return
|
|
268
|
+
|
|
269
|
+
# If the corrosponding mypy ast node type has stored here, get the values.
|
|
270
|
+
mypy_node = node.gen.mypy_ast[0]
|
|
271
|
+
if mypy_node in self.node_type_hash:
|
|
272
|
+
mytype: MyType = self.node_type_hash[mypy_node]
|
|
273
|
+
node.expr_type = self.__call_type_handler(mytype) or node.expr_type
|
|
274
|
+
|
|
275
|
+
# Set they symbol type for collection expression.
|
|
276
|
+
#
|
|
277
|
+
# GenCompr is an instance of ListCompr but we don't handle it here.
|
|
278
|
+
# so the isinstace (node, <classes>) doesn't work, I'm going with type(...) == ...
|
|
279
|
+
if type(node) in self.collection_types_map:
|
|
280
|
+
assert isinstance(node, ast.AtomExpr) # To make mypy happy.
|
|
281
|
+
collection_type = self.collection_types_map[type(node)]
|
|
282
|
+
if collection_type is not None:
|
|
283
|
+
node.name_spec.expr_type = collection_type
|
|
284
|
+
if mypy_node in self.node_type_hash:
|
|
285
|
+
node.name_spec.expr_type = (
|
|
286
|
+
self.__call_type_handler(mytype) or node.name_spec.expr_type
|
|
287
|
+
)
|
|
288
|
+
|
|
227
289
|
@__handle_node
|
|
228
290
|
def enter_name(self, node: ast.NameAtom) -> None:
|
|
229
291
|
"""Pass handler for name nodes."""
|
|
@@ -265,7 +327,10 @@ class FuseTypeInfoPass(Pass):
|
|
|
265
327
|
def enter_ability(self, node: ast.Ability) -> None:
|
|
266
328
|
"""Pass handler for Ability nodes."""
|
|
267
329
|
if isinstance(node.gen.mypy_ast[0], MypyNodes.FuncDef):
|
|
268
|
-
|
|
330
|
+
node.name_spec.expr_type = (
|
|
331
|
+
self.__call_type_handler(node.gen.mypy_ast[0].type.ret_type)
|
|
332
|
+
or node.name_spec.expr_type
|
|
333
|
+
)
|
|
269
334
|
else:
|
|
270
335
|
self.__debug_print(
|
|
271
336
|
f"{node.loc}: Can't get type of an ability from mypy node other than Ability. "
|
|
@@ -276,7 +341,10 @@ class FuseTypeInfoPass(Pass):
|
|
|
276
341
|
def enter_ability_def(self, node: ast.AbilityDef) -> None:
|
|
277
342
|
"""Pass handler for AbilityDef nodes."""
|
|
278
343
|
if isinstance(node.gen.mypy_ast[0], MypyNodes.FuncDef):
|
|
279
|
-
|
|
344
|
+
node.name_spec.expr_type = (
|
|
345
|
+
self.__call_type_handler(node.gen.mypy_ast[0].type.ret_type)
|
|
346
|
+
or node.name_spec.expr_type
|
|
347
|
+
)
|
|
280
348
|
else:
|
|
281
349
|
self.__debug_print(
|
|
282
350
|
f"{node.loc}: Can't get type of an AbilityDef from mypy node other than FuncDef. "
|
|
@@ -289,7 +357,10 @@ class FuseTypeInfoPass(Pass):
|
|
|
289
357
|
if isinstance(node.gen.mypy_ast[0], MypyNodes.Argument):
|
|
290
358
|
mypy_node: MypyNodes.Argument = node.gen.mypy_ast[0]
|
|
291
359
|
if mypy_node.variable.type:
|
|
292
|
-
|
|
360
|
+
node.name_spec.expr_type = (
|
|
361
|
+
self.__call_type_handler(mypy_node.variable.type)
|
|
362
|
+
or node.name_spec.expr_type
|
|
363
|
+
)
|
|
293
364
|
else:
|
|
294
365
|
self.__debug_print(
|
|
295
366
|
f"{node.loc}: Can't get parameter value from mypyNode other than Argument"
|
|
@@ -303,7 +374,9 @@ class FuseTypeInfoPass(Pass):
|
|
|
303
374
|
if isinstance(mypy_node, MypyNodes.AssignmentStmt):
|
|
304
375
|
n = mypy_node.lvalues[0].node
|
|
305
376
|
if isinstance(n, (MypyNodes.Var, MypyNodes.FuncDef)):
|
|
306
|
-
|
|
377
|
+
node.name_spec.expr_type = (
|
|
378
|
+
self.__call_type_handler(n.type) or node.name_spec.expr_type
|
|
379
|
+
)
|
|
307
380
|
else:
|
|
308
381
|
self.__debug_print(
|
|
309
382
|
"Getting type of 'AssignmentStmt' is only supported with Var and FuncDef"
|
|
@@ -315,67 +388,19 @@ class FuseTypeInfoPass(Pass):
|
|
|
315
388
|
|
|
316
389
|
def exit_has_var(self, node: ast.HasVar) -> None:
|
|
317
390
|
"""Pass handler for HasVar nodes."""
|
|
318
|
-
node.name_spec.
|
|
391
|
+
node.name_spec.expr_type = node.name.expr_type
|
|
319
392
|
node.name_spec.type_sym_tab = node.name.type_sym_tab
|
|
320
393
|
|
|
321
394
|
@__handle_node
|
|
322
395
|
def enter_multi_string(self, node: ast.MultiString) -> None:
|
|
323
396
|
"""Pass handler for MultiString nodes."""
|
|
324
|
-
node.name_spec.
|
|
397
|
+
node.name_spec.expr_type = "builtins.str"
|
|
325
398
|
|
|
326
399
|
@__handle_node
|
|
327
400
|
def enter_f_string(self, node: ast.FString) -> None:
|
|
328
401
|
"""Pass handler for FString nodes."""
|
|
329
402
|
self.__debug_print(f"Getting type not supported in {type(node)}")
|
|
330
403
|
|
|
331
|
-
@__handle_node
|
|
332
|
-
def enter_list_val(self, node: ast.ListVal) -> None:
|
|
333
|
-
"""Pass handler for ListVal nodes."""
|
|
334
|
-
mypy_node = node.gen.mypy_ast[0]
|
|
335
|
-
if mypy_node in self.node_type_hash:
|
|
336
|
-
node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
|
|
337
|
-
else:
|
|
338
|
-
node.name_spec.sym_type = "builtins.list"
|
|
339
|
-
|
|
340
|
-
@__handle_node
|
|
341
|
-
def enter_set_val(self, node: ast.SetVal) -> None:
|
|
342
|
-
"""Pass handler for SetVal nodes."""
|
|
343
|
-
mypy_node = node.gen.mypy_ast[0]
|
|
344
|
-
if mypy_node in self.node_type_hash:
|
|
345
|
-
node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
|
|
346
|
-
else:
|
|
347
|
-
node.name_spec.sym_type = "builtins.set"
|
|
348
|
-
|
|
349
|
-
@__handle_node
|
|
350
|
-
def enter_tuple_val(self, node: ast.TupleVal) -> None:
|
|
351
|
-
"""Pass handler for TupleVal nodes."""
|
|
352
|
-
mypy_node = node.gen.mypy_ast[0]
|
|
353
|
-
if mypy_node in self.node_type_hash:
|
|
354
|
-
node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
|
|
355
|
-
else:
|
|
356
|
-
node.name_spec.sym_type = "builtins.tuple"
|
|
357
|
-
|
|
358
|
-
@__handle_node
|
|
359
|
-
def enter_dict_val(self, node: ast.DictVal) -> None:
|
|
360
|
-
"""Pass handler for DictVal nodes."""
|
|
361
|
-
mypy_node = node.gen.mypy_ast[0]
|
|
362
|
-
if mypy_node in self.node_type_hash:
|
|
363
|
-
node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
|
|
364
|
-
else:
|
|
365
|
-
node.name_spec.sym_type = "builtins.dict"
|
|
366
|
-
|
|
367
|
-
@__handle_node
|
|
368
|
-
def enter_list_compr(self, node: ast.ListCompr) -> None:
|
|
369
|
-
"""Pass handler for ListCompr nodes."""
|
|
370
|
-
mypy_node = node.gen.mypy_ast[0]
|
|
371
|
-
node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
|
|
372
|
-
|
|
373
|
-
@__handle_node
|
|
374
|
-
def enter_dict_compr(self, node: ast.DictCompr) -> None:
|
|
375
|
-
"""Pass handler for DictCompr nodes."""
|
|
376
|
-
mypy_node = node.gen.mypy_ast[0]
|
|
377
|
-
node.name_spec.sym_type = str(self.node_type_hash[mypy_node])
|
|
378
|
-
|
|
379
404
|
@__handle_node
|
|
380
405
|
def enter_index_slice(self, node: ast.IndexSlice) -> None:
|
|
381
406
|
"""Pass handler for IndexSlice nodes."""
|
|
@@ -386,11 +411,13 @@ class FuseTypeInfoPass(Pass):
|
|
|
386
411
|
"""Pass handler for ArchRef nodes."""
|
|
387
412
|
if isinstance(node.gen.mypy_ast[0], MypyNodes.ClassDef):
|
|
388
413
|
mypy_node: MypyNodes.ClassDef = node.gen.mypy_ast[0]
|
|
389
|
-
node.name_spec.
|
|
390
|
-
self.
|
|
414
|
+
node.name_spec.expr_type = mypy_node.fullname
|
|
415
|
+
self.__set_type_sym_table_link(node)
|
|
391
416
|
elif isinstance(node.gen.mypy_ast[0], MypyNodes.FuncDef):
|
|
392
417
|
mypy_node2: MypyNodes.FuncDef = node.gen.mypy_ast[0]
|
|
393
|
-
|
|
418
|
+
node.name_spec.expr_type = (
|
|
419
|
+
self.__call_type_handler(mypy_node2.type) or node.name_spec.expr_type
|
|
420
|
+
)
|
|
394
421
|
else:
|
|
395
422
|
self.__debug_print(
|
|
396
423
|
f"{node.loc}: Can't get ArchRef value from mypyNode other than ClassDef "
|
|
@@ -420,71 +447,67 @@ class FuseTypeInfoPass(Pass):
|
|
|
420
447
|
@__handle_node
|
|
421
448
|
def enter_int(self, node: ast.Int) -> None:
|
|
422
449
|
"""Pass handler for Int nodes."""
|
|
423
|
-
node.name_spec.
|
|
450
|
+
node.name_spec.expr_type = "builtins.int"
|
|
424
451
|
|
|
425
452
|
@__handle_node
|
|
426
453
|
def enter_float(self, node: ast.Float) -> None:
|
|
427
454
|
"""Pass handler for Float nodes."""
|
|
428
|
-
node.name_spec.
|
|
455
|
+
node.name_spec.expr_type = "builtins.float"
|
|
429
456
|
|
|
430
457
|
@__handle_node
|
|
431
458
|
def enter_string(self, node: ast.String) -> None:
|
|
432
459
|
"""Pass handler for String nodes."""
|
|
433
|
-
node.name_spec.
|
|
460
|
+
node.name_spec.expr_type = "builtins.str"
|
|
434
461
|
|
|
435
462
|
@__handle_node
|
|
436
463
|
def enter_bool(self, node: ast.Bool) -> None:
|
|
437
464
|
"""Pass handler for Bool nodes."""
|
|
438
|
-
node.name_spec.
|
|
465
|
+
node.name_spec.expr_type = "builtins.bool"
|
|
439
466
|
|
|
440
467
|
@__handle_node
|
|
441
468
|
def enter_builtin_type(self, node: ast.BuiltinType) -> None:
|
|
442
469
|
"""Pass handler for BuiltinType nodes."""
|
|
443
470
|
self.__check_builltin_symbol(node)
|
|
444
|
-
node.name_spec.
|
|
471
|
+
node.name_spec.expr_type = f"builtins.{node.sym_name}"
|
|
445
472
|
|
|
446
|
-
def get_type_from_instance(
|
|
447
|
-
self, node: ast.AstSymbolNode, mypy_type: MypyTypes.Instance
|
|
448
|
-
) -> None:
|
|
473
|
+
def get_type_from_instance(self, mypy_type: MypyTypes.Instance) -> Optional[str]:
|
|
449
474
|
"""Get type info from mypy type Instance."""
|
|
450
|
-
|
|
475
|
+
# FIXME: Returning str(mypy_type) won't work for literal values since it would be
|
|
476
|
+
# like Literal['foo'] instead of builtins.str, so we need to get the type fullname.
|
|
477
|
+
# Not sure if this is the best way to do it.
|
|
478
|
+
ret = str(mypy_type)
|
|
479
|
+
if ret.startswith("Literal[") and ret.endswith("]"):
|
|
480
|
+
return mypy_type.type.fullname
|
|
481
|
+
return ret
|
|
451
482
|
|
|
452
483
|
def get_type_from_callable_type(
|
|
453
|
-
self,
|
|
454
|
-
) ->
|
|
484
|
+
self, mypy_type: MypyTypes.CallableType
|
|
485
|
+
) -> Optional[str]:
|
|
455
486
|
"""Get type info from mypy type CallableType."""
|
|
456
|
-
self.__call_type_handler(
|
|
487
|
+
return self.__call_type_handler(mypy_type.ret_type)
|
|
457
488
|
|
|
458
489
|
# TODO: Which overloaded function to get the return value from?
|
|
459
490
|
def get_type_from_overloaded(
|
|
460
|
-
self,
|
|
461
|
-
) ->
|
|
491
|
+
self, mypy_type: MypyTypes.Overloaded
|
|
492
|
+
) -> Optional[str]:
|
|
462
493
|
"""Get type info from mypy type Overloaded."""
|
|
463
|
-
self.__call_type_handler(
|
|
494
|
+
return self.__call_type_handler(mypy_type.items[0])
|
|
464
495
|
|
|
465
|
-
def get_type_from_none_type(
|
|
466
|
-
self, node: ast.AstSymbolNode, mypy_type: MypyTypes.NoneType
|
|
467
|
-
) -> None:
|
|
496
|
+
def get_type_from_none_type(self, mypy_type: MypyTypes.NoneType) -> Optional[str]:
|
|
468
497
|
"""Get type info from mypy type NoneType."""
|
|
469
|
-
|
|
498
|
+
return "None"
|
|
470
499
|
|
|
471
|
-
def get_type_from_any_type(
|
|
472
|
-
self, node: ast.AstSymbolNode, mypy_type: MypyTypes.AnyType
|
|
473
|
-
) -> None:
|
|
500
|
+
def get_type_from_any_type(self, mypy_type: MypyTypes.AnyType) -> Optional[str]:
|
|
474
501
|
"""Get type info from mypy type NoneType."""
|
|
475
|
-
|
|
502
|
+
return "Any"
|
|
476
503
|
|
|
477
|
-
def get_type_from_tuple_type(
|
|
478
|
-
self, node: ast.AstSymbolNode, mypy_type: MypyTypes.TupleType
|
|
479
|
-
) -> None:
|
|
504
|
+
def get_type_from_tuple_type(self, mypy_type: MypyTypes.TupleType) -> Optional[str]:
|
|
480
505
|
"""Get type info from mypy type TupleType."""
|
|
481
|
-
|
|
506
|
+
return "builtins.tuple"
|
|
482
507
|
|
|
483
|
-
def get_type_from_type_type(
|
|
484
|
-
self, node: ast.AstSymbolNode, mypy_type: MypyTypes.TypeType
|
|
485
|
-
) -> None:
|
|
508
|
+
def get_type_from_type_type(self, mypy_type: MypyTypes.TypeType) -> Optional[str]:
|
|
486
509
|
"""Get type info from mypy type TypeType."""
|
|
487
|
-
|
|
510
|
+
return str(mypy_type.item)
|
|
488
511
|
|
|
489
512
|
def exit_assignment(self, node: ast.Assignment) -> None:
|
|
490
513
|
"""Add new symbols in the symbol table in case of self."""
|
|
@@ -511,7 +534,7 @@ class FuseTypeInfoPass(Pass):
|
|
|
511
534
|
for target in node.target.items:
|
|
512
535
|
if (
|
|
513
536
|
isinstance(target, ast.Name)
|
|
514
|
-
and target.
|
|
537
|
+
and target.expr_type == "types.ModuleType"
|
|
515
538
|
and isinstance(node.value, ast.Name)
|
|
516
539
|
):
|
|
517
540
|
target.type_sym_tab = node.value.type_sym_tab
|
|
@@ -553,7 +576,7 @@ class FuseTypeInfoPass(Pass):
|
|
|
553
576
|
left = atom_trailer_unwind[i - 1]
|
|
554
577
|
right = atom_trailer_unwind[i]
|
|
555
578
|
|
|
556
|
-
assert isinstance(left, ast.AstSymbolNode)
|
|
579
|
+
assert isinstance(left, (ast.Expr, ast.AstSymbolNode))
|
|
557
580
|
assert isinstance(right, ast.AstSymbolNode)
|
|
558
581
|
|
|
559
582
|
if isinstance(right, ast.IndexSlice):
|
|
@@ -561,25 +584,25 @@ class FuseTypeInfoPass(Pass):
|
|
|
561
584
|
node_type: str = ""
|
|
562
585
|
|
|
563
586
|
# left type is a list
|
|
564
|
-
if left.
|
|
565
|
-
node_type = left.
|
|
587
|
+
if left.expr_type.startswith("builtins.list["):
|
|
588
|
+
node_type = left.expr_type[len("builtins.list[") : -1]
|
|
566
589
|
|
|
567
590
|
# right index slice is a range then it's type is the same as left
|
|
568
591
|
if right.is_range:
|
|
569
|
-
right.
|
|
592
|
+
right.expr_type = left.expr_type
|
|
570
593
|
continue
|
|
571
594
|
|
|
572
595
|
# left type is a dictionary
|
|
573
|
-
elif left.
|
|
596
|
+
elif left.expr_type.startswith("builtins.dict["):
|
|
574
597
|
node_type = (
|
|
575
|
-
left.
|
|
598
|
+
left.expr_type[len("builtins.dict[") : -1].split(",")[1].strip()
|
|
576
599
|
)
|
|
577
600
|
|
|
578
601
|
# unsupported type
|
|
579
602
|
else:
|
|
580
603
|
continue
|
|
581
604
|
|
|
582
|
-
right.
|
|
605
|
+
right.expr_type = node_type
|
|
583
606
|
|
|
584
607
|
# Getting the correct symbol table and link it
|
|
585
608
|
type_symtab: Optional[SymbolTable] = self.ir.sym_tab
|
|
@@ -595,7 +618,7 @@ class FuseTypeInfoPass(Pass):
|
|
|
595
618
|
type_symtab = type_symtab.find_scope(j)
|
|
596
619
|
if type_symtab is None:
|
|
597
620
|
break
|
|
598
|
-
right.
|
|
621
|
+
right.type_sym_tab = type_symtab
|
|
599
622
|
|
|
600
623
|
else:
|
|
601
624
|
if left.type_sym_tab:
|
|
@@ -279,9 +279,11 @@ class PyImportPass(JacImportPass):
|
|
|
279
279
|
return self.import_table[file_to_raise]
|
|
280
280
|
|
|
281
281
|
with open(file_to_raise, "r", encoding="utf-8") as f:
|
|
282
|
+
file_source = f.read()
|
|
282
283
|
mod = PyastBuildPass(
|
|
283
284
|
input_ir=ast.PythonModuleAst(
|
|
284
|
-
py_ast.parse(
|
|
285
|
+
py_ast.parse(file_source),
|
|
286
|
+
orig_src=ast.JacSource(file_source, file_to_raise),
|
|
285
287
|
),
|
|
286
288
|
).ir
|
|
287
289
|
SubNodeTabPass(input_ir=mod, prior=self)
|
|
@@ -313,9 +315,11 @@ class PyImportPass(JacImportPass):
|
|
|
313
315
|
/ "builtins.pyi"
|
|
314
316
|
)
|
|
315
317
|
with open(file_to_raise, "r", encoding="utf-8") as f:
|
|
318
|
+
file_source = f.read()
|
|
316
319
|
mod = PyastBuildPass(
|
|
317
320
|
input_ir=ast.PythonModuleAst(
|
|
318
|
-
py_ast.parse(
|
|
321
|
+
py_ast.parse(file_source),
|
|
322
|
+
orig_src=ast.JacSource(file_source, file_to_raise),
|
|
319
323
|
),
|
|
320
324
|
).ir
|
|
321
325
|
mod.parent = self.ir
|
|
@@ -1055,14 +1055,7 @@ class PyastGenPass(Pass):
|
|
|
1055
1055
|
ctx=ast3.Load(),
|
|
1056
1056
|
)
|
|
1057
1057
|
),
|
|
1058
|
-
args=[
|
|
1059
|
-
self.sync(ast3.Constant(value=i.sym_name)),
|
|
1060
|
-
(
|
|
1061
|
-
i.signature.arch_tag_info.gen.py_ast[0]
|
|
1062
|
-
if i.signature.arch_tag_info
|
|
1063
|
-
else self.sync(ast3.Constant(value=None))
|
|
1064
|
-
),
|
|
1065
|
-
],
|
|
1058
|
+
args=[self.sync(ast3.Constant(value=i.sym_name))],
|
|
1066
1059
|
keywords=[],
|
|
1067
1060
|
)
|
|
1068
1061
|
)
|
|
@@ -3081,23 +3074,56 @@ class PyastGenPass(Pass):
|
|
|
3081
3074
|
def exit_index_slice(self, node: ast.IndexSlice) -> None:
|
|
3082
3075
|
"""Sub objects.
|
|
3083
3076
|
|
|
3084
|
-
|
|
3085
|
-
stop: Optional[ExprType],
|
|
3086
|
-
step: Optional[ExprType],
|
|
3077
|
+
slices: list[IndexSlice.Slice],
|
|
3087
3078
|
is_range: bool,
|
|
3088
3079
|
"""
|
|
3089
3080
|
if node.is_range:
|
|
3090
|
-
node.
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3081
|
+
if len(node.slices) > 1: # Multiple slices. Example arr[a:b, c:d]
|
|
3082
|
+
node.gen.py_ast = [
|
|
3083
|
+
self.sync(
|
|
3084
|
+
ast3.Tuple(
|
|
3085
|
+
elts=[
|
|
3086
|
+
self.sync(
|
|
3087
|
+
ast3.Slice(
|
|
3088
|
+
lower=(
|
|
3089
|
+
slice.start.gen.py_ast[0]
|
|
3090
|
+
if slice.start
|
|
3091
|
+
else None
|
|
3092
|
+
),
|
|
3093
|
+
upper=(
|
|
3094
|
+
slice.stop.gen.py_ast[0]
|
|
3095
|
+
if slice.stop
|
|
3096
|
+
else None
|
|
3097
|
+
),
|
|
3098
|
+
step=(
|
|
3099
|
+
slice.step.gen.py_ast[0]
|
|
3100
|
+
if slice.step
|
|
3101
|
+
else None
|
|
3102
|
+
),
|
|
3103
|
+
)
|
|
3104
|
+
)
|
|
3105
|
+
for slice in node.slices
|
|
3106
|
+
],
|
|
3107
|
+
ctx=ast3.Load(),
|
|
3108
|
+
)
|
|
3096
3109
|
)
|
|
3097
|
-
|
|
3098
|
-
]
|
|
3110
|
+
]
|
|
3111
|
+
elif len(node.slices) == 1: # Single slice. Example arr[a]
|
|
3112
|
+
slice = node.slices[0]
|
|
3113
|
+
node.gen.py_ast = [
|
|
3114
|
+
self.sync(
|
|
3115
|
+
ast3.Slice(
|
|
3116
|
+
lower=slice.start.gen.py_ast[0] if slice.start else None,
|
|
3117
|
+
upper=slice.stop.gen.py_ast[0] if slice.stop else None,
|
|
3118
|
+
step=slice.step.gen.py_ast[0] if slice.step else None,
|
|
3119
|
+
)
|
|
3120
|
+
)
|
|
3121
|
+
]
|
|
3099
3122
|
else:
|
|
3100
|
-
node.
|
|
3123
|
+
if len(node.slices) > 0 and node.slices[0].start is not None:
|
|
3124
|
+
node.gen.py_ast = node.slices[0].start.gen.py_ast
|
|
3125
|
+
else:
|
|
3126
|
+
node.gen.py_ast = []
|
|
3101
3127
|
|
|
3102
3128
|
def exit_special_var_ref(self, node: ast.SpecialVarRef) -> None:
|
|
3103
3129
|
"""Sub objects.
|