jaclang 0.8.0__py3-none-any.whl → 0.8.2__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 +6 -0
- jaclang/cli/cli.py +23 -50
- jaclang/compiler/codeinfo.py +0 -1
- jaclang/compiler/jac.lark +14 -22
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +378 -531
- jaclang/compiler/passes/main/__init__.py +0 -14
- jaclang/compiler/passes/main/annex_pass.py +2 -8
- jaclang/compiler/passes/main/cfg_build_pass.py +39 -13
- jaclang/compiler/passes/main/def_impl_match_pass.py +14 -13
- jaclang/compiler/passes/main/def_use_pass.py +4 -7
- jaclang/compiler/passes/main/import_pass.py +6 -14
- jaclang/compiler/passes/main/inheritance_pass.py +2 -2
- jaclang/compiler/passes/main/pyast_gen_pass.py +428 -799
- jaclang/compiler/passes/main/pyast_load_pass.py +115 -311
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +8 -7
- jaclang/compiler/passes/main/sym_tab_build_pass.py +3 -3
- jaclang/compiler/passes/main/sym_tab_link_pass.py +6 -9
- jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/action/actions.jac +1 -5
- jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/main.jac +1 -8
- jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +5 -9
- jaclang/compiler/passes/main/tests/test_decl_impl_match_pass.py +7 -8
- jaclang/compiler/passes/main/tests/test_import_pass.py +5 -18
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -6
- jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -3
- jaclang/compiler/passes/main/tests/test_sym_tab_link_pass.py +20 -17
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +425 -216
- jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -0
- jaclang/compiler/passes/tool/tests/fixtures/archetype_frmt.jac +14 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +5 -4
- jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +6 -0
- jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +3 -3
- jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +9 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +18 -3
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
- jaclang/compiler/program.py +22 -66
- jaclang/compiler/tests/fixtures/fam.jac +2 -2
- jaclang/compiler/tests/fixtures/pkg_import_lib/__init__.jac +1 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/sub/__init__.jac +1 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/sub/helper.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib/tools.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +5 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/helper.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/tools.jac +3 -0
- jaclang/compiler/tests/fixtures/pkg_import_main.jac +10 -0
- jaclang/compiler/tests/fixtures/pkg_import_main_py.jac +11 -0
- jaclang/compiler/tests/test_importer.py +30 -13
- jaclang/compiler/tests/test_parser.py +1 -0
- jaclang/compiler/unitree.py +488 -320
- jaclang/langserve/__init__.jac +1 -0
- jaclang/langserve/engine.jac +503 -0
- jaclang/langserve/sem_manager.jac +309 -0
- jaclang/langserve/server.jac +201 -0
- jaclang/langserve/tests/server_test/test_lang_serve.py +139 -48
- jaclang/langserve/tests/server_test/utils.py +35 -6
- jaclang/langserve/tests/session.jac +294 -0
- jaclang/langserve/tests/test_sem_tokens.py +2 -2
- jaclang/langserve/tests/test_server.py +8 -7
- jaclang/langserve/utils.jac +51 -30
- jaclang/runtimelib/archetype.py +128 -6
- jaclang/runtimelib/builtin.py +17 -14
- jaclang/runtimelib/importer.py +51 -76
- jaclang/runtimelib/machine.py +469 -305
- jaclang/runtimelib/meta_importer.py +86 -0
- jaclang/runtimelib/tests/fixtures/graph_purger.jac +24 -26
- jaclang/runtimelib/tests/fixtures/other_root_access.jac +25 -16
- jaclang/runtimelib/tests/fixtures/traversing_save.jac +7 -5
- jaclang/runtimelib/tests/test_jaseci.py +3 -1
- jaclang/runtimelib/utils.py +3 -3
- jaclang/tests/fixtures/arch_rel_import_creation.jac +23 -23
- jaclang/tests/fixtures/async_ability.jac +43 -10
- jaclang/tests/fixtures/async_function.jac +18 -0
- jaclang/tests/fixtures/async_walker.jac +17 -12
- jaclang/tests/fixtures/backward_edge_visit.jac +31 -0
- jaclang/tests/fixtures/builtin_printgraph.jac +85 -0
- jaclang/tests/fixtures/builtin_printgraph_json.jac +21 -0
- jaclang/tests/fixtures/builtin_printgraph_mermaid.jac +16 -0
- jaclang/tests/fixtures/chandra_bugs2.jac +20 -13
- jaclang/tests/fixtures/concurrency.jac +1 -1
- jaclang/tests/fixtures/create_dynamic_archetype.jac +25 -28
- jaclang/tests/fixtures/deep/deeper/deep_outer_import.jac +7 -4
- jaclang/tests/fixtures/deep/deeper/snd_lev.jac +2 -2
- jaclang/tests/fixtures/deep/deeper/snd_lev_dup.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +2 -2
- jaclang/tests/fixtures/deep/one_lev_dup.jac +4 -3
- jaclang/tests/fixtures/dynamic_archetype.jac +19 -12
- jaclang/tests/fixtures/edge_ability.jac +49 -0
- jaclang/tests/fixtures/foo.jac +14 -22
- jaclang/tests/fixtures/guess_game.jac +1 -1
- jaclang/tests/fixtures/here_usage_error.jac +21 -0
- jaclang/tests/fixtures/here_visitor_usage.jac +21 -0
- jaclang/tests/fixtures/jac_from_py.py +1 -1
- jaclang/tests/fixtures/jp_importer.jac +6 -6
- jaclang/tests/fixtures/jp_importer_auto.jac +5 -3
- jaclang/tests/fixtures/node_del.jac +30 -36
- jaclang/tests/fixtures/unicode_strings.jac +24 -0
- jaclang/tests/fixtures/visit_traversal.jac +47 -0
- jaclang/tests/fixtures/walker_update.jac +5 -7
- jaclang/tests/test_cli.py +12 -7
- jaclang/tests/test_language.py +218 -145
- jaclang/tests/test_reference.py +9 -4
- jaclang/tests/test_typecheck.py +13 -26
- jaclang/utils/helpers.py +14 -6
- jaclang/utils/lang_tools.py +9 -8
- jaclang/utils/module_resolver.py +23 -0
- jaclang/utils/tests/test_lang_tools.py +2 -1
- jaclang/utils/treeprinter.py +3 -4
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/METADATA +4 -3
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/RECORD +112 -94
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/WHEEL +1 -1
- jaclang/compiler/passes/main/tests/fixtures/main_err.jac +0 -6
- jaclang/compiler/passes/main/tests/fixtures/second_err.jac +0 -4
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +0 -644
- jaclang/compiler/passes/tool/tests/test_doc_ir_gen_pass.py +0 -29
- jaclang/langserve/__init__.py +0 -1
- jaclang/langserve/engine.py +0 -553
- jaclang/langserve/sem_manager.py +0 -383
- jaclang/langserve/server.py +0 -167
- jaclang/langserve/tests/session.py +0 -255
- jaclang/tests/fixtures/builtin_dotgen.jac +0 -42
- jaclang/tests/fixtures/builtin_dotgen_json.jac +0 -21
- jaclang/tests/fixtures/deep/deeper/__init__.jac +0 -1
- {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/entry_points.txt +0 -0
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Collection of passes for Jac IR."""
|
|
2
2
|
|
|
3
|
-
from enum import Enum
|
|
4
|
-
|
|
5
3
|
from ..transform import Alert, Transform # noqa: I100
|
|
6
4
|
from .annex_pass import JacAnnexPass # noqa: I100
|
|
7
5
|
from .sym_tab_build_pass import SymTabBuildPass, UniPass # noqa: I100
|
|
@@ -17,17 +15,6 @@ from .pyjac_ast_link_pass import PyJacAstLinkPass # noqa: I100
|
|
|
17
15
|
from .inheritance_pass import InheritancePass # noqa: I100
|
|
18
16
|
|
|
19
17
|
|
|
20
|
-
class CompilerMode(Enum):
|
|
21
|
-
"""Compiler modes."""
|
|
22
|
-
|
|
23
|
-
PARSE = "PARSE"
|
|
24
|
-
NO_CGEN = "NO_CGEN"
|
|
25
|
-
NO_CGEN_SINGLE = "NO_CGEN_SINGLE"
|
|
26
|
-
COMPILE = "COMPILE"
|
|
27
|
-
COMPILE_SINGLE = "COMPILE_SINGLE"
|
|
28
|
-
TYPECHECK = "TYPECHECK"
|
|
29
|
-
|
|
30
|
-
|
|
31
18
|
__all__ = [
|
|
32
19
|
"Alert",
|
|
33
20
|
"Transform",
|
|
@@ -42,7 +29,6 @@ __all__ = [
|
|
|
42
29
|
"PyastBuildPass",
|
|
43
30
|
"PyastGenPass",
|
|
44
31
|
"PyBytecodeGenPass",
|
|
45
|
-
"CompilerMode",
|
|
46
32
|
"CFGBuildPass",
|
|
47
33
|
"PyJacAstLinkPass",
|
|
48
34
|
"InheritancePass",
|
|
@@ -48,8 +48,6 @@ class JacAnnexPass(Transform[uni.Module, uni.Module]):
|
|
|
48
48
|
|
|
49
49
|
def load_annexes(self, jac_program: JacProgram, node: uni.Module) -> None:
|
|
50
50
|
"""Parse and attach annex modules to the node."""
|
|
51
|
-
from jaclang.compiler.program import CompilerMode
|
|
52
|
-
|
|
53
51
|
if node.stub_only or not self.mod_path.endswith(".jac"):
|
|
54
52
|
return
|
|
55
53
|
if not self.mod_path:
|
|
@@ -64,9 +62,7 @@ class JacAnnexPass(Transform[uni.Module, uni.Module]):
|
|
|
64
62
|
path.startswith(f"{self.base_path}.")
|
|
65
63
|
or os.path.dirname(path) == self.impl_folder
|
|
66
64
|
):
|
|
67
|
-
mod = jac_program.compile(
|
|
68
|
-
file_path=path, mode=CompilerMode.NO_CGEN_SINGLE
|
|
69
|
-
)
|
|
65
|
+
mod = jac_program.compile(file_path=path, no_cgen=True)
|
|
70
66
|
if mod:
|
|
71
67
|
node.impl_mod.append(mod)
|
|
72
68
|
|
|
@@ -78,8 +74,6 @@ class JacAnnexPass(Transform[uni.Module, uni.Module]):
|
|
|
78
74
|
or os.path.dirname(path) == self.test_folder
|
|
79
75
|
)
|
|
80
76
|
):
|
|
81
|
-
mod = jac_program.compile(
|
|
82
|
-
file_path=path, mode=CompilerMode.NO_CGEN_SINGLE
|
|
83
|
-
)
|
|
77
|
+
mod = jac_program.compile(file_path=path, no_cgen=True)
|
|
84
78
|
if mod:
|
|
85
79
|
node.test_mod.append(mod)
|
|
@@ -10,6 +10,8 @@ The CFG provides a foundation for data flow analysis, optimization, and understa
|
|
|
10
10
|
The pass also includes functionality to coalesce basic blocks and generate visual representations of the CFG.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
+
from typing import Sequence
|
|
14
|
+
|
|
13
15
|
import jaclang.compiler.unitree as uni
|
|
14
16
|
from jaclang.compiler.passes import UniPass
|
|
15
17
|
|
|
@@ -65,26 +67,48 @@ class CFGBuildPass(UniPass):
|
|
|
65
67
|
else:
|
|
66
68
|
target.bb_in = [source]
|
|
67
69
|
|
|
70
|
+
def get_code_block_sequence(
|
|
71
|
+
self, node: uni.CodeBlockStmt
|
|
72
|
+
) -> list[uni.UniCFGNode] | None:
|
|
73
|
+
"""Get code block sequence."""
|
|
74
|
+
sequence: list[uni.UniCFGNode] = []
|
|
75
|
+
if hasattr(node, "body") and isinstance(node.body, Sequence):
|
|
76
|
+
for bbs in node.body:
|
|
77
|
+
if isinstance(bbs, uni.UniCFGNode):
|
|
78
|
+
sequence.append(bbs)
|
|
79
|
+
if sequence:
|
|
80
|
+
return sequence
|
|
81
|
+
else:
|
|
82
|
+
return None
|
|
83
|
+
else:
|
|
84
|
+
return None
|
|
85
|
+
|
|
68
86
|
def enter_node(self, node: uni.UniNode) -> None:
|
|
69
87
|
"""Enter BasicBlockStmt nodes."""
|
|
70
88
|
if isinstance(node, uni.UniCFGNode) and not isinstance(node, uni.Semi):
|
|
71
|
-
if
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
89
|
+
# check if the current node is a CodeBlockStmt in a sequence of statements
|
|
90
|
+
bb_stmts = self.get_code_block_sequence(node.parent)
|
|
91
|
+
if (
|
|
92
|
+
isinstance(node, uni.CodeBlockStmt)
|
|
93
|
+
and node.parent
|
|
94
|
+
and (not (isinstance(node, (uni.ElseIf, uni.ElseStmt))))
|
|
95
|
+
and bb_stmts
|
|
96
|
+
and self.first_exit
|
|
97
|
+
):
|
|
98
|
+
# bb_stmts = self.get_code_block_sequence(node.parent)
|
|
99
|
+
# bb_stmts = [
|
|
100
|
+
# bbs for bbs in node.parent.body if isinstance(bbs, uni.UniCFGNode)
|
|
101
|
+
# ]
|
|
75
102
|
if (
|
|
76
|
-
node.parent
|
|
77
|
-
and isinstance(node.parent
|
|
103
|
+
node.parent
|
|
104
|
+
and isinstance(node.parent, uni.Archetype)
|
|
78
105
|
# and isinstance(node.parent.parent, uni.BasicBlockStmt)
|
|
79
106
|
):
|
|
80
|
-
parent_obj = node.parent
|
|
107
|
+
parent_obj = node.parent
|
|
81
108
|
if parent_obj:
|
|
82
109
|
self.link_bbs(parent_obj, node)
|
|
83
110
|
elif bb_stmts[0] == node:
|
|
84
|
-
if (
|
|
85
|
-
isinstance(node.parent.parent, uni.ModuleCode)
|
|
86
|
-
and self.to_connect
|
|
87
|
-
):
|
|
111
|
+
if isinstance(node.parent, uni.ModuleCode) and self.to_connect:
|
|
88
112
|
for bb in self.to_connect:
|
|
89
113
|
self.link_bbs(bb, node)
|
|
90
114
|
self.to_connect.remove(bb) # if self.to_connect:
|
|
@@ -92,7 +116,9 @@ class CFGBuildPass(UniPass):
|
|
|
92
116
|
parent_bb = self.get_parent_bb_stmt(node)
|
|
93
117
|
if parent_bb:
|
|
94
118
|
self.link_bbs(parent_bb, node)
|
|
95
|
-
elif self.to_connect
|
|
119
|
+
elif self.to_connect and not isinstance(
|
|
120
|
+
node, (uni.ElseIf, uni.ElseStmt)
|
|
121
|
+
):
|
|
96
122
|
to_remove = []
|
|
97
123
|
for parent in self.to_connect:
|
|
98
124
|
if isinstance(parent, uni.UniCFGNode):
|
|
@@ -199,7 +225,7 @@ class CoalesceBBPass(UniPass):
|
|
|
199
225
|
}
|
|
200
226
|
self.bb_counter += 1
|
|
201
227
|
|
|
202
|
-
def
|
|
228
|
+
def printgraph_cfg(self) -> str:
|
|
203
229
|
"""Generate dot graph for CFG."""
|
|
204
230
|
cfg: dict = {}
|
|
205
231
|
dot = "digraph G {\n"
|
|
@@ -17,6 +17,8 @@ developers to define archetype and ability interfaces in one file while implemen
|
|
|
17
17
|
their behavior in separate files.
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
+
from typing import Sequence
|
|
21
|
+
|
|
20
22
|
import jaclang.compiler.unitree as uni
|
|
21
23
|
from jaclang.compiler.constant import Tokens as Tok
|
|
22
24
|
from jaclang.compiler.passes.transform import Transform
|
|
@@ -124,7 +126,7 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
|
|
|
124
126
|
|
|
125
127
|
valid_decl.body = sym.decl.name_of
|
|
126
128
|
sym.decl.name_of.decl_link = valid_decl
|
|
127
|
-
for idx, a in enumerate(sym.decl.name_of.target
|
|
129
|
+
for idx, a in enumerate(sym.decl.name_of.target):
|
|
128
130
|
if idx < len(name_of_links) and name_of_links[idx]:
|
|
129
131
|
a.name_spec.name_of = name_of_links[idx].name_of
|
|
130
132
|
a.name_spec.sym = name_of_links[idx].sym
|
|
@@ -159,7 +161,7 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
|
|
|
159
161
|
|
|
160
162
|
if params_decl and params_defn:
|
|
161
163
|
# Check if the parameter count is matched.
|
|
162
|
-
if len(params_defn
|
|
164
|
+
if len(params_defn) != len(params_decl):
|
|
163
165
|
self.log_error(
|
|
164
166
|
f"Parameter count mismatch for ability {sym.sym_name}.",
|
|
165
167
|
sym.decl.name_of.name_spec,
|
|
@@ -170,10 +172,11 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
|
|
|
170
172
|
)
|
|
171
173
|
else:
|
|
172
174
|
# Copy the parameter names from the declaration to the definition.
|
|
173
|
-
for idx in range(len(params_defn
|
|
174
|
-
params_decl
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
for idx in range(len(params_defn)):
|
|
176
|
+
if (par := params_decl[idx].parent) is not None:
|
|
177
|
+
loc_in_kid = par.kid.index(params_decl[idx])
|
|
178
|
+
par.kid[loc_in_kid] = params_defn[idx]
|
|
179
|
+
params_decl[idx] = params_defn[idx]
|
|
177
180
|
|
|
178
181
|
def check_archetypes(self, ir_in: uni.Module) -> None:
|
|
179
182
|
"""Check all archetypes for issues with attributes and methods."""
|
|
@@ -182,15 +185,13 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
|
|
|
182
185
|
|
|
183
186
|
def check_archetype(self, node: uni.Archetype) -> None:
|
|
184
187
|
"""Check a single archetype for issues."""
|
|
185
|
-
if node.arch_type.name == Tok.KW_OBJECT and isinstance(
|
|
186
|
-
node.body, uni.SubNodeList
|
|
187
|
-
):
|
|
188
|
+
if node.arch_type.name == Tok.KW_OBJECT and isinstance(node.body, Sequence):
|
|
188
189
|
self.cur_node = node
|
|
189
190
|
found_default_init = False
|
|
190
|
-
for stmnt in node.body
|
|
191
|
+
for stmnt in node.body:
|
|
191
192
|
if not isinstance(stmnt, uni.ArchHas):
|
|
192
193
|
continue
|
|
193
|
-
for var in stmnt.vars
|
|
194
|
+
for var in stmnt.vars:
|
|
194
195
|
if (var.value is not None) or (var.defer):
|
|
195
196
|
found_default_init = True
|
|
196
197
|
else:
|
|
@@ -204,10 +205,10 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
|
|
|
204
205
|
post_init_vars: list[uni.HasVar] = []
|
|
205
206
|
postinit_method: uni.Ability | None = None
|
|
206
207
|
|
|
207
|
-
for item in node.body
|
|
208
|
+
for item in node.body:
|
|
208
209
|
|
|
209
210
|
if isinstance(item, uni.ArchHas):
|
|
210
|
-
for var in item.vars
|
|
211
|
+
for var in item.vars:
|
|
211
212
|
if var.defer:
|
|
212
213
|
post_init_vars.append(var)
|
|
213
214
|
|
|
@@ -38,6 +38,7 @@ class DefUsePass(UniPass):
|
|
|
38
38
|
+ node.get_all_sub_nodes(uni.IgnoreStmt)
|
|
39
39
|
+ node.get_all_sub_nodes(uni.DisengageStmt)
|
|
40
40
|
+ node.get_all_sub_nodes(uni.EdgeOpRef)
|
|
41
|
+
+ node.get_all_sub_nodes(uni.EventSignature)
|
|
41
42
|
):
|
|
42
43
|
i.from_walker = True
|
|
43
44
|
|
|
@@ -57,19 +58,15 @@ class DefUsePass(UniPass):
|
|
|
57
58
|
node.sym_tab.def_insert(node)
|
|
58
59
|
|
|
59
60
|
def enter_has_var(self, node: uni.HasVar) -> None:
|
|
60
|
-
if isinstance(node.parent, uni.
|
|
61
|
-
node.parent.parent, uni.ArchHas
|
|
62
|
-
):
|
|
61
|
+
if isinstance(node.parent, uni.ArchHas):
|
|
63
62
|
node.sym_tab.def_insert(
|
|
64
|
-
node,
|
|
65
|
-
single_decl="has var",
|
|
66
|
-
access_spec=node.parent.parent,
|
|
63
|
+
node, single_decl="has var", access_spec=node.parent
|
|
67
64
|
)
|
|
68
65
|
else:
|
|
69
66
|
self.ice("Inconsistency in AST, has var should be under arch has")
|
|
70
67
|
|
|
71
68
|
def enter_assignment(self, node: uni.Assignment) -> None:
|
|
72
|
-
for i in node.target
|
|
69
|
+
for i in node.target:
|
|
73
70
|
if isinstance(i, uni.AtomTrailer):
|
|
74
71
|
i.sym_tab.chain_def_insert(i.as_attr_list)
|
|
75
72
|
elif isinstance(i, uni.AstSymbolNode):
|
|
@@ -63,8 +63,6 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
|
|
|
63
63
|
|
|
64
64
|
def import_jac_module(self, node: uni.ModulePath) -> None:
|
|
65
65
|
"""Import a module."""
|
|
66
|
-
from jaclang.compiler.passes.main import CompilerMode as CMode
|
|
67
|
-
|
|
68
66
|
target = node.resolve_relative_path()
|
|
69
67
|
# If the module is a package (dir)
|
|
70
68
|
if os.path.isdir(target):
|
|
@@ -73,7 +71,7 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
|
|
|
73
71
|
# And the import is a from import and I am the from module
|
|
74
72
|
if node == import_node.from_loc:
|
|
75
73
|
# Import all from items as modules or packages
|
|
76
|
-
for i in import_node.items
|
|
74
|
+
for i in import_node.items:
|
|
77
75
|
if isinstance(i, uni.ModuleItem):
|
|
78
76
|
from_mod_target = node.resolve_relative_path(i.name.value)
|
|
79
77
|
# If package
|
|
@@ -83,15 +81,11 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
|
|
|
83
81
|
else:
|
|
84
82
|
if from_mod_target in self.prog.mod.hub:
|
|
85
83
|
return
|
|
86
|
-
self.load_mod(
|
|
87
|
-
self.prog.compile(
|
|
88
|
-
file_path=from_mod_target, mode=CMode.PARSE
|
|
89
|
-
)
|
|
90
|
-
)
|
|
84
|
+
self.load_mod(self.prog.compile(file_path=from_mod_target))
|
|
91
85
|
else:
|
|
92
86
|
if target in self.prog.mod.hub:
|
|
93
87
|
return
|
|
94
|
-
self.load_mod(self.prog.compile(file_path=target
|
|
88
|
+
self.load_mod(self.prog.compile(file_path=target))
|
|
95
89
|
|
|
96
90
|
def load_mod(self, mod: uni.Module) -> None:
|
|
97
91
|
"""Attach a module to a node."""
|
|
@@ -102,13 +96,11 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
|
|
|
102
96
|
|
|
103
97
|
def import_jac_mod_from_dir(self, target: str) -> uni.Module:
|
|
104
98
|
"""Import a module from a directory."""
|
|
105
|
-
from jaclang.compiler.passes.main import CompilerMode as CMode
|
|
106
|
-
|
|
107
99
|
jac_init_path = os.path.join(target, "__init__.jac")
|
|
108
100
|
if os.path.exists(jac_init_path):
|
|
109
101
|
if jac_init_path in self.prog.mod.hub:
|
|
110
102
|
return self.prog.mod.hub[jac_init_path]
|
|
111
|
-
return self.prog.compile(file_path=jac_init_path
|
|
103
|
+
return self.prog.compile(file_path=jac_init_path)
|
|
112
104
|
elif os.path.exists(py_init_path := os.path.join(target, "__init__.py")):
|
|
113
105
|
with open(py_init_path, "r") as f:
|
|
114
106
|
file_source = f.read()
|
|
@@ -204,8 +196,8 @@ class PyImportDepsPass(JacImportDepsPass):
|
|
|
204
196
|
"""Process the imports in form of `import X`."""
|
|
205
197
|
# Expected that each ImportStatement will import one item
|
|
206
198
|
# In case of this assertion fired then we need to revisit this item
|
|
207
|
-
assert len(imp_node.items
|
|
208
|
-
imported_item = imp_node.items
|
|
199
|
+
assert len(imp_node.items) == 1
|
|
200
|
+
imported_item = imp_node.items[0]
|
|
209
201
|
assert isinstance(imported_item, uni.ModulePath)
|
|
210
202
|
|
|
211
203
|
imported_mod = self.__import_py_module(
|
|
@@ -36,11 +36,11 @@ class InheritancePass(Transform[uni.Module, uni.Module]):
|
|
|
36
36
|
|
|
37
37
|
def process_archetype_inheritance(self, node: uni.Archetype) -> None:
|
|
38
38
|
"""Fill archetype symbol tables with abilities from parent archetypes."""
|
|
39
|
-
if node.base_classes
|
|
39
|
+
if not node.base_classes:
|
|
40
40
|
return
|
|
41
41
|
|
|
42
42
|
self.cur_node = node
|
|
43
|
-
for item in node.base_classes
|
|
43
|
+
for item in node.base_classes:
|
|
44
44
|
# Handle different types of base class references
|
|
45
45
|
if isinstance(item, uni.Name):
|
|
46
46
|
self.inherit_from_name(node, item)
|