jaclang 0.0.5__py3-none-any.whl → 0.0.8__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 +2 -1
- jaclang/cli/__jac_gen__/__init__.py +0 -0
- jaclang/cli/__jac_gen__/cli.py +175 -0
- jaclang/cli/__jac_gen__/cmds.py +132 -0
- jaclang/cli/cli.jac +2 -2
- jaclang/cli/cmds.jac +8 -2
- jaclang/cli/impl/__jac_gen__/__init__.py +0 -0
- jaclang/cli/impl/__jac_gen__/cli_impl.py +16 -0
- jaclang/cli/impl/__jac_gen__/cmds_impl.py +26 -0
- jaclang/cli/impl/cli_impl.jac +25 -8
- jaclang/cli/impl/cmds_impl.jac +35 -6
- jaclang/core/__jac_gen__/__init__.py +0 -0
- jaclang/core/__jac_gen__/primitives.py +567 -0
- jaclang/core/impl/__jac_gen__/__init__.py +0 -0
- jaclang/core/impl/__jac_gen__/arch_impl.py +24 -0
- jaclang/core/impl/__jac_gen__/element_impl.py +26 -0
- jaclang/core/impl/__jac_gen__/exec_ctx_impl.py +12 -0
- jaclang/core/impl/__jac_gen__/memory_impl.py +14 -0
- jaclang/core/impl/element_impl.jac +3 -3
- jaclang/core/impl/exec_ctx_impl.jac +3 -6
- jaclang/core/primitives.jac +4 -3
- jaclang/jac/absyntree.py +555 -180
- jaclang/jac/constant.py +6 -0
- jaclang/jac/importer.py +34 -56
- jaclang/jac/langserve.py +26 -0
- jaclang/jac/lexer.py +35 -3
- jaclang/jac/parser.py +146 -115
- jaclang/jac/passes/blue/__init__.py +8 -3
- jaclang/jac/passes/blue/ast_build_pass.py +454 -305
- jaclang/jac/passes/blue/blue_pygen_pass.py +112 -74
- jaclang/jac/passes/blue/decl_def_match_pass.py +49 -277
- jaclang/jac/passes/blue/import_pass.py +1 -1
- jaclang/jac/passes/blue/pyout_pass.py +74 -0
- jaclang/jac/passes/blue/semantic_check_pass.py +37 -0
- jaclang/jac/passes/blue/sym_tab_build_pass.py +1045 -0
- jaclang/jac/passes/blue/tests/test_ast_build_pass.py +2 -2
- jaclang/jac/passes/blue/tests/test_blue_pygen_pass.py +9 -28
- jaclang/jac/passes/blue/tests/test_decl_def_match_pass.py +13 -22
- jaclang/jac/passes/blue/tests/test_sym_tab_build_pass.py +22 -0
- jaclang/jac/passes/ir_pass.py +8 -6
- jaclang/jac/passes/purple/__jac_gen__/__init__.py +0 -0
- jaclang/jac/passes/purple/__jac_gen__/analyze_pass.py +37 -0
- jaclang/jac/passes/purple/__jac_gen__/purple_pygen_pass.py +305 -0
- jaclang/jac/passes/purple/impl/__jac_gen__/__init__.py +0 -0
- jaclang/jac/passes/purple/impl/__jac_gen__/purple_pygen_pass_impl.py +23 -0
- jaclang/jac/passes/purple/impl/purple_pygen_pass_impl.jac +2 -5
- jaclang/jac/symtable.py +154 -0
- jaclang/jac/tests/fixtures/__jac_gen__/__init__.py +0 -0
- jaclang/jac/tests/fixtures/__jac_gen__/hello_world.py +16 -0
- jaclang/jac/tests/fixtures/fam.jac +7 -8
- jaclang/jac/tests/fixtures/mod_doc_test.jac +1 -0
- jaclang/jac/tests/test_parser.py +8 -0
- jaclang/jac/transform.py +41 -14
- jaclang/jac/transpiler.py +18 -9
- jaclang/utils/fstring_parser.py +2 -2
- jaclang/utils/helpers.py +41 -0
- jaclang/utils/lang_tools.py +12 -2
- jaclang/utils/test.py +41 -0
- jaclang/vendor/__init__.py +1 -0
- jaclang/vendor/pygls/__init__.py +25 -0
- jaclang/vendor/pygls/capabilities.py +502 -0
- jaclang/vendor/pygls/client.py +176 -0
- jaclang/vendor/pygls/constants.py +26 -0
- jaclang/vendor/pygls/exceptions.py +220 -0
- jaclang/vendor/pygls/feature_manager.py +241 -0
- jaclang/vendor/pygls/lsp/__init__.py +139 -0
- jaclang/vendor/pygls/lsp/client.py +2224 -0
- jaclang/vendor/pygls/lsprotocol/__init__.py +2 -0
- jaclang/vendor/pygls/lsprotocol/_hooks.py +1233 -0
- jaclang/vendor/pygls/lsprotocol/converters.py +17 -0
- jaclang/vendor/pygls/lsprotocol/types.py +12820 -0
- jaclang/vendor/pygls/lsprotocol/validators.py +47 -0
- jaclang/vendor/pygls/progress.py +79 -0
- jaclang/vendor/pygls/protocol.py +1184 -0
- jaclang/vendor/pygls/server.py +620 -0
- jaclang/vendor/pygls/uris.py +184 -0
- jaclang/vendor/pygls/workspace/__init__.py +81 -0
- jaclang/vendor/pygls/workspace/position.py +204 -0
- jaclang/vendor/pygls/workspace/text_document.py +234 -0
- jaclang/vendor/pygls/workspace/workspace.py +311 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/METADATA +1 -1
- jaclang-0.0.8.dist-info/RECORD +118 -0
- jaclang/core/jaclang.jac +0 -62
- jaclang/jac/passes/blue/tests/test_type_analyze_pass.py +0 -53
- jaclang/jac/passes/blue/type_analyze_pass.py +0 -728
- jaclang/jac/sym_table.py +0 -127
- jaclang-0.0.5.dist-info/RECORD +0 -73
- /jaclang/{utils → vendor}/sly/__init__.py +0 -0
- /jaclang/{utils → vendor}/sly/docparse.py +0 -0
- /jaclang/{utils → vendor}/sly/lex.py +0 -0
- /jaclang/{utils → vendor}/sly/yacc.py +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/WHEEL +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/entry_points.txt +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
############################################################################
|
|
2
|
+
# Copyright(c) Open Law Library. All rights reserved. #
|
|
3
|
+
# See ThirdPartyNotices.txt in the project root for additional notices. #
|
|
4
|
+
# #
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License") #
|
|
6
|
+
# you may not use this file except in compliance with the License. #
|
|
7
|
+
# You may obtain a copy of the License at #
|
|
8
|
+
# #
|
|
9
|
+
# http: // www.apache.org/licenses/LICENSE-2.0 #
|
|
10
|
+
# #
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software #
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
14
|
+
# See the License for the specific language governing permissions and #
|
|
15
|
+
# limitations under the License. #
|
|
16
|
+
############################################################################
|
|
17
|
+
from functools import reduce
|
|
18
|
+
from typing import Any, Dict, List, Optional, Set, Union
|
|
19
|
+
import logging
|
|
20
|
+
|
|
21
|
+
from jaclang.vendor.pygls.lsprotocol.types import (
|
|
22
|
+
INLAY_HINT_RESOLVE,
|
|
23
|
+
TEXT_DOCUMENT_CODE_ACTION,
|
|
24
|
+
TEXT_DOCUMENT_CODE_LENS,
|
|
25
|
+
TEXT_DOCUMENT_COMPLETION,
|
|
26
|
+
TEXT_DOCUMENT_DECLARATION,
|
|
27
|
+
TEXT_DOCUMENT_DEFINITION,
|
|
28
|
+
TEXT_DOCUMENT_DIAGNOSTIC,
|
|
29
|
+
TEXT_DOCUMENT_DOCUMENT_COLOR,
|
|
30
|
+
TEXT_DOCUMENT_DOCUMENT_HIGHLIGHT,
|
|
31
|
+
TEXT_DOCUMENT_DOCUMENT_LINK,
|
|
32
|
+
TEXT_DOCUMENT_DOCUMENT_SYMBOL,
|
|
33
|
+
TEXT_DOCUMENT_FOLDING_RANGE,
|
|
34
|
+
TEXT_DOCUMENT_FORMATTING,
|
|
35
|
+
TEXT_DOCUMENT_HOVER,
|
|
36
|
+
TEXT_DOCUMENT_IMPLEMENTATION,
|
|
37
|
+
TEXT_DOCUMENT_INLAY_HINT,
|
|
38
|
+
TEXT_DOCUMENT_INLINE_VALUE,
|
|
39
|
+
TEXT_DOCUMENT_ON_TYPE_FORMATTING,
|
|
40
|
+
TEXT_DOCUMENT_RANGE_FORMATTING,
|
|
41
|
+
TEXT_DOCUMENT_REFERENCES,
|
|
42
|
+
TEXT_DOCUMENT_RENAME,
|
|
43
|
+
TEXT_DOCUMENT_SELECTION_RANGE,
|
|
44
|
+
TEXT_DOCUMENT_SIGNATURE_HELP,
|
|
45
|
+
TEXT_DOCUMENT_PREPARE_CALL_HIERARCHY,
|
|
46
|
+
TEXT_DOCUMENT_PREPARE_TYPE_HIERARCHY,
|
|
47
|
+
TEXT_DOCUMENT_DID_CLOSE,
|
|
48
|
+
TEXT_DOCUMENT_DID_OPEN,
|
|
49
|
+
TEXT_DOCUMENT_DID_SAVE,
|
|
50
|
+
TEXT_DOCUMENT_LINKED_EDITING_RANGE,
|
|
51
|
+
TEXT_DOCUMENT_MONIKER,
|
|
52
|
+
TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL,
|
|
53
|
+
TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA,
|
|
54
|
+
TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE,
|
|
55
|
+
TEXT_DOCUMENT_WILL_SAVE,
|
|
56
|
+
TEXT_DOCUMENT_WILL_SAVE_WAIT_UNTIL,
|
|
57
|
+
TEXT_DOCUMENT_TYPE_DEFINITION,
|
|
58
|
+
WORKSPACE_DIAGNOSTIC,
|
|
59
|
+
WORKSPACE_DID_CREATE_FILES,
|
|
60
|
+
WORKSPACE_DID_DELETE_FILES,
|
|
61
|
+
WORKSPACE_DID_RENAME_FILES,
|
|
62
|
+
WORKSPACE_SYMBOL,
|
|
63
|
+
WORKSPACE_SYMBOL_RESOLVE,
|
|
64
|
+
WORKSPACE_WILL_CREATE_FILES,
|
|
65
|
+
WORKSPACE_WILL_DELETE_FILES,
|
|
66
|
+
WORKSPACE_WILL_RENAME_FILES,
|
|
67
|
+
InlayHintOptions,
|
|
68
|
+
PositionEncodingKind,
|
|
69
|
+
)
|
|
70
|
+
from jaclang.vendor.pygls.lsprotocol.types import (
|
|
71
|
+
ClientCapabilities,
|
|
72
|
+
CodeLensOptions,
|
|
73
|
+
CompletionOptions,
|
|
74
|
+
DocumentLinkOptions,
|
|
75
|
+
ExecuteCommandOptions,
|
|
76
|
+
ImplementationOptions,
|
|
77
|
+
NotebookDocumentSyncOptions,
|
|
78
|
+
SemanticTokensOptions,
|
|
79
|
+
SemanticTokensRegistrationOptions,
|
|
80
|
+
SemanticTokensOptionsFullType1,
|
|
81
|
+
ServerCapabilities,
|
|
82
|
+
ServerCapabilitiesWorkspaceType,
|
|
83
|
+
SignatureHelpOptions,
|
|
84
|
+
TextDocumentSyncKind,
|
|
85
|
+
TextDocumentSyncOptions,
|
|
86
|
+
TypeDefinitionOptions,
|
|
87
|
+
FileOperationOptions,
|
|
88
|
+
WorkspaceFoldersServerCapabilities,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
logger = logging.getLogger(__name__)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_capability(
|
|
95
|
+
client_capabilities: ClientCapabilities, field: str, default: Any = None
|
|
96
|
+
) -> Any:
|
|
97
|
+
"""Check if ClientCapabilities has some nested value without raising
|
|
98
|
+
AttributeError.
|
|
99
|
+
e.g. get_capability('text_document.synchronization.will_save')
|
|
100
|
+
"""
|
|
101
|
+
try:
|
|
102
|
+
value = reduce(getattr, field.split("."), client_capabilities)
|
|
103
|
+
except AttributeError:
|
|
104
|
+
return default
|
|
105
|
+
|
|
106
|
+
# If we reach the desired leaf value but it's None, return the default.
|
|
107
|
+
return default if value is None else value
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class ServerCapabilitiesBuilder:
|
|
111
|
+
"""Create `ServerCapabilities` instance depending on builtin and user registered
|
|
112
|
+
features.
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
def __init__(
|
|
116
|
+
self,
|
|
117
|
+
client_capabilities: ClientCapabilities,
|
|
118
|
+
features: Set[str],
|
|
119
|
+
feature_options: Dict[str, Any],
|
|
120
|
+
commands: List[str],
|
|
121
|
+
text_document_sync_kind: TextDocumentSyncKind,
|
|
122
|
+
notebook_document_sync: Optional[NotebookDocumentSyncOptions] = None,
|
|
123
|
+
):
|
|
124
|
+
self.client_capabilities = client_capabilities
|
|
125
|
+
self.features = features
|
|
126
|
+
self.feature_options = feature_options
|
|
127
|
+
self.commands = commands
|
|
128
|
+
self.text_document_sync_kind = text_document_sync_kind
|
|
129
|
+
self.notebook_document_sync = notebook_document_sync
|
|
130
|
+
|
|
131
|
+
self.server_cap = ServerCapabilities()
|
|
132
|
+
|
|
133
|
+
def _provider_options(self, feature, default=True):
|
|
134
|
+
if feature in self.features:
|
|
135
|
+
return self.feature_options.get(feature, default)
|
|
136
|
+
return None
|
|
137
|
+
|
|
138
|
+
def _with_text_document_sync(self):
|
|
139
|
+
open_close = (
|
|
140
|
+
TEXT_DOCUMENT_DID_OPEN in self.features
|
|
141
|
+
or TEXT_DOCUMENT_DID_CLOSE in self.features
|
|
142
|
+
)
|
|
143
|
+
will_save = (
|
|
144
|
+
get_capability(
|
|
145
|
+
self.client_capabilities, "text_document.synchronization.will_save"
|
|
146
|
+
)
|
|
147
|
+
and TEXT_DOCUMENT_WILL_SAVE in self.features
|
|
148
|
+
)
|
|
149
|
+
will_save_wait_until = (
|
|
150
|
+
get_capability(
|
|
151
|
+
self.client_capabilities,
|
|
152
|
+
"text_document.synchronization.will_save_wait_until",
|
|
153
|
+
)
|
|
154
|
+
and TEXT_DOCUMENT_WILL_SAVE_WAIT_UNTIL in self.features
|
|
155
|
+
)
|
|
156
|
+
if TEXT_DOCUMENT_DID_SAVE in self.features:
|
|
157
|
+
save = self.feature_options.get(TEXT_DOCUMENT_DID_SAVE, True)
|
|
158
|
+
else:
|
|
159
|
+
save = False
|
|
160
|
+
|
|
161
|
+
self.server_cap.text_document_sync = TextDocumentSyncOptions(
|
|
162
|
+
open_close=open_close,
|
|
163
|
+
change=self.text_document_sync_kind,
|
|
164
|
+
will_save=will_save,
|
|
165
|
+
will_save_wait_until=will_save_wait_until,
|
|
166
|
+
save=save,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
return self
|
|
170
|
+
|
|
171
|
+
def _with_notebook_document_sync(self):
|
|
172
|
+
if self.client_capabilities.notebook_document is None:
|
|
173
|
+
return self
|
|
174
|
+
|
|
175
|
+
self.server_cap.notebook_document_sync = self.notebook_document_sync
|
|
176
|
+
return self
|
|
177
|
+
|
|
178
|
+
def _with_completion(self):
|
|
179
|
+
value = self._provider_options(
|
|
180
|
+
TEXT_DOCUMENT_COMPLETION, default=CompletionOptions()
|
|
181
|
+
)
|
|
182
|
+
if value is not None:
|
|
183
|
+
self.server_cap.completion_provider = value
|
|
184
|
+
return self
|
|
185
|
+
|
|
186
|
+
def _with_hover(self):
|
|
187
|
+
value = self._provider_options(TEXT_DOCUMENT_HOVER)
|
|
188
|
+
if value is not None:
|
|
189
|
+
self.server_cap.hover_provider = value
|
|
190
|
+
return self
|
|
191
|
+
|
|
192
|
+
def _with_signature_help(self):
|
|
193
|
+
value = self._provider_options(
|
|
194
|
+
TEXT_DOCUMENT_SIGNATURE_HELP, default=SignatureHelpOptions()
|
|
195
|
+
)
|
|
196
|
+
if value is not None:
|
|
197
|
+
self.server_cap.signature_help_provider = value
|
|
198
|
+
return self
|
|
199
|
+
|
|
200
|
+
def _with_declaration(self):
|
|
201
|
+
value = self._provider_options(TEXT_DOCUMENT_DECLARATION)
|
|
202
|
+
if value is not None:
|
|
203
|
+
self.server_cap.declaration_provider = value
|
|
204
|
+
return self
|
|
205
|
+
|
|
206
|
+
def _with_definition(self):
|
|
207
|
+
value = self._provider_options(TEXT_DOCUMENT_DEFINITION)
|
|
208
|
+
if value is not None:
|
|
209
|
+
self.server_cap.definition_provider = value
|
|
210
|
+
return self
|
|
211
|
+
|
|
212
|
+
def _with_type_definition(self):
|
|
213
|
+
value = self._provider_options(
|
|
214
|
+
TEXT_DOCUMENT_TYPE_DEFINITION, default=TypeDefinitionOptions()
|
|
215
|
+
)
|
|
216
|
+
if value is not None:
|
|
217
|
+
self.server_cap.type_definition_provider = value
|
|
218
|
+
return self
|
|
219
|
+
|
|
220
|
+
def _with_inlay_hints(self):
|
|
221
|
+
value = self._provider_options(
|
|
222
|
+
TEXT_DOCUMENT_INLAY_HINT, default=InlayHintOptions()
|
|
223
|
+
)
|
|
224
|
+
if value is not None:
|
|
225
|
+
value.resolve_provider = INLAY_HINT_RESOLVE in self.features
|
|
226
|
+
self.server_cap.inlay_hint_provider = value
|
|
227
|
+
return self
|
|
228
|
+
|
|
229
|
+
def _with_implementation(self):
|
|
230
|
+
value = self._provider_options(
|
|
231
|
+
TEXT_DOCUMENT_IMPLEMENTATION, default=ImplementationOptions()
|
|
232
|
+
)
|
|
233
|
+
if value is not None:
|
|
234
|
+
self.server_cap.implementation_provider = value
|
|
235
|
+
return self
|
|
236
|
+
|
|
237
|
+
def _with_references(self):
|
|
238
|
+
value = self._provider_options(TEXT_DOCUMENT_REFERENCES)
|
|
239
|
+
if value is not None:
|
|
240
|
+
self.server_cap.references_provider = value
|
|
241
|
+
return self
|
|
242
|
+
|
|
243
|
+
def _with_document_highlight(self):
|
|
244
|
+
value = self._provider_options(TEXT_DOCUMENT_DOCUMENT_HIGHLIGHT)
|
|
245
|
+
if value is not None:
|
|
246
|
+
self.server_cap.document_highlight_provider = value
|
|
247
|
+
return self
|
|
248
|
+
|
|
249
|
+
def _with_document_symbol(self):
|
|
250
|
+
value = self._provider_options(TEXT_DOCUMENT_DOCUMENT_SYMBOL)
|
|
251
|
+
if value is not None:
|
|
252
|
+
self.server_cap.document_symbol_provider = value
|
|
253
|
+
return self
|
|
254
|
+
|
|
255
|
+
def _with_code_action(self):
|
|
256
|
+
value = self._provider_options(TEXT_DOCUMENT_CODE_ACTION)
|
|
257
|
+
if value is not None:
|
|
258
|
+
self.server_cap.code_action_provider = value
|
|
259
|
+
return self
|
|
260
|
+
|
|
261
|
+
def _with_code_lens(self):
|
|
262
|
+
value = self._provider_options(
|
|
263
|
+
TEXT_DOCUMENT_CODE_LENS, default=CodeLensOptions()
|
|
264
|
+
)
|
|
265
|
+
if value is not None:
|
|
266
|
+
self.server_cap.code_lens_provider = value
|
|
267
|
+
return self
|
|
268
|
+
|
|
269
|
+
def _with_document_link(self):
|
|
270
|
+
value = self._provider_options(
|
|
271
|
+
TEXT_DOCUMENT_DOCUMENT_LINK, default=DocumentLinkOptions()
|
|
272
|
+
)
|
|
273
|
+
if value is not None:
|
|
274
|
+
self.server_cap.document_link_provider = value
|
|
275
|
+
return self
|
|
276
|
+
|
|
277
|
+
def _with_color(self):
|
|
278
|
+
value = self._provider_options(TEXT_DOCUMENT_DOCUMENT_COLOR)
|
|
279
|
+
if value is not None:
|
|
280
|
+
self.server_cap.color_provider = value
|
|
281
|
+
return self
|
|
282
|
+
|
|
283
|
+
def _with_document_formatting(self):
|
|
284
|
+
value = self._provider_options(TEXT_DOCUMENT_FORMATTING)
|
|
285
|
+
if value is not None:
|
|
286
|
+
self.server_cap.document_formatting_provider = value
|
|
287
|
+
return self
|
|
288
|
+
|
|
289
|
+
def _with_document_range_formatting(self):
|
|
290
|
+
value = self._provider_options(TEXT_DOCUMENT_RANGE_FORMATTING)
|
|
291
|
+
if value is not None:
|
|
292
|
+
self.server_cap.document_range_formatting_provider = value
|
|
293
|
+
return self
|
|
294
|
+
|
|
295
|
+
def _with_document_on_type_formatting(self):
|
|
296
|
+
value = self._provider_options(TEXT_DOCUMENT_ON_TYPE_FORMATTING)
|
|
297
|
+
if value is not None:
|
|
298
|
+
self.server_cap.document_on_type_formatting_provider = value
|
|
299
|
+
return self
|
|
300
|
+
|
|
301
|
+
def _with_rename(self):
|
|
302
|
+
value = self._provider_options(TEXT_DOCUMENT_RENAME)
|
|
303
|
+
if value is not None:
|
|
304
|
+
self.server_cap.rename_provider = value
|
|
305
|
+
return self
|
|
306
|
+
|
|
307
|
+
def _with_folding_range(self):
|
|
308
|
+
value = self._provider_options(TEXT_DOCUMENT_FOLDING_RANGE)
|
|
309
|
+
if value is not None:
|
|
310
|
+
self.server_cap.folding_range_provider = value
|
|
311
|
+
return self
|
|
312
|
+
|
|
313
|
+
def _with_execute_command(self):
|
|
314
|
+
self.server_cap.execute_command_provider = ExecuteCommandOptions(
|
|
315
|
+
commands=self.commands
|
|
316
|
+
)
|
|
317
|
+
return self
|
|
318
|
+
|
|
319
|
+
def _with_selection_range(self):
|
|
320
|
+
value = self._provider_options(TEXT_DOCUMENT_SELECTION_RANGE)
|
|
321
|
+
if value is not None:
|
|
322
|
+
self.server_cap.selection_range_provider = value
|
|
323
|
+
return self
|
|
324
|
+
|
|
325
|
+
def _with_call_hierarchy(self):
|
|
326
|
+
value = self._provider_options(TEXT_DOCUMENT_PREPARE_CALL_HIERARCHY)
|
|
327
|
+
if value is not None:
|
|
328
|
+
self.server_cap.call_hierarchy_provider = value
|
|
329
|
+
return self
|
|
330
|
+
|
|
331
|
+
def _with_type_hierarchy(self):
|
|
332
|
+
value = self._provider_options(TEXT_DOCUMENT_PREPARE_TYPE_HIERARCHY)
|
|
333
|
+
if value is not None:
|
|
334
|
+
self.server_cap.type_hierarchy_provider = value
|
|
335
|
+
return self
|
|
336
|
+
|
|
337
|
+
def _with_semantic_tokens(self):
|
|
338
|
+
providers = [
|
|
339
|
+
TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL,
|
|
340
|
+
TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA,
|
|
341
|
+
TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE,
|
|
342
|
+
]
|
|
343
|
+
|
|
344
|
+
for provider in providers:
|
|
345
|
+
value = self._provider_options(provider, None)
|
|
346
|
+
if value:
|
|
347
|
+
break
|
|
348
|
+
|
|
349
|
+
if value is None:
|
|
350
|
+
return self
|
|
351
|
+
|
|
352
|
+
if isinstance(value, SemanticTokensRegistrationOptions):
|
|
353
|
+
self.server_cap.semantic_tokens_provider = value
|
|
354
|
+
return self
|
|
355
|
+
|
|
356
|
+
full_support: Union[bool, SemanticTokensOptionsFullType1] = (
|
|
357
|
+
TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL in self.features
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
if TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA in self.features:
|
|
361
|
+
full_support = SemanticTokensOptionsFullType1(delta=True)
|
|
362
|
+
|
|
363
|
+
options = SemanticTokensOptions(
|
|
364
|
+
legend=value,
|
|
365
|
+
full=full_support or None,
|
|
366
|
+
range=TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE in self.features or None,
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
if options.full or options.range:
|
|
370
|
+
self.server_cap.semantic_tokens_provider = options
|
|
371
|
+
|
|
372
|
+
return self
|
|
373
|
+
|
|
374
|
+
def _with_linked_editing_range(self):
|
|
375
|
+
value = self._provider_options(TEXT_DOCUMENT_LINKED_EDITING_RANGE)
|
|
376
|
+
if value is not None:
|
|
377
|
+
self.server_cap.linked_editing_range_provider = value
|
|
378
|
+
return self
|
|
379
|
+
|
|
380
|
+
def _with_moniker(self):
|
|
381
|
+
value = self._provider_options(TEXT_DOCUMENT_MONIKER)
|
|
382
|
+
if value is not None:
|
|
383
|
+
self.server_cap.moniker_provider = value
|
|
384
|
+
return self
|
|
385
|
+
|
|
386
|
+
def _with_workspace_symbol(self):
|
|
387
|
+
value = self._provider_options(WORKSPACE_SYMBOL)
|
|
388
|
+
if value is not None:
|
|
389
|
+
value.resolve_provider = self._provider_options(WORKSPACE_SYMBOL_RESOLVE)
|
|
390
|
+
self.server_cap.workspace_symbol_provider = value
|
|
391
|
+
return self
|
|
392
|
+
|
|
393
|
+
def _with_workspace_capabilities(self):
|
|
394
|
+
# File operations
|
|
395
|
+
file_operations = FileOperationOptions()
|
|
396
|
+
operations = [
|
|
397
|
+
(WORKSPACE_WILL_CREATE_FILES, "will_create"),
|
|
398
|
+
(WORKSPACE_DID_CREATE_FILES, "did_create"),
|
|
399
|
+
(WORKSPACE_WILL_DELETE_FILES, "will_delete"),
|
|
400
|
+
(WORKSPACE_DID_DELETE_FILES, "did_delete"),
|
|
401
|
+
(WORKSPACE_WILL_RENAME_FILES, "will_rename"),
|
|
402
|
+
(WORKSPACE_DID_RENAME_FILES, "did_rename"),
|
|
403
|
+
]
|
|
404
|
+
|
|
405
|
+
for method_name, capability_name in operations:
|
|
406
|
+
client_supports_method = get_capability(
|
|
407
|
+
self.client_capabilities, f"workspace.file_operations.{capability_name}"
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
if client_supports_method:
|
|
411
|
+
value = self._provider_options(method_name, None)
|
|
412
|
+
setattr(file_operations, capability_name, value)
|
|
413
|
+
|
|
414
|
+
self.server_cap.workspace = ServerCapabilitiesWorkspaceType(
|
|
415
|
+
workspace_folders=WorkspaceFoldersServerCapabilities(
|
|
416
|
+
supported=True,
|
|
417
|
+
change_notifications=True,
|
|
418
|
+
),
|
|
419
|
+
file_operations=file_operations,
|
|
420
|
+
)
|
|
421
|
+
return self
|
|
422
|
+
|
|
423
|
+
def _with_diagnostic_provider(self):
|
|
424
|
+
value = self._provider_options(TEXT_DOCUMENT_DIAGNOSTIC)
|
|
425
|
+
if value is not None:
|
|
426
|
+
value.workspace_diagnostics = self._provider_options(WORKSPACE_DIAGNOSTIC)
|
|
427
|
+
self.server_cap.diagnostic_provider = value
|
|
428
|
+
return self
|
|
429
|
+
|
|
430
|
+
def _with_inline_value_provider(self):
|
|
431
|
+
value = self._provider_options(TEXT_DOCUMENT_INLINE_VALUE)
|
|
432
|
+
if value is not None:
|
|
433
|
+
self.server_cap.inline_value_provider = value
|
|
434
|
+
return self
|
|
435
|
+
|
|
436
|
+
def _with_position_encodings(self):
|
|
437
|
+
self.server_cap.position_encoding = PositionEncodingKind.Utf16
|
|
438
|
+
|
|
439
|
+
general = self.client_capabilities.general
|
|
440
|
+
if general is None:
|
|
441
|
+
return self
|
|
442
|
+
|
|
443
|
+
encodings = general.position_encodings
|
|
444
|
+
if encodings is None:
|
|
445
|
+
return self
|
|
446
|
+
|
|
447
|
+
if PositionEncodingKind.Utf16 in encodings:
|
|
448
|
+
return self
|
|
449
|
+
|
|
450
|
+
if PositionEncodingKind.Utf32 in encodings:
|
|
451
|
+
self.server_cap.position_encoding = PositionEncodingKind.Utf32
|
|
452
|
+
return self
|
|
453
|
+
|
|
454
|
+
if PositionEncodingKind.Utf8 in encodings:
|
|
455
|
+
self.server_cap.position_encoding = PositionEncodingKind.Utf8
|
|
456
|
+
return self
|
|
457
|
+
|
|
458
|
+
logger.warning(f"Unknown `PositionEncoding`s: {encodings}")
|
|
459
|
+
|
|
460
|
+
return self
|
|
461
|
+
|
|
462
|
+
def _build(self):
|
|
463
|
+
return self.server_cap
|
|
464
|
+
|
|
465
|
+
def build(self):
|
|
466
|
+
return (
|
|
467
|
+
self._with_text_document_sync()
|
|
468
|
+
._with_notebook_document_sync()
|
|
469
|
+
._with_completion()
|
|
470
|
+
._with_hover()
|
|
471
|
+
._with_signature_help()
|
|
472
|
+
._with_declaration()
|
|
473
|
+
._with_definition()
|
|
474
|
+
._with_type_definition()
|
|
475
|
+
._with_inlay_hints()
|
|
476
|
+
._with_implementation()
|
|
477
|
+
._with_references()
|
|
478
|
+
._with_document_highlight()
|
|
479
|
+
._with_document_symbol()
|
|
480
|
+
._with_code_action()
|
|
481
|
+
._with_code_lens()
|
|
482
|
+
._with_document_link()
|
|
483
|
+
._with_color()
|
|
484
|
+
._with_document_formatting()
|
|
485
|
+
._with_document_range_formatting()
|
|
486
|
+
._with_document_on_type_formatting()
|
|
487
|
+
._with_rename()
|
|
488
|
+
._with_folding_range()
|
|
489
|
+
._with_execute_command()
|
|
490
|
+
._with_selection_range()
|
|
491
|
+
._with_call_hierarchy()
|
|
492
|
+
._with_type_hierarchy()
|
|
493
|
+
._with_semantic_tokens()
|
|
494
|
+
._with_linked_editing_range()
|
|
495
|
+
._with_moniker()
|
|
496
|
+
._with_workspace_symbol()
|
|
497
|
+
._with_workspace_capabilities()
|
|
498
|
+
._with_diagnostic_provider()
|
|
499
|
+
._with_inline_value_provider()
|
|
500
|
+
._with_position_encodings()
|
|
501
|
+
._build()
|
|
502
|
+
)
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
############################################################################
|
|
2
|
+
# Copyright(c) Open Law Library. All rights reserved. #
|
|
3
|
+
# See ThirdPartyNotices.txt in the project root for additional notices. #
|
|
4
|
+
# #
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License") #
|
|
6
|
+
# you may not use this file except in compliance with the License. #
|
|
7
|
+
# You may obtain a copy of the License at #
|
|
8
|
+
# #
|
|
9
|
+
# http: // www.apache.org/licenses/LICENSE-2.0 #
|
|
10
|
+
# #
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software #
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
14
|
+
# See the License for the specific language governing permissions and #
|
|
15
|
+
# limitations under the License. #
|
|
16
|
+
############################################################################
|
|
17
|
+
import asyncio
|
|
18
|
+
import logging
|
|
19
|
+
import re
|
|
20
|
+
from threading import Event
|
|
21
|
+
from typing import Any
|
|
22
|
+
from typing import Callable
|
|
23
|
+
from typing import List
|
|
24
|
+
from typing import Optional
|
|
25
|
+
from typing import Type
|
|
26
|
+
from typing import Union
|
|
27
|
+
|
|
28
|
+
from cattrs import Converter
|
|
29
|
+
|
|
30
|
+
from jaclang.vendor.pygls.exceptions import PyglsError, JsonRpcException
|
|
31
|
+
from jaclang.vendor.pygls.protocol import JsonRPCProtocol, default_converter
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
async def aio_readline(stop_event, reader, message_handler):
|
|
38
|
+
CONTENT_LENGTH_PATTERN = re.compile(rb"^Content-Length: (\d+)\r\n$")
|
|
39
|
+
|
|
40
|
+
# Initialize message buffer
|
|
41
|
+
message = []
|
|
42
|
+
content_length = 0
|
|
43
|
+
|
|
44
|
+
while not stop_event.is_set():
|
|
45
|
+
# Read a header line
|
|
46
|
+
header = await reader.readline()
|
|
47
|
+
if not header:
|
|
48
|
+
break
|
|
49
|
+
message.append(header)
|
|
50
|
+
|
|
51
|
+
# Extract content length if possible
|
|
52
|
+
if not content_length:
|
|
53
|
+
match = CONTENT_LENGTH_PATTERN.fullmatch(header)
|
|
54
|
+
if match:
|
|
55
|
+
content_length = int(match.group(1))
|
|
56
|
+
logger.debug("Content length: %s", content_length)
|
|
57
|
+
|
|
58
|
+
# Check if all headers have been read (as indicated by an empty line \r\n)
|
|
59
|
+
if content_length and not header.strip():
|
|
60
|
+
# Read body
|
|
61
|
+
body = await reader.readexactly(content_length)
|
|
62
|
+
if not body:
|
|
63
|
+
break
|
|
64
|
+
message.append(body)
|
|
65
|
+
|
|
66
|
+
# Pass message to protocol
|
|
67
|
+
message_handler(b"".join(message))
|
|
68
|
+
|
|
69
|
+
# Reset the buffer
|
|
70
|
+
message = []
|
|
71
|
+
content_length = 0
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class JsonRPCClient:
|
|
75
|
+
"""Base JSON-RPC client."""
|
|
76
|
+
|
|
77
|
+
def __init__(
|
|
78
|
+
self,
|
|
79
|
+
protocol_cls: Type[JsonRPCProtocol] = JsonRPCProtocol,
|
|
80
|
+
converter_factory: Callable[[], Converter] = default_converter,
|
|
81
|
+
):
|
|
82
|
+
# Strictly speaking `JsonRPCProtocol` wants a `LanguageServer`, not a
|
|
83
|
+
# `JsonRPCClient`. However there similar enough for our purposes, which is
|
|
84
|
+
# that this client will mostly be used in testing contexts.
|
|
85
|
+
self.protocol = protocol_cls(self, converter_factory()) # type: ignore
|
|
86
|
+
|
|
87
|
+
self._server: Optional[asyncio.subprocess.Process] = None
|
|
88
|
+
self._stop_event = Event()
|
|
89
|
+
self._async_tasks: List[asyncio.Task] = []
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def stopped(self) -> bool:
|
|
93
|
+
"""Return ``True`` if the client has been stopped."""
|
|
94
|
+
return self._stop_event.is_set()
|
|
95
|
+
|
|
96
|
+
def feature(
|
|
97
|
+
self,
|
|
98
|
+
feature_name: str,
|
|
99
|
+
options: Optional[Any] = None,
|
|
100
|
+
):
|
|
101
|
+
"""Decorator used to register LSP features.
|
|
102
|
+
|
|
103
|
+
Example
|
|
104
|
+
-------
|
|
105
|
+
::
|
|
106
|
+
|
|
107
|
+
import logging
|
|
108
|
+
from jaclang.vendor.pygls.client import JsonRPCClient
|
|
109
|
+
|
|
110
|
+
ls = JsonRPCClient()
|
|
111
|
+
|
|
112
|
+
@ls.feature('window/logMessage')
|
|
113
|
+
def completions(ls, params):
|
|
114
|
+
logging.info("%s", params.message)
|
|
115
|
+
"""
|
|
116
|
+
return self.protocol.fm.feature(feature_name, options)
|
|
117
|
+
|
|
118
|
+
async def start_io(self, cmd: str, *args, **kwargs):
|
|
119
|
+
"""Start the given server and communicate with it over stdio."""
|
|
120
|
+
|
|
121
|
+
logger.debug("Starting server process: %s", " ".join([cmd, *args]))
|
|
122
|
+
server = await asyncio.create_subprocess_exec(
|
|
123
|
+
cmd,
|
|
124
|
+
*args,
|
|
125
|
+
stdout=asyncio.subprocess.PIPE,
|
|
126
|
+
stdin=asyncio.subprocess.PIPE,
|
|
127
|
+
stderr=asyncio.subprocess.PIPE,
|
|
128
|
+
**kwargs,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
self.protocol.connection_made(server.stdin) # type: ignore
|
|
132
|
+
connection = asyncio.create_task(
|
|
133
|
+
aio_readline(self._stop_event, server.stdout, self.protocol.data_received)
|
|
134
|
+
)
|
|
135
|
+
notify_exit = asyncio.create_task(self._server_exit())
|
|
136
|
+
|
|
137
|
+
self._server = server
|
|
138
|
+
self._async_tasks.extend([connection, notify_exit])
|
|
139
|
+
|
|
140
|
+
async def _server_exit(self):
|
|
141
|
+
if self._server is not None:
|
|
142
|
+
await self._server.wait()
|
|
143
|
+
logger.debug(
|
|
144
|
+
"Server process %s exited with return code: %s",
|
|
145
|
+
self._server.pid,
|
|
146
|
+
self._server.returncode,
|
|
147
|
+
)
|
|
148
|
+
await self.server_exit(self._server)
|
|
149
|
+
self._stop_event.set()
|
|
150
|
+
|
|
151
|
+
async def server_exit(self, server: asyncio.subprocess.Process):
|
|
152
|
+
"""Called when the server process exits."""
|
|
153
|
+
|
|
154
|
+
def _report_server_error(
|
|
155
|
+
self, error: Exception, source: Union[PyglsError, JsonRpcException]
|
|
156
|
+
):
|
|
157
|
+
try:
|
|
158
|
+
self.report_server_error(error, source)
|
|
159
|
+
except Exception:
|
|
160
|
+
logger.error("Unable to report error", exc_info=True)
|
|
161
|
+
|
|
162
|
+
def report_server_error(
|
|
163
|
+
self, error: Exception, source: Union[PyglsError, JsonRpcException]
|
|
164
|
+
):
|
|
165
|
+
"""Called when the server does something unexpected e.g. respond with malformed
|
|
166
|
+
JSON."""
|
|
167
|
+
|
|
168
|
+
async def stop(self):
|
|
169
|
+
self._stop_event.set()
|
|
170
|
+
|
|
171
|
+
if self._server is not None and self._server.returncode is None:
|
|
172
|
+
logger.debug("Terminating server process: %s", self._server.pid)
|
|
173
|
+
self._server.terminate()
|
|
174
|
+
|
|
175
|
+
if len(self._async_tasks) > 0:
|
|
176
|
+
await asyncio.gather(*self._async_tasks)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
############################################################################
|
|
2
|
+
# Copyright(c) Open Law Library. All rights reserved. #
|
|
3
|
+
# See ThirdPartyNotices.txt in the project root for additional notices. #
|
|
4
|
+
# #
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License") #
|
|
6
|
+
# you may not use this file except in compliance with the License. #
|
|
7
|
+
# You may obtain a copy of the License at #
|
|
8
|
+
# #
|
|
9
|
+
# http: // www.apache.org/licenses/LICENSE-2.0 #
|
|
10
|
+
# #
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software #
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
14
|
+
# See the License for the specific language governing permissions and #
|
|
15
|
+
# limitations under the License. #
|
|
16
|
+
############################################################################
|
|
17
|
+
|
|
18
|
+
# Dynamically assigned attributes
|
|
19
|
+
ATTR_EXECUTE_IN_THREAD = "execute_in_thread"
|
|
20
|
+
ATTR_COMMAND_TYPE = "command"
|
|
21
|
+
ATTR_FEATURE_TYPE = "feature"
|
|
22
|
+
ATTR_REGISTERED_NAME = "reg_name"
|
|
23
|
+
ATTR_REGISTERED_TYPE = "reg_type"
|
|
24
|
+
|
|
25
|
+
# Parameters
|
|
26
|
+
PARAM_LS = "ls"
|