jaclang 0.6.5__py3-none-any.whl → 0.7.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jaclang might be problematic. Click here for more details.
- jaclang/compiler/absyntree.py +4 -36
- jaclang/compiler/compile.py +21 -0
- jaclang/compiler/parser.py +13 -4
- jaclang/compiler/passes/main/__init__.py +2 -2
- jaclang/compiler/passes/main/def_impl_match_pass.py +1 -5
- jaclang/compiler/passes/main/def_use_pass.py +14 -7
- jaclang/compiler/passes/main/import_pass.py +56 -10
- jaclang/compiler/passes/main/pyast_gen_pass.py +55 -2
- jaclang/compiler/passes/main/schedules.py +4 -3
- jaclang/compiler/passes/main/tests/fixtures/incautoimpl.jac +7 -0
- jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +4 -4
- jaclang/compiler/passes/main/tests/test_import_pass.py +13 -0
- jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -2
- jaclang/compiler/passes/transform.py +13 -4
- jaclang/compiler/tests/fixtures/mod_doc_test.jac +3 -1
- jaclang/langserve/engine.py +375 -0
- jaclang/langserve/server.py +112 -74
- jaclang/langserve/tests/fixtures/circle.jac +73 -0
- jaclang/langserve/tests/fixtures/circle_err.jac +73 -0
- jaclang/langserve/tests/fixtures/circle_pure.impl.jac +28 -0
- jaclang/langserve/tests/fixtures/circle_pure.jac +34 -0
- jaclang/langserve/tests/fixtures/circle_pure_err.impl.jac +32 -0
- jaclang/langserve/tests/fixtures/circle_pure_err.jac +34 -0
- jaclang/langserve/tests/test_server.py +33 -1
- jaclang/langserve/utils.py +53 -16
- jaclang/plugin/default.py +1 -1
- jaclang/tests/fixtures/type_info.jac +1 -1
- jaclang/tests/test_cli.py +1 -1
- jaclang/utils/helpers.py +3 -5
- jaclang/utils/test.py +1 -1
- {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/METADATA +8 -16
- {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/RECORD +34 -28
- jaclang/compiler/tests/test_workspace.py +0 -93
- jaclang/compiler/workspace.py +0 -234
- {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/WHEEL +0 -0
- {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/entry_points.txt +0 -0
jaclang/compiler/absyntree.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import ast as ast3
|
|
6
|
+
from hashlib import md5
|
|
6
7
|
from types import EllipsisType
|
|
7
8
|
from typing import Any, Callable, Generic, Optional, Sequence, Type, TypeVar
|
|
8
9
|
|
|
@@ -700,10 +701,12 @@ class ModuleItem(AstSymbolNode):
|
|
|
700
701
|
name: Name,
|
|
701
702
|
alias: Optional[Name],
|
|
702
703
|
kid: Sequence[AstNode],
|
|
704
|
+
sub_module: Optional[Module] = None,
|
|
703
705
|
) -> None:
|
|
704
706
|
"""Initialize module item node."""
|
|
705
707
|
self.name = name
|
|
706
708
|
self.alias = alias
|
|
709
|
+
self.sub_module = sub_module
|
|
707
710
|
AstNode.__init__(self, kid=kid)
|
|
708
711
|
AstSymbolNode.__init__(
|
|
709
712
|
self,
|
|
@@ -1026,16 +1029,6 @@ class Ability(
|
|
|
1026
1029
|
AstDocNode.__init__(self, doc=doc)
|
|
1027
1030
|
AstAsyncNode.__init__(self, is_async=is_async)
|
|
1028
1031
|
|
|
1029
|
-
@property
|
|
1030
|
-
def is_method(self) -> bool:
|
|
1031
|
-
"""Check if is method."""
|
|
1032
|
-
check = isinstance(self.parent, SubNodeList) and isinstance(
|
|
1033
|
-
self.parent.parent, Architype
|
|
1034
|
-
)
|
|
1035
|
-
if check:
|
|
1036
|
-
self.sym_type = SymbolType.METHOD
|
|
1037
|
-
return check
|
|
1038
|
-
|
|
1039
1032
|
@property
|
|
1040
1033
|
def is_func(self) -> bool:
|
|
1041
1034
|
"""Check if is func."""
|
|
@@ -1151,14 +1144,6 @@ class AbilityDef(AstSymbolNode, ElementStmt, AstImplOnlyNode, CodeBlockStmt):
|
|
|
1151
1144
|
self.set_kids(nodes=new_kid)
|
|
1152
1145
|
return res
|
|
1153
1146
|
|
|
1154
|
-
@property
|
|
1155
|
-
def is_method(self) -> bool:
|
|
1156
|
-
"""Check if is method."""
|
|
1157
|
-
return (
|
|
1158
|
-
len(self.target.archs) > 1
|
|
1159
|
-
and self.target.archs[-2].arch.name != Tok.ABILITY_OP
|
|
1160
|
-
)
|
|
1161
|
-
|
|
1162
1147
|
|
|
1163
1148
|
class FuncSignature(AstSemStrNode):
|
|
1164
1149
|
"""FuncSignature node type for Jac Ast."""
|
|
@@ -1196,13 +1181,6 @@ class FuncSignature(AstSemStrNode):
|
|
|
1196
1181
|
self.set_kids(nodes=new_kid)
|
|
1197
1182
|
return res
|
|
1198
1183
|
|
|
1199
|
-
@property
|
|
1200
|
-
def is_method(self) -> bool:
|
|
1201
|
-
"""Check if is method."""
|
|
1202
|
-
return (isinstance(self.parent, Ability) and self.parent.is_method) or (
|
|
1203
|
-
isinstance(self.parent, AbilityDef) and self.parent.is_method
|
|
1204
|
-
)
|
|
1205
|
-
|
|
1206
1184
|
@property
|
|
1207
1185
|
def is_static(self) -> bool:
|
|
1208
1186
|
"""Check if is static."""
|
|
@@ -1255,17 +1233,6 @@ class EventSignature(AstSemStrNode):
|
|
|
1255
1233
|
self.set_kids(nodes=new_kid)
|
|
1256
1234
|
return res
|
|
1257
1235
|
|
|
1258
|
-
@property
|
|
1259
|
-
def is_method(self) -> bool:
|
|
1260
|
-
"""Check if is method."""
|
|
1261
|
-
if (isinstance(self.parent, Ability) and self.parent.is_method) or (
|
|
1262
|
-
isinstance(self.parent, AbilityDef)
|
|
1263
|
-
and isinstance(self.parent.decl_link, Ability)
|
|
1264
|
-
and self.parent.decl_link.is_method
|
|
1265
|
-
):
|
|
1266
|
-
return True
|
|
1267
|
-
return False
|
|
1268
|
-
|
|
1269
1236
|
|
|
1270
1237
|
class ArchRefChain(AstNode):
|
|
1271
1238
|
"""Arch ref list node type for Jac Ast."""
|
|
@@ -4081,6 +4048,7 @@ class JacSource(EmptyToken):
|
|
|
4081
4048
|
"""Initialize source string."""
|
|
4082
4049
|
super().__init__()
|
|
4083
4050
|
self.value = source
|
|
4051
|
+
self.hash = md5(source.encode()).hexdigest()
|
|
4084
4052
|
self.file_path = mod_path
|
|
4085
4053
|
self.comments: list[CommentToken] = []
|
|
4086
4054
|
|
jaclang/compiler/compile.py
CHANGED
|
@@ -57,6 +57,27 @@ def jac_str_to_pass(
|
|
|
57
57
|
return ast_ret
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
def jac_ir_to_pass(
|
|
61
|
+
ir: ast.AstNode,
|
|
62
|
+
target: Optional[Type[Pass]] = None,
|
|
63
|
+
schedule: list[Type[Pass]] = pass_schedule,
|
|
64
|
+
) -> Pass:
|
|
65
|
+
"""Convert a Jac file to an AST."""
|
|
66
|
+
if not target:
|
|
67
|
+
target = schedule[-1] if schedule else None
|
|
68
|
+
ast_ret = (
|
|
69
|
+
Pass(input_ir=ir, prior=None)
|
|
70
|
+
if not len(schedule)
|
|
71
|
+
else schedule[0](input_ir=ir, prior=None)
|
|
72
|
+
)
|
|
73
|
+
for i in schedule[1:]:
|
|
74
|
+
if i == target:
|
|
75
|
+
break
|
|
76
|
+
ast_ret = i(input_ir=ast_ret.ir, prior=ast_ret)
|
|
77
|
+
ast_ret = target(input_ir=ast_ret.ir, prior=ast_ret) if target else ast_ret
|
|
78
|
+
return ast_ret
|
|
79
|
+
|
|
80
|
+
|
|
60
81
|
def jac_pass_to_pass(
|
|
61
82
|
in_pass: Pass,
|
|
62
83
|
target: Optional[Type[Pass]] = None,
|
jaclang/compiler/parser.py
CHANGED
|
@@ -28,7 +28,7 @@ class JacParser(Pass):
|
|
|
28
28
|
JacParser.make_dev()
|
|
29
29
|
Pass.__init__(self, input_ir=input_ir, prior=None)
|
|
30
30
|
|
|
31
|
-
def transform(self, ir: ast.AstNode) -> ast.
|
|
31
|
+
def transform(self, ir: ast.AstNode) -> ast.Module:
|
|
32
32
|
"""Transform input IR."""
|
|
33
33
|
try:
|
|
34
34
|
tree, comments = JacParser.parse(
|
|
@@ -36,6 +36,10 @@ class JacParser(Pass):
|
|
|
36
36
|
)
|
|
37
37
|
mod = JacParser.TreeToAST(parser=self).transform(tree)
|
|
38
38
|
self.source.comments = [self.proc_comment(i, mod) for i in comments]
|
|
39
|
+
if isinstance(mod, ast.Module):
|
|
40
|
+
return mod
|
|
41
|
+
else:
|
|
42
|
+
raise self.ice()
|
|
39
43
|
except jl.UnexpectedInput as e:
|
|
40
44
|
catch_error = ast.EmptyToken()
|
|
41
45
|
catch_error.file_path = self.mod_path
|
|
@@ -43,11 +47,16 @@ class JacParser(Pass):
|
|
|
43
47
|
catch_error.c_start = e.column
|
|
44
48
|
catch_error.c_end = e.column
|
|
45
49
|
self.error(f"Syntax Error: {e}", node_override=catch_error)
|
|
46
|
-
mod = self.source
|
|
47
50
|
except Exception as e:
|
|
48
|
-
mod = self.source
|
|
49
51
|
self.error(f"Internal Error: {e}")
|
|
50
|
-
return
|
|
52
|
+
return ast.Module(
|
|
53
|
+
name="",
|
|
54
|
+
source=self.source,
|
|
55
|
+
doc=None,
|
|
56
|
+
body=[],
|
|
57
|
+
is_imported=False,
|
|
58
|
+
kid=[ast.EmptyToken()],
|
|
59
|
+
)
|
|
51
60
|
|
|
52
61
|
@staticmethod
|
|
53
62
|
def proc_comment(token: jl.Token, mod: ast.AstNode) -> ast.CommentToken:
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from .sub_node_tab_pass import SubNodeTabPass
|
|
4
4
|
from .import_pass import JacImportPass, PyImportPass # noqa: I100
|
|
5
5
|
from .sym_tab_build_pass import SymTabBuildPass # noqa: I100
|
|
6
|
-
from .def_impl_match_pass import
|
|
6
|
+
from .def_impl_match_pass import DeclImplMatchPass # noqa: I100
|
|
7
7
|
from .def_use_pass import DefUsePass # noqa: I100
|
|
8
8
|
from .pyout_pass import PyOutPass # noqa: I100
|
|
9
9
|
from .pyast_load_pass import PyastBuildPass # type: ignore # noqa: I100
|
|
@@ -20,7 +20,7 @@ __all__ = [
|
|
|
20
20
|
"JacImportPass",
|
|
21
21
|
"PyImportPass",
|
|
22
22
|
"SymTabBuildPass",
|
|
23
|
-
"
|
|
23
|
+
"DeclImplMatchPass",
|
|
24
24
|
"DefUsePass",
|
|
25
25
|
"PyOutPass",
|
|
26
26
|
"PyastBuildPass",
|
|
@@ -12,7 +12,7 @@ from jaclang.compiler.passes.main import SubNodeTabPass
|
|
|
12
12
|
from jaclang.compiler.symtable import Symbol, SymbolTable, SymbolType
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
class
|
|
15
|
+
class DeclImplMatchPass(Pass):
|
|
16
16
|
"""Decls and Def matching pass."""
|
|
17
17
|
|
|
18
18
|
def enter_module(self, node: ast.Module) -> None:
|
|
@@ -76,10 +76,6 @@ class DeclDefMatchPass(Pass):
|
|
|
76
76
|
continue
|
|
77
77
|
decl_node.body = sym.decl # type: ignore
|
|
78
78
|
sym.decl.decl_link = decl_node # type: ignore
|
|
79
|
-
source_node = sym.decl.parent
|
|
80
|
-
decl_node.add_kids_right([sym.decl]) # type: ignore
|
|
81
|
-
if source_node and sym.decl in source_node.kid:
|
|
82
|
-
source_node.kid.remove(sym.decl)
|
|
83
79
|
decl_node.sym_tab.tab = sym.decl.sym_tab.tab # type: ignore
|
|
84
80
|
for i in sym_tab.kid:
|
|
85
81
|
self.connect_def_impl(i)
|
|
@@ -28,13 +28,20 @@ class DefUsePass(SymTabPass):
|
|
|
28
28
|
sym_tab: Optional[SymbolTable],
|
|
29
29
|
"""
|
|
30
30
|
if node.arch_type.name == Tok.KW_WALKER:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
self.inform_from_walker(node)
|
|
32
|
+
for i in self.get_all_sub_nodes(node, ast.Ability):
|
|
33
|
+
if isinstance(i.body, ast.AbilityDef):
|
|
34
|
+
self.inform_from_walker(i.body)
|
|
35
|
+
|
|
36
|
+
def inform_from_walker(self, node: ast.AstNode) -> None:
|
|
37
|
+
"""Inform all sub nodes that they are from a walker."""
|
|
38
|
+
for i in (
|
|
39
|
+
self.get_all_sub_nodes(node, ast.VisitStmt)
|
|
40
|
+
+ self.get_all_sub_nodes(node, ast.IgnoreStmt)
|
|
41
|
+
+ self.get_all_sub_nodes(node, ast.DisengageStmt)
|
|
42
|
+
+ self.get_all_sub_nodes(node, ast.EdgeOpRef)
|
|
43
|
+
):
|
|
44
|
+
i.from_walker = True
|
|
38
45
|
|
|
39
46
|
def enter_arch_ref(self, node: ast.ArchRef) -> None:
|
|
40
47
|
"""Sub objects.
|
|
@@ -46,14 +46,20 @@ class JacImportPass(Pass):
|
|
|
46
46
|
"""Process an import."""
|
|
47
47
|
lang = i.parent_of_type(ast.Import).hint.tag.value
|
|
48
48
|
if lang == "jac" and not i.sub_module:
|
|
49
|
-
|
|
49
|
+
self.import_jac_module(
|
|
50
50
|
node=i,
|
|
51
51
|
mod_path=node.loc.mod_path,
|
|
52
52
|
)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
|
|
54
|
+
def attach_mod_to_node(
|
|
55
|
+
self, node: ast.ModulePath | ast.ModuleItem, mod: ast.Module | None
|
|
56
|
+
) -> None:
|
|
57
|
+
"""Attach a module to a node."""
|
|
58
|
+
if mod:
|
|
59
|
+
self.run_again = True
|
|
60
|
+
node.sub_module = mod
|
|
61
|
+
self.__annex_impl(mod)
|
|
62
|
+
node.add_kids_right([mod], pos_update=False)
|
|
57
63
|
|
|
58
64
|
def __annex_impl(self, node: ast.Module) -> None:
|
|
59
65
|
"""Annex impl and test modules."""
|
|
@@ -114,15 +120,55 @@ class JacImportPass(Pass):
|
|
|
114
120
|
node.sub_module.name = node.alias.value
|
|
115
121
|
# Items matched during def/decl pass
|
|
116
122
|
|
|
117
|
-
def import_jac_module(
|
|
118
|
-
self, node: ast.ModulePath, mod_path: str
|
|
119
|
-
) -> ast.Module | None:
|
|
123
|
+
def import_jac_module(self, node: ast.ModulePath, mod_path: str) -> None:
|
|
120
124
|
"""Import a module."""
|
|
121
125
|
self.cur_node = node # impacts error reporting
|
|
122
126
|
target = import_target_to_relative_path(
|
|
123
|
-
node.level,
|
|
127
|
+
level=node.level,
|
|
128
|
+
target=node.path_str,
|
|
129
|
+
base_path=os.path.dirname(node.loc.mod_path),
|
|
124
130
|
)
|
|
125
|
-
|
|
131
|
+
# If the module is a package (dir)
|
|
132
|
+
if os.path.isdir(target):
|
|
133
|
+
self.attach_mod_to_node(node, self.import_jac_mod_from_dir(target))
|
|
134
|
+
import_node = node.parent_of_type(ast.Import)
|
|
135
|
+
# And the import is a from import and I am the from module
|
|
136
|
+
if node == import_node.from_loc:
|
|
137
|
+
# Import all from items as modules or packages
|
|
138
|
+
for i in import_node.items.items:
|
|
139
|
+
if isinstance(i, ast.ModuleItem):
|
|
140
|
+
from_mod_target = import_target_to_relative_path(
|
|
141
|
+
level=node.level,
|
|
142
|
+
target=node.path_str + "." + i.name.value,
|
|
143
|
+
base_path=os.path.dirname(node.loc.mod_path),
|
|
144
|
+
)
|
|
145
|
+
# If package
|
|
146
|
+
if os.path.isdir(from_mod_target):
|
|
147
|
+
self.attach_mod_to_node(
|
|
148
|
+
i, self.import_jac_mod_from_dir(from_mod_target)
|
|
149
|
+
)
|
|
150
|
+
# Else module
|
|
151
|
+
else:
|
|
152
|
+
self.attach_mod_to_node(
|
|
153
|
+
i, self.import_jac_mod_from_file(from_mod_target)
|
|
154
|
+
)
|
|
155
|
+
else:
|
|
156
|
+
self.attach_mod_to_node(node, self.import_jac_mod_from_file(target))
|
|
157
|
+
|
|
158
|
+
def import_jac_mod_from_dir(self, target: str) -> ast.Module | None:
|
|
159
|
+
"""Import a module from a directory."""
|
|
160
|
+
with_init = os.path.join(target, "__init__.jac")
|
|
161
|
+
if os.path.exists(with_init):
|
|
162
|
+
return self.import_jac_mod_from_file(with_init)
|
|
163
|
+
else:
|
|
164
|
+
return ast.Module(
|
|
165
|
+
name=target.split(os.path.sep)[-1],
|
|
166
|
+
source=ast.JacSource("", mod_path=target),
|
|
167
|
+
doc=None,
|
|
168
|
+
body=[],
|
|
169
|
+
is_imported=False,
|
|
170
|
+
kid=[ast.EmptyToken()],
|
|
171
|
+
)
|
|
126
172
|
|
|
127
173
|
def import_jac_mod_from_file(self, target: str) -> ast.Module | None:
|
|
128
174
|
"""Import a module from a file."""
|
|
@@ -42,6 +42,7 @@ class PyastGenPass(Pass):
|
|
|
42
42
|
"""Initialize pass."""
|
|
43
43
|
self.debuginfo: dict[str, list[str]] = {"jac_mods": []}
|
|
44
44
|
self.already_added: list[str] = []
|
|
45
|
+
self.method_sigs: list[ast.FuncSignature | ast.EventSignature] = []
|
|
45
46
|
self.preamble: list[ast3.AST] = [
|
|
46
47
|
self.sync(
|
|
47
48
|
ast3.ImportFrom(
|
|
@@ -658,6 +659,28 @@ class PyastGenPass(Pass):
|
|
|
658
659
|
)
|
|
659
660
|
]
|
|
660
661
|
|
|
662
|
+
def enter_architype(self, node: ast.Architype) -> None:
|
|
663
|
+
"""Sub objects.
|
|
664
|
+
|
|
665
|
+
name: Name,
|
|
666
|
+
arch_type: Token,
|
|
667
|
+
access: Optional[SubTag[Token]],
|
|
668
|
+
base_classes: Optional[SubNodeList[AtomType]],
|
|
669
|
+
body: Optional[SubNodeList[ArchBlockStmt] | ArchDef],
|
|
670
|
+
doc: Optional[String],
|
|
671
|
+
decorators: Optional[SubNodeList[ExprType]],
|
|
672
|
+
"""
|
|
673
|
+
# Record all signatures that are part of methods
|
|
674
|
+
for i in (
|
|
675
|
+
node.body.body.items
|
|
676
|
+
if isinstance(node.body, ast.ArchDef)
|
|
677
|
+
else node.body.items if node.body else []
|
|
678
|
+
):
|
|
679
|
+
if isinstance(i, ast.Ability) and i.signature:
|
|
680
|
+
self.method_sigs.append(i.signature)
|
|
681
|
+
if isinstance(node.body, ast.ArchDef):
|
|
682
|
+
self.traverse(node.body)
|
|
683
|
+
|
|
661
684
|
def exit_architype(self, node: ast.Architype) -> None:
|
|
662
685
|
"""Sub objects.
|
|
663
686
|
|
|
@@ -821,6 +844,19 @@ class PyastGenPass(Pass):
|
|
|
821
844
|
decorators: Optional[SubNodeList[ExprType]],
|
|
822
845
|
"""
|
|
823
846
|
|
|
847
|
+
def enter_enum(self, node: ast.Enum) -> None:
|
|
848
|
+
"""Sub objects.
|
|
849
|
+
|
|
850
|
+
name: Name,
|
|
851
|
+
access: Optional[SubTag[Token]],
|
|
852
|
+
base_classes: Optional[SubNodeList[AtomType]],
|
|
853
|
+
body: Optional[SubNodeList[EnumBlockStmt] | EnumDef],
|
|
854
|
+
doc: Optional[String],
|
|
855
|
+
decorators: Optional[SubNodeList[ExprType]],
|
|
856
|
+
"""
|
|
857
|
+
if isinstance(node.body, ast.EnumDef):
|
|
858
|
+
self.traverse(node.body)
|
|
859
|
+
|
|
824
860
|
def exit_enum(self, node: ast.Enum) -> None:
|
|
825
861
|
"""Sub objects.
|
|
826
862
|
|
|
@@ -870,6 +906,23 @@ class PyastGenPass(Pass):
|
|
|
870
906
|
decorators: Optional[SubNodeList[ExprType]],
|
|
871
907
|
"""
|
|
872
908
|
|
|
909
|
+
def enter_ability(self, node: ast.Ability) -> None:
|
|
910
|
+
"""Sub objects.
|
|
911
|
+
|
|
912
|
+
name_ref: NameType,
|
|
913
|
+
is_func: bool,
|
|
914
|
+
is_async: bool,
|
|
915
|
+
is_static: bool,
|
|
916
|
+
is_abstract: bool,
|
|
917
|
+
access: Optional[SubTag[Token]],
|
|
918
|
+
signature: Optional[FuncSignature | ExprType | EventSignature],
|
|
919
|
+
body: Optional[SubNodeList[CodeBlockStmt] | AbilityDef | FuncCall],
|
|
920
|
+
doc: Optional[String],
|
|
921
|
+
decorators: Optional[SubNodeList[ExprType]],
|
|
922
|
+
"""
|
|
923
|
+
if isinstance(node.body, ast.AbilityDef):
|
|
924
|
+
self.traverse(node.body)
|
|
925
|
+
|
|
873
926
|
def exit_ability(self, node: ast.Ability) -> None:
|
|
874
927
|
"""Sub objects.
|
|
875
928
|
|
|
@@ -1272,7 +1325,7 @@ class PyastGenPass(Pass):
|
|
|
1272
1325
|
"""
|
|
1273
1326
|
params = (
|
|
1274
1327
|
[self.sync(ast3.arg(arg="self", annotation=None))]
|
|
1275
|
-
if node.
|
|
1328
|
+
if node in self.method_sigs and not node.is_static
|
|
1276
1329
|
else []
|
|
1277
1330
|
)
|
|
1278
1331
|
vararg = None
|
|
@@ -1330,7 +1383,7 @@ class PyastGenPass(Pass):
|
|
|
1330
1383
|
posonlyargs=[],
|
|
1331
1384
|
args=(
|
|
1332
1385
|
[self.sync(ast3.arg(arg="self", annotation=None)), here]
|
|
1333
|
-
if node.
|
|
1386
|
+
if node in self.method_sigs
|
|
1334
1387
|
else [here]
|
|
1335
1388
|
),
|
|
1336
1389
|
kwonlyargs=[],
|
|
@@ -9,7 +9,7 @@ from __future__ import annotations
|
|
|
9
9
|
from .sub_node_tab_pass import SubNodeTabPass # noqa: I100
|
|
10
10
|
from .import_pass import JacImportPass, PyImportPass # noqa: I100
|
|
11
11
|
from .sym_tab_build_pass import SymTabBuildPass # noqa: I100
|
|
12
|
-
from .def_impl_match_pass import
|
|
12
|
+
from .def_impl_match_pass import DeclImplMatchPass # noqa: I100
|
|
13
13
|
from .def_use_pass import DefUsePass # noqa: I100
|
|
14
14
|
from .pyout_pass import PyOutPass # noqa: I100
|
|
15
15
|
from .pybc_gen_pass import PyBytecodeGenPass # noqa: I100
|
|
@@ -25,7 +25,7 @@ py_code_gen = [
|
|
|
25
25
|
JacImportPass,
|
|
26
26
|
PyImportPass,
|
|
27
27
|
SymTabBuildPass,
|
|
28
|
-
|
|
28
|
+
DeclImplMatchPass,
|
|
29
29
|
DefUsePass,
|
|
30
30
|
RegistryPass,
|
|
31
31
|
PyastGenPass,
|
|
@@ -33,5 +33,6 @@ py_code_gen = [
|
|
|
33
33
|
PyBytecodeGenPass,
|
|
34
34
|
]
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
type_checker_sched = [JacTypeCheckPass, FuseTypeInfoPass, AccessCheckPass]
|
|
37
|
+
py_code_gen_typed = [*py_code_gen, *type_checker_sched]
|
|
37
38
|
py_compiler = [*py_code_gen, PyOutPass]
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"""Test pass module."""
|
|
2
2
|
|
|
3
3
|
from jaclang.compiler.compile import jac_file_to_pass
|
|
4
|
-
from jaclang.compiler.passes.main import
|
|
4
|
+
from jaclang.compiler.passes.main import DeclImplMatchPass
|
|
5
5
|
from jaclang.utils.test import TestCase
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class DeclImplMatchPassTests(TestCase):
|
|
9
9
|
"""Test pass module."""
|
|
10
10
|
|
|
11
11
|
def setUp(self) -> None:
|
|
@@ -14,7 +14,7 @@ class DeclDefMatchPassTests(TestCase):
|
|
|
14
14
|
|
|
15
15
|
def test_ability_connected_to_decl(self) -> None:
|
|
16
16
|
"""Basic test for pass."""
|
|
17
|
-
state = jac_file_to_pass(self.fixture_abs_path("base.jac"),
|
|
17
|
+
state = jac_file_to_pass(self.fixture_abs_path("base.jac"), DeclImplMatchPass)
|
|
18
18
|
self.assertFalse(state.errors_had)
|
|
19
19
|
self.assertIn("(o)Test.(c)say_hi", state.ir.sym_tab.tab)
|
|
20
20
|
self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.body)
|
|
@@ -23,7 +23,7 @@ class DeclDefMatchPassTests(TestCase):
|
|
|
23
23
|
|
|
24
24
|
def test_ability_connected_to_decl_post(self) -> None:
|
|
25
25
|
"""Basic test for pass."""
|
|
26
|
-
state = jac_file_to_pass(self.fixture_abs_path("base2.jac"),
|
|
26
|
+
state = jac_file_to_pass(self.fixture_abs_path("base2.jac"), DeclImplMatchPass)
|
|
27
27
|
self.assertFalse(state.errors_had)
|
|
28
28
|
self.assertIn("(o)Test.(c)say_hi", state.ir.sym_tab.tab)
|
|
29
29
|
self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.body)
|
|
@@ -28,3 +28,16 @@ class ImportPassPassTests(TestCase):
|
|
|
28
28
|
self.assertIn("getme.impl", mod_names)
|
|
29
29
|
self.assertIn("autoimpl.impl", mod_names)
|
|
30
30
|
self.assertIn("autoimpl.something.else.impl", mod_names)
|
|
31
|
+
|
|
32
|
+
def test_import_include_auto_impl(self) -> None:
|
|
33
|
+
"""Basic test for pass."""
|
|
34
|
+
state = jac_file_to_pass(
|
|
35
|
+
self.fixture_abs_path("incautoimpl.jac"), JacImportPass
|
|
36
|
+
)
|
|
37
|
+
num_modules = len(state.ir.get_all_sub_nodes(ast.Module))
|
|
38
|
+
mod_names = [i.name for i in state.ir.get_all_sub_nodes(ast.Module)]
|
|
39
|
+
self.assertEqual(num_modules, 4)
|
|
40
|
+
self.assertIn("getme.impl", mod_names)
|
|
41
|
+
self.assertIn("autoimpl", mod_names)
|
|
42
|
+
self.assertIn("autoimpl.impl", mod_names)
|
|
43
|
+
self.assertIn("autoimpl.something.else.impl", mod_names)
|
|
@@ -1161,7 +1161,7 @@ class JacFormatPass(Pass):
|
|
|
1161
1161
|
if (
|
|
1162
1162
|
node.parent
|
|
1163
1163
|
and node.parent.parent
|
|
1164
|
-
and isinstance(node.parent.parent, (ast.Ability))
|
|
1164
|
+
and not isinstance(node.parent.parent, (ast.Ability, ast.ModuleCode))
|
|
1165
1165
|
and node.parent.kid[1].gen.jac != "self.jaseci_sdk = {};\n"
|
|
1166
1166
|
):
|
|
1167
1167
|
self.emit_ln(node, "")
|
|
@@ -1229,7 +1229,7 @@ class JacFormatPass(Pass):
|
|
|
1229
1229
|
|
|
1230
1230
|
body: CodeBlock,
|
|
1231
1231
|
"""
|
|
1232
|
-
self.emit(node, "finally")
|
|
1232
|
+
self.emit(node, " finally")
|
|
1233
1233
|
|
|
1234
1234
|
self.emit(node, node.body.gen.jac)
|
|
1235
1235
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from abc import ABC, abstractmethod
|
|
6
|
-
from typing import Generic, Optional
|
|
6
|
+
from typing import Generic, Optional, Type
|
|
7
7
|
|
|
8
8
|
from jaclang.compiler.absyntree import AstNode, T
|
|
9
9
|
from jaclang.compiler.codeloc import CodeLocInfo
|
|
@@ -13,10 +13,11 @@ from jaclang.utils.log import logging
|
|
|
13
13
|
class Alert:
|
|
14
14
|
"""Alert interface."""
|
|
15
15
|
|
|
16
|
-
def __init__(self, msg: str, loc: CodeLocInfo) -> None:
|
|
16
|
+
def __init__(self, msg: str, loc: CodeLocInfo, from_pass: Type[Transform]) -> None:
|
|
17
17
|
"""Initialize alert."""
|
|
18
18
|
self.msg = msg
|
|
19
19
|
self.loc: CodeLocInfo = loc
|
|
20
|
+
self.from_pass: Type[Transform] = from_pass
|
|
20
21
|
|
|
21
22
|
def __str__(self) -> str:
|
|
22
23
|
"""Return string representation of alert."""
|
|
@@ -52,14 +53,22 @@ class Transform(ABC, Generic[T]):
|
|
|
52
53
|
|
|
53
54
|
def log_error(self, msg: str, node_override: Optional[AstNode] = None) -> None:
|
|
54
55
|
"""Pass Error."""
|
|
55
|
-
alrt = Alert(
|
|
56
|
+
alrt = Alert(
|
|
57
|
+
msg,
|
|
58
|
+
self.cur_node.loc if not node_override else node_override.loc,
|
|
59
|
+
self.__class__,
|
|
60
|
+
)
|
|
56
61
|
self.errors_had.append(alrt)
|
|
57
62
|
# print("Error:", str(alrt))
|
|
58
63
|
self.logger.error(str(alrt))
|
|
59
64
|
|
|
60
65
|
def log_warning(self, msg: str, node_override: Optional[AstNode] = None) -> None:
|
|
61
66
|
"""Pass Error."""
|
|
62
|
-
alrt = Alert(
|
|
67
|
+
alrt = Alert(
|
|
68
|
+
msg,
|
|
69
|
+
self.cur_node.loc if not node_override else node_override.loc,
|
|
70
|
+
self.__class__,
|
|
71
|
+
)
|
|
63
72
|
self.warnings_had.append(alrt)
|
|
64
73
|
# print("Warning:", str(alrt))
|
|
65
74
|
self.logger.warning(str(alrt))
|