jaclang 0.7.30__py3-none-any.whl → 0.7.32__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 +419 -3
- jaclang/compiler/absyntree.py +3 -3
- jaclang/compiler/constant.py +4 -4
- jaclang/compiler/jac.lark +226 -175
- jaclang/compiler/parser.py +1772 -2422
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +2 -2
- jaclang/compiler/passes/main/import_pass.py +2 -1
- jaclang/compiler/passes/main/inheritance_pass.py +20 -1
- jaclang/compiler/passes/main/pyast_gen_pass.py +565 -723
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +6 -3
- jaclang/compiler/tests/test_parser.py +13 -5
- jaclang/plugin/builtin.py +11 -0
- jaclang/plugin/default.py +64 -10
- jaclang/plugin/feature.py +14 -0
- jaclang/plugin/spec.py +16 -0
- jaclang/plugin/tests/fixtures/graph_purger.jac +2 -0
- jaclang/plugin/tests/fixtures/other_root_access.jac +1 -0
- jaclang/plugin/tests/fixtures/savable_object.jac +2 -0
- jaclang/plugin/tests/fixtures/traversing_save.jac +17 -0
- jaclang/plugin/tests/test_jaseci.py +34 -1
- jaclang/runtimelib/architype.py +9 -19
- jaclang/runtimelib/context.py +25 -9
- jaclang/settings.py +2 -0
- jaclang/tests/fixtures/base_class_complex_expr.jac +38 -0
- jaclang/tests/fixtures/create_dynamic_architype.jac +1 -1
- jaclang/tests/fixtures/nested_impls.jac +55 -0
- jaclang/tests/test_cli.py +21 -0
- jaclang/tests/test_language.py +27 -13
- jaclang/tests/test_reference.py +2 -2
- jaclang/utils/helpers.py +4 -3
- jaclang/utils/profiler.py +62 -0
- {jaclang-0.7.30.dist-info → jaclang-0.7.32.dist-info}/METADATA +1 -1
- {jaclang-0.7.30.dist-info → jaclang-0.7.32.dist-info}/RECORD +35 -31
- {jaclang-0.7.30.dist-info → jaclang-0.7.32.dist-info}/WHEEL +1 -1
- {jaclang-0.7.30.dist-info → jaclang-0.7.32.dist-info}/entry_points.txt +0 -0
|
@@ -70,19 +70,22 @@ class MypyTypeCheckPassTests(TestCase):
|
|
|
70
70
|
)
|
|
71
71
|
self.assertRegex(
|
|
72
72
|
out,
|
|
73
|
-
r"129:24 - 129:28.*SpecialVarRef -
|
|
73
|
+
r"129:24 - 129:28.*SpecialVarRef - Jac.get_root\(\) \- Type\: jaclang.Root",
|
|
74
74
|
)
|
|
75
|
+
|
|
75
76
|
self.assertRegex(out, r"129:11 - 129:29.*FuncCall \- Type\: builtins\.str")
|
|
76
77
|
self.assertRegex(
|
|
77
78
|
out,
|
|
78
79
|
r"129:15 - 129:23.*Name \- node_dot \- Type\: builtins.str, SymbolTable\: str",
|
|
79
80
|
)
|
|
81
|
+
|
|
80
82
|
self.assertRegex(
|
|
81
83
|
out,
|
|
82
|
-
r"128:5 - 128:25.*BinaryExpr \- Type\: jaclang.
|
|
84
|
+
r"128:5 - 128:25.*BinaryExpr \- Type\: jaclang.Walker",
|
|
83
85
|
)
|
|
84
86
|
self.assertRegex(
|
|
85
87
|
out,
|
|
86
|
-
r"48:11 - 48:28.*EdgeRefTrailer \- Type\:
|
|
88
|
+
r"48:11 - 48:28.*EdgeRefTrailer \- Type\: jaclang.JacList\[data_spatial_types.A\]",
|
|
87
89
|
)
|
|
90
|
+
|
|
88
91
|
self.assertRegex(out, r"24:5 - 24:25.*BinaryExpr \- Type\: builtins.bool", out)
|
|
@@ -89,12 +89,20 @@ class TestLarkParser(TestCaseMicroSuite):
|
|
|
89
89
|
JacParser.TreeToAST.__base__, value.__name__, False
|
|
90
90
|
):
|
|
91
91
|
parse_funcs.append(name)
|
|
92
|
-
for
|
|
93
|
-
self.assertIn(
|
|
94
|
-
for
|
|
95
|
-
if
|
|
92
|
+
for rule in rules:
|
|
93
|
+
self.assertIn(rule, parse_funcs)
|
|
94
|
+
for fn in parse_funcs:
|
|
95
|
+
if fn.startswith("_") or fn in [
|
|
96
|
+
"ice",
|
|
97
|
+
"match",
|
|
98
|
+
"consume",
|
|
99
|
+
"match_token",
|
|
100
|
+
"consume_token",
|
|
101
|
+
"match_many",
|
|
102
|
+
"consume_many",
|
|
103
|
+
]:
|
|
96
104
|
continue
|
|
97
|
-
self.assertIn(
|
|
105
|
+
self.assertIn(fn, rules)
|
|
98
106
|
|
|
99
107
|
def test_all_ast_has_normalize(self) -> None:
|
|
100
108
|
"""Test for enter/exit name diffs with parser."""
|
jaclang/plugin/builtin.py
CHANGED
|
@@ -7,6 +7,12 @@ from typing import Optional
|
|
|
7
7
|
from jaclang.plugin.feature import JacFeature as Jac
|
|
8
8
|
from jaclang.runtimelib.constructs import Architype, NodeArchitype
|
|
9
9
|
|
|
10
|
+
__all__ = [
|
|
11
|
+
"dotgen",
|
|
12
|
+
"jid",
|
|
13
|
+
"jobj",
|
|
14
|
+
]
|
|
15
|
+
|
|
10
16
|
|
|
11
17
|
def dotgen(
|
|
12
18
|
node: Optional[NodeArchitype] = None,
|
|
@@ -44,3 +50,8 @@ def dotgen(
|
|
|
44
50
|
def jid(obj: Architype) -> str:
|
|
45
51
|
"""Get the id of the object."""
|
|
46
52
|
return Jac.object_ref(obj)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def jobj(id: str) -> Architype | None:
|
|
56
|
+
"""Get the object from the id."""
|
|
57
|
+
return Jac.get_object(id)
|
jaclang/plugin/default.py
CHANGED
|
@@ -660,11 +660,15 @@ class JacFeatureImpl(
|
|
|
660
660
|
if not hasattr(cls, "_jac_entry_funcs_") or not hasattr(
|
|
661
661
|
cls, "_jac_exit_funcs_"
|
|
662
662
|
):
|
|
663
|
-
#
|
|
664
|
-
#
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
663
|
+
# If a class only inherit from object (ie. Doesn't inherit from a class), we cannot modify
|
|
664
|
+
# the __bases__ property of it, so it's necessary to make sure the class is not a direct child of object.
|
|
665
|
+
assert cls.__bases__ != (object,)
|
|
666
|
+
bases = (
|
|
667
|
+
(cls.__bases__ + (arch_base,))
|
|
668
|
+
if arch_base not in cls.__bases__
|
|
669
|
+
else cls.__bases__
|
|
670
|
+
)
|
|
671
|
+
cls.__bases__ = bases
|
|
668
672
|
cls._jac_entry_funcs_ = on_entry # type: ignore
|
|
669
673
|
cls._jac_exit_funcs_ = on_exit # type: ignore
|
|
670
674
|
else:
|
|
@@ -724,6 +728,22 @@ class JacFeatureImpl(
|
|
|
724
728
|
|
|
725
729
|
return decorator
|
|
726
730
|
|
|
731
|
+
@staticmethod
|
|
732
|
+
@hookimpl
|
|
733
|
+
def make_root(
|
|
734
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
735
|
+
) -> Callable[[type], type]:
|
|
736
|
+
"""Create a obj architype."""
|
|
737
|
+
|
|
738
|
+
def decorator(cls: Type[Architype]) -> Type[Architype]:
|
|
739
|
+
"""Decorate class."""
|
|
740
|
+
cls = Jac.make_architype(
|
|
741
|
+
cls=cls, arch_base=Root, on_entry=on_entry, on_exit=on_exit
|
|
742
|
+
)
|
|
743
|
+
return cls
|
|
744
|
+
|
|
745
|
+
return decorator
|
|
746
|
+
|
|
727
747
|
@staticmethod
|
|
728
748
|
@hookimpl
|
|
729
749
|
def make_edge(
|
|
@@ -740,6 +760,25 @@ class JacFeatureImpl(
|
|
|
740
760
|
|
|
741
761
|
return decorator
|
|
742
762
|
|
|
763
|
+
@staticmethod
|
|
764
|
+
@hookimpl
|
|
765
|
+
def make_generic_edge(
|
|
766
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
767
|
+
) -> Callable[[type], type]:
|
|
768
|
+
"""Create a edge architype."""
|
|
769
|
+
|
|
770
|
+
def decorator(cls: Type[Architype]) -> Type[Architype]:
|
|
771
|
+
"""Decorate class."""
|
|
772
|
+
cls = Jac.make_architype(
|
|
773
|
+
cls=cls,
|
|
774
|
+
arch_base=GenericEdge,
|
|
775
|
+
on_entry=on_entry,
|
|
776
|
+
on_exit=on_exit,
|
|
777
|
+
)
|
|
778
|
+
return cls
|
|
779
|
+
|
|
780
|
+
return decorator
|
|
781
|
+
|
|
743
782
|
@staticmethod
|
|
744
783
|
@hookimpl
|
|
745
784
|
def make_walker(
|
|
@@ -1061,7 +1100,9 @@ class JacFeatureImpl(
|
|
|
1061
1100
|
@hookimpl
|
|
1062
1101
|
def get_root_type() -> Type[Root]:
|
|
1063
1102
|
"""Jac's root getter."""
|
|
1064
|
-
|
|
1103
|
+
from jaclang import Root as JRoot
|
|
1104
|
+
|
|
1105
|
+
return cast(Type[Root], JRoot)
|
|
1065
1106
|
|
|
1066
1107
|
@staticmethod
|
|
1067
1108
|
@hookimpl
|
|
@@ -1071,10 +1112,12 @@ class JacFeatureImpl(
|
|
|
1071
1112
|
conn_assign: Optional[tuple[tuple, tuple]],
|
|
1072
1113
|
) -> Callable[[NodeAnchor, NodeAnchor], EdgeArchitype]:
|
|
1073
1114
|
"""Jac's root getter."""
|
|
1074
|
-
|
|
1115
|
+
from jaclang import GenericEdge
|
|
1116
|
+
|
|
1117
|
+
ct = conn_type if conn_type else GenericEdge
|
|
1075
1118
|
|
|
1076
1119
|
def builder(source: NodeAnchor, target: NodeAnchor) -> EdgeArchitype:
|
|
1077
|
-
edge =
|
|
1120
|
+
edge = ct() if isinstance(ct, type) else ct
|
|
1078
1121
|
|
|
1079
1122
|
eanch = edge.__jac__ = EdgeAnchor(
|
|
1080
1123
|
architype=edge,
|
|
@@ -1093,8 +1136,6 @@ class JacFeatureImpl(
|
|
|
1093
1136
|
raise ValueError(f"Invalid attribute: {fld}")
|
|
1094
1137
|
if source.persistent or target.persistent:
|
|
1095
1138
|
Jac.save(eanch)
|
|
1096
|
-
Jac.save(target)
|
|
1097
|
-
Jac.save(source)
|
|
1098
1139
|
return edge
|
|
1099
1140
|
|
|
1100
1141
|
return builder
|
|
@@ -1112,6 +1153,19 @@ class JacFeatureImpl(
|
|
|
1112
1153
|
|
|
1113
1154
|
jctx.mem.set(anchor.id, anchor)
|
|
1114
1155
|
|
|
1156
|
+
match anchor:
|
|
1157
|
+
case NodeAnchor():
|
|
1158
|
+
for ed in anchor.edges:
|
|
1159
|
+
if ed.is_populated() and not ed.persistent:
|
|
1160
|
+
Jac.save(ed)
|
|
1161
|
+
case EdgeAnchor():
|
|
1162
|
+
if (src := anchor.source) and src.is_populated() and not src.persistent:
|
|
1163
|
+
Jac.save(src)
|
|
1164
|
+
if (trg := anchor.target) and trg.is_populated() and not trg.persistent:
|
|
1165
|
+
Jac.save(trg)
|
|
1166
|
+
case _:
|
|
1167
|
+
pass
|
|
1168
|
+
|
|
1115
1169
|
@staticmethod
|
|
1116
1170
|
@hookimpl
|
|
1117
1171
|
def destroy(obj: Architype | Anchor) -> None:
|
jaclang/plugin/feature.py
CHANGED
|
@@ -305,6 +305,13 @@ class JacFeature(
|
|
|
305
305
|
"""Create a node architype."""
|
|
306
306
|
return plugin_manager.hook.make_node(on_entry=on_entry, on_exit=on_exit)
|
|
307
307
|
|
|
308
|
+
@staticmethod
|
|
309
|
+
def make_root(
|
|
310
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
311
|
+
) -> Callable[[type], type]:
|
|
312
|
+
"""Create a root node architype."""
|
|
313
|
+
return plugin_manager.hook.make_root(on_entry=on_entry, on_exit=on_exit)
|
|
314
|
+
|
|
308
315
|
@staticmethod
|
|
309
316
|
def make_edge(
|
|
310
317
|
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
@@ -312,6 +319,13 @@ class JacFeature(
|
|
|
312
319
|
"""Create a edge architype."""
|
|
313
320
|
return plugin_manager.hook.make_edge(on_entry=on_entry, on_exit=on_exit)
|
|
314
321
|
|
|
322
|
+
@staticmethod
|
|
323
|
+
def make_generic_edge(
|
|
324
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
325
|
+
) -> Callable[[type], type]:
|
|
326
|
+
"""Create a edge architype."""
|
|
327
|
+
return plugin_manager.hook.make_generic_edge(on_entry=on_entry, on_exit=on_exit)
|
|
328
|
+
|
|
315
329
|
@staticmethod
|
|
316
330
|
def make_walker(
|
|
317
331
|
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
jaclang/plugin/spec.py
CHANGED
|
@@ -295,6 +295,14 @@ class JacFeatureSpec(
|
|
|
295
295
|
"""Create a node architype."""
|
|
296
296
|
raise NotImplementedError
|
|
297
297
|
|
|
298
|
+
@staticmethod
|
|
299
|
+
@hookspec(firstresult=True)
|
|
300
|
+
def make_root(
|
|
301
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
302
|
+
) -> Callable[[type], type]:
|
|
303
|
+
"""Create a root node architype."""
|
|
304
|
+
raise NotImplementedError
|
|
305
|
+
|
|
298
306
|
@staticmethod
|
|
299
307
|
@hookspec(firstresult=True)
|
|
300
308
|
def make_edge(
|
|
@@ -303,6 +311,14 @@ class JacFeatureSpec(
|
|
|
303
311
|
"""Create a edge architype."""
|
|
304
312
|
raise NotImplementedError
|
|
305
313
|
|
|
314
|
+
@staticmethod
|
|
315
|
+
@hookspec(firstresult=True)
|
|
316
|
+
def make_generic_edge(
|
|
317
|
+
on_entry: list[DSFunc], on_exit: list[DSFunc]
|
|
318
|
+
) -> Callable[[type], type]:
|
|
319
|
+
"""Create a generic edge architype."""
|
|
320
|
+
raise NotImplementedError
|
|
321
|
+
|
|
306
322
|
@staticmethod
|
|
307
323
|
@hookspec(firstresult=True)
|
|
308
324
|
def make_walker(
|
|
@@ -748,7 +748,7 @@ class TestJaseciPlugin(TestCase):
|
|
|
748
748
|
def test_savable_object(self) -> None:
|
|
749
749
|
"""Test ObjectAnchor save."""
|
|
750
750
|
global session
|
|
751
|
-
session = self.fixture_abs_path("
|
|
751
|
+
session = self.fixture_abs_path("savable_object.session")
|
|
752
752
|
|
|
753
753
|
self._output2buffer()
|
|
754
754
|
|
|
@@ -816,3 +816,36 @@ class TestJaseciPlugin(TestCase):
|
|
|
816
816
|
session=session,
|
|
817
817
|
)
|
|
818
818
|
self.assertEqual("None", self.capturedOutput.getvalue().strip())
|
|
819
|
+
|
|
820
|
+
def test_traversing_save(self) -> None:
|
|
821
|
+
"""Test traversing save."""
|
|
822
|
+
global session
|
|
823
|
+
session = self.fixture_abs_path("traversing_save.session")
|
|
824
|
+
|
|
825
|
+
self._output2buffer()
|
|
826
|
+
cli.enter(
|
|
827
|
+
filename=self.fixture_abs_path("traversing_save.jac"),
|
|
828
|
+
entrypoint="build",
|
|
829
|
+
args=[],
|
|
830
|
+
session=session,
|
|
831
|
+
)
|
|
832
|
+
|
|
833
|
+
cli.enter(
|
|
834
|
+
filename=self.fixture_abs_path("traversing_save.jac"),
|
|
835
|
+
entrypoint="view",
|
|
836
|
+
args=[],
|
|
837
|
+
session=session,
|
|
838
|
+
)
|
|
839
|
+
|
|
840
|
+
self.assertEqual(
|
|
841
|
+
"digraph {\n"
|
|
842
|
+
'node [style="filled", shape="ellipse", fillcolor="invis", fontcolor="black"];\n'
|
|
843
|
+
'0 -> 1 [label=""];\n'
|
|
844
|
+
'1 -> 2 [label=""];\n'
|
|
845
|
+
'0 [label="Root()"fillcolor="#FFE9E9"];\n'
|
|
846
|
+
'1 [label="A()"fillcolor="#F0FFF0"];\n'
|
|
847
|
+
'2 [label="B()"fillcolor="#F5E5FF"];\n}',
|
|
848
|
+
self.capturedOutput.getvalue().strip(),
|
|
849
|
+
)
|
|
850
|
+
|
|
851
|
+
self._del_session(session)
|
jaclang/runtimelib/architype.py
CHANGED
|
@@ -12,6 +12,7 @@ from types import UnionType
|
|
|
12
12
|
from typing import Any, Callable, ClassVar, Optional, TypeVar
|
|
13
13
|
from uuid import UUID, uuid4
|
|
14
14
|
|
|
15
|
+
|
|
15
16
|
logger = getLogger(__name__)
|
|
16
17
|
|
|
17
18
|
TARCH = TypeVar("TARCH", bound="Architype")
|
|
@@ -285,21 +286,13 @@ class ObjectArchitype(Architype):
|
|
|
285
286
|
self.__jac__ = ObjectAnchor(architype=self)
|
|
286
287
|
|
|
287
288
|
|
|
288
|
-
@dataclass(eq=False)
|
|
289
289
|
class GenericEdge(EdgeArchitype):
|
|
290
|
-
"""Generic
|
|
291
|
-
|
|
292
|
-
_jac_entry_funcs_: ClassVar[list[DSFunc]] = []
|
|
293
|
-
_jac_exit_funcs_: ClassVar[list[DSFunc]] = []
|
|
290
|
+
"""Generic Edge."""
|
|
294
291
|
|
|
295
292
|
|
|
296
|
-
@dataclass(eq=False)
|
|
297
293
|
class Root(NodeArchitype):
|
|
298
294
|
"""Generic Root Node."""
|
|
299
295
|
|
|
300
|
-
_jac_entry_funcs_: ClassVar[list[DSFunc]] = []
|
|
301
|
-
_jac_exit_funcs_: ClassVar[list[DSFunc]] = []
|
|
302
|
-
|
|
303
296
|
def __init__(self) -> None:
|
|
304
297
|
"""Create root node."""
|
|
305
298
|
self.__jac__ = NodeAnchor(architype=self, persistent=True, edges=[])
|
|
@@ -315,16 +308,13 @@ class DSFunc:
|
|
|
315
308
|
@cached_property
|
|
316
309
|
def trigger(self) -> type | UnionType | tuple[type | UnionType, ...] | None:
|
|
317
310
|
"""Get function parameter annotations."""
|
|
318
|
-
|
|
319
|
-
(
|
|
320
|
-
|
|
321
|
-
.
|
|
322
|
-
.annotation
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
else None
|
|
326
|
-
)
|
|
327
|
-
return None if t is inspect._empty else t
|
|
311
|
+
if self.func:
|
|
312
|
+
parameters = inspect.signature(self.func, eval_str=True).parameters
|
|
313
|
+
if len(parameters) >= 2:
|
|
314
|
+
second_param = list(parameters.values())[1]
|
|
315
|
+
ty = second_param.annotation
|
|
316
|
+
return ty if ty != inspect._empty else None
|
|
317
|
+
return None
|
|
328
318
|
|
|
329
319
|
def resolve(self, cls: type) -> None:
|
|
330
320
|
"""Resolve the function."""
|
jaclang/runtimelib/context.py
CHANGED
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import unittest
|
|
6
6
|
from contextvars import ContextVar
|
|
7
7
|
from dataclasses import MISSING
|
|
8
|
-
from typing import Any, Callable, Optional, cast
|
|
8
|
+
from typing import Any, Callable, ClassVar, Optional, cast
|
|
9
9
|
from uuid import UUID
|
|
10
10
|
|
|
11
11
|
from .architype import NodeAnchor, Root
|
|
@@ -13,13 +13,7 @@ from .memory import Memory, ShelfStorage
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
EXECUTION_CONTEXT = ContextVar[Optional["ExecutionContext"]]("ExecutionContext")
|
|
16
|
-
|
|
17
16
|
SUPER_ROOT_UUID = UUID("00000000-0000-0000-0000-000000000000")
|
|
18
|
-
SUPER_ROOT_ARCHITYPE = object.__new__(Root)
|
|
19
|
-
SUPER_ROOT_ANCHOR = NodeAnchor(
|
|
20
|
-
id=SUPER_ROOT_UUID, architype=SUPER_ROOT_ARCHITYPE, persistent=False, edges=[]
|
|
21
|
-
)
|
|
22
|
-
SUPER_ROOT_ARCHITYPE.__jac__ = SUPER_ROOT_ANCHOR
|
|
23
17
|
|
|
24
18
|
|
|
25
19
|
class ExecutionContext:
|
|
@@ -32,6 +26,9 @@ class ExecutionContext:
|
|
|
32
26
|
root: NodeAnchor
|
|
33
27
|
entry_node: NodeAnchor
|
|
34
28
|
|
|
29
|
+
# A context change event subscription list, those who want to listen ctx change will register here.
|
|
30
|
+
on_ctx_change: ClassVar[list[Callable[[ExecutionContext | None], None]]] = []
|
|
31
|
+
|
|
35
32
|
def init_anchor(
|
|
36
33
|
self,
|
|
37
34
|
anchor_id: str | None,
|
|
@@ -52,6 +49,8 @@ class ExecutionContext:
|
|
|
52
49
|
"""Close current ExecutionContext."""
|
|
53
50
|
self.mem.close()
|
|
54
51
|
EXECUTION_CONTEXT.set(None)
|
|
52
|
+
for func in ExecutionContext.on_ctx_change:
|
|
53
|
+
func(EXECUTION_CONTEXT.get(None))
|
|
55
54
|
|
|
56
55
|
@staticmethod
|
|
57
56
|
def create(
|
|
@@ -60,6 +59,8 @@ class ExecutionContext:
|
|
|
60
59
|
auto_close: bool = True,
|
|
61
60
|
) -> ExecutionContext:
|
|
62
61
|
"""Create ExecutionContext."""
|
|
62
|
+
from jaclang import Root
|
|
63
|
+
|
|
63
64
|
ctx = ExecutionContext()
|
|
64
65
|
ctx.mem = ShelfStorage(session)
|
|
65
66
|
ctx.reports = []
|
|
@@ -67,7 +68,7 @@ class ExecutionContext:
|
|
|
67
68
|
if not isinstance(
|
|
68
69
|
system_root := ctx.mem.find_by_id(SUPER_ROOT_UUID), NodeAnchor
|
|
69
70
|
):
|
|
70
|
-
system_root = Root().__jac__
|
|
71
|
+
system_root = cast(NodeAnchor, Root().__jac__) # type: ignore[attr-defined]
|
|
71
72
|
system_root.id = SUPER_ROOT_UUID
|
|
72
73
|
ctx.mem.set(system_root.id, system_root)
|
|
73
74
|
|
|
@@ -79,6 +80,8 @@ class ExecutionContext:
|
|
|
79
80
|
old_ctx.close()
|
|
80
81
|
|
|
81
82
|
EXECUTION_CONTEXT.set(ctx)
|
|
83
|
+
for func in ExecutionContext.on_ctx_change:
|
|
84
|
+
func(EXECUTION_CONTEXT.get(None))
|
|
82
85
|
|
|
83
86
|
return ctx
|
|
84
87
|
|
|
@@ -95,7 +98,20 @@ class ExecutionContext:
|
|
|
95
98
|
if ctx := EXECUTION_CONTEXT.get(None):
|
|
96
99
|
return cast(Root, ctx.root.architype)
|
|
97
100
|
|
|
98
|
-
return
|
|
101
|
+
return cast(Root, ExecutionContext.global_system_root().architype)
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def global_system_root() -> NodeAnchor:
|
|
105
|
+
"""Get global system root."""
|
|
106
|
+
from jaclang import Root
|
|
107
|
+
|
|
108
|
+
if not (sr_anch := getattr(ExecutionContext, "system_root", None)):
|
|
109
|
+
sr_arch = Root()
|
|
110
|
+
sr_anch = sr_arch.__jac__ # type: ignore[attr-defined]
|
|
111
|
+
sr_anch.id = SUPER_ROOT_UUID
|
|
112
|
+
sr_anch.persistent = False
|
|
113
|
+
ExecutionContext.system_root = sr_anch
|
|
114
|
+
return sr_anch
|
|
99
115
|
|
|
100
116
|
|
|
101
117
|
class JacTestResult(unittest.TextTestResult):
|
jaclang/settings.py
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
class Apple {
|
|
2
|
+
with entry {
|
|
3
|
+
a = 1;
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class Orange {
|
|
8
|
+
with entry {
|
|
9
|
+
b = 2;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
with entry {
|
|
14
|
+
mm = [Apple, Orange];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class Banana :mm[1]: {
|
|
18
|
+
with entry {
|
|
19
|
+
c = 3;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
can return_class() -> `Type[Apple] {
|
|
24
|
+
print('Returning Apple');
|
|
25
|
+
return Apple;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class Kiwi :return_class(): {
|
|
29
|
+
with entry {
|
|
30
|
+
d = 4;
|
|
31
|
+
;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
with entry {
|
|
36
|
+
a = Kiwi();
|
|
37
|
+
print(Kiwi.d);
|
|
38
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
obj mainObject;
|
|
2
|
+
|
|
3
|
+
:obj:mainObject{
|
|
4
|
+
can greet;
|
|
5
|
+
obj subObject;
|
|
6
|
+
}
|
|
7
|
+
can foo{
|
|
8
|
+
obj ObjInsideFunction;
|
|
9
|
+
return ObjInsideFunction();
|
|
10
|
+
}
|
|
11
|
+
:can:foo:obj:ObjInsideFunction{
|
|
12
|
+
can bar{
|
|
13
|
+
print("Hello,from bar in kk");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
with entry{
|
|
18
|
+
foo().bar();
|
|
19
|
+
}
|
|
20
|
+
:obj:mainObject:can:greet{
|
|
21
|
+
print("Greeting: Hello, World!");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
:obj:mainObject:obj:subObject{
|
|
25
|
+
can displayMessage;
|
|
26
|
+
can shortMessage{
|
|
27
|
+
print("Hello, World!");
|
|
28
|
+
}
|
|
29
|
+
obj nestedObject;
|
|
30
|
+
}
|
|
31
|
+
:obj:mainObject:obj:subObject:can:displayMessage{
|
|
32
|
+
print("Repeated: Hello!");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:obj:mainObject:obj:subObject:obj:nestedObject{
|
|
36
|
+
can lastMessage;
|
|
37
|
+
can finalMessage{
|
|
38
|
+
print("Final message:!");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
:obj:mainObject:obj:subObject:obj:nestedObject:can:lastMessage{
|
|
43
|
+
# impl mainObject.subObject.nestedObject{ # TODO
|
|
44
|
+
print("Last message:!");
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
with entry{
|
|
50
|
+
mainObject().greet();
|
|
51
|
+
mainObject().subObject().displayMessage();
|
|
52
|
+
mainObject().subObject().shortMessage();
|
|
53
|
+
mainObject().subObject().nestedObject().lastMessage();
|
|
54
|
+
mainObject().subObject().nestedObject().finalMessage();
|
|
55
|
+
}
|
jaclang/tests/test_cli.py
CHANGED
|
@@ -294,6 +294,27 @@ class JacCliTests(TestCase):
|
|
|
294
294
|
r"10:7 - 10:12.*Name - start - Type.*SymbolPath: base_class2.B.start",
|
|
295
295
|
)
|
|
296
296
|
|
|
297
|
+
def test_base_class_complex_expr(self) -> None:
|
|
298
|
+
"""Testing for print AstTool."""
|
|
299
|
+
from jaclang.settings import settings
|
|
300
|
+
|
|
301
|
+
# settings.ast_symbol_info_detailed = True
|
|
302
|
+
captured_output = io.StringIO()
|
|
303
|
+
sys.stdout = captured_output
|
|
304
|
+
|
|
305
|
+
cli.tool(
|
|
306
|
+
"ir", ["ast", f"{self.fixture_abs_path('base_class_complex_expr.jac')}"]
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
sys.stdout = sys.__stdout__
|
|
310
|
+
stdout_value = captured_output.getvalue()
|
|
311
|
+
settings.ast_symbol_info_detailed = False
|
|
312
|
+
|
|
313
|
+
self.assertRegex(
|
|
314
|
+
stdout_value,
|
|
315
|
+
r"36\:9 \- 36\:13.*Name \- Kiwi \- Type\: base_class_complex_expr.Kiwi, SymbolTable\: Kiwi",
|
|
316
|
+
)
|
|
317
|
+
|
|
297
318
|
def test_expr_types(self) -> None:
|
|
298
319
|
"""Testing for print AstTool."""
|
|
299
320
|
captured_output = io.StringIO()
|