jaclang 0.7.27__py3-none-any.whl → 0.7.29__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 +3 -0
- jaclang/compiler/absyntree.py +18 -3
- jaclang/compiler/passes/main/__init__.py +1 -1
- jaclang/compiler/passes/main/access_modifier_pass.py +1 -1
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +62 -33
- jaclang/compiler/passes/main/import_pass.py +284 -63
- jaclang/compiler/passes/main/inheritance_pass.py +103 -0
- jaclang/compiler/passes/main/py_collect_dep_pass.py +5 -5
- jaclang/compiler/passes/main/pyast_load_pass.py +1 -1
- jaclang/compiler/passes/main/schedules.py +2 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +17 -0
- jaclang/compiler/passes/main/tests/fixtures/data_spatial_types.jac +130 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.py +3 -3
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.pyi +3 -3
- jaclang/compiler/passes/main/tests/test_import_pass.py +13 -17
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +24 -0
- jaclang/compiler/passes/main/type_check_pass.py +3 -2
- jaclang/compiler/py_info.py +22 -0
- jaclang/compiler/symtable.py +9 -2
- jaclang/langserve/tests/test_server.py +2 -2
- jaclang/plugin/default.py +82 -50
- jaclang/plugin/feature.py +2 -0
- jaclang/plugin/spec.py +1 -0
- jaclang/runtimelib/architype.py +18 -14
- jaclang/runtimelib/test.py +59 -4
- jaclang/runtimelib/utils.py +15 -0
- jaclang/settings.py +3 -0
- jaclang/tests/fixtures/base_class1.jac +11 -0
- jaclang/tests/fixtures/base_class2.jac +11 -0
- jaclang/tests/fixtures/import_all.jac +7 -0
- jaclang/tests/fixtures/import_all_py.py +8 -0
- jaclang/tests/fixtures/jactest_imported.jac +6 -0
- jaclang/tests/fixtures/jactest_main.jac +22 -0
- jaclang/tests/fixtures/multi_dim_array_split.jac +2 -6
- jaclang/tests/fixtures/test_py.py +12 -0
- jaclang/tests/fixtures/visit_sequence.jac +50 -0
- jaclang/tests/test_cli.py +82 -0
- jaclang/tests/test_language.py +24 -9
- jaclang/utils/helpers.py +9 -1
- jaclang/utils/treeprinter.py +6 -3
- {jaclang-0.7.27.dist-info → jaclang-0.7.29.dist-info}/METADATA +2 -2
- {jaclang-0.7.27.dist-info → jaclang-0.7.29.dist-info}/RECORD +44 -33
- {jaclang-0.7.27.dist-info → jaclang-0.7.29.dist-info}/WHEEL +1 -1
- {jaclang-0.7.27.dist-info → jaclang-0.7.29.dist-info}/entry_points.txt +0 -0
jaclang/plugin/default.py
CHANGED
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import ast as ast3
|
|
6
6
|
import fnmatch
|
|
7
7
|
import html
|
|
8
|
+
import inspect
|
|
8
9
|
import os
|
|
9
10
|
import types
|
|
10
11
|
from collections import OrderedDict
|
|
@@ -42,8 +43,11 @@ from jaclang.runtimelib.constructs import (
|
|
|
42
43
|
from jaclang.runtimelib.importer import ImportPathSpec, JacImporter, PythonImporter
|
|
43
44
|
from jaclang.runtimelib.machine import JacMachine, JacProgram
|
|
44
45
|
from jaclang.runtimelib.memory import Shelf, ShelfStorage
|
|
45
|
-
from jaclang.runtimelib.utils import
|
|
46
|
-
|
|
46
|
+
from jaclang.runtimelib.utils import (
|
|
47
|
+
all_issubclass,
|
|
48
|
+
collect_node_connections,
|
|
49
|
+
traverse_graph,
|
|
50
|
+
)
|
|
47
51
|
|
|
48
52
|
import pluggy
|
|
49
53
|
|
|
@@ -398,64 +402,85 @@ class JacWalkerImpl:
|
|
|
398
402
|
|
|
399
403
|
walker.path = []
|
|
400
404
|
walker.next = [node]
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
405
|
+
current_node = node.architype
|
|
406
|
+
|
|
407
|
+
# walker entry
|
|
408
|
+
for i in warch._jac_entry_funcs_:
|
|
409
|
+
if i.func and not i.trigger:
|
|
410
|
+
i.func(warch, current_node)
|
|
411
|
+
if walker.disengaged:
|
|
412
|
+
return warch
|
|
413
|
+
|
|
410
414
|
while len(walker.next):
|
|
411
415
|
if current_node := walker.next.pop(0).architype:
|
|
416
|
+
# walker entry with
|
|
417
|
+
for i in warch._jac_entry_funcs_:
|
|
418
|
+
if (
|
|
419
|
+
i.func
|
|
420
|
+
and i.trigger
|
|
421
|
+
and all_issubclass(i.trigger, NodeArchitype)
|
|
422
|
+
and isinstance(current_node, i.trigger)
|
|
423
|
+
):
|
|
424
|
+
i.func(warch, current_node)
|
|
425
|
+
if walker.disengaged:
|
|
426
|
+
return warch
|
|
427
|
+
|
|
428
|
+
# node entry
|
|
412
429
|
for i in current_node._jac_entry_funcs_:
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
if i.func:
|
|
416
|
-
i.func(current_node, warch)
|
|
417
|
-
else:
|
|
418
|
-
raise ValueError(f"No function {i.name} to call.")
|
|
430
|
+
if i.func and not i.trigger:
|
|
431
|
+
i.func(current_node, warch)
|
|
419
432
|
if walker.disengaged:
|
|
420
433
|
return warch
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
434
|
+
|
|
435
|
+
# node entry with
|
|
436
|
+
for i in current_node._jac_entry_funcs_:
|
|
437
|
+
if (
|
|
438
|
+
i.func
|
|
439
|
+
and i.trigger
|
|
440
|
+
and all_issubclass(i.trigger, WalkerArchitype)
|
|
441
|
+
and isinstance(warch, i.trigger)
|
|
442
|
+
):
|
|
443
|
+
i.func(current_node, warch)
|
|
430
444
|
if walker.disengaged:
|
|
431
445
|
return warch
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
446
|
+
|
|
447
|
+
# node exit with
|
|
448
|
+
for i in current_node._jac_exit_funcs_:
|
|
449
|
+
if (
|
|
450
|
+
i.func
|
|
451
|
+
and i.trigger
|
|
452
|
+
and all_issubclass(i.trigger, WalkerArchitype)
|
|
453
|
+
and isinstance(warch, i.trigger)
|
|
454
|
+
):
|
|
455
|
+
i.func(current_node, warch)
|
|
441
456
|
if walker.disengaged:
|
|
442
457
|
return warch
|
|
458
|
+
|
|
459
|
+
# node exit
|
|
443
460
|
for i in current_node._jac_exit_funcs_:
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
if i.func:
|
|
447
|
-
i.func(current_node, warch)
|
|
448
|
-
else:
|
|
449
|
-
raise ValueError(f"No function {i.name} to call.")
|
|
461
|
+
if i.func and not i.trigger:
|
|
462
|
+
i.func(current_node, warch)
|
|
450
463
|
if walker.disengaged:
|
|
451
464
|
return warch
|
|
465
|
+
|
|
466
|
+
# walker exit with
|
|
467
|
+
for i in warch._jac_exit_funcs_:
|
|
468
|
+
if (
|
|
469
|
+
i.func
|
|
470
|
+
and i.trigger
|
|
471
|
+
and all_issubclass(i.trigger, NodeArchitype)
|
|
472
|
+
and isinstance(current_node, i.trigger)
|
|
473
|
+
):
|
|
474
|
+
i.func(warch, current_node)
|
|
475
|
+
if walker.disengaged:
|
|
476
|
+
return warch
|
|
477
|
+
# walker exit
|
|
452
478
|
for i in warch._jac_exit_funcs_:
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
raise ValueError(f"No function {i.name} to call.")
|
|
479
|
+
if i.func and not i.trigger:
|
|
480
|
+
i.func(warch, current_node)
|
|
481
|
+
if walker.disengaged:
|
|
482
|
+
return warch
|
|
483
|
+
|
|
459
484
|
walker.ignores = []
|
|
460
485
|
return warch
|
|
461
486
|
|
|
@@ -818,12 +843,14 @@ class JacFeatureImpl(
|
|
|
818
843
|
@hookimpl
|
|
819
844
|
def create_test(test_fun: Callable) -> Callable:
|
|
820
845
|
"""Create a new test."""
|
|
846
|
+
file_path = inspect.getfile(test_fun)
|
|
847
|
+
func_name = test_fun.__name__
|
|
821
848
|
|
|
822
849
|
def test_deco() -> None:
|
|
823
850
|
test_fun(JacTestCheck())
|
|
824
851
|
|
|
825
852
|
test_deco.__name__ = test_fun.__name__
|
|
826
|
-
JacTestCheck.add_test(test_deco)
|
|
853
|
+
JacTestCheck.add_test(file_path, func_name, test_deco)
|
|
827
854
|
|
|
828
855
|
return test_deco
|
|
829
856
|
|
|
@@ -831,6 +858,7 @@ class JacFeatureImpl(
|
|
|
831
858
|
@hookimpl
|
|
832
859
|
def run_test(
|
|
833
860
|
filepath: str,
|
|
861
|
+
func_name: Optional[str],
|
|
834
862
|
filter: Optional[str],
|
|
835
863
|
xit: bool,
|
|
836
864
|
maxfail: Optional[int],
|
|
@@ -849,7 +877,9 @@ class JacFeatureImpl(
|
|
|
849
877
|
mod_name = mod_name[:-5]
|
|
850
878
|
JacTestCheck.reset()
|
|
851
879
|
Jac.jac_import(target=mod_name, base_path=base, cachable=False)
|
|
852
|
-
JacTestCheck.run_test(
|
|
880
|
+
JacTestCheck.run_test(
|
|
881
|
+
xit, maxfail, verbose, os.path.abspath(filepath), func_name
|
|
882
|
+
)
|
|
853
883
|
ret_count = JacTestCheck.failcount
|
|
854
884
|
else:
|
|
855
885
|
print("Not a .jac file.")
|
|
@@ -875,7 +905,9 @@ class JacFeatureImpl(
|
|
|
875
905
|
print(f"\n\n\t\t* Inside {root_dir}" + "/" + f"{file} *")
|
|
876
906
|
JacTestCheck.reset()
|
|
877
907
|
Jac.jac_import(target=file[:-4], base_path=root_dir)
|
|
878
|
-
JacTestCheck.run_test(
|
|
908
|
+
JacTestCheck.run_test(
|
|
909
|
+
xit, maxfail, verbose, os.path.abspath(file), func_name
|
|
910
|
+
)
|
|
879
911
|
|
|
880
912
|
if JacTestCheck.breaker and (xit or maxfail):
|
|
881
913
|
break
|
jaclang/plugin/feature.py
CHANGED
|
@@ -359,6 +359,7 @@ class JacFeature(
|
|
|
359
359
|
@staticmethod
|
|
360
360
|
def run_test(
|
|
361
361
|
filepath: str,
|
|
362
|
+
func_name: Optional[str] = None,
|
|
362
363
|
filter: Optional[str] = None,
|
|
363
364
|
xit: bool = False,
|
|
364
365
|
maxfail: Optional[int] = None,
|
|
@@ -368,6 +369,7 @@ class JacFeature(
|
|
|
368
369
|
"""Run the test suite in the specified .jac file."""
|
|
369
370
|
return plugin_manager.hook.run_test(
|
|
370
371
|
filepath=filepath,
|
|
372
|
+
func_name=func_name,
|
|
371
373
|
filter=filter,
|
|
372
374
|
xit=xit,
|
|
373
375
|
maxfail=maxfail,
|
jaclang/plugin/spec.py
CHANGED
jaclang/runtimelib/architype.py
CHANGED
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import inspect
|
|
6
6
|
from dataclasses import asdict, dataclass, field, fields, is_dataclass
|
|
7
7
|
from enum import IntEnum
|
|
8
|
+
from functools import cached_property
|
|
8
9
|
from logging import getLogger
|
|
9
10
|
from pickle import dumps
|
|
10
11
|
from types import UnionType
|
|
@@ -220,9 +221,9 @@ class WalkerAnchor(Anchor):
|
|
|
220
221
|
"""Walker Anchor."""
|
|
221
222
|
|
|
222
223
|
architype: WalkerArchitype
|
|
223
|
-
path: list[
|
|
224
|
-
next: list[
|
|
225
|
-
ignores: list[
|
|
224
|
+
path: list[NodeAnchor] = field(default_factory=list)
|
|
225
|
+
next: list[NodeAnchor] = field(default_factory=list)
|
|
226
|
+
ignores: list[NodeAnchor] = field(default_factory=list)
|
|
226
227
|
disengaged: bool = False
|
|
227
228
|
|
|
228
229
|
|
|
@@ -311,17 +312,20 @@ class DSFunc:
|
|
|
311
312
|
name: str
|
|
312
313
|
func: Callable[[Any, Any], Any] | None = None
|
|
313
314
|
|
|
315
|
+
@cached_property
|
|
316
|
+
def trigger(self) -> type | UnionType | tuple[type | UnionType, ...] | None:
|
|
317
|
+
"""Get function parameter annotations."""
|
|
318
|
+
t = (
|
|
319
|
+
(
|
|
320
|
+
inspect.signature(self.func, eval_str=True)
|
|
321
|
+
.parameters["_jac_here_"]
|
|
322
|
+
.annotation
|
|
323
|
+
)
|
|
324
|
+
if self.func
|
|
325
|
+
else None
|
|
326
|
+
)
|
|
327
|
+
return None if t is inspect._empty else t
|
|
328
|
+
|
|
314
329
|
def resolve(self, cls: type) -> None:
|
|
315
330
|
"""Resolve the function."""
|
|
316
331
|
self.func = getattr(cls, self.name)
|
|
317
|
-
|
|
318
|
-
def get_funcparam_annotations(
|
|
319
|
-
self, func: Callable[[Any, Any], Any] | None
|
|
320
|
-
) -> type | UnionType | tuple[type | UnionType, ...] | None:
|
|
321
|
-
"""Get function parameter annotations."""
|
|
322
|
-
if not func:
|
|
323
|
-
return None
|
|
324
|
-
annotation = (
|
|
325
|
-
inspect.signature(func, eval_str=True).parameters["_jac_here_"].annotation
|
|
326
|
-
)
|
|
327
|
-
return annotation if annotation != inspect._empty else None
|
jaclang/runtimelib/test.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import unittest
|
|
6
|
+
from dataclasses import dataclass
|
|
6
7
|
from typing import Callable, Optional
|
|
7
8
|
|
|
8
9
|
|
|
@@ -56,6 +57,16 @@ class JacTestCheck:
|
|
|
56
57
|
|
|
57
58
|
test_case = unittest.TestCase()
|
|
58
59
|
test_suite = unittest.TestSuite()
|
|
60
|
+
|
|
61
|
+
@dataclass
|
|
62
|
+
class TestSuite:
|
|
63
|
+
"""Test Suite."""
|
|
64
|
+
|
|
65
|
+
test_case: unittest.FunctionTestCase
|
|
66
|
+
func_name: str
|
|
67
|
+
|
|
68
|
+
test_suite_path: dict[str, list[TestSuite]] = {}
|
|
69
|
+
|
|
59
70
|
breaker = False
|
|
60
71
|
failcount = 0
|
|
61
72
|
|
|
@@ -64,13 +75,45 @@ class JacTestCheck:
|
|
|
64
75
|
"""Clear the test suite."""
|
|
65
76
|
JacTestCheck.test_case = unittest.TestCase()
|
|
66
77
|
JacTestCheck.test_suite = unittest.TestSuite()
|
|
78
|
+
JacTestCheck.test_suite_path = {}
|
|
67
79
|
|
|
68
80
|
@staticmethod
|
|
69
|
-
def run_test(
|
|
81
|
+
def run_test(
|
|
82
|
+
xit: bool,
|
|
83
|
+
maxfail: int | None,
|
|
84
|
+
verbose: bool,
|
|
85
|
+
filepath: str | None,
|
|
86
|
+
func_name: str | None,
|
|
87
|
+
) -> None:
|
|
70
88
|
"""Run the test suite."""
|
|
71
89
|
verb = 2 if verbose else 1
|
|
90
|
+
test_suite = JacTestCheck.test_suite
|
|
91
|
+
|
|
92
|
+
if filepath and filepath.endswith(".test.jac"):
|
|
93
|
+
filepath = filepath[:-9]
|
|
94
|
+
elif filepath and filepath.endswith(".jac"):
|
|
95
|
+
filepath = filepath[:-4]
|
|
96
|
+
|
|
97
|
+
if filepath:
|
|
98
|
+
test_cases = JacTestCheck.test_suite_path.get(filepath)
|
|
99
|
+
if test_cases is not None:
|
|
100
|
+
test_suite = unittest.TestSuite()
|
|
101
|
+
for test_case in test_cases:
|
|
102
|
+
if func_name:
|
|
103
|
+
if test_case.func_name == func_name:
|
|
104
|
+
test_suite.addTest(test_case.test_case)
|
|
105
|
+
else:
|
|
106
|
+
test_suite.addTest(test_case.test_case)
|
|
107
|
+
|
|
108
|
+
elif func_name:
|
|
109
|
+
test_suite = unittest.TestSuite()
|
|
110
|
+
for test_cases in JacTestCheck.test_suite_path.values():
|
|
111
|
+
for test_case in test_cases:
|
|
112
|
+
if test_case.func_name == func_name:
|
|
113
|
+
test_suite.addTest(test_case.test_case)
|
|
114
|
+
|
|
72
115
|
runner = JacTextTestRunner(max_failures=maxfail, failfast=xit, verbosity=verb)
|
|
73
|
-
result = runner.run(
|
|
116
|
+
result = runner.run(test_suite)
|
|
74
117
|
if result.wasSuccessful():
|
|
75
118
|
print("Passed successfully.")
|
|
76
119
|
else:
|
|
@@ -81,9 +124,21 @@ class JacTestCheck:
|
|
|
81
124
|
)
|
|
82
125
|
|
|
83
126
|
@staticmethod
|
|
84
|
-
def add_test(
|
|
127
|
+
def add_test(filepath: str, func_name: str, test_func: Callable) -> None:
|
|
85
128
|
"""Create a new test."""
|
|
86
|
-
|
|
129
|
+
if filepath and filepath.endswith(".test.jac"):
|
|
130
|
+
filepath = filepath[:-9]
|
|
131
|
+
elif filepath and filepath.endswith(".jac"):
|
|
132
|
+
filepath = filepath[:-4]
|
|
133
|
+
|
|
134
|
+
if filepath not in JacTestCheck.test_suite_path:
|
|
135
|
+
JacTestCheck.test_suite_path[filepath] = []
|
|
136
|
+
|
|
137
|
+
test_case = unittest.FunctionTestCase(test_func)
|
|
138
|
+
JacTestCheck.test_suite_path[filepath].append(
|
|
139
|
+
JacTestCheck.TestSuite(test_case=test_case, func_name=func_name)
|
|
140
|
+
)
|
|
141
|
+
JacTestCheck.test_suite.addTest(test_case)
|
|
87
142
|
|
|
88
143
|
def __getattr__(self, name: str) -> object:
|
|
89
144
|
"""Make convenient check.Equal(...) etc."""
|
jaclang/runtimelib/utils.py
CHANGED
|
@@ -231,3 +231,18 @@ def is_instance(
|
|
|
231
231
|
return isinstance(obj, target)
|
|
232
232
|
case _:
|
|
233
233
|
return False
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def all_issubclass(
|
|
237
|
+
classes: type | UnionType | tuple[type | UnionType, ...], target: type
|
|
238
|
+
) -> bool:
|
|
239
|
+
"""Check if all classes is subclass of target type."""
|
|
240
|
+
match classes:
|
|
241
|
+
case type():
|
|
242
|
+
return issubclass(classes, target)
|
|
243
|
+
case UnionType():
|
|
244
|
+
return all((all_issubclass(cls, target) for cls in classes.__args__))
|
|
245
|
+
case tuple():
|
|
246
|
+
return all((all_issubclass(cls, target) for cls in classes))
|
|
247
|
+
case _:
|
|
248
|
+
return False
|
jaclang/settings.py
CHANGED
|
@@ -16,10 +16,13 @@ class Settings:
|
|
|
16
16
|
pass_timer: bool = False
|
|
17
17
|
collect_py_dep_debug: bool = False
|
|
18
18
|
print_py_raised_ast: bool = False
|
|
19
|
+
py_import_pass_debug: bool = False
|
|
20
|
+
inherit_pass_debug: bool = False
|
|
19
21
|
|
|
20
22
|
# Compiler configuration
|
|
21
23
|
disable_mtllm: bool = False
|
|
22
24
|
ignore_test_annex: bool = False
|
|
25
|
+
allow_import_from: bool = False
|
|
23
26
|
|
|
24
27
|
# Formatter configuration
|
|
25
28
|
max_line_length: int = 88
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import jactest_imported;
|
|
2
|
+
|
|
3
|
+
can fib(n: int) -> int {
|
|
4
|
+
if n <= 1 {
|
|
5
|
+
return n;
|
|
6
|
+
}
|
|
7
|
+
return fib(n - 1) + fib(n - 2);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
test first_two {
|
|
12
|
+
print("Testing first 2 fibonacci numbers.");
|
|
13
|
+
assert fib(0) == 0;
|
|
14
|
+
assert fib(1) == 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
test from_2_to_10 {
|
|
18
|
+
print("Testing fibonacci numbers from 2 to 10.");
|
|
19
|
+
for i in range(2, 10) {
|
|
20
|
+
assert fib(i) == fib(i - 1) + fib(i - 2);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import:py numpy as np;
|
|
2
|
-
|
|
3
1
|
with entry {
|
|
4
|
-
arr =
|
|
5
|
-
[[1, 2, 3, 4, 5],
|
|
2
|
+
arr = [[1, 2, 3, 4, 5],
|
|
6
3
|
[6, 7, 8, 9, 10],
|
|
7
4
|
[11, 12, 13, 14, 15],
|
|
8
5
|
[16, 17, 18, 19, 20],
|
|
9
|
-
[21, 22, 23, 24, 25]]
|
|
10
|
-
);
|
|
6
|
+
[21, 22, 23, 24, 25]];
|
|
11
7
|
|
|
12
8
|
print('Original Array:');
|
|
13
9
|
print(arr);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
node Node {
|
|
2
|
+
has val: str;
|
|
3
|
+
|
|
4
|
+
can entry1 with entry {
|
|
5
|
+
print(f"{self.val}-2");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
can entry2 with Walker entry {
|
|
9
|
+
print(f"{self.val}-3");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
can exit1 with Walker exit {
|
|
13
|
+
print(f"{self.val}-4");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
can exit2 with exit {
|
|
17
|
+
print(f"{self.val}-5");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
walker Walker {
|
|
22
|
+
can entry1 with entry {
|
|
23
|
+
print("walker entry");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
can entry2 with `root entry {
|
|
27
|
+
print("walker enter to root");
|
|
28
|
+
visit [-->];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
can entry3 with Node entry {
|
|
32
|
+
print(f"{here.val}-1");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
can exit1 with Node exit {
|
|
36
|
+
print(f"{here.val}-6");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
can exit2 with exit {
|
|
40
|
+
print("walker exit");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
with entry{
|
|
45
|
+
root ++> Node(val = "a");
|
|
46
|
+
root ++> Node(val = "b");
|
|
47
|
+
root ++> Node(val = "c");
|
|
48
|
+
|
|
49
|
+
Walker() spawn root;
|
|
50
|
+
}
|
jaclang/tests/test_cli.py
CHANGED
|
@@ -233,6 +233,67 @@ class JacCliTests(TestCase):
|
|
|
233
233
|
r"13\:12 \- 13\:18.*Name - append - .*SymbolPath: builtins_test.builtins.list.append",
|
|
234
234
|
)
|
|
235
235
|
|
|
236
|
+
def test_import_all(self) -> None:
|
|
237
|
+
"""Testing for print AstTool."""
|
|
238
|
+
from jaclang.settings import settings
|
|
239
|
+
|
|
240
|
+
settings.ast_symbol_info_detailed = True
|
|
241
|
+
captured_output = io.StringIO()
|
|
242
|
+
sys.stdout = captured_output
|
|
243
|
+
|
|
244
|
+
cli.tool("ir", ["ast", f"{self.fixture_abs_path('import_all.jac')}"])
|
|
245
|
+
|
|
246
|
+
sys.stdout = sys.__stdout__
|
|
247
|
+
stdout_value = captured_output.getvalue()
|
|
248
|
+
settings.ast_symbol_info_detailed = False
|
|
249
|
+
|
|
250
|
+
self.assertRegex(
|
|
251
|
+
stdout_value,
|
|
252
|
+
r"6\:25 - 6\:30.*Name - floor -.*SymbolPath: import_all.import_all_py.floor",
|
|
253
|
+
)
|
|
254
|
+
self.assertRegex(
|
|
255
|
+
stdout_value,
|
|
256
|
+
r"5\:25 - 5\:27.*Name - pi -.*SymbolPath: import_all.import_all_py.pi",
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def test_sub_class_symbol_table_fix_1(self) -> None:
|
|
260
|
+
"""Testing for print AstTool."""
|
|
261
|
+
from jaclang.settings import settings
|
|
262
|
+
|
|
263
|
+
settings.ast_symbol_info_detailed = True
|
|
264
|
+
captured_output = io.StringIO()
|
|
265
|
+
sys.stdout = captured_output
|
|
266
|
+
|
|
267
|
+
cli.tool("ir", ["ast", f"{self.fixture_abs_path('base_class1.jac')}"])
|
|
268
|
+
|
|
269
|
+
sys.stdout = sys.__stdout__
|
|
270
|
+
stdout_value = captured_output.getvalue()
|
|
271
|
+
settings.ast_symbol_info_detailed = False
|
|
272
|
+
|
|
273
|
+
self.assertRegex(
|
|
274
|
+
stdout_value,
|
|
275
|
+
r"10:7 - 10:12.*Name - start - Type.*SymbolPath: base_class1.B.start",
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
def test_sub_class_symbol_table_fix_2(self) -> None:
|
|
279
|
+
"""Testing for print AstTool."""
|
|
280
|
+
from jaclang.settings import settings
|
|
281
|
+
|
|
282
|
+
settings.ast_symbol_info_detailed = True
|
|
283
|
+
captured_output = io.StringIO()
|
|
284
|
+
sys.stdout = captured_output
|
|
285
|
+
|
|
286
|
+
cli.tool("ir", ["ast", f"{self.fixture_abs_path('base_class2.jac')}"])
|
|
287
|
+
|
|
288
|
+
sys.stdout = sys.__stdout__
|
|
289
|
+
stdout_value = captured_output.getvalue()
|
|
290
|
+
settings.ast_symbol_info_detailed = False
|
|
291
|
+
|
|
292
|
+
self.assertRegex(
|
|
293
|
+
stdout_value,
|
|
294
|
+
r"10:7 - 10:12.*Name - start - Type.*SymbolPath: base_class2.B.start",
|
|
295
|
+
)
|
|
296
|
+
|
|
236
297
|
def test_expr_types(self) -> None:
|
|
237
298
|
"""Testing for print AstTool."""
|
|
238
299
|
captured_output = io.StringIO()
|
|
@@ -393,6 +454,27 @@ class JacCliTests(TestCase):
|
|
|
393
454
|
self.assertIn("...F", stderr)
|
|
394
455
|
self.assertIn("F.F", stderr)
|
|
395
456
|
|
|
457
|
+
def test_run_specific_test_only(self) -> None:
|
|
458
|
+
"""Test a specific test case."""
|
|
459
|
+
process = subprocess.Popen(
|
|
460
|
+
[
|
|
461
|
+
"jac",
|
|
462
|
+
"test",
|
|
463
|
+
"-t",
|
|
464
|
+
"from_2_to_10",
|
|
465
|
+
self.fixture_abs_path("jactest_main.jac"),
|
|
466
|
+
],
|
|
467
|
+
stdin=subprocess.PIPE,
|
|
468
|
+
stdout=subprocess.PIPE,
|
|
469
|
+
stderr=subprocess.PIPE,
|
|
470
|
+
text=True,
|
|
471
|
+
)
|
|
472
|
+
stdout, stderr = process.communicate()
|
|
473
|
+
self.assertIn("Ran 1 test", stderr)
|
|
474
|
+
self.assertIn("Testing fibonacci numbers from 2 to 10.", stdout)
|
|
475
|
+
self.assertNotIn("Testing first 2 fibonacci numbers.", stdout)
|
|
476
|
+
self.assertNotIn("This test should not run after import.", stdout)
|
|
477
|
+
|
|
396
478
|
def test_graph_coverage(self) -> None:
|
|
397
479
|
"""Test for coverage of graph cmd."""
|
|
398
480
|
graph_params = set(inspect.signature(cli.dot).parameters.keys())
|