jaclang 0.8.9__py3-none-any.whl → 0.8.10__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 -25
- jaclang/cli/cmdreg.py +144 -8
- jaclang/compiler/__init__.py +6 -1
- jaclang/compiler/codeinfo.py +16 -1
- jaclang/compiler/constant.py +33 -13
- jaclang/compiler/jac.lark +130 -31
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +567 -176
- jaclang/compiler/passes/__init__.py +2 -1
- jaclang/compiler/passes/ast_gen/__init__.py +5 -0
- jaclang/compiler/passes/ast_gen/base_ast_gen_pass.py +54 -0
- jaclang/compiler/passes/ast_gen/jsx_processor.py +344 -0
- jaclang/compiler/passes/ecmascript/__init__.py +25 -0
- jaclang/compiler/passes/ecmascript/es_unparse.py +576 -0
- jaclang/compiler/passes/ecmascript/esast_gen_pass.py +2068 -0
- jaclang/compiler/passes/ecmascript/estree.py +972 -0
- jaclang/compiler/passes/ecmascript/tests/__init__.py +1 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/advanced_language_features.jac +170 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.impl.jac +30 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.jac +14 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/client_jsx.jac +89 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/core_language_features.jac +195 -0
- jaclang/compiler/passes/ecmascript/tests/test_esast_gen_pass.py +167 -0
- jaclang/compiler/passes/ecmascript/tests/test_js_generation.py +239 -0
- jaclang/compiler/passes/main/__init__.py +0 -3
- jaclang/compiler/passes/main/annex_pass.py +23 -1
- jaclang/compiler/passes/main/pyast_gen_pass.py +324 -234
- jaclang/compiler/passes/main/pyast_load_pass.py +46 -11
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +2 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +18 -1
- jaclang/compiler/passes/main/tests/fixtures/autoimpl.cl.jac +7 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_arity.jac +3 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_class_construct.jac +33 -0
- jaclang/compiler/passes/main/tests/fixtures/defuse_modpath.jac +7 -0
- jaclang/compiler/passes/main/tests/fixtures/member_access_type_resolve.jac +2 -1
- jaclang/compiler/passes/main/tests/test_checker_pass.py +31 -2
- jaclang/compiler/passes/main/tests/test_def_use_pass.py +12 -0
- jaclang/compiler/passes/main/tests/test_import_pass.py +23 -4
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +25 -0
- jaclang/compiler/passes/main/type_checker_pass.py +7 -0
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +115 -0
- jaclang/compiler/passes/tool/fuse_comments_pass.py +1 -10
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +4 -1
- jaclang/compiler/passes/transform.py +9 -1
- jaclang/compiler/passes/uni_pass.py +5 -7
- jaclang/compiler/program.py +22 -25
- jaclang/compiler/tests/test_client_codegen.py +113 -0
- jaclang/compiler/tests/test_importer.py +12 -10
- jaclang/compiler/tests/test_parser.py +249 -3
- jaclang/compiler/type_system/type_evaluator.jac +169 -50
- jaclang/compiler/type_system/type_utils.py +1 -1
- jaclang/compiler/type_system/types.py +6 -0
- jaclang/compiler/unitree.py +430 -84
- jaclang/langserve/engine.jac +224 -288
- jaclang/langserve/sem_manager.jac +12 -8
- jaclang/langserve/server.jac +48 -48
- jaclang/langserve/tests/fixtures/greet.py +17 -0
- jaclang/langserve/tests/fixtures/md_path.jac +22 -0
- jaclang/langserve/tests/fixtures/user.jac +15 -0
- jaclang/langserve/tests/test_server.py +66 -371
- jaclang/lib.py +1 -1
- jaclang/runtimelib/client_bundle.py +169 -0
- jaclang/runtimelib/client_runtime.jac +586 -0
- jaclang/runtimelib/constructs.py +2 -0
- jaclang/runtimelib/machine.py +259 -100
- jaclang/runtimelib/meta_importer.py +111 -22
- jaclang/runtimelib/mtp.py +15 -0
- jaclang/runtimelib/server.py +1089 -0
- jaclang/runtimelib/tests/fixtures/client_app.jac +18 -0
- jaclang/runtimelib/tests/fixtures/custom_access_validation.jac +1 -1
- jaclang/runtimelib/tests/fixtures/savable_object.jac +4 -5
- jaclang/runtimelib/tests/fixtures/serve_api.jac +75 -0
- jaclang/runtimelib/tests/test_client_bundle.py +55 -0
- jaclang/runtimelib/tests/test_client_render.py +63 -0
- jaclang/runtimelib/tests/test_serve.py +1069 -0
- jaclang/settings.py +0 -2
- jaclang/tests/fixtures/iife_functions.jac +142 -0
- jaclang/tests/fixtures/iife_functions_client.jac +143 -0
- jaclang/tests/fixtures/multistatement_lambda.jac +116 -0
- jaclang/tests/fixtures/multistatement_lambda_client.jac +113 -0
- jaclang/tests/fixtures/needs_import_dup.jac +6 -4
- jaclang/tests/fixtures/py_run.py +7 -5
- jaclang/tests/fixtures/pyfunc_fstr.py +2 -2
- jaclang/tests/fixtures/simple_lambda_test.jac +12 -0
- jaclang/tests/test_cli.py +1 -1
- jaclang/tests/test_language.py +10 -39
- jaclang/tests/test_reference.py +17 -2
- jaclang/utils/NonGPT.py +375 -0
- jaclang/utils/helpers.py +44 -16
- jaclang/utils/lang_tools.py +31 -4
- jaclang/utils/tests/test_lang_tools.py +1 -1
- jaclang/utils/treeprinter.py +8 -3
- {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/METADATA +3 -3
- {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/RECORD +96 -66
- jaclang/compiler/passes/main/binder_pass.py +0 -594
- jaclang/compiler/passes/main/tests/fixtures/sym_binder.jac +0 -47
- jaclang/compiler/passes/main/tests/test_binder_pass.py +0 -111
- jaclang/langserve/tests/session.jac +0 -294
- jaclang/langserve/tests/test_dev_server.py +0 -80
- jaclang/runtimelib/importer.py +0 -351
- jaclang/tests/test_typecheck.py +0 -542
- {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/WHEEL +0 -0
- {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/entry_points.txt +0 -0
|
@@ -7,41 +7,10 @@ import lsprotocol.types as lspt
|
|
|
7
7
|
import pytest
|
|
8
8
|
from jaclang import JacMachineInterface as _
|
|
9
9
|
from jaclang.langserve.engine import JacLangServer
|
|
10
|
-
from .session import LspSession
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class TestJacLangServer(TestCase):
|
|
14
13
|
|
|
15
|
-
def test_formatting(self) -> None:
|
|
16
|
-
with LspSession() as s:
|
|
17
|
-
s.initialize()
|
|
18
|
-
with open(self.fixture_abs_path("hello.jac"), "w") as f:
|
|
19
|
-
f.write('with entry {print("Hello, World!");}')
|
|
20
|
-
with open(self.fixture_abs_path("hello.jac"), "r") as f:
|
|
21
|
-
self.assertEqual(f.read(), 'with entry {print("Hello, World!");}')
|
|
22
|
-
params_json = {
|
|
23
|
-
"textDocument": {
|
|
24
|
-
"uri": uris.from_fs_path(self.fixture_abs_path("hello.jac")),
|
|
25
|
-
"languageId": "jac",
|
|
26
|
-
"version": 1,
|
|
27
|
-
"text": "with entry {print('Hello, World!');}",
|
|
28
|
-
},
|
|
29
|
-
"options": {"tabSize": 4, "insertSpaces": True},
|
|
30
|
-
}
|
|
31
|
-
text_edits = s.text_document_formatting(params_json)
|
|
32
|
-
self.assertEqual(
|
|
33
|
-
text_edits,
|
|
34
|
-
[
|
|
35
|
-
{
|
|
36
|
-
"range": {
|
|
37
|
-
"start": {"line": 0, "character": 0},
|
|
38
|
-
"end": {"line": 2, "character": 0},
|
|
39
|
-
},
|
|
40
|
-
"newText": 'with entry {\n print("Hello, World!");\n}\n',
|
|
41
|
-
}
|
|
42
|
-
],
|
|
43
|
-
)
|
|
44
|
-
|
|
45
14
|
def test_impl_stay_connected(self) -> None:
|
|
46
15
|
"""Test that the server doesn't run if there is a syntax error."""
|
|
47
16
|
lsp = JacLangServer()
|
|
@@ -53,17 +22,17 @@ class TestJacLangServer(TestCase):
|
|
|
53
22
|
circle_impl_file = uris.from_fs_path(
|
|
54
23
|
self.fixture_abs_path("circle_pure.impl.jac")
|
|
55
24
|
)
|
|
56
|
-
lsp.
|
|
25
|
+
lsp.type_check_file(circle_file)
|
|
57
26
|
pos = lspt.Position(20, 8)
|
|
58
27
|
self.assertIn(
|
|
59
28
|
"Circle class inherits from Shape.",
|
|
60
29
|
lsp.get_hover_info(circle_file, pos).contents.value,
|
|
61
30
|
)
|
|
62
|
-
lsp.
|
|
31
|
+
lsp.type_check_file(circle_impl_file)
|
|
63
32
|
pos = lspt.Position(8, 11)
|
|
64
33
|
self.assertIn(
|
|
65
34
|
# "ability) calculate_area: float",
|
|
66
|
-
"ability) calculate_area
|
|
35
|
+
"ability) calculate_area\\n( radius : float ) -> float",
|
|
67
36
|
lsp.get_hover_info(circle_impl_file, pos).contents.value.replace("'", ""),
|
|
68
37
|
)
|
|
69
38
|
|
|
@@ -77,30 +46,14 @@ class TestJacLangServer(TestCase):
|
|
|
77
46
|
circle_impl_file = uris.from_fs_path(
|
|
78
47
|
self.fixture_abs_path("circle_pure.impl.jac")
|
|
79
48
|
)
|
|
80
|
-
lsp.
|
|
49
|
+
lsp.type_check_file(circle_impl_file)
|
|
81
50
|
pos = lspt.Position(8, 11)
|
|
82
51
|
self.assertIn(
|
|
83
52
|
# "ability) calculate_area: float",
|
|
84
|
-
"(public ability) calculate_area
|
|
53
|
+
"(public ability) calculate_area\\n( radius : float ) -> float",
|
|
85
54
|
lsp.get_hover_info(circle_impl_file, pos).contents.value.replace("'", ""),
|
|
86
55
|
)
|
|
87
56
|
|
|
88
|
-
@pytest.mark.xfail(reason="TODO: Fix when we have the type checker")
|
|
89
|
-
def test_show_type_impl(self) -> None:
|
|
90
|
-
"""Test that the server doesn't run if there is a syntax error."""
|
|
91
|
-
lsp = JacLangServer()
|
|
92
|
-
# Set up the workspace path to "fixtures/"
|
|
93
|
-
workspace_path = self.fixture_abs_path("")
|
|
94
|
-
workspace = Workspace(workspace_path, lsp)
|
|
95
|
-
lsp.lsp._workspace = workspace
|
|
96
|
-
target = uris.from_fs_path(self.examples_abs_path("guess_game/guess_game4.jac"))
|
|
97
|
-
lsp.deep_check(target)
|
|
98
|
-
pos = lspt.Position(43, 18)
|
|
99
|
-
self.assertIn(
|
|
100
|
-
"attempts: int",
|
|
101
|
-
lsp.get_hover_info(target, pos).contents.value,
|
|
102
|
-
)
|
|
103
|
-
|
|
104
57
|
def test_outline_symbols(self) -> None:
|
|
105
58
|
"""Test that the outline symbols are correct."""
|
|
106
59
|
lsp = JacLangServer()
|
|
@@ -108,7 +61,7 @@ class TestJacLangServer(TestCase):
|
|
|
108
61
|
workspace = Workspace(workspace_path, lsp)
|
|
109
62
|
lsp.lsp._workspace = workspace
|
|
110
63
|
circle_file = uris.from_fs_path(self.fixture_abs_path("circle_pure.jac"))
|
|
111
|
-
lsp.
|
|
64
|
+
lsp.type_check_file(circle_file)
|
|
112
65
|
self.assertEqual(8, len(lsp.get_outline(circle_file)))
|
|
113
66
|
|
|
114
67
|
def test_go_to_definition(self) -> None:
|
|
@@ -118,7 +71,7 @@ class TestJacLangServer(TestCase):
|
|
|
118
71
|
workspace = Workspace(workspace_path, lsp)
|
|
119
72
|
lsp.lsp._workspace = workspace
|
|
120
73
|
circle_file = uris.from_fs_path(self.fixture_abs_path("circle_pure.jac"))
|
|
121
|
-
lsp.
|
|
74
|
+
lsp.type_check_file(circle_file)
|
|
122
75
|
self.assertIn(
|
|
123
76
|
"fixtures/circle_pure.impl.jac:8:5-8:19",
|
|
124
77
|
str(lsp.get_definition(circle_file, lspt.Position(9, 16))),
|
|
@@ -128,24 +81,6 @@ class TestJacLangServer(TestCase):
|
|
|
128
81
|
str(lsp.get_definition(circle_file, lspt.Position(20, 16))),
|
|
129
82
|
)
|
|
130
83
|
|
|
131
|
-
@pytest.mark.xfail(
|
|
132
|
-
reason="Incorrect handling of 'self' in DefUsePass.TODO: Fix chain_use_lookup."
|
|
133
|
-
)
|
|
134
|
-
def test_go_to_definition_method(self) -> None:
|
|
135
|
-
"""Test that the go to definition is correct."""
|
|
136
|
-
lsp = JacLangServer()
|
|
137
|
-
workspace_path = self.fixture_abs_path("")
|
|
138
|
-
workspace = Workspace(workspace_path, lsp)
|
|
139
|
-
lsp.lsp._workspace = workspace
|
|
140
|
-
guess_game_file = uris.from_fs_path(
|
|
141
|
-
self.examples_abs_path("guess_game/guess_game3.impl.jac")
|
|
142
|
-
)
|
|
143
|
-
lsp.deep_check(guess_game_file)
|
|
144
|
-
self.assertIn(
|
|
145
|
-
"guess_game3.jac:16:8-16:21",
|
|
146
|
-
str(lsp.get_definition(guess_game_file, lspt.Position(15, 17))),
|
|
147
|
-
)
|
|
148
|
-
|
|
149
84
|
def test_go_to_definition_method_manual_impl(self) -> None:
|
|
150
85
|
"""Test that the go to definition is correct."""
|
|
151
86
|
lsp = JacLangServer()
|
|
@@ -155,161 +90,106 @@ class TestJacLangServer(TestCase):
|
|
|
155
90
|
decldef_file = uris.from_fs_path(
|
|
156
91
|
self.examples_abs_path("micro/decl_defs_main.impl.jac")
|
|
157
92
|
)
|
|
158
|
-
lsp.
|
|
93
|
+
lsp.type_check_file(decldef_file)
|
|
159
94
|
decldef_main_file = uris.from_fs_path(
|
|
160
95
|
self.examples_abs_path("micro/decl_defs_main.jac")
|
|
161
96
|
)
|
|
162
|
-
lsp.
|
|
163
|
-
lsp.
|
|
97
|
+
lsp.type_check_file(decldef_main_file)
|
|
98
|
+
lsp.type_check_file(decldef_file)
|
|
164
99
|
self.assertIn(
|
|
165
100
|
"decl_defs_main.jac:7:8-7:17",
|
|
166
101
|
str(lsp.get_definition(decldef_file, lspt.Position(2, 20))),
|
|
167
102
|
)
|
|
168
103
|
|
|
169
|
-
|
|
170
|
-
reason="TODO: Fix the go to definition for imports[ abs_path is not set]"
|
|
171
|
-
)
|
|
172
|
-
def test_test_annex(self) -> None:
|
|
173
|
-
"""Test that the server doesn't run if there is a syntax error."""
|
|
174
|
-
lsp = JacLangServer()
|
|
175
|
-
# Set up the workspace path to "fixtures/"
|
|
176
|
-
workspace_path = self.fixture_abs_path("")
|
|
177
|
-
workspace = Workspace(workspace_path, lsp)
|
|
178
|
-
lsp.lsp._workspace = workspace
|
|
179
|
-
circle_file = uris.from_fs_path(self.fixture_abs_path("circle_pure.test.jac"))
|
|
180
|
-
lsp.deep_check(circle_file)
|
|
181
|
-
pos = lspt.Position(13, 21)
|
|
182
|
-
self.assertIn(
|
|
183
|
-
"shape_type: circle_pure.ShapeType",
|
|
184
|
-
lsp.get_hover_info(circle_file, pos).contents.value,
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
@pytest.mark.xfail(
|
|
188
|
-
reason="TODO: Fix the go to definition for imports[ abs_path is not set]"
|
|
189
|
-
)
|
|
190
|
-
def test_go_to_defintion_import(self) -> None:
|
|
104
|
+
def test_go_to_definition_md_path(self) -> None:
|
|
191
105
|
"""Test that the go to definition is correct."""
|
|
192
106
|
lsp = JacLangServer()
|
|
193
107
|
workspace_path = self.fixture_abs_path("")
|
|
194
108
|
workspace = Workspace(workspace_path, lsp)
|
|
195
109
|
lsp.lsp._workspace = workspace
|
|
196
|
-
import_file = uris.from_fs_path(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
lsp.deep_check(import_file)
|
|
110
|
+
import_file = uris.from_fs_path(self.fixture_abs_path("md_path.jac"))
|
|
111
|
+
lsp.type_check_file(import_file)
|
|
112
|
+
# fmt: off
|
|
200
113
|
positions = [
|
|
201
|
-
(
|
|
202
|
-
(
|
|
203
|
-
(
|
|
204
|
-
(
|
|
205
|
-
|
|
206
|
-
(
|
|
207
|
-
(
|
|
208
|
-
|
|
209
|
-
|
|
114
|
+
(3, 11, "asyncio/__init__.py:0:0-0:0"),
|
|
115
|
+
(6, 17, "concurrent/__init__.py:0:0-0:0"),
|
|
116
|
+
(6, 28, "concurrent/futures/__init__.py:0:0-0:0"),
|
|
117
|
+
(7, 17, "typing.py:0:0-0:0"),
|
|
118
|
+
# not a good one since there may be different typing.py versions
|
|
119
|
+
# (7, 27, "typing.py:2636:0-2636:7"),
|
|
120
|
+
(9, 18, "compiler/__init__.py:0:0-0:0"),
|
|
121
|
+
(9, 38, "compiler/unitree.py:0:0-0:0"),
|
|
122
|
+
(11, 35, "compiler/constant.py:0:0-0:0"),
|
|
123
|
+
(11, 47, "compiler/constant.py:5:0-34:9"),
|
|
124
|
+
(13, 47, "compiler/type_system/type_utils.py:0:0-0:0"),
|
|
125
|
+
(14, 34, "compiler/type_system/__init__.py:0:0-0:0"),
|
|
126
|
+
(14, 55, "compiler/type_system/types.py:143:0-232:8"),
|
|
127
|
+
(15, 34, "compiler/unitree.py:0:0-0:0"),
|
|
128
|
+
(15, 48, "compiler/unitree.py:304:0-504:11"),
|
|
129
|
+
(17, 22, "langserve/tests/fixtures/circle.jac:8:5-8:8"),
|
|
130
|
+
(18, 38, "vendor/pygls/uris.py:0:0-0:0"),
|
|
131
|
+
(19, 52, "vendor/pygls/server.py:351:0-615:13"),
|
|
132
|
+
(21, 31, "vendor/lsprotocol/types.py:0:0-0:0"),
|
|
210
133
|
]
|
|
134
|
+
# fmt: on
|
|
211
135
|
|
|
212
136
|
for line, char, expected in positions:
|
|
213
137
|
with self.subTest(line=line, char=char):
|
|
214
138
|
self.assertIn(
|
|
215
139
|
expected,
|
|
216
|
-
str(
|
|
140
|
+
str(
|
|
141
|
+
lsp.get_definition(
|
|
142
|
+
import_file, lspt.Position(line - 1, char - 1)
|
|
143
|
+
)
|
|
144
|
+
),
|
|
217
145
|
)
|
|
218
146
|
|
|
219
|
-
|
|
220
|
-
reason="TODO: Fix the go to definition for imports[ abs_path is not set]"
|
|
221
|
-
)
|
|
222
|
-
def test_go_to_definition_foolme(self) -> None:
|
|
147
|
+
def test_go_to_definition_atom_trailer(self) -> None:
|
|
223
148
|
"""Test that the go to definition is correct."""
|
|
224
149
|
lsp = JacLangServer()
|
|
225
150
|
workspace_path = self.fixture_abs_path("")
|
|
226
151
|
workspace = Workspace(workspace_path, lsp)
|
|
227
152
|
lsp.lsp._workspace = workspace
|
|
228
|
-
import_file = uris.from_fs_path(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
)
|
|
232
|
-
)
|
|
233
|
-
lsp.deep_check(import_file)
|
|
153
|
+
import_file = uris.from_fs_path(self.fixture_abs_path("user.jac"))
|
|
154
|
+
lsp.type_check_file(import_file)
|
|
155
|
+
# fmt: off
|
|
234
156
|
positions = [
|
|
235
|
-
(
|
|
236
|
-
(
|
|
237
|
-
(7, 31, "/pygame_mock/__init__.pyi:2:0-2:0"),
|
|
238
|
-
(7, 35, "/pygame_mock/constants.py:3:0-4:1"),
|
|
239
|
-
(20, 51, "/py_imp_test.jac:6:4-6:11"),
|
|
240
|
-
(20, 64, "/pygame_mock/constants.py:4:3-4:15"),
|
|
241
|
-
(21, 48, "/py_imp_test.jac:10:4-10:6"),
|
|
242
|
-
(21, 58, "/py_imp_test.jac:11:8-11:15"),
|
|
243
|
-
(21, 68, "/pygame_mock/constants.py:4:3-4:15"),
|
|
244
|
-
(23, 58, "/pygame_mock/constants.py:4:3-4:15"),
|
|
157
|
+
(14, 16, "fixtures/greet.py:12:3-13:15"),
|
|
158
|
+
(14, 28, "fixtures/greet.py:5:3-6:15"),
|
|
245
159
|
]
|
|
160
|
+
# fmt: on
|
|
246
161
|
|
|
247
162
|
for line, char, expected in positions:
|
|
248
163
|
with self.subTest(line=line, char=char):
|
|
249
164
|
self.assertIn(
|
|
250
165
|
expected,
|
|
251
|
-
str(
|
|
166
|
+
str(
|
|
167
|
+
lsp.get_definition(
|
|
168
|
+
import_file, lspt.Position(line - 1, char - 1)
|
|
169
|
+
)
|
|
170
|
+
),
|
|
252
171
|
)
|
|
253
172
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
"""Test that the go to definition is correct."""
|
|
173
|
+
def test_missing_mod_warning(self) -> None:
|
|
174
|
+
"""Test that the missing module warning is correct."""
|
|
257
175
|
lsp = JacLangServer()
|
|
258
176
|
workspace_path = self.fixture_abs_path("")
|
|
259
177
|
workspace = Workspace(workspace_path, lsp)
|
|
260
178
|
lsp.lsp._workspace = workspace
|
|
261
|
-
import_file = uris.from_fs_path(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
lsp.deep_check(import_file)
|
|
179
|
+
import_file = uris.from_fs_path(self.fixture_abs_path("md_path.jac"))
|
|
180
|
+
lsp.type_check_file(import_file)
|
|
181
|
+
|
|
265
182
|
positions = [
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
(27, 33, "index_slice.jac:2:8-2:13"),
|
|
183
|
+
"fixtures/md_path.jac, line 16, col 13: Module not found",
|
|
184
|
+
"fixtures/md_path.jac, line 22, col 8: Module not found",
|
|
269
185
|
]
|
|
186
|
+
for idx, expected in enumerate(positions):
|
|
187
|
+
self.assertIn(
|
|
188
|
+
expected,
|
|
189
|
+
str(lsp.warnings_had[idx]),
|
|
190
|
+
)
|
|
270
191
|
|
|
271
|
-
|
|
272
|
-
with self.subTest(line=line, char=char):
|
|
273
|
-
print(str(lsp.get_definition(import_file, lspt.Position(line, char))))
|
|
274
|
-
self.assertIn(
|
|
275
|
-
expected,
|
|
276
|
-
str(lsp.get_definition(import_file, lspt.Position(line, char))),
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
@pytest.mark.xfail(reason="TODO: Fix when we have the type checker")
|
|
280
|
-
def test_sem_tokens(self) -> None:
|
|
281
|
-
"""Test that the Semantic Tokens are generated correctly."""
|
|
282
|
-
lsp = JacLangServer()
|
|
283
|
-
workspace_path = self.fixture_abs_path("")
|
|
284
|
-
workspace = Workspace(workspace_path, lsp)
|
|
285
|
-
lsp.lsp._workspace = workspace
|
|
286
|
-
circle_file = uris.from_fs_path(self.fixture_abs_path("circle.jac"))
|
|
287
|
-
lsp.deep_check(circle_file)
|
|
288
|
-
sem_list = lsp.get_semantic_tokens(circle_file).data
|
|
289
|
-
expected_counts = [
|
|
290
|
-
("<JacSemTokenType.VARIABLE: 8>, <JacSemTokenModifier.READONLY: 4>", 12),
|
|
291
|
-
(
|
|
292
|
-
"<JacSemTokenType.PROPERTY: 9>, <JacSemTokenModifier.DEFINITION: 2>,",
|
|
293
|
-
21,
|
|
294
|
-
),
|
|
295
|
-
(
|
|
296
|
-
"<JacSemTokenType.PARAMETER: 7>, <JacSemTokenModifier.DECLARATION: 1>,",
|
|
297
|
-
5,
|
|
298
|
-
),
|
|
299
|
-
(
|
|
300
|
-
"<JacSemTokenType.FUNCTION: 12>, <JacSemTokenModifier.DECLARATION: 1>,",
|
|
301
|
-
8,
|
|
302
|
-
),
|
|
303
|
-
("<JacSemTokenType.METHOD: 13>, <JacSemTokenModifier.DECLARATION: 1>", 6),
|
|
304
|
-
("<JacSemTokenType.ENUM: 3>, <JacSemTokenModifier.DECLARATION: 1>,", 4),
|
|
305
|
-
("<JacSemTokenType.CLASS: 2>, <JacSemTokenModifier.DECLARATION: ", 12),
|
|
306
|
-
(
|
|
307
|
-
"<JacSemTokenType.NAMESPACE: 0>, <JacSemTokenModifier.DEFINITION: 2>,",
|
|
308
|
-
3,
|
|
309
|
-
),
|
|
310
|
-
]
|
|
311
|
-
for token_type, expected_count in expected_counts:
|
|
312
|
-
self.assertEqual(str(sem_list).count(token_type), expected_count)
|
|
192
|
+
|
|
313
193
|
|
|
314
194
|
def test_completion(self) -> None:
|
|
315
195
|
"""Test that the completions are correct."""
|
|
@@ -320,7 +200,7 @@ class TestJacLangServer(TestCase):
|
|
|
320
200
|
base_module_file = uris.from_fs_path(
|
|
321
201
|
self.fixture_abs_path("completion_test_err.jac")
|
|
322
202
|
)
|
|
323
|
-
lsp.
|
|
203
|
+
lsp.type_check_file(base_module_file)
|
|
324
204
|
|
|
325
205
|
@dataclass
|
|
326
206
|
class Case:
|
|
@@ -349,7 +229,7 @@ class TestJacLangServer(TestCase):
|
|
|
349
229
|
lsp.lsp._workspace = workspace
|
|
350
230
|
|
|
351
231
|
circle_file = uris.from_fs_path(self.fixture_abs_path("circle.jac"))
|
|
352
|
-
lsp.
|
|
232
|
+
lsp.type_check_file(circle_file)
|
|
353
233
|
test_cases = [
|
|
354
234
|
(47, 12, ["circle.jac:47:8-47:14", "69:8-69:14", "74:8-74:14"]),
|
|
355
235
|
(54, 66, ["54:62-54:76", "65:23-65:37"]),
|
|
@@ -360,188 +240,3 @@ class TestJacLangServer(TestCase):
|
|
|
360
240
|
for expected in expected_refs:
|
|
361
241
|
self.assertIn(expected, references)
|
|
362
242
|
|
|
363
|
-
@pytest.mark.xfail(reason="TODO: Fix when we have the type checker")
|
|
364
|
-
def test_py_type__definition(self) -> None:
|
|
365
|
-
"""Test that the go to definition is correct for pythoon imports."""
|
|
366
|
-
lsp = JacLangServer()
|
|
367
|
-
workspace_path = self.fixture_abs_path("")
|
|
368
|
-
workspace = Workspace(workspace_path, lsp)
|
|
369
|
-
lsp.lsp._workspace = workspace
|
|
370
|
-
import_file = uris.from_fs_path(
|
|
371
|
-
self.fixture_abs_path(
|
|
372
|
-
"../../../../jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac"
|
|
373
|
-
)
|
|
374
|
-
)
|
|
375
|
-
lsp.deep_check(import_file)
|
|
376
|
-
positions = [
|
|
377
|
-
(19, 29, "pygame_mock/color.py:0:0-2:4"),
|
|
378
|
-
(3, 17, "/pygame_mock/__init__.py:0:0-0:0"),
|
|
379
|
-
(20, 45, "pygame_mock/color.py:0:0-2:4"),
|
|
380
|
-
(19, 77, "mock/constants.py:4:3-4:15"),
|
|
381
|
-
(26, 28, "mock/display.py:0:0-1:7"),
|
|
382
|
-
(24, 22, "vendor/mypy/typeshed/stdlib/argparse.pyi:125:0-256:13"),
|
|
383
|
-
(19, 74, "pygame_mock/constants.py:4:3-4:15"),
|
|
384
|
-
# TODO: Need to properly support this
|
|
385
|
-
# (27, 17, "/stdlib/os/__init__.pyi:50:0-50:3"),
|
|
386
|
-
]
|
|
387
|
-
|
|
388
|
-
for line, char, expected in positions:
|
|
389
|
-
with self.subTest(line=line, char=char):
|
|
390
|
-
self.assertIn(
|
|
391
|
-
expected,
|
|
392
|
-
str(lsp.get_definition(import_file, lspt.Position(line, char))),
|
|
393
|
-
msg=positions.index((line, char, expected)) + 1,
|
|
394
|
-
)
|
|
395
|
-
|
|
396
|
-
@pytest.mark.xfail(reason="TODO: Fix when we have the type checker")
|
|
397
|
-
def test_py_type__references(self) -> None:
|
|
398
|
-
"""Test that the go to definition is correct for pythoon imports."""
|
|
399
|
-
lsp = JacLangServer()
|
|
400
|
-
workspace_path = self.fixture_abs_path("")
|
|
401
|
-
workspace = Workspace(workspace_path, lsp)
|
|
402
|
-
lsp.lsp._workspace = workspace
|
|
403
|
-
|
|
404
|
-
circle_file = uris.from_fs_path(
|
|
405
|
-
self.fixture_abs_path(
|
|
406
|
-
"../../../../jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac"
|
|
407
|
-
)
|
|
408
|
-
)
|
|
409
|
-
lsp.deep_check(circle_file)
|
|
410
|
-
test_cases = [
|
|
411
|
-
(
|
|
412
|
-
2,
|
|
413
|
-
21,
|
|
414
|
-
[
|
|
415
|
-
":6:21-6:32",
|
|
416
|
-
":7:11-7:22",
|
|
417
|
-
":11:25-11:36",
|
|
418
|
-
":12:15-12:26",
|
|
419
|
-
":18:33-18:44",
|
|
420
|
-
"19:46-19:57",
|
|
421
|
-
":19:8-19:19",
|
|
422
|
-
":19:46-19:57",
|
|
423
|
-
":20:8-20:19",
|
|
424
|
-
"21:8-21:19,",
|
|
425
|
-
"23:8-23:19",
|
|
426
|
-
":26:4-26:15",
|
|
427
|
-
],
|
|
428
|
-
),
|
|
429
|
-
(
|
|
430
|
-
19,
|
|
431
|
-
63,
|
|
432
|
-
[
|
|
433
|
-
"6:33-6:42",
|
|
434
|
-
"7:23-7:32",
|
|
435
|
-
"18:45-18:54",
|
|
436
|
-
"19:58-19:67",
|
|
437
|
-
"11:37-11:46",
|
|
438
|
-
"12:27-12:36",
|
|
439
|
-
],
|
|
440
|
-
),
|
|
441
|
-
(
|
|
442
|
-
24,
|
|
443
|
-
53,
|
|
444
|
-
[
|
|
445
|
-
"24:42-24:56",
|
|
446
|
-
"24:16-24:30",
|
|
447
|
-
"argparse.pyi:358:21-358:35",
|
|
448
|
-
"argparse.pyi:164:29-164:43",
|
|
449
|
-
"argparse.pyi:32:52-32:66",
|
|
450
|
-
],
|
|
451
|
-
),
|
|
452
|
-
]
|
|
453
|
-
for line, char, expected_refs in test_cases:
|
|
454
|
-
references = str(lsp.get_references(circle_file, lspt.Position(line, char)))
|
|
455
|
-
for expected in expected_refs:
|
|
456
|
-
self.assertIn(expected, references)
|
|
457
|
-
|
|
458
|
-
@pytest.mark.xfail(reason="TODO: Fix when we have the type checker")
|
|
459
|
-
def test_rename_symbol(self) -> None:
|
|
460
|
-
"""Test that the rename is correct."""
|
|
461
|
-
lsp = JacLangServer()
|
|
462
|
-
workspace_path = self.fixture_abs_path("")
|
|
463
|
-
workspace = Workspace(workspace_path, lsp)
|
|
464
|
-
lsp.lsp._workspace = workspace
|
|
465
|
-
|
|
466
|
-
circle_file = uris.from_fs_path(self.fixture_abs_path("circle.jac"))
|
|
467
|
-
lsp.deep_check(circle_file)
|
|
468
|
-
test_cases = [
|
|
469
|
-
(
|
|
470
|
-
20,
|
|
471
|
-
14,
|
|
472
|
-
"ShapeKind",
|
|
473
|
-
"27:20-27:29,",
|
|
474
|
-
"36:19-36:28",
|
|
475
|
-
"75:26-75:35",
|
|
476
|
-
"20:5-20:14",
|
|
477
|
-
),
|
|
478
|
-
(12, 34, "circleRadius", "12:21-12:27", "12:30-12:36", "11:19-11:25"),
|
|
479
|
-
(62, 14, "target_area", "65:43-65:56", "70:32-70:45", "62:5-62:18"),
|
|
480
|
-
(57, 33, "type_of_shape", "75:12-75:22", "27:8-27:18,", "57:23-57:33"),
|
|
481
|
-
]
|
|
482
|
-
for tup in test_cases:
|
|
483
|
-
line, char, new_name, *expected_refs = tup
|
|
484
|
-
references = str(
|
|
485
|
-
lsp.rename_symbol(circle_file, lspt.Position(line, char), new_name)
|
|
486
|
-
)
|
|
487
|
-
for expected in expected_refs:
|
|
488
|
-
self.assertIn(expected, references)
|
|
489
|
-
|
|
490
|
-
@pytest.mark.xfail(reason="TODO: Fix when we have the type checker")
|
|
491
|
-
def test_rename_uses(self) -> None:
|
|
492
|
-
"""Test that the rename is correct."""
|
|
493
|
-
lsp = JacLangServer()
|
|
494
|
-
workspace_path = self.fixture_abs_path("")
|
|
495
|
-
workspace = Workspace(workspace_path, lsp)
|
|
496
|
-
lsp.lsp._workspace = workspace
|
|
497
|
-
|
|
498
|
-
circle_file = uris.from_fs_path(self.fixture_abs_path("rename.jac"))
|
|
499
|
-
lsp.deep_check(circle_file)
|
|
500
|
-
# fmt: off
|
|
501
|
-
test_cases = [
|
|
502
|
-
(0, 7, "func", "25:4-25:7", "0:4-0:7", "4:5-4:8",),
|
|
503
|
-
(4, 8, "func", "25:4-25:7", "0:4-0:7", "4:5-4:8",),
|
|
504
|
-
(25, 6, "func", "25:4-25:7", "0:4-0:7", "4:5-4:8",),
|
|
505
|
-
(10, 10, "canBar", "27:8-27:11", "10:8-10:11"),
|
|
506
|
-
(27, 9, "canBar", "27:8-27:11", "10:8-10:11"),
|
|
507
|
-
(9, 6, "canBar", "26:10-26:13", "28:4-28:7", "16:5-16:8", "9:4-9:7"),
|
|
508
|
-
(26, 11, "canBar", "26:10-26:13", "28:4-28:7", "16:5-16:8", "9:4-9:7"),
|
|
509
|
-
(16, 8, "canBar", "26:10-26:13", "28:4-28:7", "16:5-16:8", "9:4-9:7"),
|
|
510
|
-
(28, 6, "canBar", "26:10-26:13", "28:4-28:7", "16:5-16:8", "9:4-9:7"),
|
|
511
|
-
(11, 10, "canBar", "11:8-11:11", "16:9-16:12", "28:11-28:14"),
|
|
512
|
-
(16, 12, "canBar", "11:8-11:11", "16:9-16:12", "28:11-28:14"),
|
|
513
|
-
(28, 13, "canBar", "11:8-11:11", "16:9-16:12", "28:11-28:14"),
|
|
514
|
-
(12, 10, "canBaz", "12:8-12:11", "20:9-20:12"),
|
|
515
|
-
(20, 12, "canBaz", "12:8-12:11", "20:9-20:12"),
|
|
516
|
-
(26, 6, "count", "27:4-27:7", "26:4-26:7"),
|
|
517
|
-
(27, 5, "count", "27:4-27:7", "26:4-26:7"),
|
|
518
|
-
]
|
|
519
|
-
# fmt: on
|
|
520
|
-
for tup in test_cases:
|
|
521
|
-
line, char, new_name, *expected_refs = tup
|
|
522
|
-
references = str(
|
|
523
|
-
lsp.rename_symbol(circle_file, lspt.Position(line, char), new_name)
|
|
524
|
-
)
|
|
525
|
-
for expected in expected_refs:
|
|
526
|
-
self.assertIn(expected, references)
|
|
527
|
-
|
|
528
|
-
def test_binder_go_to_module(self) -> None:
|
|
529
|
-
"""Test that the go to definition is correct."""
|
|
530
|
-
lsp = JacLangServer()
|
|
531
|
-
workspace_path = self.fixture_abs_path("")
|
|
532
|
-
workspace = Workspace(workspace_path, lsp)
|
|
533
|
-
lsp.lsp._workspace = workspace
|
|
534
|
-
guess_game_file = uris.from_fs_path(
|
|
535
|
-
self.fixture_abs_path(
|
|
536
|
-
"../../../compiler/passes/main/tests/fixtures/sym_binder.jac"
|
|
537
|
-
)
|
|
538
|
-
)
|
|
539
|
-
lsp.deep_check(guess_game_file)
|
|
540
|
-
self.assertIn(
|
|
541
|
-
"/tests/fixtures/M1.jac:0:0-0:0",
|
|
542
|
-
str(lsp.get_definition(guess_game_file, lspt.Position(29, 9))),
|
|
543
|
-
)
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
TestJacLangServer().test_completion()
|
jaclang/lib.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from jaclang.runtimelib.machine import JacMachineInterface
|
|
4
4
|
|
|
5
5
|
# Automatically expose all public attributes from JacMachineInterface
|
|
6
|
-
# This includes archetype classes (Obj, Node, Edge, Walker, Root,
|
|
6
|
+
# This includes archetype classes (Obj, Node, Edge, Walker, Root, OPath) and all methods
|
|
7
7
|
_jac_interface_attrs = {
|
|
8
8
|
name: getattr(JacMachineInterface, name)
|
|
9
9
|
for name in dir(JacMachineInterface)
|