jaclang 0.8.1__py3-none-any.whl → 0.8.2__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/__init__.py +6 -0
- jaclang/cli/cli.py +21 -50
- jaclang/compiler/codeinfo.py +0 -1
- jaclang/compiler/jac.lark +12 -10
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +18 -10
- jaclang/compiler/passes/main/__init__.py +0 -14
- jaclang/compiler/passes/main/annex_pass.py +2 -8
- jaclang/compiler/passes/main/cfg_build_pass.py +38 -12
- jaclang/compiler/passes/main/import_pass.py +3 -11
- jaclang/compiler/passes/main/pyast_gen_pass.py +243 -592
- jaclang/compiler/passes/main/sym_tab_link_pass.py +2 -5
- jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +2 -8
- jaclang/compiler/passes/main/tests/test_decl_impl_match_pass.py +7 -8
- jaclang/compiler/passes/main/tests/test_import_pass.py +5 -18
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -6
- jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -3
- jaclang/compiler/passes/main/tests/test_sym_tab_link_pass.py +20 -17
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +237 -105
- jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -0
- jaclang/compiler/passes/tool/tests/fixtures/archetype_frmt.jac +14 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +5 -4
- jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +6 -0
- jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +3 -3
- jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +9 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +18 -3
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
- jaclang/compiler/program.py +21 -60
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +2 -8
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +1 -5
- jaclang/compiler/tests/test_importer.py +10 -13
- jaclang/compiler/unitree.py +32 -16
- jaclang/langserve/__init__.jac +1 -1
- jaclang/langserve/engine.jac +113 -108
- jaclang/langserve/server.jac +17 -2
- jaclang/langserve/tests/server_test/test_lang_serve.py +138 -46
- jaclang/langserve/tests/server_test/utils.py +35 -9
- jaclang/langserve/tests/test_sem_tokens.py +1 -1
- jaclang/langserve/tests/test_server.py +3 -7
- jaclang/runtimelib/archetype.py +127 -5
- jaclang/runtimelib/importer.py +51 -94
- jaclang/runtimelib/machine.py +391 -268
- jaclang/runtimelib/meta_importer.py +86 -0
- jaclang/runtimelib/tests/fixtures/graph_purger.jac +24 -26
- jaclang/runtimelib/tests/fixtures/other_root_access.jac +25 -16
- jaclang/runtimelib/tests/test_jaseci.py +3 -1
- jaclang/tests/fixtures/arch_rel_import_creation.jac +23 -23
- jaclang/tests/fixtures/async_ability.jac +43 -10
- jaclang/tests/fixtures/async_function.jac +18 -0
- jaclang/tests/fixtures/async_walker.jac +17 -12
- jaclang/tests/fixtures/create_dynamic_archetype.jac +25 -28
- jaclang/tests/fixtures/deep/deeper/deep_outer_import.jac +7 -4
- jaclang/tests/fixtures/deep/deeper/snd_lev.jac +2 -2
- jaclang/tests/fixtures/deep/deeper/snd_lev_dup.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +2 -2
- jaclang/tests/fixtures/deep/one_lev_dup.jac +4 -3
- jaclang/tests/fixtures/dynamic_archetype.jac +19 -12
- jaclang/tests/fixtures/foo.jac +14 -22
- jaclang/tests/fixtures/jac_from_py.py +1 -1
- jaclang/tests/fixtures/jp_importer.jac +6 -6
- jaclang/tests/fixtures/jp_importer_auto.jac +5 -3
- jaclang/tests/fixtures/unicode_strings.jac +24 -0
- jaclang/tests/fixtures/walker_update.jac +5 -7
- jaclang/tests/test_language.py +138 -140
- jaclang/tests/test_reference.py +9 -4
- jaclang/tests/test_typecheck.py +13 -26
- jaclang/utils/lang_tools.py +7 -5
- jaclang/utils/module_resolver.py +23 -0
- {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/METADATA +1 -1
- {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/RECORD +72 -70
- jaclang/compiler/passes/main/tests/fixtures/main_err.jac +0 -6
- jaclang/compiler/passes/main/tests/fixtures/second_err.jac +0 -4
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +0 -644
- jaclang/compiler/passes/tool/tests/test_doc_ir_gen_pass.py +0 -29
- jaclang/tests/fixtures/deep/deeper/__init__.jac +0 -1
- {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/WHEEL +0 -0
- {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/entry_points.txt +0 -0
jaclang/langserve/engine.jac
CHANGED
|
@@ -8,7 +8,6 @@ import from typing { Callable , Optional }
|
|
|
8
8
|
|
|
9
9
|
import jaclang.compiler.unitree as uni;
|
|
10
10
|
import from jaclang { JacMachineInterface as Jac }
|
|
11
|
-
import from jaclang.compiler.passes.main { CompilerMode as CMode }
|
|
12
11
|
import from jaclang.compiler.program { JacProgram }
|
|
13
12
|
import from jaclang.compiler.unitree { UniScopeNode }
|
|
14
13
|
import from sem_manager { SemTokManager }
|
|
@@ -33,9 +32,9 @@ class ModuleManager {
|
|
|
33
32
|
) -> None {
|
|
34
33
|
file_path = file_path.removeprefix('file://');
|
|
35
34
|
self.program.mod.hub[file_path] = build;
|
|
36
|
-
self.sem_managers[file_path] = SemTokManager(ir=build);
|
|
37
35
|
if update_annexed {
|
|
38
|
-
|
|
36
|
+
self.sem_managers[file_path] = SemTokManager(ir=build);
|
|
37
|
+
for (p, mod) in self.program.mod.hub.items() { if p != file_path {
|
|
39
38
|
self.sem_managers[p] = SemTokManager(ir=mod);
|
|
40
39
|
} }
|
|
41
40
|
}
|
|
@@ -43,8 +42,10 @@ class ModuleManager {
|
|
|
43
42
|
|
|
44
43
|
"""Remove errors and warnings for a specific file from the lists."""
|
|
45
44
|
def clear_alerts_for_file(self: ModuleManager, file_path_fs: str) -> None {
|
|
46
|
-
self.program.errors_had =
|
|
47
|
-
|
|
45
|
+
self.program.errors_had =
|
|
46
|
+
[ e for e in self.program.errors_had if e.loc.mod_path != file_path_fs ];
|
|
47
|
+
self.program.warnings_had =
|
|
48
|
+
[ w for w in self.program.warnings_had if w.loc.mod_path != file_path_fs ];
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -56,16 +57,17 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
56
57
|
LanguageServer.init(self, 'jac-lsp', 'v0.1');
|
|
57
58
|
JacProgram.init(self);
|
|
58
59
|
self.executor = ThreadPoolExecutor();
|
|
59
|
-
self.tasks: <>dict[(str,asyncio.Task)] = {};
|
|
60
|
-
self.sem_managers: <>dict[(str,SemTokManager)] = {};
|
|
60
|
+
self.tasks: <>dict[(str, asyncio.Task)] = {} ;
|
|
61
|
+
self.sem_managers: <>dict[(str, SemTokManager)] = {} ;
|
|
61
62
|
self.module_manager = ModuleManager(self, self.sem_managers);
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
"""Return diagnostics for all files as a dict {uri: diagnostics}."""
|
|
65
66
|
@ property
|
|
66
67
|
def diagnostics(self: JacLangServer, ) -> <>dict[str, <>list] {
|
|
67
|
-
result = {};
|
|
68
|
-
for file_path in self.mod.hub { uri = uris.from_fs_path(file_path); result[uri] =
|
|
68
|
+
result = {} ;
|
|
69
|
+
for file_path in self.mod.hub { uri = uris.from_fs_path(file_path); result[uri] =
|
|
70
|
+
utils.gen_diagnostics(uri, self.errors_had, self.warnings_had); }
|
|
69
71
|
return result;
|
|
70
72
|
}
|
|
71
73
|
|
|
@@ -90,28 +92,30 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
90
92
|
|
|
91
93
|
"""Rebuild a file (syntax only)."""
|
|
92
94
|
def quick_check(self: JacLangServer, file_path: str) -> bool {
|
|
93
|
-
try { file_path_fs = file_path.removeprefix('file://'); document =
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
try { file_path_fs = file_path.removeprefix('file://'); document =
|
|
96
|
+
self.workspace.get_text_document(file_path); self._clear_alerts_for_file(file_path_fs); build =
|
|
97
|
+
self.compile(use_str=document.source, file_path=document.path); self.update_modules(file_path_fs, build, need=False); self.publish_diagnostics(
|
|
96
98
|
file_path, utils.gen_diagnostics(
|
|
97
99
|
file_path, self.errors_had, self.warnings_had
|
|
98
100
|
)
|
|
99
|
-
);
|
|
101
|
+
); build_errors =
|
|
102
|
+
[ e for e in self.errors_had if e.loc.mod_path == file_path_fs ]; return len(build_errors) == 0; } except Exception as e { self.log_error(f"'Error during syntax check: '{e}"); return False; }
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
"""Rebuild a file and its dependencies (typecheck)."""
|
|
103
106
|
def deep_check(
|
|
104
107
|
self: JacLangServer, file_path: str, annex_view: Optional[str] = None
|
|
105
108
|
) -> bool {
|
|
106
|
-
try { start_time = time.time(); file_path_fs =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
+
try { start_time = time.time(); file_path_fs =
|
|
110
|
+
file_path.removeprefix('file://'); document =
|
|
111
|
+
self.workspace.get_text_document(file_path); self._clear_alerts_for_file(file_path_fs); build =
|
|
112
|
+
self.build(use_str=document.source, file_path=document.path); self.update_modules(file_path_fs, build); if build.annexable_by {
|
|
109
113
|
return self.deep_check(
|
|
110
114
|
uris.from_fs_path(build.annexable_by), annex_view=file_path
|
|
111
115
|
);
|
|
112
116
|
} self.publish_diagnostics(
|
|
113
|
-
annex_view if annex_view else file_path
|
|
114
|
-
annex_view if annex_view else file_path
|
|
117
|
+
annex_view if annex_view else file_path, utils.gen_diagnostics(
|
|
118
|
+
annex_view if annex_view else file_path, self.errors_had, self.warnings_had
|
|
115
119
|
)
|
|
116
120
|
); if annex_view {
|
|
117
121
|
self.publish_diagnostics(
|
|
@@ -121,12 +125,12 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
121
125
|
);
|
|
122
126
|
} self.log_py(
|
|
123
127
|
f"'PROFILE: Deep check took '{(time.time() - start_time)}' seconds.'"
|
|
124
|
-
); return len(self.errors_had) == 0;
|
|
128
|
+
); return len(self.errors_had) == 0; } except Exception as e { self.log_py(f"'Error during deep check: '{e}"); return False; }
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
"""Analyze and publish diagnostics."""
|
|
128
|
-
async def launch_quick_check(self: JacLangServer, uri: str) ->
|
|
129
|
-
await asyncio.get_event_loop().run_in_executor(
|
|
132
|
+
async def launch_quick_check(self: JacLangServer, uri: str) -> bool {
|
|
133
|
+
return await asyncio.get_event_loop().run_in_executor(
|
|
130
134
|
self.executor, self.quick_check, uri
|
|
131
135
|
);
|
|
132
136
|
}
|
|
@@ -134,7 +138,7 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
134
138
|
"""Analyze and publish diagnostics."""
|
|
135
139
|
async def launch_deep_check(self: JacLangServer, uri: str) -> None {
|
|
136
140
|
async def run_in_executor(
|
|
137
|
-
func: Callable[([str,Optional[str]],bool)], file_path: str, annex_view: Optional[str] = None
|
|
141
|
+
func: Callable[([str, Optional[str]], bool)], file_path: str, annex_view: Optional[str] = None
|
|
138
142
|
) -> None {
|
|
139
143
|
loop = asyncio.get_event_loop();
|
|
140
144
|
await loop.run_in_executor(self.executor, func, file_path, annex_view);
|
|
@@ -142,7 +146,7 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
142
146
|
if uri in self.tasks and not self.tasks[uri].done() {
|
|
143
147
|
self.log_py(f"'Canceling '{uri}' deep check...'");
|
|
144
148
|
self.tasks[uri].cancel();
|
|
145
|
-
del (self.tasks[uri],) ;
|
|
149
|
+
del (self.tasks[uri], ) ;
|
|
146
150
|
}
|
|
147
151
|
self.log_py(f"'Analyzing '{uri}'...'");
|
|
148
152
|
task = asyncio.create_task(run_in_executor(self.deep_check, uri));
|
|
@@ -154,49 +158,42 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
154
158
|
def get_completion(
|
|
155
159
|
self: JacLangServer, file_path: str, position: lspt.Position, completion_trigger: Optional[str]
|
|
156
160
|
) -> lspt.CompletionList {
|
|
157
|
-
document = self.workspace.get_text_document(file_path);
|
|
158
|
-
|
|
159
|
-
if not mod_ir {
|
|
161
|
+
try { document = self.workspace.get_text_document(file_path); mod_ir =
|
|
162
|
+
self.get_ir(file_path); if not mod_ir {
|
|
160
163
|
return lspt.CompletionList(is_incomplete=False, items=[]);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
node_selected = utils.find_deepest_symbol_node_at_pos(
|
|
172
|
-
mod_ir, position.line, (position.character - 2)
|
|
173
|
-
);
|
|
174
|
-
mod_tab = mod_ir.sym_tab if not node_selected else node_selected.sym_tab ;
|
|
175
|
-
current_symbol_table = mod_tab;
|
|
176
|
-
if completion_trigger == '.' {
|
|
164
|
+
} current_line = document.lines[position.line]; current_pos =
|
|
165
|
+
position.character; current_symbol_path =
|
|
166
|
+
utils.parse_symbol_path(current_line, current_pos); builtin_mod =
|
|
167
|
+
next(( mod for (name, mod) in self.mod.hub.items() if 'builtins' in name )); builtin_tab =
|
|
168
|
+
builtin_mod.sym_tab; assert isinstance(builtin_tab, UniScopeNode) ; completion_items =
|
|
169
|
+
[]; node_selected =
|
|
170
|
+
utils.find_deepest_symbol_node_at_pos(
|
|
171
|
+
mod_ir, position.line, (position.character - 2)
|
|
172
|
+
); mod_tab = mod_ir.sym_tab if not node_selected else node_selected.sym_tab; current_symbol_table =
|
|
173
|
+
mod_tab; if completion_trigger == '.' {
|
|
177
174
|
if current_symbol_path {
|
|
178
175
|
temp_tab = mod_tab;
|
|
179
176
|
for symbol in current_symbol_path { if symbol == 'self' {
|
|
180
|
-
is_ability_def =
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
177
|
+
is_ability_def =
|
|
178
|
+
temp_tab
|
|
179
|
+
if isinstance(temp_tab, uni.ImplDef)
|
|
180
|
+
else temp_tab.find_parent_of_type(uni.ImplDef);
|
|
184
181
|
if not is_ability_def {
|
|
185
182
|
archi_owner = mod_tab.find_parent_of_type(uni.Archetype);
|
|
186
|
-
temp_tab =
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
183
|
+
temp_tab =
|
|
184
|
+
archi_owner.sym_tab
|
|
185
|
+
if archi_owner and archi_owner.sym_tab
|
|
186
|
+
else mod_tab;
|
|
190
187
|
continue;
|
|
191
188
|
} else {
|
|
192
|
-
archi_owner =
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
temp_tab =
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
189
|
+
archi_owner =
|
|
190
|
+
is_ability_def.decl_link.find_parent_of_type(uni.Archetype)
|
|
191
|
+
if is_ability_def.decl_link
|
|
192
|
+
else None;
|
|
193
|
+
temp_tab =
|
|
194
|
+
archi_owner.sym_tab
|
|
195
|
+
if archi_owner and archi_owner.sym_tab
|
|
196
|
+
else temp_tab;
|
|
200
197
|
continue;
|
|
201
198
|
}
|
|
202
199
|
} symb = temp_tab.lookup(symbol); if symb {
|
|
@@ -204,14 +201,14 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
204
201
|
if fetc_tab {
|
|
205
202
|
temp_tab = fetc_tab;
|
|
206
203
|
} else {
|
|
207
|
-
temp_tab =
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
204
|
+
temp_tab =
|
|
205
|
+
symb.defn[0].type_sym_tab
|
|
206
|
+
if symb.defn[0].type_sym_tab
|
|
207
|
+
else temp_tab;
|
|
211
208
|
}
|
|
212
209
|
} else {
|
|
213
210
|
break;
|
|
214
|
-
}
|
|
211
|
+
} }
|
|
215
212
|
completion_items += utils.collect_all_symbols_in_scope(
|
|
216
213
|
temp_tab, up_tree=False
|
|
217
214
|
);
|
|
@@ -230,11 +227,14 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
230
227
|
} elif node_selected and node_selected.find_parent_of_type(uni.Archetype)
|
|
231
228
|
or node_selected.find_parent_of_type(uni.ImplDef)
|
|
232
229
|
{
|
|
233
|
-
self_symbol =
|
|
230
|
+
self_symbol =
|
|
231
|
+
|
|
232
|
+
[lspt.CompletionItem(
|
|
233
|
+
label='self', kind=lspt.CompletionItemKind.Variable
|
|
234
|
+
)];
|
|
234
235
|
} else {
|
|
235
236
|
self_symbol = [];
|
|
236
|
-
}
|
|
237
|
-
return lspt.CompletionList(is_incomplete=False, items=completion_items);
|
|
237
|
+
} return lspt.CompletionList(is_incomplete=False, items=completion_items); } except Exception as e { self.log_py(f"'Error during completion: '{e}"); return lspt.CompletionList(is_incomplete=False, items=[]); }
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
"""Rename module."""
|
|
@@ -242,27 +242,30 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
242
242
|
if old_path in self.mod.hub and new_path != old_path {
|
|
243
243
|
self.mod.hub[new_path] = self.mod.hub[old_path];
|
|
244
244
|
self.sem_managers[new_path] = self.sem_managers[old_path];
|
|
245
|
-
del (self.mod.hub[old_path],) ;
|
|
246
|
-
del (self.sem_managers[old_path],) ;
|
|
245
|
+
del (self.mod.hub[old_path], ) ;
|
|
246
|
+
del (self.sem_managers[old_path], ) ;
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
"""Delete module."""
|
|
251
251
|
def delete_module(self: JacLangServer, uri: str) -> None {
|
|
252
252
|
if uri in self.mod.hub {
|
|
253
|
-
del (self.mod.hub[uri],) ;
|
|
253
|
+
del (self.mod.hub[uri], ) ;
|
|
254
254
|
}
|
|
255
255
|
if uri in self.sem_managers {
|
|
256
|
-
del (self.sem_managers[uri],) ;
|
|
256
|
+
del (self.sem_managers[uri], ) ;
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
"""Return formatted jac."""
|
|
261
261
|
def formatted_jac(self: JacLangServer, file_path: str) -> <>list[lspt.TextEdit] {
|
|
262
|
-
try { document = self.workspace.get_text_document(file_path); formatted_text =
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
262
|
+
try { document = self.workspace.get_text_document(file_path); formatted_text =
|
|
263
|
+
JacProgram.jac_str_formatter(
|
|
264
|
+
source_str=document.source, file_path=document.path
|
|
265
|
+
); } except Exception as e { self.log_error(f"'Error during formatting: '{e}"); formatted_text =
|
|
266
|
+
document.source; }
|
|
267
|
+
return
|
|
268
|
+
[lspt.TextEdit(
|
|
266
269
|
range=lspt.Range(
|
|
267
270
|
start=lspt.Position(line=0, character=0), end=lspt.Position(
|
|
268
271
|
line=(len(document.source.splitlines()) + 1), character=0
|
|
@@ -283,14 +286,13 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
283
286
|
if not sem_mgr {
|
|
284
287
|
return None;
|
|
285
288
|
}
|
|
286
|
-
token_index =
|
|
287
|
-
sem_mgr.sem_tokens, position.line, position.character
|
|
288
|
-
);
|
|
289
|
+
token_index =
|
|
290
|
+
utils.find_index(sem_mgr.sem_tokens, position.line, position.character);
|
|
289
291
|
if token_index is None {
|
|
290
292
|
return None;
|
|
291
293
|
}
|
|
292
294
|
node_selected = sem_mgr.static_sem_tokens[token_index][3];
|
|
293
|
-
value = self.get_node_info(node_selected) if node_selected else None
|
|
295
|
+
value = self.get_node_info(node_selected) if node_selected else None;
|
|
294
296
|
if value {
|
|
295
297
|
return lspt.Hover(
|
|
296
298
|
contents=lspt.MarkupContent(
|
|
@@ -305,7 +307,8 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
305
307
|
def get_node_info(self: JacLangServer, <>node: uni.AstSymbolNode) -> Optional[str] {
|
|
306
308
|
try { if isinstance(<>node, uni.NameAtom) {
|
|
307
309
|
<>node = <>node.name_of;
|
|
308
|
-
} access = (<>node.sym.access.value + ' ') if <>node.sym else None
|
|
310
|
+
} access = (<>node.sym.access.value + ' ') if <>node.sym else None; node_info =
|
|
311
|
+
f"'('{access if access else ''}{<>node.sym_category.value}') '{<>node.sym_name}"; if <>node.name_spec.clean_type {
|
|
309
312
|
node_info += f"': '{<>node.name_spec.clean_type}";
|
|
310
313
|
} if isinstance(<>node, uni.AstDocNode) and <>node.doc {
|
|
311
314
|
node_info += f"'\n'{<>node.doc.value}";
|
|
@@ -338,9 +341,8 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
338
341
|
if not sem_mgr {
|
|
339
342
|
return None;
|
|
340
343
|
}
|
|
341
|
-
token_index =
|
|
342
|
-
sem_mgr.sem_tokens, position.line, position.character
|
|
343
|
-
);
|
|
344
|
+
token_index =
|
|
345
|
+
utils.find_index(sem_mgr.sem_tokens, position.line, position.character);
|
|
344
346
|
if token_index is None {
|
|
345
347
|
return None;
|
|
346
348
|
}
|
|
@@ -352,7 +354,7 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
352
354
|
{
|
|
353
355
|
spec = node_selected.parent.parent.abs_path;
|
|
354
356
|
if spec {
|
|
355
|
-
spec = spec[ 5 : ] if spec.startswith('File:') else spec
|
|
357
|
+
spec = spec[ 5 : ] if spec.startswith('File:') else spec;
|
|
356
358
|
return lspt.Location(
|
|
357
359
|
uri=uris.from_fs_path(spec), range=lspt.Range(
|
|
358
360
|
start=lspt.Position(line=0, character=0), end=lspt.Position(line=0, character=0)
|
|
@@ -364,12 +366,13 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
364
366
|
} elif node_selected.parent
|
|
365
367
|
and isinstance(node_selected.parent, uni.ModuleItem)
|
|
366
368
|
{
|
|
367
|
-
path =
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
369
|
+
path =
|
|
370
|
+
node_selected.parent.abs_path
|
|
371
|
+
or node_selected.parent.from_mod_path.abs_path
|
|
372
|
+
;
|
|
373
|
+
loc_range = (0, 0, 0, 0);
|
|
371
374
|
if path and loc_range {
|
|
372
|
-
path = path[ 5 : ] if path.startswith('File:') else path
|
|
375
|
+
path = path[ 5 : ] if path.startswith('File:') else path;
|
|
373
376
|
return lspt.Location(
|
|
374
377
|
uri=uris.from_fs_path(path), range=lspt.Range(
|
|
375
378
|
start=lspt.Position(
|
|
@@ -381,16 +384,15 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
381
384
|
} elif isinstance(node_selected, uni.ElementStmt) {
|
|
382
385
|
return None;
|
|
383
386
|
}
|
|
384
|
-
decl_node =
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
;
|
|
387
|
+
decl_node =
|
|
388
|
+
node_selected.parent.body.target
|
|
389
|
+
if node_selected.parent
|
|
390
|
+
and isinstance(node_selected.parent, uni.AstImplNeedingNode)
|
|
391
|
+
and isinstance(node_selected.parent.body, uni.ImplDef)
|
|
392
|
+
|
|
393
|
+
else node_selected.sym.decl
|
|
394
|
+
if node_selected.sym and node_selected.sym.decl
|
|
395
|
+
else node_selected;
|
|
394
396
|
if isinstance(decl_node, list) {
|
|
395
397
|
valid_path = decl_node[0].loc.mod_path;
|
|
396
398
|
} else {
|
|
@@ -402,7 +404,7 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
402
404
|
} else {
|
|
403
405
|
valid_range = decl_node.loc;
|
|
404
406
|
}
|
|
405
|
-
try { decl_range = utils.create_range(valid_range); } except ValueError { return None;
|
|
407
|
+
try { decl_range = utils.create_range(valid_range); } except ValueError { return None; }
|
|
406
408
|
decl_location = lspt.Location(uri=decl_uri, range=decl_range);
|
|
407
409
|
return decl_location;
|
|
408
410
|
} else {
|
|
@@ -422,15 +424,17 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
422
424
|
if not sem_mgr {
|
|
423
425
|
return [];
|
|
424
426
|
}
|
|
425
|
-
index1 =
|
|
427
|
+
index1 =
|
|
428
|
+
utils.find_index(sem_mgr.sem_tokens, position.line, position.character);
|
|
426
429
|
if index1 is None {
|
|
427
430
|
return [];
|
|
428
431
|
}
|
|
429
432
|
node_selected = sem_mgr.static_sem_tokens[index1][3];
|
|
430
433
|
if node_selected and node_selected.sym {
|
|
431
|
-
list_of_references: <>list[lspt.Location] =
|
|
432
|
-
|
|
433
|
-
|
|
434
|
+
list_of_references: <>list[lspt.Location] =
|
|
435
|
+
[ lspt.Location(
|
|
436
|
+
uri=uris.from_fs_path(<>node.loc.mod_path), range=utils.create_range(<>node.loc)
|
|
437
|
+
) for <>node in node_selected.sym.uses ];
|
|
434
438
|
return list_of_references;
|
|
435
439
|
}
|
|
436
440
|
return [];
|
|
@@ -448,16 +452,17 @@ class JacLangServer ( JacProgram , LanguageServer ) {
|
|
|
448
452
|
if not sem_mgr {
|
|
449
453
|
return None;
|
|
450
454
|
}
|
|
451
|
-
index1 =
|
|
455
|
+
index1 =
|
|
456
|
+
utils.find_index(sem_mgr.sem_tokens, position.line, position.character);
|
|
452
457
|
if index1 is None {
|
|
453
458
|
return None;
|
|
454
459
|
}
|
|
455
460
|
node_selected = sem_mgr.static_sem_tokens[index1][3];
|
|
456
461
|
if node_selected and node_selected.sym {
|
|
457
|
-
changes: <>dict[(str
|
|
458
|
-
for <>node in [*node_selected.sym.uses,node_selected.sym.defn[0]] { key =
|
|
459
|
-
|
|
460
|
-
|
|
462
|
+
changes: <>dict[(str, <>list[lspt.TextEdit])] = {} ;
|
|
463
|
+
for <>node in [*node_selected.sym.uses, node_selected.sym.defn[0]] { key =
|
|
464
|
+
uris.from_fs_path(<>node.loc.mod_path); new_edit =
|
|
465
|
+
lspt.TextEdit(range=utils.create_range(<>node.loc), new_text=new_name); utils.add_unique_text_edit(changes, key, new_edit); }
|
|
461
466
|
return lspt.WorkspaceEdit(changes=changes);
|
|
462
467
|
}
|
|
463
468
|
return None;
|
jaclang/langserve/server.jac
CHANGED
|
@@ -30,6 +30,10 @@ async def did_open(ls: JacLangServer, params: lspt.DidOpenTextDocumentParams) ->
|
|
|
30
30
|
@server.feature(lspt.TEXT_DOCUMENT_DID_SAVE)
|
|
31
31
|
async def did_save(ls: JacLangServer, params: lspt.DidOpenTextDocumentParams) -> None {
|
|
32
32
|
file_path = params.text_document.uri;
|
|
33
|
+
quick_check_passed = await ls.launch_quick_check(file_path);
|
|
34
|
+
if not quick_check_passed {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
33
37
|
await ls.launch_deep_check(file_path);
|
|
34
38
|
ls.lsp.send_request(lspt.WORKSPACE_SEMANTIC_TOKENS_REFRESH);
|
|
35
39
|
}
|
|
@@ -42,8 +46,19 @@ async def did_change(
|
|
|
42
46
|
params: lspt.DidChangeTextDocumentParams
|
|
43
47
|
) -> None {
|
|
44
48
|
file_path = params.text_document.uri;
|
|
45
|
-
await ls.launch_quick_check(file_path);
|
|
46
|
-
|
|
49
|
+
quick_check_passed = await ls.launch_quick_check(file_path);
|
|
50
|
+
|
|
51
|
+
if quick_check_passed {
|
|
52
|
+
document = ls.workspace.get_text_document(file_path);
|
|
53
|
+
lines = document.source.splitlines();
|
|
54
|
+
sem_manager = ls.sem_managers[file_path.removeprefix('file://')];
|
|
55
|
+
sem_manager.update_sem_tokens(
|
|
56
|
+
params,sem_manager.sem_tokens,lines
|
|
57
|
+
);
|
|
58
|
+
ls.lsp.send_request(lspt.WORKSPACE_SEMANTIC_TOKENS_REFRESH);
|
|
59
|
+
await ls.launch_deep_check(file_path);
|
|
60
|
+
ls.lsp.send_request(lspt.WORKSPACE_SEMANTIC_TOKENS_REFRESH);
|
|
61
|
+
}
|
|
47
62
|
}
|
|
48
63
|
|
|
49
64
|
|