jaclang 0.8.7__py3-none-any.whl → 0.8.9__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 +77 -29
- jaclang/cli/cmdreg.py +44 -0
- jaclang/compiler/constant.py +6 -2
- jaclang/compiler/jac.lark +37 -47
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +356 -61
- jaclang/compiler/passes/main/__init__.py +2 -4
- jaclang/compiler/passes/main/def_use_pass.py +1 -4
- jaclang/compiler/passes/main/predynamo_pass.py +221 -0
- jaclang/compiler/passes/main/pyast_gen_pass.py +221 -135
- jaclang/compiler/passes/main/pyast_load_pass.py +54 -20
- jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -1
- jaclang/compiler/passes/main/tests/fixtures/checker/import_sym.jac +2 -0
- jaclang/compiler/passes/main/tests/fixtures/checker/import_sym_test.jac +6 -0
- jaclang/compiler/passes/main/tests/fixtures/checker/imported_sym.jac +5 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_arg_param_match.jac +37 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_arity.jac +18 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_cat_is_animal.jac +18 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_float.jac +7 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_param_types.jac +11 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_self_type.jac +9 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_sym_inherit.jac +42 -0
- jaclang/compiler/passes/main/tests/fixtures/predynamo_fix3.jac +43 -0
- jaclang/compiler/passes/main/tests/fixtures/predynamo_where_assign.jac +13 -0
- jaclang/compiler/passes/main/tests/fixtures/predynamo_where_return.jac +11 -0
- jaclang/compiler/passes/main/tests/test_checker_pass.py +190 -0
- jaclang/compiler/passes/main/tests/test_predynamo_pass.py +56 -0
- jaclang/compiler/passes/main/type_checker_pass.py +29 -73
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +302 -58
- jaclang/compiler/passes/tool/jac_formatter_pass.py +119 -69
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +3 -3
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +4 -5
- jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +7 -1
- jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +276 -10
- jaclang/compiler/passes/transform.py +12 -8
- jaclang/compiler/program.py +19 -7
- jaclang/compiler/tests/fixtures/jac_import_py_files.py +4 -0
- jaclang/compiler/tests/fixtures/jac_module.jac +3 -0
- jaclang/compiler/tests/fixtures/multiple_syntax_errors.jac +10 -0
- jaclang/compiler/tests/fixtures/python_module.py +1 -0
- jaclang/compiler/tests/test_importer.py +39 -0
- jaclang/compiler/tests/test_parser.py +49 -0
- jaclang/compiler/type_system/type_evaluator.jac +959 -0
- jaclang/compiler/type_system/type_utils.py +246 -0
- jaclang/compiler/type_system/types.py +58 -2
- jaclang/compiler/unitree.py +102 -107
- jaclang/langserve/engine.jac +138 -159
- jaclang/langserve/server.jac +25 -1
- 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/completion_test_err.jac +10 -0
- jaclang/langserve/tests/server_test/circle_template.jac +80 -0
- jaclang/langserve/tests/server_test/glob_template.jac +4 -0
- jaclang/langserve/tests/server_test/test_lang_serve.py +154 -309
- jaclang/langserve/tests/server_test/utils.py +153 -116
- jaclang/langserve/tests/test_server.py +21 -84
- jaclang/langserve/utils.jac +12 -15
- jaclang/lib.py +17 -0
- jaclang/runtimelib/archetype.py +25 -25
- jaclang/runtimelib/constructs.py +2 -2
- jaclang/runtimelib/machine.py +63 -46
- jaclang/runtimelib/meta_importer.py +27 -1
- jaclang/runtimelib/tests/fixtures/custom_access_validation.jac +1 -1
- jaclang/runtimelib/tests/fixtures/savable_object.jac +2 -2
- jaclang/settings.py +19 -16
- jaclang/tests/fixtures/abc_check.jac +3 -3
- jaclang/tests/fixtures/arch_rel_import_creation.jac +12 -12
- jaclang/tests/fixtures/attr_pattern_case.jac +18 -0
- jaclang/tests/fixtures/chandra_bugs2.jac +3 -3
- jaclang/tests/fixtures/create_dynamic_archetype.jac +13 -13
- jaclang/tests/fixtures/funccall_genexpr.jac +7 -0
- jaclang/tests/fixtures/funccall_genexpr.py +5 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
- jaclang/tests/fixtures/params/param_syntax_err.jac +9 -0
- jaclang/tests/fixtures/params/test_complex_params.jac +42 -0
- jaclang/tests/fixtures/params/test_failing_kwonly.jac +207 -0
- jaclang/tests/fixtures/params/test_failing_posonly.jac +116 -0
- jaclang/tests/fixtures/params/test_failing_varargs.jac +300 -0
- jaclang/tests/fixtures/params/test_kwonly_params.jac +29 -0
- jaclang/tests/fixtures/py2jac_params.py +8 -0
- jaclang/tests/fixtures/run_test.jac +4 -4
- jaclang/tests/test_cli.py +159 -7
- jaclang/tests/test_language.py +213 -38
- jaclang/tests/test_reference.py +3 -1
- jaclang/utils/helpers.py +67 -6
- jaclang/utils/module_resolver.py +10 -0
- jaclang/utils/test.py +8 -0
- jaclang/utils/tests/test_lang_tools.py +4 -15
- jaclang/utils/treeprinter.py +0 -18
- {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/METADATA +1 -2
- {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/RECORD +95 -65
- {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/WHEEL +1 -1
- jaclang/compiler/passes/main/inheritance_pass.py +0 -131
- jaclang/compiler/type_system/type_evaluator.py +0 -560
- jaclang/langserve/dev_engine.jac +0 -645
- jaclang/langserve/dev_server.jac +0 -201
- /jaclang/{langserve/tests/server_test/code_test.py → tests/fixtures/py2jac_empty.py} +0 -0
- {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/entry_points.txt +0 -0
|
@@ -1,350 +1,195 @@
|
|
|
1
|
-
"""Test for Jac language server
|
|
1
|
+
"""Test suite for Jac language server features."""
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
3
|
import pytest
|
|
5
4
|
|
|
6
5
|
from lsprotocol.types import (
|
|
7
|
-
DidOpenTextDocumentParams,
|
|
8
|
-
TextDocumentItem,
|
|
9
|
-
DidSaveTextDocumentParams,
|
|
10
|
-
DidChangeTextDocumentParams,
|
|
11
6
|
DocumentFormattingParams,
|
|
12
7
|
TextEdit,
|
|
13
|
-
VersionedTextDocumentIdentifier,
|
|
14
8
|
TextDocumentIdentifier,
|
|
15
9
|
)
|
|
16
10
|
from jaclang.langserve.tests.server_test.utils import (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
TestFile,
|
|
12
|
+
LanguageServerTestHelper,
|
|
13
|
+
create_ls_with_workspace,
|
|
14
|
+
load_jac_template,
|
|
21
15
|
)
|
|
22
16
|
from jaclang.vendor.pygls.uris import from_fs_path
|
|
23
|
-
from jaclang.
|
|
24
|
-
from jaclang import JacMachineInterface as _
|
|
25
|
-
from jaclang.langserve.engine import JacLangServer
|
|
26
|
-
from jaclang.langserve.server import did_open, did_save, did_change, formatting
|
|
17
|
+
from jaclang.langserve.server import formatting
|
|
27
18
|
|
|
28
19
|
|
|
29
20
|
class TestLangServe:
|
|
30
|
-
"""Test
|
|
31
|
-
|
|
21
|
+
"""Test suite for Jac language server features."""
|
|
22
|
+
|
|
23
|
+
CIRCLE_TEMPLATE = "circle_template.jac"
|
|
24
|
+
GLOB_TEMPLATE = "glob_template.jac"
|
|
25
|
+
EXPECTED_CIRCLE_TOKEN_COUNT = 340
|
|
26
|
+
EXPECTED_GLOB_TOKEN_COUNT = 15
|
|
27
|
+
|
|
32
28
|
@pytest.mark.asyncio
|
|
33
29
|
async def test_open_valid_file_no_diagnostics(self):
|
|
34
|
-
"""Test opening a Jac file
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
text_document=TextDocumentItem(
|
|
44
|
-
uri=uri,
|
|
45
|
-
language_id="jac",
|
|
46
|
-
version=1,
|
|
47
|
-
text=code,
|
|
48
|
-
)
|
|
49
|
-
)
|
|
50
|
-
await did_open(ls, params)
|
|
51
|
-
|
|
52
|
-
diagnostics = ls.diagnostics.get(uri, [])
|
|
30
|
+
"""Test opening a valid Jac file produces no diagnostics."""
|
|
31
|
+
test_file = TestFile.from_template(self.CIRCLE_TEMPLATE)
|
|
32
|
+
uri, ls = create_ls_with_workspace(test_file.path)
|
|
33
|
+
test_file.uri = uri
|
|
34
|
+
helper = LanguageServerTestHelper(ls, test_file)
|
|
35
|
+
|
|
36
|
+
await helper.open_document()
|
|
37
|
+
helper.assert_no_diagnostics()
|
|
38
|
+
|
|
53
39
|
ls.shutdown()
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
os.remove(temp_file_path)
|
|
57
|
-
|
|
40
|
+
test_file.cleanup()
|
|
41
|
+
|
|
58
42
|
@pytest.mark.asyncio
|
|
59
43
|
async def test_open_with_syntax_error(self):
|
|
60
|
-
"""Test opening a Jac file with
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
text=code,
|
|
74
|
-
)
|
|
75
|
-
)
|
|
76
|
-
await did_open(ls, params)
|
|
77
|
-
|
|
78
|
-
diagnostics = ls.diagnostics.get(uri, [])
|
|
44
|
+
"""Test opening a Jac file with syntax error produces diagnostics."""
|
|
45
|
+
test_file = TestFile.from_template(self.CIRCLE_TEMPLATE, "error")
|
|
46
|
+
uri, ls = create_ls_with_workspace(test_file.path)
|
|
47
|
+
if uri:
|
|
48
|
+
test_file.uri = uri
|
|
49
|
+
helper = LanguageServerTestHelper(ls, test_file)
|
|
50
|
+
|
|
51
|
+
await helper.open_document()
|
|
52
|
+
helper.assert_has_diagnostics(count=1, message_contains="Unexpected token 'error'")
|
|
53
|
+
|
|
54
|
+
diagnostics = helper.get_diagnostics()
|
|
55
|
+
assert str(diagnostics[0].range) == "65:0-65:5"
|
|
56
|
+
|
|
79
57
|
ls.shutdown()
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
assert str(diagnostics[0].range) == "66:0-66:1"
|
|
83
|
-
|
|
84
|
-
os.remove(temp_file_path)
|
|
85
|
-
|
|
58
|
+
test_file.cleanup()
|
|
59
|
+
|
|
86
60
|
@pytest.mark.asyncio
|
|
87
61
|
async def test_did_open_and_simple_syntax_error(self):
|
|
88
|
-
"""Test diagnostics
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
)
|
|
104
|
-
await
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
broken_code = get_code("error")
|
|
110
|
-
with open(temp_file_path, "w") as f:
|
|
111
|
-
f.write(broken_code)
|
|
112
|
-
params = DidOpenTextDocumentParams(
|
|
113
|
-
text_document=TextDocumentItem(
|
|
114
|
-
uri=uri,
|
|
115
|
-
language_id="jac",
|
|
116
|
-
version=1,
|
|
117
|
-
text=broken_code,
|
|
118
|
-
)
|
|
119
|
-
)
|
|
120
|
-
await did_open(ls, params)
|
|
121
|
-
diagnostics = ls.diagnostics.get(uri, [])
|
|
122
|
-
assert isinstance(diagnostics, list)
|
|
123
|
-
assert len(diagnostics) == 1
|
|
124
|
-
|
|
125
|
-
sem_tokens = ls.get_semantic_tokens(uri)
|
|
126
|
-
print(sem_tokens)
|
|
62
|
+
"""Test diagnostics evolution from valid to invalid code."""
|
|
63
|
+
test_file = TestFile.from_template(self.CIRCLE_TEMPLATE)
|
|
64
|
+
uri, ls = create_ls_with_workspace(test_file.path)
|
|
65
|
+
test_file.uri = uri
|
|
66
|
+
helper = LanguageServerTestHelper(ls, test_file)
|
|
67
|
+
|
|
68
|
+
# Open valid file
|
|
69
|
+
print("Opening valid file...")
|
|
70
|
+
await helper.open_document()
|
|
71
|
+
helper.assert_no_diagnostics()
|
|
72
|
+
|
|
73
|
+
# Introduce syntax error
|
|
74
|
+
broken_code = load_jac_template(
|
|
75
|
+
test_file._get_template_path(self.CIRCLE_TEMPLATE),
|
|
76
|
+
"error"
|
|
77
|
+
)
|
|
78
|
+
await helper.change_document(broken_code)
|
|
79
|
+
helper.assert_has_diagnostics(count=1)
|
|
80
|
+
helper.assert_semantic_tokens_count(self.EXPECTED_CIRCLE_TOKEN_COUNT)
|
|
81
|
+
|
|
127
82
|
ls.shutdown()
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
assert (
|
|
131
|
-
len(sem_tokens.data) == 0
|
|
132
|
-
) # TODO: we should retain the sem tokens, will be fixed in next PR
|
|
133
|
-
|
|
134
|
-
os.remove(temp_file_path)
|
|
135
|
-
|
|
83
|
+
test_file.cleanup()
|
|
84
|
+
|
|
136
85
|
@pytest.mark.asyncio
|
|
137
86
|
async def test_did_save(self):
|
|
138
|
-
"""Test saving a Jac file triggers diagnostics."""
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
uri
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
language_id="jac",
|
|
159
|
-
version=2,
|
|
160
|
-
text=code,
|
|
161
|
-
)
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
await did_save(ls, params)
|
|
165
|
-
diagnostics = ls.diagnostics.get(uri, [])
|
|
166
|
-
assert isinstance(diagnostics, list)
|
|
167
|
-
assert len(diagnostics) == 0
|
|
168
|
-
|
|
169
|
-
# Now simulate a syntax error by updating the workspace and saving
|
|
170
|
-
broken_code = get_code("error")
|
|
171
|
-
ls.workspace.put_text_document(
|
|
172
|
-
TextDocumentItem(
|
|
173
|
-
uri=uri,
|
|
174
|
-
language_id="jac",
|
|
175
|
-
version=3,
|
|
176
|
-
text=broken_code,
|
|
177
|
-
)
|
|
178
|
-
)
|
|
179
|
-
params = DidSaveTextDocumentParams(
|
|
180
|
-
text_document=TextDocumentItem(
|
|
181
|
-
uri=uri,
|
|
182
|
-
language_id="jac",
|
|
183
|
-
version=3,
|
|
184
|
-
text=broken_code,
|
|
185
|
-
)
|
|
186
|
-
)
|
|
187
|
-
await did_save(ls, params)
|
|
188
|
-
sem_tokens = ls.get_semantic_tokens(uri)
|
|
189
|
-
# semantic tokens should still be present even if there is a syntax error
|
|
190
|
-
assert len(sem_tokens.data) == 340
|
|
191
|
-
diagnostics = ls.diagnostics.get(uri, [])
|
|
192
|
-
assert isinstance(diagnostics, list)
|
|
193
|
-
assert len(diagnostics) == 1
|
|
194
|
-
assert diagnostics[0].message == "Syntax Error"
|
|
195
|
-
|
|
87
|
+
"""Test saving a Jac file triggers appropriate diagnostics."""
|
|
88
|
+
test_file = TestFile.from_template(self.CIRCLE_TEMPLATE)
|
|
89
|
+
uri, ls = create_ls_with_workspace(test_file.path)
|
|
90
|
+
if uri:
|
|
91
|
+
test_file.uri = uri
|
|
92
|
+
helper = LanguageServerTestHelper(ls, test_file)
|
|
93
|
+
|
|
94
|
+
await helper.open_document()
|
|
95
|
+
await helper.save_document()
|
|
96
|
+
helper.assert_no_diagnostics()
|
|
97
|
+
|
|
98
|
+
# Save with syntax error
|
|
99
|
+
broken_code = load_jac_template(
|
|
100
|
+
test_file._get_template_path(self.CIRCLE_TEMPLATE),
|
|
101
|
+
"error"
|
|
102
|
+
)
|
|
103
|
+
await helper.save_document(broken_code)
|
|
104
|
+
helper.assert_semantic_tokens_count(self.EXPECTED_CIRCLE_TOKEN_COUNT)
|
|
105
|
+
helper.assert_has_diagnostics(count=1, message_contains="Unexpected token 'error'")
|
|
106
|
+
|
|
196
107
|
ls.shutdown()
|
|
197
|
-
|
|
198
|
-
|
|
108
|
+
test_file.cleanup()
|
|
109
|
+
|
|
199
110
|
@pytest.mark.asyncio
|
|
200
111
|
async def test_did_change(self):
|
|
201
112
|
"""Test changing a Jac file triggers diagnostics."""
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
uri
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
params = DidChangeTextDocumentParams(
|
|
220
|
-
text_document=VersionedTextDocumentIdentifier(uri=uri, version=2),
|
|
221
|
-
content_changes=[{"text": "\n" + code}],
|
|
222
|
-
)
|
|
223
|
-
ls.workspace.put_text_document(
|
|
224
|
-
TextDocumentItem(
|
|
225
|
-
uri=uri,
|
|
226
|
-
language_id="jac",
|
|
227
|
-
version=2,
|
|
228
|
-
text="\n" + code,
|
|
229
|
-
)
|
|
230
|
-
)
|
|
231
|
-
await did_change(ls, params)
|
|
232
|
-
diagnostics = ls.diagnostics.get(uri, [])
|
|
233
|
-
assert isinstance(diagnostics, list)
|
|
234
|
-
assert len(diagnostics) == 0
|
|
235
|
-
|
|
236
|
-
# Now add a syntax error and update workspace
|
|
237
|
-
# This should trigger diagnostics with a syntax error
|
|
238
|
-
error_code = "\nerror"
|
|
239
|
-
params = DidChangeTextDocumentParams(
|
|
240
|
-
text_document=VersionedTextDocumentIdentifier(uri=uri, version=3),
|
|
241
|
-
content_changes=[{"text": error_code + code}],
|
|
242
|
-
)
|
|
243
|
-
ls.workspace.put_text_document(
|
|
244
|
-
TextDocumentItem(
|
|
245
|
-
uri=uri,
|
|
246
|
-
language_id="jac",
|
|
247
|
-
version=3,
|
|
248
|
-
text=error_code + code,
|
|
249
|
-
)
|
|
250
|
-
)
|
|
251
|
-
await did_change(ls, params)
|
|
252
|
-
sem_tokens = ls.get_semantic_tokens(uri)
|
|
253
|
-
# semantic tokens should still be present even if there is a syntax error
|
|
254
|
-
assert len(sem_tokens.data) == 340
|
|
255
|
-
diagnostics = ls.diagnostics.get(uri, [])
|
|
256
|
-
assert isinstance(diagnostics, list)
|
|
257
|
-
assert len(diagnostics) == 1
|
|
258
|
-
assert diagnostics[0].message == "Syntax Error"
|
|
259
|
-
|
|
113
|
+
test_file = TestFile.from_template(self.CIRCLE_TEMPLATE)
|
|
114
|
+
uri, ls = create_ls_with_workspace(test_file.path)
|
|
115
|
+
if uri:
|
|
116
|
+
test_file.uri = uri
|
|
117
|
+
helper = LanguageServerTestHelper(ls, test_file)
|
|
118
|
+
|
|
119
|
+
await helper.open_document()
|
|
120
|
+
|
|
121
|
+
# Change without error
|
|
122
|
+
await helper.change_document("\n" + test_file.code)
|
|
123
|
+
helper.assert_no_diagnostics()
|
|
124
|
+
|
|
125
|
+
# Change with syntax error
|
|
126
|
+
await helper.change_document("\nerror" + test_file.code)
|
|
127
|
+
helper.assert_semantic_tokens_count(self.EXPECTED_CIRCLE_TOKEN_COUNT)
|
|
128
|
+
helper.assert_has_diagnostics(count=1, message_contains="Unexpected token")
|
|
129
|
+
|
|
260
130
|
ls.shutdown()
|
|
261
|
-
|
|
262
|
-
|
|
131
|
+
test_file.cleanup()
|
|
132
|
+
|
|
263
133
|
def test_vsce_formatting(self):
|
|
264
|
-
"""Test formatting a Jac file returns edits."""
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
134
|
+
"""Test formatting a Jac file returns valid edits."""
|
|
135
|
+
test_file = TestFile.from_template(self.CIRCLE_TEMPLATE)
|
|
136
|
+
uri, ls = create_ls_with_workspace(test_file.path)
|
|
137
|
+
|
|
138
|
+
from lsprotocol.types import FormattingOptions
|
|
139
|
+
|
|
268
140
|
params = DocumentFormattingParams(
|
|
269
|
-
text_document=TextDocumentIdentifier(uri=uri),
|
|
270
|
-
options=
|
|
141
|
+
text_document=TextDocumentIdentifier(uri=uri or ""),
|
|
142
|
+
options=FormattingOptions(tab_size=4, insert_spaces=True),
|
|
271
143
|
)
|
|
272
144
|
edits = formatting(ls, params)
|
|
145
|
+
|
|
273
146
|
assert isinstance(edits, list)
|
|
147
|
+
assert len(edits) > 0
|
|
274
148
|
assert isinstance(edits[0], TextEdit)
|
|
275
|
-
assert (
|
|
276
|
-
|
|
277
|
-
) # it is a random number to check if the text is changed
|
|
278
|
-
print(edits[0].new_text)
|
|
149
|
+
assert len(edits[0].new_text) > 100
|
|
150
|
+
|
|
279
151
|
ls.shutdown()
|
|
280
|
-
|
|
281
|
-
|
|
152
|
+
test_file.cleanup()
|
|
153
|
+
|
|
282
154
|
@pytest.mark.asyncio
|
|
283
155
|
async def test_multifile_workspace(self):
|
|
284
156
|
"""Test opening multiple Jac files in a workspace."""
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
before_sem_tokens_1 = ls.get_semantic_tokens(uri1)
|
|
323
|
-
before_sem_tokens_2 = ls.get_semantic_tokens(uri2)
|
|
324
|
-
assert len(before_sem_tokens_1.data) == 15
|
|
325
|
-
assert len(before_sem_tokens_2.data) == 0
|
|
326
|
-
|
|
327
|
-
changed_code = get_simple_code("glob x = 90;")
|
|
328
|
-
ls.workspace.put_text_document(
|
|
329
|
-
TextDocumentItem(
|
|
330
|
-
uri=uri1,
|
|
331
|
-
language_id="jac",
|
|
332
|
-
version=2,
|
|
333
|
-
text=changed_code,
|
|
334
|
-
)
|
|
335
|
-
)
|
|
336
|
-
params = DidChangeTextDocumentParams(
|
|
337
|
-
text_document=VersionedTextDocumentIdentifier(uri=uri1, version=2),
|
|
338
|
-
content_changes=[{"text": changed_code}],
|
|
339
|
-
)
|
|
340
|
-
await did_change(ls, params)
|
|
341
|
-
|
|
342
|
-
after_sem_tokens_1 = ls.get_semantic_tokens(uri1)
|
|
343
|
-
after_sem_tokens_2 = ls.get_semantic_tokens(uri2)
|
|
344
|
-
|
|
345
|
-
assert len(after_sem_tokens_1.data) == 20
|
|
346
|
-
assert len(after_sem_tokens_2.data) == 0
|
|
347
|
-
|
|
157
|
+
file1 = TestFile.from_template(self.GLOB_TEMPLATE)
|
|
158
|
+
file2 = TestFile.from_template(self.GLOB_TEMPLATE, "error")
|
|
159
|
+
|
|
160
|
+
uri1, ls = create_ls_with_workspace(file1.path)
|
|
161
|
+
if uri1:
|
|
162
|
+
file1.uri = uri1
|
|
163
|
+
file2_uri = from_fs_path(file2.path)
|
|
164
|
+
if file2_uri:
|
|
165
|
+
file2.uri = file2_uri
|
|
166
|
+
|
|
167
|
+
helper1 = LanguageServerTestHelper(ls, file1)
|
|
168
|
+
helper2 = LanguageServerTestHelper(ls, file2)
|
|
169
|
+
|
|
170
|
+
# Open both files
|
|
171
|
+
await helper1.open_document()
|
|
172
|
+
await helper2.open_document()
|
|
173
|
+
|
|
174
|
+
# Verify initial state
|
|
175
|
+
helper1.assert_no_diagnostics()
|
|
176
|
+
helper2.assert_has_diagnostics(count=1, message_contains="Unexpected token")
|
|
177
|
+
|
|
178
|
+
# Check semantic tokens before change
|
|
179
|
+
helper1.assert_semantic_tokens_count(self.EXPECTED_GLOB_TOKEN_COUNT)
|
|
180
|
+
helper2.assert_semantic_tokens_count(self.EXPECTED_GLOB_TOKEN_COUNT)
|
|
181
|
+
|
|
182
|
+
# Change first file
|
|
183
|
+
changed_code = load_jac_template(
|
|
184
|
+
file1._get_template_path(self.GLOB_TEMPLATE),
|
|
185
|
+
"glob x = 90;"
|
|
186
|
+
)
|
|
187
|
+
await helper1.change_document(changed_code)
|
|
188
|
+
|
|
189
|
+
# Verify semantic tokens after change
|
|
190
|
+
helper1.assert_semantic_tokens_count(20)
|
|
191
|
+
helper2.assert_semantic_tokens_count(self.EXPECTED_GLOB_TOKEN_COUNT)
|
|
192
|
+
|
|
348
193
|
ls.shutdown()
|
|
349
|
-
|
|
350
|
-
|
|
194
|
+
file1.cleanup()
|
|
195
|
+
file2.cleanup()
|