jaclang 0.5.17__py3-none-any.whl → 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jaclang might be problematic. Click here for more details.
- jaclang/__init__.py +2 -6
- jaclang/cli/cli.py +4 -2
- jaclang/compiler/__init__.py +12 -5
- jaclang/compiler/absyntree.py +23 -23
- jaclang/compiler/generated/jac_parser.py +2 -2
- jaclang/compiler/jac.lark +9 -9
- jaclang/compiler/parser.py +76 -21
- jaclang/compiler/passes/ir_pass.py +10 -8
- jaclang/compiler/passes/main/__init__.py +3 -2
- jaclang/compiler/passes/main/access_modifier_pass.py +173 -0
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +3 -2
- jaclang/compiler/passes/main/import_pass.py +33 -21
- jaclang/compiler/passes/main/pyast_gen_pass.py +99 -44
- jaclang/compiler/passes/main/pyast_load_pass.py +141 -77
- jaclang/compiler/passes/main/pyout_pass.py +14 -13
- jaclang/compiler/passes/main/registry_pass.py +8 -3
- jaclang/compiler/passes/main/schedules.py +5 -3
- jaclang/compiler/passes/main/sym_tab_build_pass.py +47 -37
- jaclang/compiler/passes/main/tests/test_import_pass.py +2 -2
- jaclang/compiler/passes/tool/jac_formatter_pass.py +85 -23
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -4
- jaclang/compiler/passes/transform.py +2 -0
- jaclang/compiler/symtable.py +10 -3
- jaclang/compiler/tests/test_importer.py +9 -0
- jaclang/compiler/workspace.py +19 -11
- jaclang/core/aott.py +34 -63
- jaclang/core/importer.py +73 -65
- jaclang/core/llms/__init__.py +20 -0
- jaclang/core/llms/anthropic.py +61 -0
- jaclang/core/llms/base.py +206 -0
- jaclang/core/llms/groq.py +67 -0
- jaclang/core/llms/huggingface.py +73 -0
- jaclang/core/llms/ollama.py +78 -0
- jaclang/core/llms/openai.py +61 -0
- jaclang/core/llms/togetherai.py +60 -0
- jaclang/core/llms/utils.py +9 -0
- jaclang/core/utils.py +16 -1
- jaclang/plugin/default.py +47 -16
- jaclang/plugin/feature.py +9 -6
- jaclang/plugin/spec.py +8 -1
- jaclang/settings.py +95 -0
- jaclang/utils/helpers.py +6 -2
- jaclang/utils/treeprinter.py +9 -6
- jaclang/vendor/mypy/checker.py +2 -3
- jaclang-0.6.0.dist-info/METADATA +17 -0
- {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/RECORD +49 -39
- jaclang/core/llms.py +0 -29
- jaclang-0.5.17.dist-info/METADATA +0 -7
- {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/WHEEL +0 -0
- {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/entry_points.txt +0 -0
- {jaclang-0.5.17.dist-info → jaclang-0.6.0.dist-info}/top_level.txt +0 -0
jaclang/compiler/jac.lark
CHANGED
|
@@ -195,8 +195,8 @@ list_inner_pattern: (pattern_seq | STAR_MUL NAME)
|
|
|
195
195
|
dict_inner_pattern: (literal_pattern COLON pattern_seq | STAR_POW NAME)
|
|
196
196
|
|
|
197
197
|
// Match class patterns
|
|
198
|
-
class_pattern: NAME LPAREN kw_pattern_list? RPAREN
|
|
199
|
-
| NAME LPAREN pattern_list (COMMA kw_pattern_list)? RPAREN
|
|
198
|
+
class_pattern: NAME (DOT NAME)* LPAREN kw_pattern_list? RPAREN
|
|
199
|
+
| NAME (DOT NAME)* LPAREN pattern_list (COMMA kw_pattern_list)? RPAREN
|
|
200
200
|
|
|
201
201
|
pattern_list: (pattern_list COMMA)? pattern_seq
|
|
202
202
|
kw_pattern_list: (kw_pattern_list COMMA)? named_ref EQ pattern_seq
|
|
@@ -317,9 +317,9 @@ cmp_op: KW_ISN
|
|
|
317
317
|
|
|
318
318
|
// Arithmetic expressions
|
|
319
319
|
arithmetic: (arithmetic (MINUS | PLUS))? term
|
|
320
|
-
term: (term (MOD | DIV | FLOOR_DIV | STAR_MUL | DECOR_OP))?
|
|
321
|
-
|
|
322
|
-
|
|
320
|
+
term: (term (MOD | DIV | FLOOR_DIV | STAR_MUL | DECOR_OP))? power
|
|
321
|
+
power: (power STAR_POW)? factor
|
|
322
|
+
factor: (BW_NOT | MINUS | PLUS) factor | connect
|
|
323
323
|
|
|
324
324
|
// Connect expressions
|
|
325
325
|
connect: (connect (connect_op | disconnect_op))? atomic_pipe
|
|
@@ -539,16 +539,16 @@ KW_POST_INIT: "postinit"
|
|
|
539
539
|
KW_SUPER: "super"
|
|
540
540
|
KW_ROOT: "root"
|
|
541
541
|
|
|
542
|
-
FLOAT: /(\d+(\.\d*)|\.\d+)([eE][+-]?\d+)
|
|
542
|
+
FLOAT: /(\d+(\.\d*)|\.\d+)([eE][+-]?\d+)?|\d+([eE][-+]?\d+)/
|
|
543
543
|
DOC_STRING.1: /"""(.|\n|\r)*?"""|'''(.|\n|\r)*?'''/
|
|
544
544
|
PYNLINE: /::py::(.|\n|\r)*?::py::/
|
|
545
545
|
STRING: /(r?b?|b?r?)"[^"\r\n]*"|(r?b?|b?r?)'[^'\r\n]*'/
|
|
546
546
|
BOOL.1: /True|False/
|
|
547
547
|
KW_NIN.1: /\bnot\s+in\b/
|
|
548
548
|
KW_ISN.1: /\bis\s+not\b/
|
|
549
|
-
HEX: /0[xX][0-9a-fA-F_]+/
|
|
550
|
-
BIN: /0[bB][01_]+/
|
|
551
|
-
OCT: /0[oO][0-7_]+/
|
|
549
|
+
HEX.1: /0[xX][0-9a-fA-F_]+/
|
|
550
|
+
BIN.1: /0[bB][01_]+/
|
|
551
|
+
OCT.1: /0[oO][0-7_]+/
|
|
552
552
|
INT: /[0-9][0-9_]*/
|
|
553
553
|
NULL.1: /None/
|
|
554
554
|
KWESC_NAME: /<>[a-zA-Z_][a-zA-Z0-9_]*/
|
jaclang/compiler/parser.py
CHANGED
|
@@ -287,17 +287,22 @@ class JacParser(Pass):
|
|
|
287
287
|
if len(kid) == 1 and isinstance(kid[0], ast.Import):
|
|
288
288
|
return self.nu(kid[0])
|
|
289
289
|
lang = kid[1]
|
|
290
|
-
|
|
290
|
+
from_path = kid[3] if isinstance(kid[3], ast.ModulePath) else None
|
|
291
|
+
if from_path:
|
|
292
|
+
items = kid[-2] if isinstance(kid[-2], ast.SubNodeList) else None
|
|
293
|
+
else:
|
|
294
|
+
paths = [i for i in kid if isinstance(i, ast.ModulePath)]
|
|
295
|
+
items = ast.SubNodeList[ast.ModulePath](
|
|
296
|
+
items=paths, delim=Tok.COMMA, kid=kid[2:-1]
|
|
297
|
+
)
|
|
298
|
+
kid = kid[:2] + [items] + kid[-1:]
|
|
291
299
|
|
|
292
|
-
items = kid[-2] if isinstance(kid[-2], ast.SubNodeList) else None
|
|
293
300
|
is_absorb = False
|
|
294
|
-
if isinstance(lang, ast.SubTag) and (
|
|
295
|
-
isinstance(items, ast.SubNodeList) or items is None
|
|
296
|
-
):
|
|
301
|
+
if isinstance(lang, ast.SubTag) and (isinstance(items, ast.SubNodeList)):
|
|
297
302
|
return self.nu(
|
|
298
303
|
ast.Import(
|
|
299
304
|
hint=lang,
|
|
300
|
-
|
|
305
|
+
from_loc=from_path,
|
|
301
306
|
items=items,
|
|
302
307
|
is_absorb=is_absorb,
|
|
303
308
|
kid=kid,
|
|
@@ -342,14 +347,20 @@ class JacParser(Pass):
|
|
|
342
347
|
include_stmt: KW_INCLUDE sub_name import_path SEMI
|
|
343
348
|
"""
|
|
344
349
|
lang = kid[1]
|
|
345
|
-
|
|
350
|
+
from_path = kid[2]
|
|
351
|
+
if not isinstance(from_path, ast.ModulePath):
|
|
352
|
+
raise self.ice()
|
|
353
|
+
items = ast.SubNodeList[ast.ModulePath](
|
|
354
|
+
items=[from_path], delim=Tok.COMMA, kid=[from_path]
|
|
355
|
+
)
|
|
356
|
+
kid = kid[:2] + [items] + kid[3:]
|
|
346
357
|
is_absorb = True
|
|
347
358
|
if isinstance(lang, ast.SubTag):
|
|
348
359
|
return self.nu(
|
|
349
360
|
ast.Import(
|
|
350
361
|
hint=lang,
|
|
351
|
-
|
|
352
|
-
items=
|
|
362
|
+
from_loc=None,
|
|
363
|
+
items=items,
|
|
353
364
|
is_absorb=is_absorb,
|
|
354
365
|
kid=kid,
|
|
355
366
|
)
|
|
@@ -1919,13 +1930,17 @@ class JacParser(Pass):
|
|
|
1919
1930
|
sig_kid.append(params)
|
|
1920
1931
|
if return_type:
|
|
1921
1932
|
sig_kid.append(return_type)
|
|
1922
|
-
signature =
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1933
|
+
signature = (
|
|
1934
|
+
ast.FuncSignature(
|
|
1935
|
+
params=params,
|
|
1936
|
+
return_type=return_type,
|
|
1937
|
+
kid=sig_kid,
|
|
1938
|
+
)
|
|
1939
|
+
if params or return_type
|
|
1940
|
+
else None
|
|
1926
1941
|
)
|
|
1927
1942
|
new_kid = [i for i in kid if i != params and i != return_type]
|
|
1928
|
-
new_kid.insert(1, signature)
|
|
1943
|
+
new_kid.insert(1, signature) if signature else None
|
|
1929
1944
|
if isinstance(chomp[0], ast.Expr):
|
|
1930
1945
|
return self.nu(
|
|
1931
1946
|
ast.LambdaExpr(
|
|
@@ -3724,12 +3739,43 @@ class JacParser(Pass):
|
|
|
3724
3739
|
def class_pattern(self, kid: list[ast.AstNode]) -> ast.MatchArch:
|
|
3725
3740
|
"""Grammar rule.
|
|
3726
3741
|
|
|
3727
|
-
class_pattern: NAME LPAREN kw_pattern_list? RPAREN
|
|
3728
|
-
| NAME LPAREN pattern_list (COMMA kw_pattern_list)? RPAREN
|
|
3742
|
+
class_pattern: NAME (DOT NAME)* LPAREN kw_pattern_list? RPAREN
|
|
3743
|
+
| NAME (DOT NAME)* LPAREN pattern_list (COMMA kw_pattern_list)? RPAREN
|
|
3729
3744
|
"""
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3745
|
+
chomp = [*kid]
|
|
3746
|
+
cur_element = chomp[0]
|
|
3747
|
+
chomp = chomp[1:]
|
|
3748
|
+
while not (isinstance(chomp[0], ast.Token) and chomp[0].name == Tok.LPAREN):
|
|
3749
|
+
if isinstance(chomp[0], ast.Token) and chomp[0].name == Tok.DOT:
|
|
3750
|
+
target_ = cur_element
|
|
3751
|
+
right_ = chomp[1]
|
|
3752
|
+
if isinstance(right_, (ast.Expr, ast.AtomExpr)) and isinstance(
|
|
3753
|
+
target_, ast.Expr
|
|
3754
|
+
):
|
|
3755
|
+
cur_element = ast.AtomTrailer(
|
|
3756
|
+
target=target_,
|
|
3757
|
+
right=right_,
|
|
3758
|
+
is_attr=True,
|
|
3759
|
+
is_null_ok=False,
|
|
3760
|
+
kid=[target_, chomp[0], right_],
|
|
3761
|
+
)
|
|
3762
|
+
chomp = chomp[2:]
|
|
3763
|
+
else:
|
|
3764
|
+
raise self.ice()
|
|
3765
|
+
elif isinstance(cur_element, ast.NameSpec):
|
|
3766
|
+
chomp = chomp[1:]
|
|
3767
|
+
else:
|
|
3768
|
+
break
|
|
3769
|
+
name = cur_element
|
|
3770
|
+
lparen = chomp[0]
|
|
3771
|
+
rapren = chomp[-1]
|
|
3772
|
+
first = chomp[1]
|
|
3773
|
+
if len(chomp) > 4:
|
|
3774
|
+
second = chomp[3]
|
|
3775
|
+
comma = chomp[2]
|
|
3776
|
+
else:
|
|
3777
|
+
second = None
|
|
3778
|
+
comma = None
|
|
3733
3779
|
arg = (
|
|
3734
3780
|
first
|
|
3735
3781
|
if isinstance(first, ast.SubNodeList)
|
|
@@ -3747,13 +3793,22 @@ class JacParser(Pass):
|
|
|
3747
3793
|
else None
|
|
3748
3794
|
)
|
|
3749
3795
|
)
|
|
3750
|
-
if isinstance(name, ast.NameSpec):
|
|
3796
|
+
if isinstance(name, (ast.NameSpec, ast.AtomTrailer)):
|
|
3797
|
+
kid_nodes = [name, lparen]
|
|
3798
|
+
if arg:
|
|
3799
|
+
kid_nodes.append(arg)
|
|
3800
|
+
if kw:
|
|
3801
|
+
kid_nodes.extend([comma, kw]) if comma else kid_nodes.append(kw)
|
|
3802
|
+
elif kw:
|
|
3803
|
+
kid_nodes.append(kw)
|
|
3804
|
+
kid_nodes.append(rapren)
|
|
3805
|
+
|
|
3751
3806
|
return self.nu(
|
|
3752
3807
|
ast.MatchArch(
|
|
3753
3808
|
name=name,
|
|
3754
3809
|
arg_patterns=arg,
|
|
3755
3810
|
kw_patterns=kw,
|
|
3756
|
-
kid=
|
|
3811
|
+
kid=kid_nodes,
|
|
3757
3812
|
)
|
|
3758
3813
|
)
|
|
3759
3814
|
else:
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"""Abstract class for IR Passes for Jac."""
|
|
2
2
|
|
|
3
|
-
from typing import Optional, Type
|
|
3
|
+
from typing import Optional, Type, TypeVar
|
|
4
4
|
|
|
5
5
|
import jaclang.compiler.absyntree as ast
|
|
6
6
|
from jaclang.compiler.passes.transform import Transform
|
|
7
7
|
from jaclang.utils.helpers import pascal_to_snake
|
|
8
8
|
|
|
9
|
+
T = TypeVar("T", bound=ast.AstNode)
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
class Pass(Transform[T]):
|
|
11
13
|
"""Abstract class for IR passes."""
|
|
12
14
|
|
|
13
|
-
def __init__(self, input_ir:
|
|
15
|
+
def __init__(self, input_ir: T, prior: Optional[Transform]) -> None:
|
|
14
16
|
"""Initialize parser."""
|
|
15
17
|
self.term_signal = False
|
|
16
18
|
self.prune_signal = False
|
|
@@ -45,10 +47,10 @@ class Pass(Transform[ast.T]):
|
|
|
45
47
|
|
|
46
48
|
@staticmethod
|
|
47
49
|
def get_all_sub_nodes(
|
|
48
|
-
node: ast.AstNode, typ: Type[
|
|
49
|
-
) -> list[
|
|
50
|
+
node: ast.AstNode, typ: Type[T], brute_force: bool = False
|
|
51
|
+
) -> list[T]:
|
|
50
52
|
"""Get all sub nodes of type."""
|
|
51
|
-
result: list[
|
|
53
|
+
result: list[T] = []
|
|
52
54
|
# Assumes pass built the sub node table
|
|
53
55
|
if not node:
|
|
54
56
|
return result
|
|
@@ -69,7 +71,7 @@ class Pass(Transform[ast.T]):
|
|
|
69
71
|
return result
|
|
70
72
|
|
|
71
73
|
@staticmethod
|
|
72
|
-
def has_parent_of_type(node: ast.AstNode, typ: Type[
|
|
74
|
+
def has_parent_of_type(node: ast.AstNode, typ: Type[T]) -> Optional[T]:
|
|
73
75
|
"""Check if node has parent of type."""
|
|
74
76
|
while node.parent:
|
|
75
77
|
if isinstance(node.parent, typ):
|
|
@@ -97,7 +99,7 @@ class Pass(Transform[ast.T]):
|
|
|
97
99
|
|
|
98
100
|
# Transform Implementations
|
|
99
101
|
# -------------------------
|
|
100
|
-
def transform(self, ir:
|
|
102
|
+
def transform(self, ir: T) -> ast.AstNode:
|
|
101
103
|
"""Run pass."""
|
|
102
104
|
# Only performs passes on proper ASTs
|
|
103
105
|
if not isinstance(ir, ast.AstNode):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Collection of passes for Jac IR."""
|
|
2
2
|
|
|
3
3
|
from .sub_node_tab_pass import SubNodeTabPass
|
|
4
|
-
from .import_pass import
|
|
4
|
+
from .import_pass import JacImportPass, PyImportPass # noqa: I100
|
|
5
5
|
from .sym_tab_build_pass import SymTabBuildPass # noqa: I100
|
|
6
6
|
from .def_impl_match_pass import DeclDefMatchPass # noqa: I100
|
|
7
7
|
from .def_use_pass import DefUsePass # noqa: I100
|
|
@@ -17,7 +17,8 @@ pass_schedule = py_code_gen
|
|
|
17
17
|
|
|
18
18
|
__all__ = [
|
|
19
19
|
"SubNodeTabPass",
|
|
20
|
-
"
|
|
20
|
+
"JacImportPass",
|
|
21
|
+
"PyImportPass",
|
|
21
22
|
"SymTabBuildPass",
|
|
22
23
|
"DeclDefMatchPass",
|
|
23
24
|
"DefUsePass",
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""Access check pass for the Jac compiler.
|
|
2
|
+
|
|
3
|
+
This pass checks for access to attributes in the Jac language.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import jaclang.compiler.absyntree as ast
|
|
10
|
+
from jaclang.compiler.passes.main.sym_tab_build_pass import SymTabPass, SymbolAccess
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AccessCheckPass(SymTabPass):
|
|
14
|
+
"""Jac Ast Access Check pass."""
|
|
15
|
+
|
|
16
|
+
def after_pass(self) -> None:
|
|
17
|
+
"""After pass."""
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
def access_check(self, node: ast.Name) -> None:
|
|
21
|
+
"""Access check."""
|
|
22
|
+
node_info = (
|
|
23
|
+
node.sym_tab.lookup(node.sym_name)
|
|
24
|
+
if isinstance(node.sym_tab, ast.SymbolTable)
|
|
25
|
+
else None
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
if node.sym_link:
|
|
29
|
+
decl_package_path = os.path.dirname(
|
|
30
|
+
os.path.abspath(node.sym_link.defn[-1].loc.mod_path)
|
|
31
|
+
)
|
|
32
|
+
use_package_path = os.path.dirname(os.path.abspath(node.loc.mod_path))
|
|
33
|
+
else:
|
|
34
|
+
decl_package_path = use_package_path = ""
|
|
35
|
+
|
|
36
|
+
if (
|
|
37
|
+
node_info
|
|
38
|
+
and node.sym_link
|
|
39
|
+
and node_info.access == SymbolAccess.PROTECTED
|
|
40
|
+
and decl_package_path != use_package_path
|
|
41
|
+
):
|
|
42
|
+
return self.error(
|
|
43
|
+
f'Can not access protected variable "{node.sym_name}" from {decl_package_path}'
|
|
44
|
+
f" to {use_package_path}."
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
node_info
|
|
49
|
+
and node.sym_link
|
|
50
|
+
and node_info.access == SymbolAccess.PRIVATE
|
|
51
|
+
and node.sym_link.defn[-1].loc.mod_path != node.loc.mod_path
|
|
52
|
+
):
|
|
53
|
+
return self.error(
|
|
54
|
+
f'Can not access private variable "{node.sym_name}" from {node.sym_link.defn[-1].loc.mod_path}'
|
|
55
|
+
f" to {node.loc.mod_path}."
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def access_register(
|
|
59
|
+
self, node: ast.AstSymbolNode, acc_tag: Optional[SymbolAccess] = None
|
|
60
|
+
) -> None:
|
|
61
|
+
"""Access register."""
|
|
62
|
+
node.sym_info.acc_tag = acc_tag
|
|
63
|
+
|
|
64
|
+
def enter_global_vars(self, node: ast.GlobalVars) -> None:
|
|
65
|
+
"""Sub objects.
|
|
66
|
+
|
|
67
|
+
access: Optional[SubTag[Token]],
|
|
68
|
+
assignments: SubNodeList[Assignment],
|
|
69
|
+
is_frozen: bool,
|
|
70
|
+
"""
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
def enter_module(self, node: ast.Module) -> None:
|
|
74
|
+
"""Sub objects.
|
|
75
|
+
|
|
76
|
+
name: str,
|
|
77
|
+
doc: Token,
|
|
78
|
+
body: Optional['Elements'],
|
|
79
|
+
mod_path: str,
|
|
80
|
+
is_imported: bool,
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
def enter_architype(self, node: ast.Architype) -> None:
|
|
84
|
+
"""Sub objects.
|
|
85
|
+
|
|
86
|
+
name: Name,
|
|
87
|
+
arch_type: Token,
|
|
88
|
+
access: Optional[SubTag[Token]],
|
|
89
|
+
base_classes: Optional[SubNodeList[Expr]],
|
|
90
|
+
body: Optional[SubNodeList[ArchBlockStmt] | ArchDef],
|
|
91
|
+
decorators: Optional[SubNodeList[Expr]] = None,
|
|
92
|
+
"""
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
def enter_enum(self, node: ast.Enum) -> None:
|
|
96
|
+
"""Sub objects.
|
|
97
|
+
|
|
98
|
+
name: Name,
|
|
99
|
+
access: Optional[SubTag[Token]],
|
|
100
|
+
base_classes: Optional[SubNodeList[Expr]],
|
|
101
|
+
body: Optional[SubNodeList[EnumBlockStmt] | EnumDef],
|
|
102
|
+
decorators: Optional[SubNodeList[Expr]] = None,
|
|
103
|
+
"""
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
def enter_ability(self, node: ast.Ability) -> None:
|
|
107
|
+
"""Sub objects.
|
|
108
|
+
|
|
109
|
+
name_ref: NameSpec,
|
|
110
|
+
is_func: bool,
|
|
111
|
+
is_async: bool,
|
|
112
|
+
is_override: bool,
|
|
113
|
+
is_static: bool,
|
|
114
|
+
is_abstract: bool,
|
|
115
|
+
access: Optional[SubTag[Token]],
|
|
116
|
+
signature: Optional[FuncSignature | EventSignature],
|
|
117
|
+
body: Optional[SubNodeList[CodeBlockStmt] | AbilityDef],
|
|
118
|
+
decorators: Optional[SubNodeList[Expr]] = None,
|
|
119
|
+
"""
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
def enter_sub_node_list(self, node: ast.SubNodeList) -> None:
|
|
123
|
+
"""Sub objects.
|
|
124
|
+
|
|
125
|
+
items: list[T]
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
def enter_arch_has(self, node: ast.ArchHas) -> None:
|
|
129
|
+
"""Sub objects.
|
|
130
|
+
|
|
131
|
+
is_static: bool,
|
|
132
|
+
access: Optional[SubTag[Token]],
|
|
133
|
+
vars: SubNodeList[HasVar],
|
|
134
|
+
is_frozen: bool,
|
|
135
|
+
"""
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
def enter_atom_trailer(self, node: ast.AtomTrailer) -> None:
|
|
139
|
+
"""Sub objects.
|
|
140
|
+
|
|
141
|
+
access: Optional[SubTag[Token]],
|
|
142
|
+
"""
|
|
143
|
+
pass
|
|
144
|
+
|
|
145
|
+
def enter_func_call(self, node: ast.FuncCall) -> None:
|
|
146
|
+
"""Sub objects.
|
|
147
|
+
|
|
148
|
+
target: Expr,
|
|
149
|
+
params: Optional[SubNodeList[Expr | KWPair]],
|
|
150
|
+
genai_call: Optional[FuncCall],
|
|
151
|
+
kid: Sequence[AstNode],
|
|
152
|
+
"""
|
|
153
|
+
pass
|
|
154
|
+
|
|
155
|
+
def enter_name(self, node: ast.Name) -> None:
|
|
156
|
+
"""Sub objects.
|
|
157
|
+
|
|
158
|
+
name: str,
|
|
159
|
+
value: str,
|
|
160
|
+
col_start: int,
|
|
161
|
+
col_end: int,
|
|
162
|
+
pos_start: int,
|
|
163
|
+
pos_end: int,
|
|
164
|
+
"""
|
|
165
|
+
from jaclang.compiler.passes import Pass
|
|
166
|
+
|
|
167
|
+
if isinstance(node.parent, ast.FuncCall):
|
|
168
|
+
self.access_check(node)
|
|
169
|
+
|
|
170
|
+
if node.sym_link and Pass.has_parent_of_type(
|
|
171
|
+
node=node.sym_link.defn[-1], typ=ast.GlobalVars
|
|
172
|
+
):
|
|
173
|
+
self.access_check(node)
|
|
@@ -6,15 +6,16 @@ mypy apis into Jac and use jac py ast in it.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
import os
|
|
10
9
|
import traceback
|
|
11
10
|
from typing import Callable, TypeVar
|
|
12
11
|
|
|
13
12
|
import jaclang.compiler.absyntree as ast
|
|
14
13
|
from jaclang.compiler.passes import Pass
|
|
14
|
+
from jaclang.settings import settings
|
|
15
15
|
from jaclang.utils.helpers import pascal_to_snake
|
|
16
16
|
from jaclang.vendor.mypy.nodes import Node as VNode # bit of a hack
|
|
17
17
|
|
|
18
|
+
|
|
18
19
|
import mypy.nodes as MypyNodes # noqa N812
|
|
19
20
|
import mypy.types as MypyTypes # noqa N812
|
|
20
21
|
from mypy.checkexpr import Type as MyType
|
|
@@ -29,7 +30,7 @@ class FuseTypeInfoPass(Pass):
|
|
|
29
30
|
node_type_hash: dict[MypyNodes.Node | VNode, MyType] = {}
|
|
30
31
|
|
|
31
32
|
def __debug_print(self, *argv: object) -> None:
|
|
32
|
-
if
|
|
33
|
+
if settings.fuse_type_info_debug:
|
|
33
34
|
print("FuseTypeInfo::", *argv)
|
|
34
35
|
|
|
35
36
|
def __call_type_handler(
|
|
@@ -7,7 +7,6 @@ symbols are available for matching.
|
|
|
7
7
|
|
|
8
8
|
import ast as py_ast
|
|
9
9
|
import importlib.util
|
|
10
|
-
import os
|
|
11
10
|
import sys
|
|
12
11
|
from os import path
|
|
13
12
|
from typing import Optional
|
|
@@ -16,11 +15,12 @@ from typing import Optional
|
|
|
16
15
|
import jaclang.compiler.absyntree as ast
|
|
17
16
|
from jaclang.compiler.passes import Pass
|
|
18
17
|
from jaclang.compiler.passes.main import SubNodeTabPass
|
|
18
|
+
from jaclang.settings import settings
|
|
19
19
|
from jaclang.utils.helpers import import_target_to_relative_path
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
class
|
|
23
|
-
"""Jac statically imports
|
|
22
|
+
class JacImportPass(Pass):
|
|
23
|
+
"""Jac statically imports Jac modules."""
|
|
24
24
|
|
|
25
25
|
def before_pass(self) -> None:
|
|
26
26
|
"""Run once before pass."""
|
|
@@ -29,6 +29,7 @@ class ImportPass(Pass):
|
|
|
29
29
|
def enter_module(self, node: ast.Module) -> None:
|
|
30
30
|
"""Run Importer."""
|
|
31
31
|
self.cur_node = node
|
|
32
|
+
self.import_table[node.loc.mod_path] = node
|
|
32
33
|
self.annex_impl(node)
|
|
33
34
|
self.terminate() # Turns off auto traversal for deliberate traversal
|
|
34
35
|
self.run_again = True
|
|
@@ -36,29 +37,26 @@ class ImportPass(Pass):
|
|
|
36
37
|
self.run_again = False
|
|
37
38
|
all_imports = self.get_all_sub_nodes(node, ast.ModulePath)
|
|
38
39
|
for i in all_imports:
|
|
39
|
-
|
|
40
|
-
self.run_again = True
|
|
41
|
-
mod = self.import_module(
|
|
42
|
-
node=i,
|
|
43
|
-
mod_path=node.loc.mod_path,
|
|
44
|
-
)
|
|
45
|
-
if not mod:
|
|
46
|
-
self.run_again = False
|
|
47
|
-
continue
|
|
48
|
-
self.annex_impl(mod)
|
|
49
|
-
i.sub_module = mod
|
|
50
|
-
i.add_kids_right([mod], pos_update=False)
|
|
51
|
-
elif i.parent.hint.tag.value == "py" and os.environ.get(
|
|
52
|
-
"JAC_PROC_DEBUG", False
|
|
53
|
-
):
|
|
54
|
-
mod = self.import_py_module(node=i, mod_path=node.loc.mod_path)
|
|
55
|
-
i.sub_module = mod
|
|
56
|
-
i.add_kids_right([mod], pos_update=False)
|
|
40
|
+
self.process_import(node, i)
|
|
57
41
|
self.enter_module_path(i)
|
|
58
42
|
SubNodeTabPass(prior=self, input_ir=node)
|
|
59
43
|
self.annex_impl(node)
|
|
60
44
|
node.mod_deps = self.import_table
|
|
61
45
|
|
|
46
|
+
def process_import(self, node: ast.Module, i: ast.ModulePath) -> None:
|
|
47
|
+
"""Process an import."""
|
|
48
|
+
lang = i.parent_of_type(ast.Import).hint.tag.value
|
|
49
|
+
if lang == "jac" and not i.sub_module:
|
|
50
|
+
mod = self.import_module(
|
|
51
|
+
node=i,
|
|
52
|
+
mod_path=node.loc.mod_path,
|
|
53
|
+
)
|
|
54
|
+
if mod:
|
|
55
|
+
self.run_again = True
|
|
56
|
+
self.annex_impl(mod)
|
|
57
|
+
i.sub_module = mod
|
|
58
|
+
i.add_kids_right([mod], pos_update=False)
|
|
59
|
+
|
|
62
60
|
def annex_impl(self, node: ast.Module) -> None:
|
|
63
61
|
"""Annex impl and test modules."""
|
|
64
62
|
if not node.loc.mod_path:
|
|
@@ -166,3 +164,17 @@ class ImportPass(Pass):
|
|
|
166
164
|
)
|
|
167
165
|
raise e
|
|
168
166
|
return None
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class PyImportPass(JacImportPass):
|
|
170
|
+
"""Jac statically imports Python modules."""
|
|
171
|
+
|
|
172
|
+
def process_import(self, node: ast.Module, i: ast.ModulePath) -> None:
|
|
173
|
+
"""Process an import."""
|
|
174
|
+
lang = i.parent_of_type(ast.Import).hint.tag.value
|
|
175
|
+
if lang == "py" and not i.sub_module and settings.py_raise:
|
|
176
|
+
mod = self.import_py_module(node=i, mod_path=node.loc.mod_path)
|
|
177
|
+
if mod:
|
|
178
|
+
# self.run_again = True
|
|
179
|
+
i.sub_module = mod
|
|
180
|
+
i.add_kids_right([mod], pos_update=False)
|