jaclang 0.7.14__py3-none-any.whl → 0.7.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jaclang might be problematic. Click here for more details.
- jaclang/cli/cli.py +147 -77
- jaclang/cli/cmdreg.py +9 -12
- jaclang/compiler/__init__.py +19 -53
- jaclang/compiler/absyntree.py +94 -16
- jaclang/compiler/constant.py +8 -8
- jaclang/compiler/jac.lark +4 -3
- jaclang/compiler/parser.py +41 -25
- jaclang/compiler/passes/ir_pass.py +4 -13
- jaclang/compiler/passes/main/__init__.py +1 -1
- jaclang/compiler/passes/main/access_modifier_pass.py +96 -147
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +155 -54
- jaclang/compiler/passes/main/import_pass.py +99 -75
- jaclang/compiler/passes/main/py_collect_dep_pass.py +70 -0
- jaclang/compiler/passes/main/pyast_gen_pass.py +328 -565
- jaclang/compiler/passes/main/pyast_load_pass.py +33 -6
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -0
- jaclang/compiler/passes/main/registry_pass.py +37 -3
- jaclang/compiler/passes/main/schedules.py +9 -2
- jaclang/compiler/passes/main/sym_tab_build_pass.py +10 -6
- jaclang/compiler/passes/main/tests/__init__.py +1 -1
- jaclang/compiler/passes/main/tests/fixtures/autoimpl.empty.impl.jac +0 -0
- jaclang/compiler/passes/main/tests/fixtures/autoimpl.jac +1 -1
- jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac +29 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.py +3 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/color.py +3 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/constants.py +5 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/display.py +2 -0
- jaclang/compiler/passes/main/tests/test_import_pass.py +72 -13
- jaclang/compiler/passes/main/type_check_pass.py +22 -5
- jaclang/compiler/passes/tool/jac_formatter_pass.py +135 -89
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +37 -41
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +37 -42
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/access_mod_check.jac +27 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/architype_test.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comment_alignment.jac +11 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comments.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/decorator_stack.jac +37 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/esc_keywords.jac +5 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/long_names.jac +19 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +6 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -0
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +33 -39
- jaclang/compiler/passes/transform.py +4 -0
- jaclang/compiler/passes/utils/mypy_ast_build.py +45 -0
- jaclang/compiler/semtable.py +31 -7
- jaclang/compiler/symtable.py +16 -11
- jaclang/compiler/tests/test_importer.py +25 -10
- jaclang/langserve/engine.py +104 -118
- jaclang/langserve/sem_manager.py +379 -0
- jaclang/langserve/server.py +24 -11
- jaclang/langserve/tests/fixtures/base_module_structure.jac +27 -6
- jaclang/langserve/tests/fixtures/circle.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_pure.test.jac +3 -3
- jaclang/langserve/tests/fixtures/import_include_statements.jac +1 -1
- jaclang/langserve/tests/fixtures/rename.jac +30 -0
- jaclang/langserve/tests/test_sem_tokens.py +277 -0
- jaclang/langserve/tests/test_server.py +287 -17
- jaclang/langserve/utils.py +184 -98
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +288 -92
- jaclang/plugin/feature.py +65 -27
- jaclang/plugin/spec.py +62 -23
- jaclang/plugin/tests/fixtures/other_root_access.jac +82 -0
- jaclang/plugin/tests/test_jaseci.py +414 -42
- jaclang/runtimelib/architype.py +650 -0
- jaclang/{core → runtimelib}/constructs.py +5 -8
- jaclang/{core → runtimelib}/context.py +86 -59
- jaclang/runtimelib/importer.py +361 -0
- jaclang/runtimelib/machine.py +158 -0
- jaclang/runtimelib/memory.py +158 -0
- jaclang/{core → runtimelib}/utils.py +30 -15
- jaclang/settings.py +5 -4
- jaclang/tests/fixtures/abc.jac +3 -3
- jaclang/tests/fixtures/access_checker.jac +12 -17
- jaclang/tests/fixtures/access_modifier.jac +88 -33
- jaclang/tests/fixtures/baddy.jac +3 -0
- jaclang/tests/fixtures/baddy.test.jac +3 -0
- jaclang/tests/fixtures/bar.jac +34 -0
- jaclang/tests/fixtures/byllmissue.jac +1 -5
- jaclang/tests/fixtures/chandra_bugs2.jac +11 -10
- jaclang/tests/fixtures/cls_method.jac +41 -0
- jaclang/tests/fixtures/dblhello.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +3 -3
- jaclang/tests/fixtures/deep/one_lev_dup.jac +2 -3
- jaclang/tests/fixtures/deep_import_mods.jac +13 -0
- jaclang/tests/fixtures/edge_node_walk.jac +1 -1
- jaclang/tests/fixtures/edge_ops.jac +1 -1
- jaclang/tests/fixtures/edges_walk.jac +1 -1
- jaclang/tests/fixtures/err.impl.jac +3 -0
- jaclang/tests/fixtures/err.jac +4 -2
- jaclang/tests/fixtures/err_runtime.jac +15 -0
- jaclang/tests/fixtures/foo.jac +43 -0
- jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
- jaclang/tests/fixtures/hello.jac +4 -0
- jaclang/tests/fixtures/impl_grab.impl.jac +2 -1
- jaclang/tests/fixtures/impl_grab.jac +4 -1
- jaclang/tests/fixtures/import.jac +9 -0
- jaclang/tests/fixtures/index_slice.jac +30 -0
- jaclang/tests/fixtures/jp_importer_auto.jac +14 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
- jaclang/tests/fixtures/needs_import.jac +2 -2
- jaclang/tests/fixtures/pyfunc_1.py +1 -1
- jaclang/tests/fixtures/pyfunc_2.py +5 -2
- jaclang/tests/fixtures/pygame_mock/__init__.py +3 -0
- jaclang/tests/fixtures/pygame_mock/color.py +3 -0
- jaclang/tests/fixtures/pygame_mock/constants.py +5 -0
- jaclang/tests/fixtures/pygame_mock/display.py +2 -0
- jaclang/tests/fixtures/pygame_mock/inner/__init__.py +0 -0
- jaclang/tests/fixtures/pygame_mock/inner/iner_mod.py +2 -0
- jaclang/tests/fixtures/registry.jac +9 -0
- jaclang/tests/fixtures/run_test.jac +4 -4
- jaclang/tests/fixtures/semstr.jac +1 -4
- jaclang/tests/fixtures/simple_archs.jac +1 -1
- jaclang/tests/test_cli.py +109 -3
- jaclang/tests/test_language.py +170 -68
- jaclang/tests/test_reference.py +2 -3
- jaclang/utils/helpers.py +45 -21
- jaclang/utils/test.py +9 -0
- jaclang/utils/treeprinter.py +30 -7
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/METADATA +3 -2
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/RECORD +126 -90
- jaclang/core/architype.py +0 -502
- jaclang/core/importer.py +0 -344
- jaclang/core/memory.py +0 -99
- jaclang/tests/fixtures/aott_raise.jac +0 -25
- jaclang/tests/fixtures/package_import.jac +0 -6
- /jaclang/{core → runtimelib}/__init__.py +0 -0
- /jaclang/{core → runtimelib}/test.py +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/WHEEL +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/entry_points.txt +0 -0
jaclang/core/architype.py
DELETED
|
@@ -1,502 +0,0 @@
|
|
|
1
|
-
"""Core constructs for Jac Language."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import types
|
|
6
|
-
from dataclasses import dataclass, field
|
|
7
|
-
from typing import Any, Callable, Optional
|
|
8
|
-
from uuid import UUID, uuid4
|
|
9
|
-
|
|
10
|
-
from jaclang.compiler.constant import EdgeDir
|
|
11
|
-
from jaclang.core.utils import collect_node_connections
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@dataclass(eq=False)
|
|
15
|
-
class ElementAnchor:
|
|
16
|
-
"""Element Anchor."""
|
|
17
|
-
|
|
18
|
-
obj: Architype
|
|
19
|
-
id: UUID = field(default_factory=uuid4)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@dataclass(eq=False)
|
|
23
|
-
class ObjectAnchor(ElementAnchor):
|
|
24
|
-
"""Object Anchor."""
|
|
25
|
-
|
|
26
|
-
def spawn_call(self, walk: WalkerArchitype) -> WalkerArchitype:
|
|
27
|
-
"""Invoke data spatial call."""
|
|
28
|
-
return walk._jac_.spawn_call(self.obj)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@dataclass(eq=False)
|
|
32
|
-
class NodeAnchor(ObjectAnchor):
|
|
33
|
-
"""Node Anchor."""
|
|
34
|
-
|
|
35
|
-
obj: NodeArchitype
|
|
36
|
-
edges: list[EdgeArchitype] = field(default_factory=lambda: [])
|
|
37
|
-
edge_ids: list[UUID] = field(default_factory=lambda: [])
|
|
38
|
-
persistent: bool = False
|
|
39
|
-
|
|
40
|
-
def __getstate__(self) -> dict:
|
|
41
|
-
"""Override getstate for pickle and shelve."""
|
|
42
|
-
state = self.__dict__.copy()
|
|
43
|
-
state.pop("obj")
|
|
44
|
-
if self.edges and "edges" in state:
|
|
45
|
-
edges = state.pop("edges")
|
|
46
|
-
state["edge_ids"] = [e._jac_.id for e in edges]
|
|
47
|
-
|
|
48
|
-
return state
|
|
49
|
-
|
|
50
|
-
def __setstate__(self, state: dict) -> None:
|
|
51
|
-
"""Override setstate for pickle and shelve."""
|
|
52
|
-
self.__dict__.update(state)
|
|
53
|
-
if "edge_ids" in state:
|
|
54
|
-
self.edge_ids = state.pop("edge_ids")
|
|
55
|
-
|
|
56
|
-
def populate_edges(self) -> None:
|
|
57
|
-
"""Populate edges from edge ids."""
|
|
58
|
-
from jaclang.plugin.feature import JacFeature as Jac
|
|
59
|
-
|
|
60
|
-
if len(self.edges) == 0 and len(self.edge_ids) > 0:
|
|
61
|
-
for e_id in self.edge_ids:
|
|
62
|
-
edge = Jac.context().get_obj(e_id)
|
|
63
|
-
if edge is None:
|
|
64
|
-
raise ValueError(f"Edge with id {e_id} not found.")
|
|
65
|
-
elif not isinstance(edge, EdgeArchitype):
|
|
66
|
-
raise ValueError(f"Object with id {e_id} is not an edge.")
|
|
67
|
-
else:
|
|
68
|
-
self.edges.append(edge)
|
|
69
|
-
self.edge_ids.clear()
|
|
70
|
-
|
|
71
|
-
def connect_node(self, nd: NodeArchitype, edg: EdgeArchitype) -> NodeArchitype:
|
|
72
|
-
"""Connect a node with given edge."""
|
|
73
|
-
edg._jac_.attach(self.obj, nd)
|
|
74
|
-
return self.obj
|
|
75
|
-
|
|
76
|
-
def get_edges(
|
|
77
|
-
self,
|
|
78
|
-
dir: EdgeDir,
|
|
79
|
-
filter_func: Optional[Callable[[list[EdgeArchitype]], list[EdgeArchitype]]],
|
|
80
|
-
target_obj: Optional[list[NodeArchitype]],
|
|
81
|
-
) -> list[EdgeArchitype]:
|
|
82
|
-
"""Get edges connected to this node."""
|
|
83
|
-
self.populate_edges()
|
|
84
|
-
|
|
85
|
-
edge_list: list[EdgeArchitype] = [*self.edges]
|
|
86
|
-
ret_edges: list[EdgeArchitype] = []
|
|
87
|
-
edge_list = filter_func(edge_list) if filter_func else edge_list
|
|
88
|
-
for e in edge_list:
|
|
89
|
-
if (
|
|
90
|
-
e._jac_.target
|
|
91
|
-
and e._jac_.source
|
|
92
|
-
and (
|
|
93
|
-
dir in [EdgeDir.OUT, EdgeDir.ANY]
|
|
94
|
-
and self.obj == e._jac_.source
|
|
95
|
-
and (not target_obj or e._jac_.target in target_obj)
|
|
96
|
-
)
|
|
97
|
-
or (
|
|
98
|
-
dir in [EdgeDir.IN, EdgeDir.ANY]
|
|
99
|
-
and self.obj == e._jac_.target
|
|
100
|
-
and (not target_obj or e._jac_.source in target_obj)
|
|
101
|
-
)
|
|
102
|
-
):
|
|
103
|
-
ret_edges.append(e)
|
|
104
|
-
return ret_edges
|
|
105
|
-
|
|
106
|
-
def edges_to_nodes(
|
|
107
|
-
self,
|
|
108
|
-
dir: EdgeDir,
|
|
109
|
-
filter_func: Optional[Callable[[list[EdgeArchitype]], list[EdgeArchitype]]],
|
|
110
|
-
target_obj: Optional[list[NodeArchitype]],
|
|
111
|
-
) -> list[NodeArchitype]:
|
|
112
|
-
"""Get set of nodes connected to this node."""
|
|
113
|
-
self.populate_edges()
|
|
114
|
-
for edge in self.edges:
|
|
115
|
-
edge.populate_nodes()
|
|
116
|
-
edge_list: list[EdgeArchitype] = [*self.edges]
|
|
117
|
-
node_list: list[NodeArchitype] = []
|
|
118
|
-
edge_list = filter_func(edge_list) if filter_func else edge_list
|
|
119
|
-
for e in edge_list:
|
|
120
|
-
if e._jac_.target and e._jac_.source:
|
|
121
|
-
if (
|
|
122
|
-
dir in [EdgeDir.OUT, EdgeDir.ANY]
|
|
123
|
-
and self.obj == e._jac_.source
|
|
124
|
-
and (not target_obj or e._jac_.target in target_obj)
|
|
125
|
-
):
|
|
126
|
-
node_list.append(e._jac_.target)
|
|
127
|
-
if (
|
|
128
|
-
dir in [EdgeDir.IN, EdgeDir.ANY]
|
|
129
|
-
and self.obj == e._jac_.target
|
|
130
|
-
and (not target_obj or e._jac_.source in target_obj)
|
|
131
|
-
):
|
|
132
|
-
node_list.append(e._jac_.source)
|
|
133
|
-
return node_list
|
|
134
|
-
|
|
135
|
-
def gen_dot(self, dot_file: Optional[str] = None) -> str:
|
|
136
|
-
"""Generate Dot file for visualizing nodes and edges."""
|
|
137
|
-
visited_nodes: set[NodeAnchor] = set()
|
|
138
|
-
connections: set[tuple[NodeArchitype, NodeArchitype, str]] = set()
|
|
139
|
-
unique_node_id_dict = {}
|
|
140
|
-
|
|
141
|
-
collect_node_connections(self, visited_nodes, connections)
|
|
142
|
-
dot_content = 'digraph {\nnode [style="filled", shape="ellipse", fillcolor="invis", fontcolor="black"];\n'
|
|
143
|
-
for idx, i in enumerate([nodes_.obj for nodes_ in visited_nodes]):
|
|
144
|
-
unique_node_id_dict[i] = (i.__class__.__name__, str(idx))
|
|
145
|
-
dot_content += f'{idx} [label="{i}"];\n'
|
|
146
|
-
dot_content += 'edge [color="gray", style="solid"];\n'
|
|
147
|
-
|
|
148
|
-
for pair in list(set(connections)):
|
|
149
|
-
dot_content += (
|
|
150
|
-
f"{unique_node_id_dict[pair[0]][1]} -> {unique_node_id_dict[pair[1]][1]}"
|
|
151
|
-
f' [label="{pair[2]}"];\n'
|
|
152
|
-
)
|
|
153
|
-
if dot_file:
|
|
154
|
-
with open(dot_file, "w") as f:
|
|
155
|
-
f.write(dot_content + "}")
|
|
156
|
-
return dot_content + "}"
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
@dataclass(eq=False)
|
|
160
|
-
class EdgeAnchor(ObjectAnchor):
|
|
161
|
-
"""Edge Anchor."""
|
|
162
|
-
|
|
163
|
-
obj: EdgeArchitype
|
|
164
|
-
source: Optional[NodeArchitype] = None
|
|
165
|
-
target: Optional[NodeArchitype] = None
|
|
166
|
-
source_id: Optional[UUID] = None
|
|
167
|
-
target_id: Optional[UUID] = None
|
|
168
|
-
is_undirected: bool = False
|
|
169
|
-
persistent: bool = False
|
|
170
|
-
|
|
171
|
-
def __getstate__(self) -> dict:
|
|
172
|
-
"""Override getstate for pickle and shelve."""
|
|
173
|
-
state = self.__dict__.copy()
|
|
174
|
-
state.pop("obj")
|
|
175
|
-
|
|
176
|
-
if self.source:
|
|
177
|
-
state["source_id"] = self.source._jac_.id
|
|
178
|
-
state.pop("source")
|
|
179
|
-
|
|
180
|
-
if self.target:
|
|
181
|
-
state["target_id"] = self.target._jac_.id
|
|
182
|
-
state.pop("target")
|
|
183
|
-
|
|
184
|
-
return state
|
|
185
|
-
|
|
186
|
-
def __setstate__(self, state: dict) -> None:
|
|
187
|
-
"""Override setstate for pickle and shelve."""
|
|
188
|
-
self.__dict__.update(state)
|
|
189
|
-
|
|
190
|
-
def attach(
|
|
191
|
-
self, src: NodeArchitype, trg: NodeArchitype, is_undirected: bool = False
|
|
192
|
-
) -> EdgeAnchor:
|
|
193
|
-
"""Attach edge to nodes."""
|
|
194
|
-
self.source = src
|
|
195
|
-
self.target = trg
|
|
196
|
-
self.is_undirected = is_undirected
|
|
197
|
-
src._jac_.edges.append(self.obj)
|
|
198
|
-
trg._jac_.edges.append(self.obj)
|
|
199
|
-
return self
|
|
200
|
-
|
|
201
|
-
def detach(
|
|
202
|
-
self, src: NodeArchitype, trg: NodeArchitype, is_undirected: bool = False
|
|
203
|
-
) -> None:
|
|
204
|
-
"""Detach edge from nodes."""
|
|
205
|
-
self.is_undirected = is_undirected
|
|
206
|
-
src._jac_.edges.remove(self.obj)
|
|
207
|
-
trg._jac_.edges.remove(self.obj)
|
|
208
|
-
self.source = None
|
|
209
|
-
self.target = None
|
|
210
|
-
del self
|
|
211
|
-
|
|
212
|
-
def spawn_call(self, walk: WalkerArchitype) -> WalkerArchitype:
|
|
213
|
-
"""Invoke data spatial call."""
|
|
214
|
-
if self.target:
|
|
215
|
-
return walk._jac_.spawn_call(self.target)
|
|
216
|
-
else:
|
|
217
|
-
raise ValueError("Edge has no target.")
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
@dataclass(eq=False)
|
|
221
|
-
class WalkerAnchor(ObjectAnchor):
|
|
222
|
-
"""Walker Anchor."""
|
|
223
|
-
|
|
224
|
-
obj: WalkerArchitype
|
|
225
|
-
path: list[Architype] = field(default_factory=lambda: [])
|
|
226
|
-
next: list[Architype] = field(default_factory=lambda: [])
|
|
227
|
-
ignores: list[Architype] = field(default_factory=lambda: [])
|
|
228
|
-
disengaged: bool = False
|
|
229
|
-
|
|
230
|
-
def visit_node(
|
|
231
|
-
self,
|
|
232
|
-
nds: (
|
|
233
|
-
list[NodeArchitype | EdgeArchitype]
|
|
234
|
-
| list[NodeArchitype]
|
|
235
|
-
| list[EdgeArchitype]
|
|
236
|
-
| NodeArchitype
|
|
237
|
-
| EdgeArchitype
|
|
238
|
-
),
|
|
239
|
-
) -> bool:
|
|
240
|
-
"""Walker visits node."""
|
|
241
|
-
nd_list: list[NodeArchitype | EdgeArchitype]
|
|
242
|
-
if not isinstance(nds, list):
|
|
243
|
-
nd_list = [nds]
|
|
244
|
-
else:
|
|
245
|
-
nd_list = list(nds)
|
|
246
|
-
before_len = len(self.next)
|
|
247
|
-
for i in nd_list:
|
|
248
|
-
if i not in self.ignores:
|
|
249
|
-
if isinstance(i, NodeArchitype):
|
|
250
|
-
self.next.append(i)
|
|
251
|
-
elif isinstance(i, EdgeArchitype):
|
|
252
|
-
if i._jac_.target:
|
|
253
|
-
self.next.append(i._jac_.target)
|
|
254
|
-
else:
|
|
255
|
-
raise ValueError("Edge has no target.")
|
|
256
|
-
return len(self.next) > before_len
|
|
257
|
-
|
|
258
|
-
def ignore_node(
|
|
259
|
-
self,
|
|
260
|
-
nds: (
|
|
261
|
-
list[NodeArchitype | EdgeArchitype]
|
|
262
|
-
| list[NodeArchitype]
|
|
263
|
-
| list[EdgeArchitype]
|
|
264
|
-
| NodeArchitype
|
|
265
|
-
| EdgeArchitype
|
|
266
|
-
),
|
|
267
|
-
) -> bool:
|
|
268
|
-
"""Walker ignores node."""
|
|
269
|
-
nd_list: list[NodeArchitype | EdgeArchitype]
|
|
270
|
-
if not isinstance(nds, list):
|
|
271
|
-
nd_list = [nds]
|
|
272
|
-
else:
|
|
273
|
-
nd_list = list(nds)
|
|
274
|
-
before_len = len(self.ignores)
|
|
275
|
-
for i in nd_list:
|
|
276
|
-
if i not in self.ignores:
|
|
277
|
-
if isinstance(i, NodeArchitype):
|
|
278
|
-
self.ignores.append(i)
|
|
279
|
-
elif isinstance(i, EdgeArchitype):
|
|
280
|
-
if i._jac_.target:
|
|
281
|
-
self.ignores.append(i._jac_.target)
|
|
282
|
-
else:
|
|
283
|
-
raise ValueError("Edge has no target.")
|
|
284
|
-
return len(self.ignores) > before_len
|
|
285
|
-
|
|
286
|
-
def disengage_now(self) -> None:
|
|
287
|
-
"""Disengage walker from traversal."""
|
|
288
|
-
self.disengaged = True
|
|
289
|
-
|
|
290
|
-
def spawn_call(self, nd: Architype) -> WalkerArchitype:
|
|
291
|
-
"""Invoke data spatial call."""
|
|
292
|
-
self.path = []
|
|
293
|
-
self.next = [nd]
|
|
294
|
-
while len(self.next):
|
|
295
|
-
nd = self.next.pop(0)
|
|
296
|
-
for i in nd._jac_entry_funcs_:
|
|
297
|
-
if not i.trigger or isinstance(self.obj, i.trigger):
|
|
298
|
-
if i.func:
|
|
299
|
-
i.func(nd, self.obj)
|
|
300
|
-
else:
|
|
301
|
-
raise ValueError(f"No function {i.name} to call.")
|
|
302
|
-
if self.disengaged:
|
|
303
|
-
return self.obj
|
|
304
|
-
for i in self.obj._jac_entry_funcs_:
|
|
305
|
-
if not i.trigger or isinstance(nd, i.trigger):
|
|
306
|
-
if i.func:
|
|
307
|
-
i.func(self.obj, nd)
|
|
308
|
-
else:
|
|
309
|
-
raise ValueError(f"No function {i.name} to call.")
|
|
310
|
-
if self.disengaged:
|
|
311
|
-
return self.obj
|
|
312
|
-
for i in self.obj._jac_exit_funcs_:
|
|
313
|
-
if not i.trigger or isinstance(nd, i.trigger):
|
|
314
|
-
if i.func:
|
|
315
|
-
i.func(self.obj, nd)
|
|
316
|
-
else:
|
|
317
|
-
raise ValueError(f"No function {i.name} to call.")
|
|
318
|
-
if self.disengaged:
|
|
319
|
-
return self.obj
|
|
320
|
-
for i in nd._jac_exit_funcs_:
|
|
321
|
-
if not i.trigger or isinstance(self.obj, i.trigger):
|
|
322
|
-
if i.func:
|
|
323
|
-
i.func(nd, self.obj)
|
|
324
|
-
else:
|
|
325
|
-
raise ValueError(f"No function {i.name} to call.")
|
|
326
|
-
if self.disengaged:
|
|
327
|
-
return self.obj
|
|
328
|
-
self.ignores = []
|
|
329
|
-
return self.obj
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
class Architype:
|
|
333
|
-
"""Architype Protocol."""
|
|
334
|
-
|
|
335
|
-
_jac_entry_funcs_: list[DSFunc]
|
|
336
|
-
_jac_exit_funcs_: list[DSFunc]
|
|
337
|
-
|
|
338
|
-
def __init__(self) -> None:
|
|
339
|
-
"""Create default architype."""
|
|
340
|
-
self._jac_: ObjectAnchor = ObjectAnchor(obj=self)
|
|
341
|
-
|
|
342
|
-
def __hash__(self) -> int:
|
|
343
|
-
"""Override hash for architype."""
|
|
344
|
-
return hash(self._jac_.id)
|
|
345
|
-
|
|
346
|
-
def __eq__(self, other: object) -> bool:
|
|
347
|
-
"""Override equality for architype."""
|
|
348
|
-
if not isinstance(other, Architype):
|
|
349
|
-
return False
|
|
350
|
-
else:
|
|
351
|
-
return self._jac_.id == other._jac_.id
|
|
352
|
-
|
|
353
|
-
def __repr__(self) -> str:
|
|
354
|
-
"""Override repr for architype."""
|
|
355
|
-
return f"{self.__class__.__name__}"
|
|
356
|
-
|
|
357
|
-
def __getstate__(self) -> dict:
|
|
358
|
-
"""Override getstate for pickle and shelve."""
|
|
359
|
-
raise NotImplementedError
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
class NodeArchitype(Architype):
|
|
363
|
-
"""Node Architype Protocol."""
|
|
364
|
-
|
|
365
|
-
_jac_: NodeAnchor
|
|
366
|
-
|
|
367
|
-
def __init__(self) -> None:
|
|
368
|
-
"""Create node architype."""
|
|
369
|
-
from jaclang.plugin.feature import JacFeature as Jac
|
|
370
|
-
|
|
371
|
-
self._jac_: NodeAnchor = NodeAnchor(obj=self)
|
|
372
|
-
Jac.context().save_obj(self, persistent=self._jac_.persistent)
|
|
373
|
-
|
|
374
|
-
def save(self) -> None:
|
|
375
|
-
"""Save the node to the memory/storage hierarchy."""
|
|
376
|
-
from jaclang.plugin.feature import JacFeature as Jac
|
|
377
|
-
|
|
378
|
-
self._jac_.persistent = True
|
|
379
|
-
Jac.context().save_obj(self, persistent=True)
|
|
380
|
-
|
|
381
|
-
def __getstate__(self) -> dict:
|
|
382
|
-
"""Override getstate for pickle and shelve."""
|
|
383
|
-
state = self.__dict__.copy()
|
|
384
|
-
state["_jac_"] = self._jac_.__getstate__()
|
|
385
|
-
return state
|
|
386
|
-
|
|
387
|
-
def __setstate__(self, state: dict) -> None:
|
|
388
|
-
"""Override setstate for pickle and shelve."""
|
|
389
|
-
self.__dict__.update(state)
|
|
390
|
-
self._jac_ = NodeAnchor(obj=self)
|
|
391
|
-
self._jac_.__setstate__(state["_jac_"])
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
class EdgeArchitype(Architype):
|
|
395
|
-
"""Edge Architype Protocol."""
|
|
396
|
-
|
|
397
|
-
_jac_: EdgeAnchor
|
|
398
|
-
persistent: bool = False
|
|
399
|
-
|
|
400
|
-
def __init__(self) -> None:
|
|
401
|
-
"""Create edge architype."""
|
|
402
|
-
from jaclang.plugin.feature import JacFeature as Jac
|
|
403
|
-
|
|
404
|
-
self._jac_: EdgeAnchor = EdgeAnchor(obj=self)
|
|
405
|
-
Jac.context().save_obj(self, persistent=self.persistent)
|
|
406
|
-
|
|
407
|
-
def save(self) -> None:
|
|
408
|
-
"""Save the edge to the memory/storage hierarchy."""
|
|
409
|
-
from jaclang.plugin.feature import JacFeature as Jac
|
|
410
|
-
|
|
411
|
-
self.persistent = True
|
|
412
|
-
Jac.context().save_obj(self, persistent=True)
|
|
413
|
-
|
|
414
|
-
def __getstate__(self) -> dict:
|
|
415
|
-
"""Override getstate for pickle and shelve."""
|
|
416
|
-
state = self.__dict__.copy()
|
|
417
|
-
state["_jac_"] = self._jac_.__getstate__()
|
|
418
|
-
return state
|
|
419
|
-
|
|
420
|
-
def __setstate__(self, state: dict) -> None:
|
|
421
|
-
"""Override setstate for pickle and shelve."""
|
|
422
|
-
self.__dict__.update(state)
|
|
423
|
-
self._jac_ = EdgeAnchor(obj=self)
|
|
424
|
-
self._jac_.__setstate__(state["_jac_"])
|
|
425
|
-
|
|
426
|
-
def populate_nodes(self) -> None:
|
|
427
|
-
"""Populate nodes for the edges from node ids."""
|
|
428
|
-
from jaclang.plugin.feature import JacFeature as Jac
|
|
429
|
-
|
|
430
|
-
if self._jac_.source_id:
|
|
431
|
-
obj = Jac.context().get_obj(self._jac_.source_id)
|
|
432
|
-
if obj is None:
|
|
433
|
-
raise ValueError(f"Node with id {self._jac_.source_id} not found.")
|
|
434
|
-
elif not isinstance(obj, NodeArchitype):
|
|
435
|
-
raise ValueError(
|
|
436
|
-
f"Object with id {self._jac_.source_id} is not a node."
|
|
437
|
-
)
|
|
438
|
-
else:
|
|
439
|
-
self._jac_.source = obj
|
|
440
|
-
self._jac_.source_id = None
|
|
441
|
-
if self._jac_.target_id:
|
|
442
|
-
obj = Jac.context().get_obj(self._jac_.target_id)
|
|
443
|
-
if obj is None:
|
|
444
|
-
raise ValueError(f"Node with id {self._jac_.target_id} not found.")
|
|
445
|
-
elif not isinstance(obj, NodeArchitype):
|
|
446
|
-
raise ValueError(
|
|
447
|
-
f"Object with id {self._jac_.target_id} is not a node."
|
|
448
|
-
)
|
|
449
|
-
else:
|
|
450
|
-
self._jac_.target = obj
|
|
451
|
-
self._jac_.target_id = None
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
class WalkerArchitype(Architype):
|
|
455
|
-
"""Walker Architype Protocol."""
|
|
456
|
-
|
|
457
|
-
_jac_: WalkerAnchor
|
|
458
|
-
|
|
459
|
-
def __init__(self) -> None:
|
|
460
|
-
"""Create walker architype."""
|
|
461
|
-
self._jac_: WalkerAnchor = WalkerAnchor(obj=self)
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
class GenericEdge(EdgeArchitype):
|
|
465
|
-
"""Generic Root Node."""
|
|
466
|
-
|
|
467
|
-
_jac_entry_funcs_ = []
|
|
468
|
-
_jac_exit_funcs_ = []
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
class Root(NodeArchitype):
|
|
472
|
-
"""Generic Root Node."""
|
|
473
|
-
|
|
474
|
-
_jac_entry_funcs_ = []
|
|
475
|
-
_jac_exit_funcs_ = []
|
|
476
|
-
reachable_nodes: list[NodeArchitype] = []
|
|
477
|
-
connections: set[tuple[NodeArchitype, NodeArchitype, EdgeArchitype]] = set()
|
|
478
|
-
|
|
479
|
-
def __init__(self) -> None:
|
|
480
|
-
"""Create root node."""
|
|
481
|
-
super().__init__()
|
|
482
|
-
self._jac_.id = UUID(int=0)
|
|
483
|
-
self._jac_.persistent = True
|
|
484
|
-
|
|
485
|
-
def reset(self) -> None:
|
|
486
|
-
"""Reset the root."""
|
|
487
|
-
self.reachable_nodes = []
|
|
488
|
-
self.connections = set()
|
|
489
|
-
self._jac_.edges = []
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
@dataclass(eq=False)
|
|
493
|
-
class DSFunc:
|
|
494
|
-
"""Data Spatial Function."""
|
|
495
|
-
|
|
496
|
-
name: str
|
|
497
|
-
trigger: type | types.UnionType | tuple[type | types.UnionType, ...] | None
|
|
498
|
-
func: Callable[[Any, Any], Any] | None = None
|
|
499
|
-
|
|
500
|
-
def resolve(self, cls: type) -> None:
|
|
501
|
-
"""Resolve the function."""
|
|
502
|
-
self.func = getattr(cls, self.name)
|