jaclang 0.6.5__py3-none-any.whl → 0.7.1__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/compiler/absyntree.py +4 -36
- jaclang/compiler/compile.py +21 -0
- jaclang/compiler/parser.py +13 -4
- jaclang/compiler/passes/main/__init__.py +2 -2
- jaclang/compiler/passes/main/def_impl_match_pass.py +1 -5
- jaclang/compiler/passes/main/def_use_pass.py +14 -7
- jaclang/compiler/passes/main/import_pass.py +56 -10
- jaclang/compiler/passes/main/pyast_gen_pass.py +55 -2
- jaclang/compiler/passes/main/schedules.py +4 -3
- jaclang/compiler/passes/main/tests/fixtures/incautoimpl.jac +7 -0
- jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +4 -4
- jaclang/compiler/passes/main/tests/test_import_pass.py +13 -0
- jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -2
- jaclang/compiler/passes/transform.py +13 -4
- jaclang/compiler/tests/fixtures/mod_doc_test.jac +3 -1
- jaclang/langserve/engine.py +375 -0
- jaclang/langserve/server.py +112 -74
- jaclang/langserve/tests/fixtures/circle.jac +73 -0
- jaclang/langserve/tests/fixtures/circle_err.jac +73 -0
- jaclang/langserve/tests/fixtures/circle_pure.impl.jac +28 -0
- jaclang/langserve/tests/fixtures/circle_pure.jac +34 -0
- jaclang/langserve/tests/fixtures/circle_pure_err.impl.jac +32 -0
- jaclang/langserve/tests/fixtures/circle_pure_err.jac +34 -0
- jaclang/langserve/tests/test_server.py +33 -1
- jaclang/langserve/utils.py +53 -16
- jaclang/plugin/default.py +1 -1
- jaclang/tests/fixtures/type_info.jac +1 -1
- jaclang/tests/test_cli.py +1 -1
- jaclang/utils/helpers.py +3 -5
- jaclang/utils/test.py +1 -1
- {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/METADATA +8 -16
- {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/RECORD +34 -28
- jaclang/compiler/tests/test_workspace.py +0 -93
- jaclang/compiler/workspace.py +0 -234
- {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/WHEEL +0 -0
- {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
"""Tests for Jac Workspace."""
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
|
|
5
|
-
from jaclang.compiler.workspace import Workspace
|
|
6
|
-
from jaclang.utils.test import TestCase
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TestWorkspace(TestCase):
|
|
10
|
-
"""Test Jac Workspace."""
|
|
11
|
-
|
|
12
|
-
def test_workspace_basic(self) -> None:
|
|
13
|
-
"""Basic test of functionarlity."""
|
|
14
|
-
ws = Workspace(path=os.path.join(os.path.dirname(__file__)))
|
|
15
|
-
self.assertGreater(len(ws.modules.keys()), 4)
|
|
16
|
-
|
|
17
|
-
def test_dependecies_basic(self) -> None:
|
|
18
|
-
"""Basic test of functionarlity."""
|
|
19
|
-
ws = Workspace(path=os.path.join(os.path.dirname(__file__)))
|
|
20
|
-
key = [i for i in ws.modules.keys() if "fam.jac" in i][0]
|
|
21
|
-
self.assertGreater(len(ws.get_dependencies(key)), 0)
|
|
22
|
-
|
|
23
|
-
def test_symbols_basic(self) -> None:
|
|
24
|
-
"""Basic test of functionarlity."""
|
|
25
|
-
ws = Workspace(path=os.path.join(os.path.dirname(__file__)))
|
|
26
|
-
key = [i for i in ws.modules.keys() if "fam.jac" in i][0]
|
|
27
|
-
self.assertGreater(len(ws.get_symbols(key)), 5)
|
|
28
|
-
|
|
29
|
-
def test_get_defs_basic(self) -> None:
|
|
30
|
-
"""Basic test of functionarlity."""
|
|
31
|
-
ws = Workspace(path=os.path.join(os.path.dirname(__file__)))
|
|
32
|
-
key = [i for i in ws.modules.keys() if "fam.jac" in i][0]
|
|
33
|
-
self.assertGreater(len(ws.get_definitions(key)), 5)
|
|
34
|
-
|
|
35
|
-
def test_get_uses_basic(self) -> None:
|
|
36
|
-
"""Basic test of functionarlity."""
|
|
37
|
-
ws = Workspace(path=os.path.join(os.path.dirname(__file__)))
|
|
38
|
-
key = [i for i in ws.modules.keys() if "fam.jac" in i][0]
|
|
39
|
-
self.assertGreater(len(ws.get_uses(key)), 5)
|
|
40
|
-
|
|
41
|
-
def test_man_code_dir(self) -> None:
|
|
42
|
-
"""Test of circle workspace."""
|
|
43
|
-
loc = os.path.join(os.path.dirname(__file__))
|
|
44
|
-
ws = Workspace(path=loc + "/../../../examples/manual_code")
|
|
45
|
-
key = [i for i in ws.modules.keys() if "circle.jac" in i][0]
|
|
46
|
-
# print(ws.modules[key].ir.sym_tab.pp())
|
|
47
|
-
# for i in ws.get_symbols(key):
|
|
48
|
-
# print(i.decl.pp(depth=2))
|
|
49
|
-
out = ""
|
|
50
|
-
for i in ws.get_uses(key):
|
|
51
|
-
# print(i.pp(depth=2).strip())
|
|
52
|
-
out += i.pp(depth=2)
|
|
53
|
-
for i in [
|
|
54
|
-
"math",
|
|
55
|
-
"calculate_area",
|
|
56
|
-
"RAD",
|
|
57
|
-
"expected_area",
|
|
58
|
-
"Circle",
|
|
59
|
-
"c",
|
|
60
|
-
"ShapeType",
|
|
61
|
-
"float",
|
|
62
|
-
"radius",
|
|
63
|
-
"CIRCLE",
|
|
64
|
-
"Shape",
|
|
65
|
-
"__init__",
|
|
66
|
-
"print",
|
|
67
|
-
]:
|
|
68
|
-
self.assertIn(i, out)
|
|
69
|
-
|
|
70
|
-
# def test_decl_impl(self) -> None:
|
|
71
|
-
# """Test of circle workspace."""
|
|
72
|
-
# loc = os.path.join(os.path.dirname(__file__))
|
|
73
|
-
# ws = Workspace(path=loc + "/../../../examples/manual_code")
|
|
74
|
-
# key = [i for i in ws.modules.keys() if "circle_clean.jac" in i][0]
|
|
75
|
-
# out = ""
|
|
76
|
-
# for i in ws.get_uses(key):
|
|
77
|
-
# out += i.pp(depth=2)
|
|
78
|
-
# for i in [
|
|
79
|
-
# "math",
|
|
80
|
-
# "calculate_area",
|
|
81
|
-
# "RAD",
|
|
82
|
-
# "expected_area",
|
|
83
|
-
# "Circle",
|
|
84
|
-
# "c",
|
|
85
|
-
# "ShapeType",
|
|
86
|
-
# "float",
|
|
87
|
-
# "radius",
|
|
88
|
-
# "CIRCLE",
|
|
89
|
-
# "Shape",
|
|
90
|
-
# "__init__",
|
|
91
|
-
# "print",
|
|
92
|
-
# ]:
|
|
93
|
-
# self.assertIn(i, out)
|
jaclang/compiler/workspace.py
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
"""Living Workspace of Jac project."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
from typing import Optional, Sequence
|
|
7
|
-
|
|
8
|
-
import jaclang.compiler.absyntree as ast
|
|
9
|
-
from jaclang.compiler.compile import jac_str_to_pass
|
|
10
|
-
from jaclang.compiler.passes.main import DefUsePass, schedules
|
|
11
|
-
from jaclang.compiler.passes.transform import Alert
|
|
12
|
-
from jaclang.compiler.symtable import Symbol, SymbolTable
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def sym_tab_list(sym_tab: SymbolTable, file_path: str) -> Sequence[SymbolTable]:
|
|
16
|
-
"""Iterate through symbol table."""
|
|
17
|
-
sym_tabs = (
|
|
18
|
-
[sym_tab]
|
|
19
|
-
if not (
|
|
20
|
-
isinstance(sym_tab.owner, ast.Module)
|
|
21
|
-
and sym_tab.owner.loc.mod_path != file_path
|
|
22
|
-
)
|
|
23
|
-
else []
|
|
24
|
-
)
|
|
25
|
-
for i in sym_tab.kid:
|
|
26
|
-
sym_tabs += sym_tab_list(i, file_path=file_path)
|
|
27
|
-
return sym_tabs
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class ModuleInfo:
|
|
31
|
-
"""Module IR and Stats."""
|
|
32
|
-
|
|
33
|
-
def __init__(
|
|
34
|
-
self,
|
|
35
|
-
ir: Optional[ast.Module],
|
|
36
|
-
errors: Sequence[Alert],
|
|
37
|
-
warnings: Sequence[Alert],
|
|
38
|
-
) -> None:
|
|
39
|
-
"""Initialize module info."""
|
|
40
|
-
self.ir = ir
|
|
41
|
-
self.errors = errors
|
|
42
|
-
self.warnings = warnings
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class Workspace:
|
|
46
|
-
"""Class for managing workspace."""
|
|
47
|
-
|
|
48
|
-
def __init__(
|
|
49
|
-
self, path: str, lazy_parse: bool = False, type_check: bool = False
|
|
50
|
-
) -> None:
|
|
51
|
-
"""Initialize workspace."""
|
|
52
|
-
self.path = path
|
|
53
|
-
self.modules: dict[str, ModuleInfo] = {}
|
|
54
|
-
self.lazy_parse = lazy_parse
|
|
55
|
-
self.type_check = type_check
|
|
56
|
-
self.rebuild_workspace()
|
|
57
|
-
|
|
58
|
-
def rebuild_workspace(self) -> None:
|
|
59
|
-
"""Rebuild workspace."""
|
|
60
|
-
self.modules = {}
|
|
61
|
-
for file in [
|
|
62
|
-
os.path.normpath(os.path.join(root, name))
|
|
63
|
-
for root, _, files in os.walk(self.path)
|
|
64
|
-
for name in files
|
|
65
|
-
if name.endswith(".jac")
|
|
66
|
-
]:
|
|
67
|
-
if file in self.modules:
|
|
68
|
-
continue
|
|
69
|
-
if self.lazy_parse:
|
|
70
|
-
# If lazy_parse is True, add the file to modules with empty IR
|
|
71
|
-
self.modules[file] = ModuleInfo(
|
|
72
|
-
ir=None,
|
|
73
|
-
errors=[],
|
|
74
|
-
warnings=[],
|
|
75
|
-
)
|
|
76
|
-
continue
|
|
77
|
-
|
|
78
|
-
with open(file, "r") as f:
|
|
79
|
-
source = f.read()
|
|
80
|
-
build = jac_str_to_pass(
|
|
81
|
-
jac_str=source,
|
|
82
|
-
file_path=file,
|
|
83
|
-
schedule=(
|
|
84
|
-
schedules.py_code_gen_typed
|
|
85
|
-
if self.type_check
|
|
86
|
-
else schedules.py_code_gen
|
|
87
|
-
),
|
|
88
|
-
target=DefUsePass if not self.type_check else None,
|
|
89
|
-
)
|
|
90
|
-
if not isinstance(build.ir, ast.Module):
|
|
91
|
-
src = ast.JacSource(source, mod_path=file)
|
|
92
|
-
self.modules[file] = ModuleInfo(
|
|
93
|
-
ir=ast.Module(
|
|
94
|
-
name="",
|
|
95
|
-
doc=None,
|
|
96
|
-
body=[],
|
|
97
|
-
source=src,
|
|
98
|
-
is_imported=False,
|
|
99
|
-
kid=[src],
|
|
100
|
-
),
|
|
101
|
-
errors=build.errors_had,
|
|
102
|
-
warnings=build.warnings_had,
|
|
103
|
-
)
|
|
104
|
-
continue
|
|
105
|
-
self.modules[file] = ModuleInfo(
|
|
106
|
-
ir=build.ir,
|
|
107
|
-
errors=build.errors_had,
|
|
108
|
-
warnings=build.warnings_had,
|
|
109
|
-
)
|
|
110
|
-
if build.ir:
|
|
111
|
-
for sub in build.ir.mod_deps:
|
|
112
|
-
self.modules[sub] = ModuleInfo(
|
|
113
|
-
ir=build.ir.mod_deps[sub],
|
|
114
|
-
errors=build.errors_had,
|
|
115
|
-
warnings=build.warnings_had,
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
def rebuild_file(
|
|
119
|
-
self, file_path: str, deep: bool = False, source: str = ""
|
|
120
|
-
) -> bool:
|
|
121
|
-
"""Rebuild a file."""
|
|
122
|
-
if source == "":
|
|
123
|
-
with open(file_path, "r") as f:
|
|
124
|
-
source = f.read()
|
|
125
|
-
build = jac_str_to_pass(
|
|
126
|
-
jac_str=source,
|
|
127
|
-
file_path=file_path,
|
|
128
|
-
schedule=(
|
|
129
|
-
schedules.py_code_gen_typed
|
|
130
|
-
if self.type_check
|
|
131
|
-
else schedules.py_code_gen
|
|
132
|
-
),
|
|
133
|
-
target=DefUsePass if not self.type_check else None,
|
|
134
|
-
)
|
|
135
|
-
if not isinstance(build.ir, ast.Module):
|
|
136
|
-
src = ast.JacSource(source, mod_path=file_path)
|
|
137
|
-
self.modules[file_path] = ModuleInfo(
|
|
138
|
-
ir=ast.Module(
|
|
139
|
-
name="",
|
|
140
|
-
doc=None,
|
|
141
|
-
body=[],
|
|
142
|
-
source=src,
|
|
143
|
-
is_imported=False,
|
|
144
|
-
kid=[src],
|
|
145
|
-
),
|
|
146
|
-
errors=build.errors_had,
|
|
147
|
-
warnings=build.warnings_had,
|
|
148
|
-
)
|
|
149
|
-
return False
|
|
150
|
-
self.modules[file_path] = ModuleInfo(
|
|
151
|
-
ir=build.ir,
|
|
152
|
-
errors=build.errors_had,
|
|
153
|
-
warnings=build.warnings_had,
|
|
154
|
-
)
|
|
155
|
-
if deep:
|
|
156
|
-
for sub in build.ir.mod_deps:
|
|
157
|
-
self.modules[sub] = ModuleInfo(
|
|
158
|
-
ir=build.ir.mod_deps[sub],
|
|
159
|
-
errors=build.errors_had,
|
|
160
|
-
warnings=build.warnings_had,
|
|
161
|
-
)
|
|
162
|
-
return True
|
|
163
|
-
|
|
164
|
-
def add_file(self, file_path: str) -> None:
|
|
165
|
-
"""Add a file to the workspace."""
|
|
166
|
-
self.rebuild_file(file_path)
|
|
167
|
-
|
|
168
|
-
def del_file(self, file_path: str) -> None:
|
|
169
|
-
"""Delete a file from the workspace."""
|
|
170
|
-
del self.modules[file_path]
|
|
171
|
-
|
|
172
|
-
def file_list(self) -> Sequence[str]:
|
|
173
|
-
"""Return a list of files in the workspace."""
|
|
174
|
-
return list(self.modules.keys())
|
|
175
|
-
|
|
176
|
-
def get_dependencies(
|
|
177
|
-
self, file_path: str, deep: bool = False
|
|
178
|
-
) -> list[ast.ModulePath]:
|
|
179
|
-
"""Return a list of dependencies for a file."""
|
|
180
|
-
mod_ir = self.modules[file_path].ir
|
|
181
|
-
if deep:
|
|
182
|
-
return (
|
|
183
|
-
[
|
|
184
|
-
i
|
|
185
|
-
for i in mod_ir.get_all_sub_nodes(ast.ModulePath)
|
|
186
|
-
if i.parent_of_type(ast.Import).hint.tag.value == "jac"
|
|
187
|
-
]
|
|
188
|
-
if mod_ir
|
|
189
|
-
else []
|
|
190
|
-
)
|
|
191
|
-
else:
|
|
192
|
-
return (
|
|
193
|
-
[
|
|
194
|
-
i
|
|
195
|
-
for i in mod_ir.get_all_sub_nodes(ast.ModulePath)
|
|
196
|
-
if i.loc.mod_path == file_path
|
|
197
|
-
and i.parent_of_type(ast.Import).hint.tag.value == "jac"
|
|
198
|
-
]
|
|
199
|
-
if mod_ir
|
|
200
|
-
else []
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
def get_symbols(self, file_path: str) -> Sequence[Symbol]:
|
|
204
|
-
"""Return a list of symbols for a file."""
|
|
205
|
-
symbols = []
|
|
206
|
-
mod_ir = self.modules[file_path].ir
|
|
207
|
-
if file_path in self.modules:
|
|
208
|
-
root_table = mod_ir.sym_tab if mod_ir else None
|
|
209
|
-
if file_path in self.modules and root_table:
|
|
210
|
-
for i in sym_tab_list(sym_tab=root_table, file_path=file_path):
|
|
211
|
-
symbols += list(i.tab.values())
|
|
212
|
-
return symbols
|
|
213
|
-
|
|
214
|
-
def get_definitions(
|
|
215
|
-
self, file_path: str
|
|
216
|
-
) -> Sequence[ast.AstSymbolNode]: # need test
|
|
217
|
-
"""Return a list of definitions for a file."""
|
|
218
|
-
defs = []
|
|
219
|
-
for i in self.get_symbols(file_path):
|
|
220
|
-
defs += i.defn
|
|
221
|
-
return defs
|
|
222
|
-
|
|
223
|
-
def get_uses(self, file_path: str) -> Sequence[ast.AstSymbolNode]: # need test
|
|
224
|
-
"""Return a list of definitions for a file."""
|
|
225
|
-
mod_ir = self.modules[file_path].ir
|
|
226
|
-
uses: list[ast.AstSymbolNode] = []
|
|
227
|
-
if self.lazy_parse:
|
|
228
|
-
return uses
|
|
229
|
-
if file_path in self.modules:
|
|
230
|
-
root_table = mod_ir.sym_tab if mod_ir else None
|
|
231
|
-
if file_path in self.modules and root_table:
|
|
232
|
-
for i in sym_tab_list(sym_tab=root_table, file_path=file_path):
|
|
233
|
-
uses += i.uses
|
|
234
|
-
return uses
|
|
File without changes
|
|
File without changes
|