jaclang 0.7.13__py3-none-any.whl → 0.7.16__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.

Files changed (96) hide show
  1. jaclang/cli/cli.py +15 -10
  2. jaclang/cli/cmdreg.py +9 -12
  3. jaclang/compiler/__init__.py +19 -53
  4. jaclang/compiler/absyntree.py +95 -17
  5. jaclang/compiler/jac.lark +4 -3
  6. jaclang/compiler/parser.py +35 -23
  7. jaclang/compiler/passes/ir_pass.py +4 -13
  8. jaclang/compiler/passes/main/access_modifier_pass.py +1 -1
  9. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +4 -5
  10. jaclang/compiler/passes/main/import_pass.py +19 -23
  11. jaclang/compiler/passes/main/pyast_gen_pass.py +308 -567
  12. jaclang/compiler/passes/main/pyast_load_pass.py +33 -6
  13. jaclang/compiler/passes/main/registry_pass.py +37 -3
  14. jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -1
  15. jaclang/compiler/passes/main/tests/__init__.py +1 -1
  16. jaclang/compiler/passes/main/tests/test_import_pass.py +5 -1
  17. jaclang/compiler/passes/main/type_check_pass.py +7 -0
  18. jaclang/compiler/passes/tool/fuse_comments_pass.py +14 -2
  19. jaclang/compiler/passes/tool/jac_formatter_pass.py +144 -94
  20. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +0 -1
  21. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/architype_test.jac +13 -0
  22. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comment_alignment.jac +11 -0
  23. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comments.jac +13 -0
  24. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/decorator_stack.jac +37 -0
  25. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/esc_keywords.jac +5 -0
  26. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/long_names.jac +19 -0
  27. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +6 -0
  28. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -0
  29. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +33 -39
  30. jaclang/compiler/passes/transform.py +4 -0
  31. jaclang/compiler/semtable.py +31 -7
  32. jaclang/compiler/tests/test_importer.py +12 -5
  33. jaclang/langserve/engine.py +82 -143
  34. jaclang/langserve/sem_manager.py +379 -0
  35. jaclang/langserve/server.py +8 -10
  36. jaclang/langserve/tests/fixtures/base_module_structure.jac +27 -6
  37. jaclang/langserve/tests/fixtures/circle.jac +3 -3
  38. jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
  39. jaclang/langserve/tests/fixtures/circle_pure.test.jac +3 -3
  40. jaclang/langserve/tests/fixtures/import_include_statements.jac +1 -1
  41. jaclang/langserve/tests/test_sem_tokens.py +277 -0
  42. jaclang/langserve/tests/test_server.py +96 -16
  43. jaclang/langserve/utils.py +163 -96
  44. jaclang/plugin/builtin.py +1 -1
  45. jaclang/plugin/default.py +214 -24
  46. jaclang/plugin/feature.py +59 -11
  47. jaclang/plugin/spec.py +58 -6
  48. jaclang/{core → runtimelib}/architype.py +1 -1
  49. jaclang/{core → runtimelib}/context.py +8 -1
  50. jaclang/runtimelib/importer.py +361 -0
  51. jaclang/runtimelib/machine.py +94 -0
  52. jaclang/{core → runtimelib}/utils.py +13 -5
  53. jaclang/settings.py +4 -1
  54. jaclang/tests/fixtures/abc.jac +3 -3
  55. jaclang/tests/fixtures/blankwithentry.jac +3 -0
  56. jaclang/tests/fixtures/byllmissue.jac +1 -5
  57. jaclang/tests/fixtures/chandra_bugs2.jac +11 -10
  58. jaclang/tests/fixtures/cls_method.jac +41 -0
  59. jaclang/tests/fixtures/dblhello.jac +6 -0
  60. jaclang/tests/fixtures/deep/one_lev.jac +3 -3
  61. jaclang/tests/fixtures/deep/one_lev_dup.jac +2 -3
  62. jaclang/tests/fixtures/deep_import_mods.jac +13 -0
  63. jaclang/tests/fixtures/err.impl.jac +3 -0
  64. jaclang/tests/fixtures/err.jac +4 -2
  65. jaclang/tests/fixtures/err.test.jac +3 -0
  66. jaclang/tests/fixtures/err_runtime.jac +15 -0
  67. jaclang/tests/fixtures/game1.jac +1 -1
  68. jaclang/tests/fixtures/hello.jac +4 -0
  69. jaclang/tests/fixtures/impl_grab.impl.jac +2 -1
  70. jaclang/tests/fixtures/impl_grab.jac +4 -1
  71. jaclang/tests/fixtures/jp_importer_auto.jac +14 -0
  72. jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
  73. jaclang/tests/fixtures/needs_import.jac +2 -2
  74. jaclang/tests/fixtures/pyfunc_2.py +3 -0
  75. jaclang/tests/fixtures/registry.jac +9 -0
  76. jaclang/tests/fixtures/run_test.jac +4 -4
  77. jaclang/tests/fixtures/semstr.jac +1 -4
  78. jaclang/tests/fixtures/simple_archs.jac +1 -1
  79. jaclang/tests/test_cli.py +65 -2
  80. jaclang/tests/test_language.py +83 -7
  81. jaclang/tests/test_man_code.py +17 -0
  82. jaclang/tests/test_reference.py +6 -0
  83. jaclang/utils/helpers.py +45 -21
  84. jaclang/utils/test.py +9 -0
  85. jaclang/utils/treeprinter.py +0 -4
  86. {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/METADATA +3 -2
  87. {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/RECORD +93 -77
  88. jaclang/core/importer.py +0 -344
  89. jaclang/tests/fixtures/aott_raise.jac +0 -25
  90. jaclang/tests/fixtures/package_import.jac +0 -6
  91. /jaclang/{core → runtimelib}/__init__.py +0 -0
  92. /jaclang/{core → runtimelib}/constructs.py +0 -0
  93. /jaclang/{core → runtimelib}/memory.py +0 -0
  94. /jaclang/{core → runtimelib}/test.py +0 -0
  95. {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/WHEEL +0 -0
  96. {jaclang-0.7.13.dist-info → jaclang-0.7.16.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,277 @@
1
+ """Test Semantic Tokens Update."""
2
+
3
+ import copy
4
+ import lsprotocol.types as lspt
5
+
6
+ from jaclang.langserve.sem_manager import SemTokManager
7
+ from jaclang.utils.test import TestCase
8
+
9
+ from typing import Tuple
10
+
11
+
12
+ class TestUpdateSemTokens(TestCase):
13
+ """Test update semantic tokens"""
14
+
15
+ def setUp(self) -> None:
16
+ """Set up test."""
17
+ # fmt: off
18
+ self.initial_sem_tokens = [
19
+ 1, 10, 4, 0, 2, 3, 4, 14, 12, 1, 0, 15, 6, 7, 1, 0, 8, 5, 2, 1,
20
+ 0, 10, 5, 2, 1, 1, 11, 4, 0, 2, 0, 10, 6, 7, 1, 0, 9, 6, 7, 1
21
+ ]
22
+ # fmt: on
23
+
24
+ self.document_lines = [
25
+ "",
26
+ "import:py math;",
27
+ "",
28
+ '"""Function to calculate the area of a circle."""',
29
+ "can calculate_area(radius: float) -> float {",
30
+ " return math.pi * radius * radius;",
31
+ "}",
32
+ " ",
33
+ ]
34
+
35
+ def check_semantic_token_update(self, case: Tuple, expected_output: str) -> None:
36
+ """Check semantic token update."""
37
+ doc_lines = copy.deepcopy(self.document_lines)
38
+
39
+ updated_semtokens = SemTokManager.update_sem_tokens(
40
+ "circle_ir",
41
+ lspt.DidChangeTextDocumentParams(
42
+ text_document=lspt.VersionedTextDocumentIdentifier(
43
+ version=32,
44
+ uri="...jaclang/examples/manual_code/circle.jac",
45
+ ),
46
+ content_changes=[
47
+ lspt.TextDocumentContentChangeEvent_Type1(
48
+ range=lspt.Range(start=case[0], end=case[1]),
49
+ text=case[2],
50
+ range_length=case[3],
51
+ )
52
+ ],
53
+ ),
54
+ sem_tokens=copy.deepcopy(self.initial_sem_tokens),
55
+ document_lines=doc_lines,
56
+ )
57
+ self.assertIn(
58
+ expected_output, str(updated_semtokens), f"\nFailed for case: {case[4]}"
59
+ )
60
+
61
+ def test_multiline_before_first_token(self) -> None:
62
+ """Test multiline before first token."""
63
+ case = (
64
+ lspt.Position(line=0, character=0),
65
+ lspt.Position(line=0, character=0),
66
+ "\n",
67
+ 0,
68
+ "Multiline before first token (Basic)",
69
+ )
70
+ self.document_lines.insert(1, "")
71
+ self.check_semantic_token_update(case, "2, 10, 4, 0, 2, 3, 4, 14,")
72
+
73
+ def test_multiline_between_tokens(self) -> None:
74
+ """Test multiline between tokens."""
75
+ case = (
76
+ lspt.Position(line=5, character=19),
77
+ lspt.Position(line=5, character=19),
78
+ "\n ",
79
+ 0,
80
+ "Multiline between tokens (Basic)",
81
+ )
82
+ self.document_lines[5] = " return math.pi "
83
+ self.document_lines.insert(6, " * radius * radius;")
84
+ self.check_semantic_token_update(case, "2, 1, 6, 6, 7, 1, ")
85
+
86
+ def test_multiline_at_end_of_line(self) -> None:
87
+ """Test multiline at end of line."""
88
+ case = (
89
+ lspt.Position(line=4, character=37),
90
+ lspt.Position(line=4, character=37),
91
+ "\n",
92
+ 0,
93
+ "Multiline at end of line",
94
+ )
95
+ self.document_lines[4] = "can calculate_area(radius: float) -> "
96
+ self.document_lines.insert(5, "float {")
97
+ self.check_semantic_token_update(case, " 2, 1, 1, 0, 5, 2, 1, ")
98
+
99
+ def test_sameline_space_between_tokens(self) -> None:
100
+ """Test sameline space between tokens."""
101
+ case = (
102
+ lspt.Position(line=5, character=20),
103
+ lspt.Position(line=5, character=20),
104
+ " ",
105
+ 0,
106
+ "Sameline space between tokens (Basic)",
107
+ )
108
+ self.check_semantic_token_update(case, "0, 11, 6, 7, 1,")
109
+
110
+ def test_sameline_tab_between_tokens(self) -> None:
111
+ """Test sameline tab between tokens."""
112
+ case = (
113
+ lspt.Position(line=5, character=20),
114
+ lspt.Position(line=5, character=20),
115
+ " ",
116
+ 0,
117
+ "Sameline tab between tokens (Basic)",
118
+ )
119
+ self.check_semantic_token_update(case, "0, 14, 6, 7, 1")
120
+
121
+ def test_tab_at_start_of_token(self) -> None:
122
+ """Test tab at start of token."""
123
+ case = (
124
+ lspt.Position(line=5, character=21),
125
+ lspt.Position(line=5, character=21),
126
+ " ",
127
+ 0,
128
+ "Tab at start of a token",
129
+ )
130
+ self.check_semantic_token_update(case, "0, 13, 6, 7, 1,")
131
+
132
+ def test_insert_inside_token(self) -> None:
133
+ """Test insert inside token."""
134
+ case = (
135
+ lspt.Position(line=5, character=13),
136
+ lspt.Position(line=5, character=13),
137
+ "calculate",
138
+ 0,
139
+ "insert inside a token",
140
+ )
141
+ self.check_semantic_token_update(case, "1, 11, 13, 0, 2, 0, 19, 6, 7, 1")
142
+
143
+ def test_insert_inside_token_selected_range(self) -> None:
144
+ """Test insert inside token selected range."""
145
+ case = (
146
+ lspt.Position(line=5, character=12),
147
+ lspt.Position(line=5, character=14),
148
+ "calculate",
149
+ 2,
150
+ "insert inside a token in a selected range",
151
+ )
152
+ self.check_semantic_token_update(case, "1, 11, 11, 0, 2, 0, 17, 6, 7, 1,")
153
+
154
+ def test_newline_at_start_of_token(self) -> None:
155
+ """Test newline at start of token."""
156
+ case = (
157
+ lspt.Position(line=5, character=21),
158
+ lspt.Position(line=5, character=21),
159
+ "\n ",
160
+ 0,
161
+ "Newline at start of a token",
162
+ )
163
+ self.document_lines[5] = " return math.pi * "
164
+ self.document_lines.insert(6, " radius * radius;")
165
+ self.check_semantic_token_update(case, "0, 2, 1, 4, 6, 7, 1, 0")
166
+
167
+ def test_newline_after_parenthesis(self) -> None:
168
+ """Test newline after parenthesis."""
169
+ case = (
170
+ lspt.Position(line=4, character=19),
171
+ lspt.Position(line=4, character=19),
172
+ "\n ",
173
+ 0,
174
+ "Newline after parenthesis",
175
+ )
176
+ self.document_lines[4] = "can calculate_area("
177
+ self.document_lines.insert(5, " radius: float) -> float {")
178
+ self.check_semantic_token_update(case, "12, 1, 1, 4, 6, 7, 1, 0, 8")
179
+
180
+ def test_insert_newline_at_end_of_token(self) -> None:
181
+ """Test insert newline at end of token."""
182
+ case = (
183
+ lspt.Position(line=5, character=27),
184
+ lspt.Position(line=5, character=27),
185
+ "\n ",
186
+ 0,
187
+ "Insert Newline at end of a token",
188
+ )
189
+ self.document_lines[5] = " return math.pi * radius"
190
+ self.document_lines.insert(6, " * radius;")
191
+ self.check_semantic_token_update(case, "7, 1, 1, 7, 6, 7")
192
+
193
+ def test_deletion_basic(self) -> None:
194
+ """Test deletion basic."""
195
+ case = (
196
+ lspt.Position(line=5, character=4),
197
+ lspt.Position(line=5, character=4),
198
+ "",
199
+ 4,
200
+ "Deletion Basic",
201
+ )
202
+ self.check_semantic_token_update(case, "0, 10, 5, 2, 1, 1, 7, 4, 0, 2, 0")
203
+
204
+ def test_multiline_deletion(self) -> None:
205
+ """Test multiline deletion."""
206
+ case = (
207
+ lspt.Position(line=3, character=49),
208
+ lspt.Position(line=4, character=0),
209
+ "",
210
+ 4,
211
+ "Multiline Deletion",
212
+ )
213
+ self.document_lines[3] = (
214
+ '"""Function to calculate the area of a circle."""can calculate_area(radius: float) -> float {'
215
+ )
216
+ del self.document_lines[4]
217
+ self.check_semantic_token_update(case, "2, 2, 53, 14, 12, 1, 0")
218
+
219
+ def test_single_deletion_inside_token(self) -> None:
220
+ """Test single deletion inside token."""
221
+ case = (
222
+ lspt.Position(line=5, character=12),
223
+ lspt.Position(line=5, character=13),
224
+ "",
225
+ 1,
226
+ "single Deletion inside token",
227
+ )
228
+ self.check_semantic_token_update(case, "1, 1, 11, 3, 0, 2, 0, 9, 6")
229
+
230
+ def test_deletion_inside_token_selected_range(self) -> None:
231
+ """Test deletion inside token selected range."""
232
+ case = (
233
+ lspt.Position(line=4, character=10),
234
+ lspt.Position(line=4, character=15),
235
+ "",
236
+ 5,
237
+ "Deletion inside token- selected range",
238
+ )
239
+ self.check_semantic_token_update(case, "4, 9, 12, 1, 0, 10, 6")
240
+
241
+ def test_selected_multiline_deletion(self) -> None:
242
+ """Test selected multiline deletion."""
243
+ case = (
244
+ lspt.Position(line=4, character=44),
245
+ lspt.Position(line=5, character=4),
246
+ "",
247
+ 5,
248
+ "selected Multi line Deletion",
249
+ )
250
+ self.document_lines[3] = (
251
+ "can calculate_area(radius: float) -> float {return math.pi * radius * radius;"
252
+ )
253
+ del self.document_lines[4]
254
+ self.check_semantic_token_update(case, "4, 0, 2, 3, 4, 14, 12, 1, 0, 15")
255
+
256
+ def test_multi_line_insert_on_selected_region(self) -> None:
257
+ """Test multi line insert on selected region."""
258
+ case = (
259
+ lspt.Position(line=4, character=26),
260
+ lspt.Position(line=4, character=27),
261
+ ':= a + a // 2) > 5 {\n print("b is grater than 5");\n }',
262
+ 1,
263
+ "multi line insert on selected region ",
264
+ )
265
+ self.document_lines = [
266
+ "",
267
+ "import:py math;",
268
+ "",
269
+ '"""Function to calculate the area of a circle."""',
270
+ "can calculate_area(radius::= a + a // 2) > 5 {",
271
+ ' print("b is grater than 5");',
272
+ " }float) -> float {",
273
+ " return math.pi * radius * radius;",
274
+ "}",
275
+ " ",
276
+ ]
277
+ self.check_semantic_token_update(case, " 2, 1, 2, 14, 5, 2, 1, 1, ")
@@ -103,7 +103,7 @@ class TestJacLangServer(TestCase):
103
103
  lsp.lsp._workspace = workspace
104
104
  circle_file = uris.from_fs_path(self.fixture_abs_path("circle_pure.jac"))
105
105
  lsp.deep_check(circle_file)
106
- self.assertEqual(8, len(lsp.get_document_symbols(circle_file)))
106
+ self.assertEqual(8, len(lsp.get_outline(circle_file)))
107
107
 
108
108
  def test_go_to_definition(self) -> None:
109
109
  """Test that the go to definition is correct."""
@@ -119,7 +119,7 @@ class TestJacLangServer(TestCase):
119
119
  )
120
120
  self.assertIn(
121
121
  "fixtures/circle_pure.jac:13:11-13:16",
122
- str(lsp.get_definition(circle_file, lspt.Position(20, 17))),
122
+ str(lsp.get_definition(circle_file, lspt.Position(20, 16))),
123
123
  )
124
124
 
125
125
  def test_go_to_definition_method(self) -> None:
@@ -137,6 +137,30 @@ class TestJacLangServer(TestCase):
137
137
  str(lsp.get_definition(guess_game_file, lspt.Position(46, 45))),
138
138
  )
139
139
 
140
+ def test_go_to_definition_method_manual_impl(self) -> None:
141
+ """Test that the go to definition is correct."""
142
+ lsp = JacLangServer()
143
+ workspace_path = self.fixture_abs_path("")
144
+ workspace = Workspace(workspace_path, lsp)
145
+ lsp.lsp._workspace = workspace
146
+ decldef_file = uris.from_fs_path(
147
+ self.examples_abs_path("micro/decl_defs_impl.jac")
148
+ )
149
+ lsp.deep_check(decldef_file)
150
+ self.assertNotIn(
151
+ "decl_defs_main.jac:8:8-8:17",
152
+ str(lsp.get_definition(decldef_file, lspt.Position(2, 24))),
153
+ )
154
+ decldef_main_file = uris.from_fs_path(
155
+ self.examples_abs_path("micro/decl_defs_main.jac")
156
+ )
157
+ lsp.deep_check(decldef_main_file)
158
+ lsp.deep_check(decldef_file)
159
+ self.assertIn(
160
+ "decl_defs_main.jac:8:8-8:17",
161
+ str(lsp.get_definition(decldef_file, lspt.Position(2, 24))),
162
+ )
163
+
140
164
  def test_test_annex(self) -> None:
141
165
  """Test that the server doesn't run if there is a syntax error."""
142
166
  lsp = JacLangServer()
@@ -146,7 +170,7 @@ class TestJacLangServer(TestCase):
146
170
  lsp.lsp._workspace = workspace
147
171
  circle_file = uris.from_fs_path(self.fixture_abs_path("circle_pure.test.jac"))
148
172
  lsp.deep_check(circle_file)
149
- pos = lspt.Position(13, 29)
173
+ pos = lspt.Position(13, 21)
150
174
  self.assertIn(
151
175
  "shape_type: circle_pure.ShapeType",
152
176
  lsp.get_hover_info(circle_file, pos).contents.value,
@@ -163,7 +187,7 @@ class TestJacLangServer(TestCase):
163
187
  )
164
188
  lsp.deep_check(import_file)
165
189
  positions = [
166
- (2, 16, "datetime.py:0:0-0:0"),
190
+ (2, 24, "datetime.py:0:0-0:0"),
167
191
  (3, 17, "base_module_structure.jac:0:0-0:0"),
168
192
  (3, 87, "base_module_structure.jac:23:0-23:5"),
169
193
  (5, 65, "py_import.py:12:0-20:5"),
@@ -198,7 +222,7 @@ class TestJacLangServer(TestCase):
198
222
  ),
199
223
  (
200
224
  "<JacSemTokenType.FUNCTION: 12>, <JacSemTokenModifier.DECLARATION: 1>,",
201
- 9,
225
+ 6,
202
226
  ),
203
227
  ("<JacSemTokenType.METHOD: 13>, <JacSemTokenModifier.DECLARATION: 1>", 6),
204
228
  ("<JacSemTokenType.ENUM: 3>, <JacSemTokenModifier.DECLARATION: 1>,", 4),
@@ -208,6 +232,7 @@ class TestJacLangServer(TestCase):
208
232
  3,
209
233
  ),
210
234
  ]
235
+ print(str(sem_list))
211
236
  for token_type, expected_count in expected_counts:
212
237
  self.assertEqual(str(sem_list).count(token_type), expected_count)
213
238
 
@@ -222,32 +247,87 @@ class TestJacLangServer(TestCase):
222
247
  )
223
248
  lsp.deep_check(base_module_file)
224
249
  test_cases = [
225
- (lspt.Position(37, 16), ["get_color1", "color1", "point1"], 3),
250
+ (lspt.Position(38, 16), ["get_color1", "color1", "point1"], 3),
251
+ (lspt.Position(42, 22), ["RED", "GREEN", "BLUE"], 3),
252
+ (lspt.Position(42, 33), ["RED", "GREEN", "BLUE"], 3),
253
+ (lspt.Position(42, 45), ["RED", "GREEN", "BLUE"], 3),
254
+ (lspt.Position(46, 20), ["RED22", "GREEN22", "BLUE22"], 3),
255
+ (lspt.Position(46, 30), ["RED22", "GREEN22", "BLUE22"], 3),
256
+ (lspt.Position(46, 41), ["RED22", "GREEN22", "BLUE22"], 3),
257
+ (
258
+ lspt.Position(51, 32),
259
+ ["RED22", "GREEN22", "BLUE22"],
260
+ 3,
261
+ ),
226
262
  (
227
- lspt.Position(51, 12),
263
+ lspt.Position(65, 13),
228
264
  [
229
265
  "get_color1",
230
266
  "color1",
231
267
  "point1",
232
268
  "base_colorred",
233
269
  "pointred",
234
- "color2",
270
+ "inner_red",
271
+ "doubleinner",
272
+ "apply_red",
235
273
  ],
236
- 6,
274
+ 8,
275
+ ),
276
+ (
277
+ lspt.Position(65, 23),
278
+ ["color22", "doublepoint22", "point22", "apply_inner_red", "enum_red"],
279
+ 5,
280
+ ),
281
+ (
282
+ lspt.Position(65, 31),
283
+ ["RED22", "GREEN22", "BLUE22"],
284
+ 3,
285
+ ),
286
+ (
287
+ lspt.Position(35, 28),
288
+ [],
289
+ 0,
290
+ ),
291
+ (
292
+ lspt.Position(72, 12),
293
+ [
294
+ "get_color1",
295
+ "color1",
296
+ "point1",
297
+ "base_colorred",
298
+ "pointred",
299
+ "inner_red",
300
+ "doubleinner",
301
+ "apply_red",
302
+ ],
303
+ 8,
304
+ ),
305
+ (
306
+ lspt.Position(73, 22),
307
+ ["color22", "doublepoint22", "apply_inner_red", "point22", "enum_red"],
308
+ 5,
309
+ ),
310
+ (
311
+ lspt.Position(37, 12),
312
+ ["self", "add", "subtract", "x", "Colorenum", "Colour1", "red", "r"],
313
+ 8,
314
+ None,
237
315
  ),
238
- (lspt.Position(52, 19), ["color22", "point22"], 2),
239
316
  ]
240
- for position, expected_completions, expected_length in test_cases:
317
+ default_trigger = "."
318
+ for case in test_cases:
319
+ position, expected_completions, expected_length = case[:3]
320
+ completion_trigger = case[3] if len(case) > 3 else default_trigger
241
321
  completions = lsp.get_completion(
242
- base_module_file, position, completion_trigger="."
322
+ base_module_file, position, completion_trigger=completion_trigger
243
323
  ).items
244
324
  for completion in expected_completions:
245
325
  self.assertIn(completion, str(completions))
246
326
  self.assertEqual(expected_length, len(completions))
247
327
 
248
- if position == lspt.Position(47, 12):
328
+ if position == lspt.Position(73, 12):
249
329
  self.assertEqual(
250
- 1, str(completions).count("kind=<CompletionItemKind.Function: 3>")
330
+ 2, str(completions).count("kind=<CompletionItemKind.Function: 3>")
251
331
  )
252
332
  self.assertEqual(
253
333
  4, str(completions).count("kind=<CompletionItemKind.Field: 5>")
@@ -264,8 +344,8 @@ class TestJacLangServer(TestCase):
264
344
  lsp.deep_check(circle_file)
265
345
  test_cases = [
266
346
  (47, 12, ["circle.jac:47:8-47:14", "69:8-69:14", "74:8-74:14"]),
267
- (54, 66, ["54:62-54:76", "65:28-65:42"]),
268
- (62, 14, ["65:49-65:62", "70:38-70:51"]),
347
+ (54, 66, ["54:62-54:76", "65:22-65:36"]),
348
+ (62, 14, ["65:43-65:56", "70:32-70:45"]),
269
349
  ]
270
350
  for line, char, expected_refs in test_cases:
271
351
  references = str(lsp.get_references(circle_file, lspt.Position(line, char)))