jaclang 0.4.7__py3-none-any.whl → 0.5.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 +5 -2
- jaclang/cli/cli.py +56 -8
- jaclang/cli/cmdreg.py +16 -9
- jaclang/compiler/__jac_gen__/jac_parser.py +11 -15
- jaclang/compiler/absyntree.py +53 -19
- jaclang/compiler/codeloc.py +3 -1
- jaclang/compiler/{transpiler.py → compile.py} +3 -2
- jaclang/compiler/constant.py +4 -0
- jaclang/compiler/parser.py +156 -108
- jaclang/compiler/passes/ir_pass.py +1 -0
- jaclang/compiler/passes/main/__init__.py +2 -1
- jaclang/compiler/passes/main/def_impl_match_pass.py +1 -0
- jaclang/compiler/passes/main/def_use_pass.py +1 -0
- jaclang/compiler/passes/main/import_pass.py +18 -18
- jaclang/compiler/passes/main/pyast_gen_pass.py +1228 -853
- jaclang/compiler/passes/main/pyast_load_pass.py +3 -1
- jaclang/compiler/passes/main/pybc_gen_pass.py +46 -0
- jaclang/compiler/passes/main/pyout_pass.py +6 -7
- jaclang/compiler/passes/main/schedules.py +5 -9
- jaclang/compiler/passes/main/sub_node_tab_pass.py +1 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +21 -9
- jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +2 -1
- jaclang/compiler/passes/main/tests/test_def_use_pass.py +2 -1
- jaclang/compiler/passes/main/tests/test_import_pass.py +2 -1
- jaclang/compiler/passes/main/tests/test_pyast_build_pass.py +1 -0
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +15 -38
- jaclang/compiler/passes/main/tests/test_pybc_gen_pass.py +25 -0
- jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -1
- jaclang/compiler/passes/main/tests/test_sym_tab_build_pass.py +2 -1
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +17 -1
- jaclang/compiler/passes/main/type_check_pass.py +9 -6
- jaclang/compiler/passes/tool/__init__.py +1 -0
- jaclang/compiler/passes/tool/ast_printer_pass.py +1 -0
- jaclang/compiler/passes/tool/fuse_comments_pass.py +1 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +69 -32
- jaclang/compiler/passes/tool/schedules.py +1 -0
- jaclang/compiler/passes/tool/sym_tab_printer_pass.py +1 -0
- jaclang/compiler/passes/tool/tests/test_ast_print_pass.py +2 -1
- jaclang/compiler/passes/tool/tests/test_fuse_comments_pass.py +1 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +4 -3
- jaclang/compiler/passes/tool/tests/test_symtab_print_pass.py +2 -1
- jaclang/compiler/passes/transform.py +1 -0
- jaclang/compiler/passes/utils/mypy_ast_build.py +203 -17
- jaclang/compiler/symtable.py +1 -0
- jaclang/compiler/tests/test_importer.py +3 -2
- jaclang/compiler/tests/test_parser.py +1 -0
- jaclang/compiler/tests/test_workspace.py +1 -0
- jaclang/compiler/workspace.py +18 -5
- jaclang/core/construct.py +9 -32
- jaclang/{compiler → core}/importer.py +95 -85
- jaclang/core/utils.py +17 -12
- jaclang/plugin/__init__.py +1 -0
- jaclang/plugin/default.py +145 -43
- jaclang/plugin/feature.py +65 -19
- jaclang/plugin/spec.py +56 -34
- jaclang/plugin/tests/test_features.py +9 -0
- jaclang/utils/helpers.py +1 -0
- jaclang/utils/lang_tools.py +13 -19
- jaclang/utils/tests/test_lang_tools.py +2 -1
- jaclang/utils/treeprinter.py +2 -1
- jaclang/vendor/lark/common.py +3 -1
- jaclang/vendor/lark/lexer.py +6 -12
- jaclang/vendor/lark/parsers/lalr_parser.py +1 -0
- jaclang/vendor/mypy/applytype.py +2 -1
- jaclang/vendor/mypy/binder.py +1 -1
- jaclang/vendor/mypy/build.py +7 -9
- jaclang/vendor/mypy/checker.py +57 -33
- jaclang/vendor/mypy/checkexpr.py +42 -29
- jaclang/vendor/mypy/checkmember.py +13 -1
- jaclang/vendor/mypy/checkpattern.py +1 -1
- jaclang/vendor/mypy/checkstrformat.py +2 -4
- jaclang/vendor/mypy/constraints.py +10 -5
- jaclang/vendor/mypy/dmypy_server.py +3 -3
- jaclang/vendor/mypy/dmypy_util.py +62 -3
- jaclang/vendor/mypy/errors.py +1 -1
- jaclang/vendor/mypy/evalexpr.py +1 -0
- jaclang/vendor/mypy/expandtype.py +29 -29
- jaclang/vendor/mypy/fastparse.py +51 -31
- jaclang/vendor/mypy/inspections.py +5 -3
- jaclang/vendor/mypy/join.py +4 -4
- jaclang/vendor/mypy/main.py +6 -6
- jaclang/vendor/mypy/message_registry.py +1 -2
- jaclang/vendor/mypy/messages.py +31 -23
- jaclang/vendor/mypy/metastore.py +1 -2
- jaclang/vendor/mypy/modulefinder.py +2 -22
- jaclang/vendor/mypy/nodes.py +22 -20
- jaclang/vendor/mypy/options.py +4 -0
- jaclang/vendor/mypy/parse.py +6 -2
- jaclang/vendor/mypy/patterns.py +6 -6
- jaclang/vendor/mypy/plugin.py +3 -1
- jaclang/vendor/mypy/plugins/attrs.py +52 -10
- jaclang/vendor/mypy/plugins/common.py +2 -1
- jaclang/vendor/mypy/plugins/enums.py +3 -2
- jaclang/vendor/mypy/plugins/functools.py +1 -0
- jaclang/vendor/mypy/renaming.py +1 -1
- jaclang/vendor/mypy/report.py +15 -15
- jaclang/vendor/mypy/semanal.py +22 -13
- jaclang/vendor/mypy/semanal_enum.py +1 -1
- jaclang/vendor/mypy/semanal_namedtuple.py +1 -2
- jaclang/vendor/mypy/semanal_shared.py +3 -6
- jaclang/vendor/mypy/semanal_typeddict.py +16 -5
- jaclang/vendor/mypy/server/astdiff.py +15 -9
- jaclang/vendor/mypy/server/astmerge.py +5 -5
- jaclang/vendor/mypy/stats.py +0 -5
- jaclang/vendor/mypy/stubdoc.py +1 -1
- jaclang/vendor/mypy/stubgen.py +12 -21
- jaclang/vendor/mypy/stubgenc.py +16 -8
- jaclang/vendor/mypy/stubtest.py +57 -48
- jaclang/vendor/mypy/stubutil.py +28 -15
- jaclang/vendor/mypy/subtypes.py +4 -4
- jaclang/vendor/mypy/test/helpers.py +2 -2
- jaclang/vendor/mypy/test/meta/test_parse_data.py +1 -0
- jaclang/vendor/mypy/test/meta/test_update_data.py +1 -0
- jaclang/vendor/mypy/test/testargs.py +1 -0
- jaclang/vendor/mypy/test/testcheck.py +4 -1
- jaclang/vendor/mypy/test/testconstraints.py +25 -7
- jaclang/vendor/mypy/test/testerrorstream.py +1 -0
- jaclang/vendor/mypy/test/testformatter.py +2 -2
- jaclang/vendor/mypy/test/testparse.py +6 -4
- jaclang/vendor/mypy/test/testpythoneval.py +1 -0
- jaclang/vendor/mypy/test/testreports.py +1 -0
- jaclang/vendor/mypy/test/teststubgen.py +1 -2
- jaclang/vendor/mypy/test/teststubtest.py +98 -4
- jaclang/vendor/mypy/test/testtypes.py +1 -1
- jaclang/vendor/mypy/test/testutil.py +22 -0
- jaclang/vendor/mypy/typeanal.py +302 -158
- jaclang/vendor/mypy/typeops.py +22 -13
- jaclang/vendor/mypy/types.py +33 -34
- jaclang/vendor/mypy/typestate.py +2 -2
- jaclang/vendor/mypy/util.py +7 -6
- jaclang/vendor/mypy/version.py +1 -1
- jaclang/vendor/mypyc/analysis/ircheck.py +1 -0
- jaclang/vendor/mypyc/codegen/emitfunc.py +5 -3
- jaclang/vendor/mypyc/codegen/emitmodule.py +12 -12
- jaclang/vendor/mypyc/codegen/emitwrapper.py +2 -2
- jaclang/vendor/mypyc/ir/class_ir.py +10 -6
- jaclang/vendor/mypyc/irbuild/builder.py +3 -4
- jaclang/vendor/mypyc/irbuild/function.py +5 -3
- jaclang/vendor/mypyc/irbuild/nonlocalcontrol.py +1 -2
- jaclang/vendor/mypyc/irbuild/prepare.py +6 -6
- jaclang/vendor/mypyc/primitives/registry.py +15 -5
- jaclang/vendor/mypyc/test/test_run.py +1 -2
- jaclang/vendor/mypyc/transform/uninit.py +3 -3
- jaclang/vendor/pluggy/_callers.py +1 -0
- jaclang/vendor/pluggy/_hooks.py +6 -10
- jaclang/vendor/pluggy/_result.py +1 -0
- jaclang/vendor/pluggy/_tracing.py +1 -0
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/METADATA +1 -1
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/RECORD +152 -150
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/WHEEL +0 -0
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/entry_points.txt +0 -0
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/top_level.txt +0 -0
jaclang/core/construct.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Core constructs for Jac Language."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import types
|
|
@@ -15,7 +16,7 @@ from jaclang.core.utils import collect_node_connections
|
|
|
15
16
|
class ElementAnchor:
|
|
16
17
|
"""Element Anchor."""
|
|
17
18
|
|
|
18
|
-
obj:
|
|
19
|
+
obj: Architype
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
@dataclass(eq=False)
|
|
@@ -41,30 +42,6 @@ class NodeAnchor(ObjectAnchor):
|
|
|
41
42
|
edg._jac_.attach(self.obj, nd)
|
|
42
43
|
return self.obj
|
|
43
44
|
|
|
44
|
-
# def edges_to_nodes(
|
|
45
|
-
# self, dir: EdgeDir, filter_type: Optional[type], filter_func: Optional[Callable]
|
|
46
|
-
# ) -> list[NodeArchitype]:
|
|
47
|
-
# """Get set of nodes connected to this node."""
|
|
48
|
-
# filter_func = filter_func if filter_func else lambda x: x
|
|
49
|
-
# ret_nodes: list[NodeArchitype] = []
|
|
50
|
-
# if dir in [EdgeDir.OUT]:
|
|
51
|
-
# edge_list = []
|
|
52
|
-
# for x in self.edges[EdgeDir.OUT]:
|
|
53
|
-
# if x._jac_.target and (not filter_type or isinstance(x, filter_type)):
|
|
54
|
-
# edge_list.append(x)
|
|
55
|
-
# new_edge = filter_func(edge_list)
|
|
56
|
-
# for i in new_edge:
|
|
57
|
-
# ret_nodes.append(i._jac_.target)
|
|
58
|
-
# elif dir in [EdgeDir.IN]:
|
|
59
|
-
# edge_list = []
|
|
60
|
-
# for i in self.edges[EdgeDir.IN]:
|
|
61
|
-
# if i._jac_.source and (not filter_type or isinstance(i, filter_type)):
|
|
62
|
-
# edge_list.append(i)
|
|
63
|
-
# new_edge = filter_func(edge_list)
|
|
64
|
-
# for i in new_edge:
|
|
65
|
-
# ret_nodes.append(i._jac_.source)
|
|
66
|
-
# return ret_nodes
|
|
67
|
-
|
|
68
45
|
def edges_to_nodes(
|
|
69
46
|
self, dir: EdgeDir, filter_type: Optional[type], filter_func: Optional[Callable]
|
|
70
47
|
) -> list[NodeArchitype]:
|
|
@@ -83,8 +60,8 @@ class NodeAnchor(ObjectAnchor):
|
|
|
83
60
|
|
|
84
61
|
def gen_dot(self, dot_file: Optional[str] = None) -> str:
|
|
85
62
|
"""Generate Dot file for visualizing nodes and edges."""
|
|
86
|
-
visited_nodes = set()
|
|
87
|
-
connections = set()
|
|
63
|
+
visited_nodes: set[NodeAnchor] = set()
|
|
64
|
+
connections: set[tuple[NodeArchitype, NodeArchitype, str]] = set()
|
|
88
65
|
unique_node_id_dict = {}
|
|
89
66
|
|
|
90
67
|
collect_node_connections(self, visited_nodes, connections)
|
|
@@ -96,7 +73,7 @@ class NodeAnchor(ObjectAnchor):
|
|
|
96
73
|
|
|
97
74
|
for pair in list(set(connections)):
|
|
98
75
|
dot_content += (
|
|
99
|
-
f"{unique_node_id_dict
|
|
76
|
+
f"{unique_node_id_dict[pair[0]][1]} -> {unique_node_id_dict[pair[1]][1]}"
|
|
100
77
|
f' [label="{pair[2]}"];\n'
|
|
101
78
|
)
|
|
102
79
|
if dot_file:
|
|
@@ -246,7 +223,7 @@ class Architype:
|
|
|
246
223
|
|
|
247
224
|
def __init__(self) -> None:
|
|
248
225
|
"""Create default architype."""
|
|
249
|
-
self._jac_ = ObjectAnchor(obj=self)
|
|
226
|
+
self._jac_: ObjectAnchor = ObjectAnchor(obj=self)
|
|
250
227
|
|
|
251
228
|
|
|
252
229
|
class NodeArchitype(Architype):
|
|
@@ -254,7 +231,7 @@ class NodeArchitype(Architype):
|
|
|
254
231
|
|
|
255
232
|
def __init__(self) -> None:
|
|
256
233
|
"""Create node architype."""
|
|
257
|
-
self._jac_ = NodeAnchor(obj=self)
|
|
234
|
+
self._jac_: NodeAnchor = NodeAnchor(obj=self)
|
|
258
235
|
|
|
259
236
|
|
|
260
237
|
class EdgeArchitype(Architype):
|
|
@@ -262,7 +239,7 @@ class EdgeArchitype(Architype):
|
|
|
262
239
|
|
|
263
240
|
def __init__(self) -> None:
|
|
264
241
|
"""Create edge architype."""
|
|
265
|
-
self._jac_ = EdgeAnchor(obj=self)
|
|
242
|
+
self._jac_: EdgeAnchor = EdgeAnchor(obj=self)
|
|
266
243
|
|
|
267
244
|
|
|
268
245
|
class WalkerArchitype(Architype):
|
|
@@ -270,7 +247,7 @@ class WalkerArchitype(Architype):
|
|
|
270
247
|
|
|
271
248
|
def __init__(self) -> None:
|
|
272
249
|
"""Create walker architype."""
|
|
273
|
-
self._jac_ = WalkerAnchor(obj=self)
|
|
250
|
+
self._jac_: WalkerAnchor = WalkerAnchor(obj=self)
|
|
274
251
|
|
|
275
252
|
|
|
276
253
|
class Root(NodeArchitype):
|
|
@@ -1,85 +1,95 @@
|
|
|
1
|
-
"""Special Imports for Jac Code."""
|
|
2
|
-
|
|
3
|
-
import marshal
|
|
4
|
-
import sys
|
|
5
|
-
import types
|
|
6
|
-
from os import path
|
|
7
|
-
from typing import Optional
|
|
8
|
-
|
|
9
|
-
from jaclang.compiler.
|
|
10
|
-
from jaclang.compiler.
|
|
11
|
-
from jaclang.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return sys.modules[module_name]
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
else
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
1
|
+
"""Special Imports for Jac Code."""
|
|
2
|
+
|
|
3
|
+
import marshal
|
|
4
|
+
import sys
|
|
5
|
+
import types
|
|
6
|
+
from os import path
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
from jaclang.compiler.absyntree import Module
|
|
10
|
+
from jaclang.compiler.compile import compile_jac
|
|
11
|
+
from jaclang.compiler.constant import Constants as Con
|
|
12
|
+
from jaclang.utils.log import logging
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def jac_importer(
|
|
16
|
+
target: str,
|
|
17
|
+
base_path: str,
|
|
18
|
+
cachable: bool = True,
|
|
19
|
+
override_name: Optional[str] = None,
|
|
20
|
+
mod_bundle: Optional[Module] = None,
|
|
21
|
+
) -> Optional[types.ModuleType]:
|
|
22
|
+
"""Core Import Process."""
|
|
23
|
+
dir_path, file_name = path.split(path.join(*(target.split("."))) + ".jac")
|
|
24
|
+
|
|
25
|
+
module_name = path.splitext(file_name)[0]
|
|
26
|
+
package_path = dir_path.replace(path.sep, ".")
|
|
27
|
+
|
|
28
|
+
if package_path and f"{package_path}.{module_name}" in sys.modules:
|
|
29
|
+
return sys.modules[f"{package_path}.{module_name}"]
|
|
30
|
+
elif not package_path and module_name in sys.modules:
|
|
31
|
+
return sys.modules[module_name]
|
|
32
|
+
|
|
33
|
+
caller_dir = path.dirname(base_path) if not path.isdir(base_path) else base_path
|
|
34
|
+
caller_dir = path.dirname(caller_dir) if target.startswith("..") else caller_dir
|
|
35
|
+
caller_dir = path.join(caller_dir, dir_path)
|
|
36
|
+
|
|
37
|
+
full_target = path.normpath(path.join(caller_dir, file_name))
|
|
38
|
+
|
|
39
|
+
if mod_bundle:
|
|
40
|
+
codeobj = (
|
|
41
|
+
mod_bundle.gen.py_bytecode
|
|
42
|
+
if full_target == mod_bundle.loc.mod_path
|
|
43
|
+
else mod_bundle.mod_deps[full_target].gen.py_bytecode
|
|
44
|
+
)
|
|
45
|
+
if isinstance(codeobj, bytes):
|
|
46
|
+
codeobj = marshal.loads(codeobj)
|
|
47
|
+
else:
|
|
48
|
+
gen_dir = path.join(caller_dir, Con.JAC_GEN_DIR)
|
|
49
|
+
py_file_path = path.join(gen_dir, module_name + ".py")
|
|
50
|
+
pyc_file_path = path.join(gen_dir, module_name + ".jbc")
|
|
51
|
+
if (
|
|
52
|
+
cachable
|
|
53
|
+
and path.exists(py_file_path)
|
|
54
|
+
and path.getmtime(py_file_path) > path.getmtime(full_target)
|
|
55
|
+
):
|
|
56
|
+
with open(pyc_file_path, "rb") as f:
|
|
57
|
+
codeobj = marshal.load(f)
|
|
58
|
+
else:
|
|
59
|
+
if error := compile_jac(full_target):
|
|
60
|
+
if error:
|
|
61
|
+
for e in error:
|
|
62
|
+
print(e)
|
|
63
|
+
logging.error(e)
|
|
64
|
+
return None
|
|
65
|
+
with open(pyc_file_path, "rb") as f:
|
|
66
|
+
codeobj = marshal.load(f)
|
|
67
|
+
|
|
68
|
+
module_name = override_name if override_name else module_name
|
|
69
|
+
module = types.ModuleType(module_name)
|
|
70
|
+
module.__file__ = full_target
|
|
71
|
+
module.__name__ = module_name
|
|
72
|
+
module.__dict__["__jac_mod_bundle__"] = mod_bundle
|
|
73
|
+
|
|
74
|
+
if package_path:
|
|
75
|
+
parts = package_path.split(".")
|
|
76
|
+
for i in range(len(parts)):
|
|
77
|
+
package_name = ".".join(parts[: i + 1])
|
|
78
|
+
if package_name not in sys.modules:
|
|
79
|
+
sys.modules[package_name] = types.ModuleType(package_name)
|
|
80
|
+
|
|
81
|
+
setattr(sys.modules[package_path], module_name, module)
|
|
82
|
+
sys.modules[f"{package_path}.{module_name}"] = module
|
|
83
|
+
sys.modules[module_name] = module
|
|
84
|
+
|
|
85
|
+
path_added = False
|
|
86
|
+
if caller_dir not in sys.path:
|
|
87
|
+
sys.path.append(caller_dir)
|
|
88
|
+
path_added = True
|
|
89
|
+
if not codeobj:
|
|
90
|
+
raise ImportError(f"No bytecode found for {full_target}")
|
|
91
|
+
exec(codeobj, module.__dict__)
|
|
92
|
+
if path_added:
|
|
93
|
+
sys.path.remove(caller_dir)
|
|
94
|
+
|
|
95
|
+
return module
|
jaclang/core/utils.py
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
"""Helper for construct."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
2
5
|
from typing import TYPE_CHECKING
|
|
3
6
|
|
|
4
7
|
from jaclang.compiler.constant import EdgeDir
|
|
5
8
|
|
|
6
9
|
|
|
7
10
|
if TYPE_CHECKING:
|
|
8
|
-
from jaclang.core.construct import
|
|
11
|
+
from jaclang.core.construct import NodeAnchor
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
def collect_node_connections(
|
|
12
|
-
current_node:
|
|
15
|
+
current_node: NodeAnchor,
|
|
13
16
|
visited_nodes: set,
|
|
14
17
|
connections: set,
|
|
15
18
|
) -> None:
|
|
@@ -20,15 +23,17 @@ def collect_node_connections(
|
|
|
20
23
|
in_edges = current_node.edges.get(EdgeDir.IN, [])
|
|
21
24
|
|
|
22
25
|
for edge_ in out_edges:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
(
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
target = edge_._jac_.target
|
|
27
|
+
if target:
|
|
28
|
+
connections.add(
|
|
29
|
+
(current_node.obj, target._jac_.obj, edge_.__class__.__name__)
|
|
30
|
+
)
|
|
31
|
+
collect_node_connections(target._jac_, visited_nodes, connections)
|
|
28
32
|
|
|
29
33
|
for edge_ in in_edges:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
(
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
source = edge_._jac_.source
|
|
35
|
+
if source:
|
|
36
|
+
connections.add(
|
|
37
|
+
(source._jac_.obj, current_node.obj, edge_.__class__.__name__)
|
|
38
|
+
)
|
|
39
|
+
collect_node_connections(source._jac_, visited_nodes, connections)
|
jaclang/plugin/__init__.py
CHANGED
jaclang/plugin/default.py
CHANGED
|
@@ -1,76 +1,174 @@
|
|
|
1
1
|
"""Jac Language Features."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import os
|
|
6
|
+
import types
|
|
5
7
|
from dataclasses import dataclass, field
|
|
6
8
|
from functools import wraps
|
|
7
9
|
from typing import Any, Callable, Optional, Type
|
|
8
10
|
|
|
9
|
-
from jaclang import
|
|
10
|
-
from jaclang.
|
|
11
|
-
|
|
11
|
+
from jaclang.compiler.absyntree import Module
|
|
12
|
+
from jaclang.compiler.constant import EdgeDir
|
|
13
|
+
from jaclang.core.construct import (
|
|
12
14
|
Architype,
|
|
13
15
|
DSFunc,
|
|
14
16
|
EdgeAnchor,
|
|
15
17
|
EdgeArchitype,
|
|
16
|
-
EdgeDir,
|
|
17
18
|
GenericEdge,
|
|
18
19
|
JacTestCheck,
|
|
20
|
+
NodeAnchor,
|
|
19
21
|
NodeArchitype,
|
|
20
|
-
|
|
22
|
+
ObjectAnchor,
|
|
23
|
+
Root,
|
|
24
|
+
WalkerAnchor,
|
|
21
25
|
WalkerArchitype,
|
|
22
26
|
root,
|
|
23
27
|
)
|
|
28
|
+
from jaclang.core.importer import jac_importer
|
|
29
|
+
from jaclang.plugin.feature import JacFeature as Jac
|
|
30
|
+
from jaclang.plugin.spec import T
|
|
24
31
|
|
|
25
32
|
|
|
26
33
|
import pluggy
|
|
27
34
|
|
|
35
|
+
|
|
36
|
+
__all__ = [
|
|
37
|
+
"EdgeAnchor",
|
|
38
|
+
"GenericEdge",
|
|
39
|
+
"JacTestCheck",
|
|
40
|
+
"NodeAnchor",
|
|
41
|
+
"ObjectAnchor",
|
|
42
|
+
"WalkerAnchor",
|
|
43
|
+
"NodeArchitype",
|
|
44
|
+
"EdgeArchitype",
|
|
45
|
+
"WalkerArchitype",
|
|
46
|
+
"Architype",
|
|
47
|
+
"DSFunc",
|
|
48
|
+
"root",
|
|
49
|
+
"Root",
|
|
50
|
+
"jac_importer",
|
|
51
|
+
"T",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
|
|
28
55
|
hookimpl = pluggy.HookimplMarker("jac")
|
|
29
56
|
|
|
30
57
|
|
|
31
58
|
class JacFeatureDefaults:
|
|
32
59
|
"""Jac Feature."""
|
|
33
60
|
|
|
61
|
+
pm = pluggy.PluginManager("jac")
|
|
62
|
+
|
|
34
63
|
@staticmethod
|
|
35
64
|
@hookimpl
|
|
36
65
|
def make_architype(
|
|
37
|
-
|
|
66
|
+
cls: type,
|
|
67
|
+
arch_base: Type[Architype],
|
|
68
|
+
on_entry: list[DSFunc],
|
|
69
|
+
on_exit: list[DSFunc],
|
|
70
|
+
) -> Type[Architype]:
|
|
71
|
+
"""Create a new architype."""
|
|
72
|
+
cls = dataclass(eq=False)(cls)
|
|
73
|
+
for i in on_entry + on_exit:
|
|
74
|
+
i.resolve(cls)
|
|
75
|
+
if not issubclass(cls, arch_base):
|
|
76
|
+
cls = type(cls.__name__, (cls, arch_base), {})
|
|
77
|
+
cls._jac_entry_funcs_ = on_entry
|
|
78
|
+
cls._jac_exit_funcs_ = on_exit
|
|
79
|
+
inner_init = cls.__init__
|
|
80
|
+
|
|
81
|
+
@wraps(inner_init)
|
|
82
|
+
def new_init(self: Architype, *args: object, **kwargs: object) -> None:
|
|
83
|
+
inner_init(self, *args, **kwargs)
|
|
84
|
+
arch_base.__init__(self)
|
|
85
|
+
|
|
86
|
+
cls.__init__ = new_init # type: ignore
|
|
87
|
+
return cls
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
@hookimpl
|
|
91
|
+
def make_obj(
|
|
92
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
38
93
|
) -> Callable[[type], type]:
|
|
39
94
|
"""Create a new architype."""
|
|
40
95
|
|
|
41
|
-
def decorator(cls: Type[
|
|
96
|
+
def decorator(cls: Type[Architype]) -> Type[Architype]:
|
|
97
|
+
"""Decorate class."""
|
|
98
|
+
cls = Jac.make_architype(
|
|
99
|
+
cls=cls, arch_base=Architype, on_entry=on_entry, on_exit=on_exit
|
|
100
|
+
)
|
|
101
|
+
return cls
|
|
102
|
+
|
|
103
|
+
return decorator
|
|
104
|
+
|
|
105
|
+
@staticmethod
|
|
106
|
+
@hookimpl
|
|
107
|
+
def make_node(
|
|
108
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
109
|
+
) -> Callable[[type], type]:
|
|
110
|
+
"""Create a obj architype."""
|
|
111
|
+
|
|
112
|
+
def decorator(cls: Type[Architype]) -> Type[Architype]:
|
|
113
|
+
"""Decorate class."""
|
|
114
|
+
cls = Jac.make_architype(
|
|
115
|
+
cls=cls, arch_base=NodeArchitype, on_entry=on_entry, on_exit=on_exit
|
|
116
|
+
)
|
|
117
|
+
return cls
|
|
118
|
+
|
|
119
|
+
return decorator
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
@hookimpl
|
|
123
|
+
def make_edge(
|
|
124
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
125
|
+
) -> Callable[[type], type]:
|
|
126
|
+
"""Create a edge architype."""
|
|
127
|
+
|
|
128
|
+
def decorator(cls: Type[Architype]) -> Type[Architype]:
|
|
42
129
|
"""Decorate class."""
|
|
43
|
-
cls =
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
match arch_type:
|
|
48
|
-
case "obj":
|
|
49
|
-
arch_cls = Architype
|
|
50
|
-
case "node":
|
|
51
|
-
arch_cls = NodeArchitype
|
|
52
|
-
case "edge":
|
|
53
|
-
arch_cls = EdgeArchitype
|
|
54
|
-
case "walker":
|
|
55
|
-
arch_cls = WalkerArchitype
|
|
56
|
-
case _:
|
|
57
|
-
raise TypeError("Invalid archetype type")
|
|
58
|
-
if not issubclass(cls, arch_cls):
|
|
59
|
-
cls = type(cls.__name__, (cls, arch_cls), {})
|
|
60
|
-
cls._jac_entry_funcs_ = on_entry
|
|
61
|
-
cls._jac_exit_funcs_ = on_exit
|
|
62
|
-
inner_init = cls.__init__
|
|
63
|
-
|
|
64
|
-
@wraps(inner_init)
|
|
65
|
-
def new_init(self: ArchBound, *args: object, **kwargs: object) -> None:
|
|
66
|
-
inner_init(self, *args, **kwargs)
|
|
67
|
-
arch_cls.__init__(self)
|
|
68
|
-
|
|
69
|
-
cls.__init__ = new_init
|
|
130
|
+
cls = Jac.make_architype(
|
|
131
|
+
cls=cls, arch_base=EdgeArchitype, on_entry=on_entry, on_exit=on_exit
|
|
132
|
+
)
|
|
70
133
|
return cls
|
|
71
134
|
|
|
72
135
|
return decorator
|
|
73
136
|
|
|
137
|
+
@staticmethod
|
|
138
|
+
@hookimpl
|
|
139
|
+
def make_walker(
|
|
140
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
141
|
+
) -> Callable[[type], type]:
|
|
142
|
+
"""Create a walker architype."""
|
|
143
|
+
|
|
144
|
+
def decorator(cls: Type[Architype]) -> Type[Architype]:
|
|
145
|
+
"""Decorate class."""
|
|
146
|
+
cls = Jac.make_architype(
|
|
147
|
+
cls=cls, arch_base=WalkerArchitype, on_entry=on_entry, on_exit=on_exit
|
|
148
|
+
)
|
|
149
|
+
return cls
|
|
150
|
+
|
|
151
|
+
return decorator
|
|
152
|
+
|
|
153
|
+
@staticmethod
|
|
154
|
+
@hookimpl
|
|
155
|
+
def jac_import(
|
|
156
|
+
target: str,
|
|
157
|
+
base_path: str,
|
|
158
|
+
cachable: bool,
|
|
159
|
+
override_name: Optional[str],
|
|
160
|
+
mod_bundle: Optional[Module],
|
|
161
|
+
) -> Optional[types.ModuleType]:
|
|
162
|
+
"""Core Import Process."""
|
|
163
|
+
result = jac_importer(
|
|
164
|
+
target=target,
|
|
165
|
+
base_path=base_path,
|
|
166
|
+
cachable=cachable,
|
|
167
|
+
override_name=override_name,
|
|
168
|
+
mod_bundle=mod_bundle,
|
|
169
|
+
)
|
|
170
|
+
return result
|
|
171
|
+
|
|
74
172
|
@staticmethod
|
|
75
173
|
@hookimpl
|
|
76
174
|
def create_test(test_fun: Callable) -> Callable:
|
|
@@ -86,7 +184,7 @@ class JacFeatureDefaults:
|
|
|
86
184
|
|
|
87
185
|
@staticmethod
|
|
88
186
|
@hookimpl
|
|
89
|
-
def run_test(filename: str) ->
|
|
187
|
+
def run_test(filename: str) -> bool:
|
|
90
188
|
"""Run the test suite in the specified .jac file.
|
|
91
189
|
|
|
92
190
|
:param filename: The path to the .jac file.
|
|
@@ -96,10 +194,11 @@ class JacFeatureDefaults:
|
|
|
96
194
|
base = base if base else "./"
|
|
97
195
|
mod_name = mod_name[:-4]
|
|
98
196
|
JacTestCheck.reset()
|
|
99
|
-
jac_import(target=mod_name, base_path=base)
|
|
197
|
+
Jac.jac_import(target=mod_name, base_path=base)
|
|
100
198
|
JacTestCheck.run_test()
|
|
101
199
|
else:
|
|
102
200
|
print("Not a .jac file.")
|
|
201
|
+
return True
|
|
103
202
|
|
|
104
203
|
@staticmethod
|
|
105
204
|
@hookimpl
|
|
@@ -109,15 +208,21 @@ class JacFeatureDefaults:
|
|
|
109
208
|
|
|
110
209
|
@staticmethod
|
|
111
210
|
@hookimpl
|
|
112
|
-
def has_instance_default(gen_func: Callable
|
|
211
|
+
def has_instance_default(gen_func: Callable[[], T]) -> T:
|
|
113
212
|
"""Jac's has container default feature."""
|
|
114
213
|
return field(default_factory=lambda: gen_func())
|
|
115
214
|
|
|
116
215
|
@staticmethod
|
|
117
216
|
@hookimpl
|
|
118
|
-
def spawn_call(op1: Architype, op2: Architype) ->
|
|
217
|
+
def spawn_call(op1: Architype, op2: Architype) -> bool:
|
|
119
218
|
"""Jac's spawn operator feature."""
|
|
120
|
-
|
|
219
|
+
if isinstance(op1, WalkerArchitype):
|
|
220
|
+
op1._jac_.spawn_call(op2)
|
|
221
|
+
elif isinstance(op2, WalkerArchitype):
|
|
222
|
+
op2._jac_.spawn_call(op1)
|
|
223
|
+
else:
|
|
224
|
+
raise TypeError("Invalid walker object")
|
|
225
|
+
return True
|
|
121
226
|
|
|
122
227
|
@staticmethod
|
|
123
228
|
@hookimpl
|
|
@@ -131,10 +236,7 @@ class JacFeatureDefaults:
|
|
|
131
236
|
expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
|
|
132
237
|
) -> bool:
|
|
133
238
|
"""Jac's ignore stmt feature."""
|
|
134
|
-
|
|
135
|
-
return walker._jac_.ignore_node(expr)
|
|
136
|
-
else:
|
|
137
|
-
raise TypeError("Invalid walker object")
|
|
239
|
+
return walker._jac_.ignore_node(expr)
|
|
138
240
|
|
|
139
241
|
@staticmethod
|
|
140
242
|
@hookimpl
|