summaryrefslogtreecommitdiffstats
path: root/packages/python/lsprotocol/_hooks.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/python/lsprotocol/_hooks.py')
-rw-r--r--packages/python/lsprotocol/_hooks.py1233
1 files changed, 1233 insertions, 0 deletions
diff --git a/packages/python/lsprotocol/_hooks.py b/packages/python/lsprotocol/_hooks.py
new file mode 100644
index 0000000..e1ba9d6
--- /dev/null
+++ b/packages/python/lsprotocol/_hooks.py
@@ -0,0 +1,1233 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+import sys
+from typing import Any, List, Optional, Tuple, Union
+
+import attrs
+import cattrs
+
+from . import types as lsp_types
+
+LSPAny = lsp_types.LSPAny
+OptionalPrimitive = Optional[Union[bool, int, str, float]]
+
+# Flag to ensure we only resolve forward references once.
+_resolved_forward_references = False
+
+
+def _resolve_forward_references() -> None:
+ """Resolve forward references for faster processing with cattrs."""
+ global _resolved_forward_references
+ if not _resolved_forward_references:
+
+ def _filter(p: Tuple[str, object]) -> bool:
+ return isinstance(p[1], type) and attrs.has(p[1])
+
+ # Creating a concrete list here because `resolve_types` mutates the provided map.
+ items = list(filter(_filter, lsp_types.ALL_TYPES_MAP.items()))
+ for _, value in items:
+ if isinstance(value, type):
+ attrs.resolve_types(value, lsp_types.ALL_TYPES_MAP, {}) # type: ignore
+ _resolved_forward_references = True
+
+
+def register_hooks(converter: cattrs.Converter) -> cattrs.Converter:
+ _resolve_forward_references()
+ converter = _register_capabilities_hooks(converter)
+ converter = _register_required_structure_hooks(converter)
+ return _register_custom_property_hooks(converter)
+
+
+def _register_capabilities_hooks(converter: cattrs.Converter) -> cattrs.Converter:
+ def _text_document_sync_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.TextDocumentSyncOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.TextDocumentSyncOptions)
+
+ def _notebook_document_sync_hook(
+ object_: Any, _: type
+ ) -> Optional[
+ Union[
+ lsp_types.NotebookDocumentSyncRegistrationOptions,
+ lsp_types.NotebookDocumentSyncOptions,
+ ]
+ ]:
+ if object_ is None:
+ return None
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.NotebookDocumentSyncRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.NotebookDocumentSyncOptions)
+
+ def _hover_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.HoverOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.HoverOptions)
+
+ def _declaration_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.DeclarationRegistrationOptions,
+ lsp_types.DeclarationOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.DeclarationRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.DeclarationOptions)
+
+ def _definition_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.DefinitionOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.DefinitionOptions)
+
+ def _type_definition_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.TypeDefinitionRegistrationOptions,
+ lsp_types.TypeDefinitionOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.TypeDefinitionRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.TypeDefinitionOptions)
+
+ def _implementation_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.ImplementationRegistrationOptions,
+ lsp_types.ImplementationOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.ImplementationRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.ImplementationOptions)
+
+ def _references_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.ReferenceOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.ReferenceOptions)
+
+ def _position_encoding_hook(
+ object_: Union[lsp_types.PositionEncodingKind, OptionalPrimitive], _: type
+ ) -> Union[lsp_types.PositionEncodingKind, OptionalPrimitive]:
+ return object_
+
+ def _document_highlight_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.DocumentHighlightOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.DocumentHighlightOptions)
+
+ def _document_symbol_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.DocumentSymbolOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.DocumentSymbolOptions)
+
+ def _code_action_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.CodeActionOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.CodeActionOptions)
+
+ def _color_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.DocumentColorRegistrationOptions,
+ lsp_types.DocumentColorOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.DocumentColorRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.DocumentColorOptions)
+
+ def _workspace_symbol_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.WorkspaceSymbolOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.WorkspaceSymbolOptions)
+
+ def _document_formatting_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.DocumentFormattingOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.DocumentFormattingOptions)
+
+ def _document_range_formatting_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.DocumentRangeFormattingOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.DocumentRangeFormattingOptions)
+
+ def _rename_provider_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.RenameOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.RenameOptions)
+
+ def _folding_range_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.FoldingRangeRegistrationOptions,
+ lsp_types.FoldingRangeOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.FoldingRangeRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.FoldingRangeOptions)
+
+ def _selection_range_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.SelectionRangeRegistrationOptions,
+ lsp_types.SelectionRangeOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.SelectionRangeRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.SelectionRangeOptions)
+
+ def _call_hierarchy_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.CallHierarchyRegistrationOptions,
+ lsp_types.CallHierarchyOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.CallHierarchyRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.CallHierarchyOptions)
+
+ def _linked_editing_range_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.LinkedEditingRangeRegistrationOptions,
+ lsp_types.LinkedEditingRangeOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.LinkedEditingRangeRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.LinkedEditingRangeOptions)
+
+ def _semantic_tokens_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.SemanticTokensRegistrationOptions,
+ lsp_types.SemanticTokensOptions,
+ ]:
+ if object_ is None:
+ return None
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.SemanticTokensRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.SemanticTokensOptions)
+
+ def _moniker_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.MonikerRegistrationOptions,
+ lsp_types.MonikerOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(object_, lsp_types.MonikerRegistrationOptions)
+ else:
+ return converter.structure(object_, lsp_types.MonikerOptions)
+
+ def _type_hierarchy_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.TypeHierarchyRegistrationOptions,
+ lsp_types.TypeHierarchyOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.TypeHierarchyRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.TypeHierarchyOptions)
+
+ def _inline_value_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.InlineValueRegistrationOptions,
+ lsp_types.InlineValueOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(
+ object_, lsp_types.InlineValueRegistrationOptions
+ )
+ else:
+ return converter.structure(object_, lsp_types.InlineValueOptions)
+
+ def _inlay_hint_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.InlayHintRegistrationOptions,
+ lsp_types.InlayHintOptions,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if "id" in object_:
+ return converter.structure(object_, lsp_types.InlayHintRegistrationOptions)
+ else:
+ return converter.structure(object_, lsp_types.InlayHintOptions)
+
+ def _inlay_hint_label_part_hook(
+ object_: Any, _: type
+ ) -> Union[str, List[lsp_types.InlayHintLabelPart]]:
+ if isinstance(object_, str):
+ return object_
+
+ return [
+ converter.structure(item, lsp_types.InlayHintLabelPart) for item in object_
+ ]
+
+ def _diagnostic_provider_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.DiagnosticRegistrationOptions,
+ lsp_types.DiagnosticOptions,
+ ]:
+ if object_ is None:
+ return None
+ if "id" in object_:
+ return converter.structure(object_, lsp_types.DiagnosticRegistrationOptions)
+ else:
+ return converter.structure(object_, lsp_types.DiagnosticOptions)
+
+ def _save_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.SaveOptions]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.SaveOptions)
+
+ def _code_action_hook(
+ object_: Any, _: type
+ ) -> Union[lsp_types.Command, lsp_types.CodeAction]:
+ if "command" in object_:
+ return converter.structure(object_, lsp_types.Command)
+ else:
+ return converter.structure(object_, lsp_types.CodeAction)
+
+ def _completion_list_hook(
+ object_: Any, _: type
+ ) -> Optional[Union[lsp_types.CompletionList, List[lsp_types.CompletionItem]]]:
+ if object_ is None:
+ return None
+ if isinstance(object_, list):
+ return [
+ converter.structure(item, lsp_types.CompletionItem) for item in object_
+ ]
+ else:
+ return converter.structure(object_, lsp_types.CompletionList)
+
+ def _location_hook(
+ object_: Any, _: type
+ ) -> Optional[
+ Union[
+ lsp_types.Location,
+ List[lsp_types.Location],
+ List[lsp_types.LocationLink],
+ ]
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, list):
+ if len(object_) == 0:
+ return [] # type: ignore[return-value]
+ if "targetUri" in object_[0]:
+ return [
+ converter.structure(item, lsp_types.LocationLink)
+ for item in object_
+ ]
+ else:
+ return [
+ converter.structure(item, lsp_types.Location) for item in object_
+ ]
+ else:
+ return converter.structure(object_, lsp_types.Location)
+
+ def _symbol_hook(
+ object_: Any, _: type
+ ) -> Optional[
+ Union[List[lsp_types.DocumentSymbol], List[lsp_types.SymbolInformation]]
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, list):
+ if len(object_) == 0:
+ return [] # type: ignore[return-value]
+ if "location" in object_[0]:
+ return [
+ converter.structure(item, lsp_types.SymbolInformation)
+ for item in object_
+ ]
+ else:
+ return [
+ converter.structure(item, lsp_types.DocumentSymbol)
+ for item in object_
+ ]
+ else:
+ return None
+
+ def _markup_content_hook(
+ object_: Any, _: type
+ ) -> Optional[
+ Union[
+ OptionalPrimitive,
+ lsp_types.MarkupContent,
+ lsp_types.MarkedString_Type1,
+ List[Union[OptionalPrimitive, lsp_types.MarkedString_Type1]],
+ ]
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ if isinstance(object_, list):
+ return [
+ (
+ item
+ if isinstance(item, (bool, int, str, float))
+ else converter.structure(item, lsp_types.MarkedString_Type1)
+ )
+ for item in object_
+ ]
+ if "kind" in object_:
+ return converter.structure(object_, lsp_types.MarkupContent)
+ else:
+ return converter.structure(object_, lsp_types.MarkedString_Type1)
+
+ def _document_edit_hook(
+ object_: Any, _: type
+ ) -> Optional[
+ Union[
+ lsp_types.TextDocumentEdit,
+ lsp_types.CreateFile,
+ lsp_types.RenameFile,
+ lsp_types.DeleteFile,
+ ]
+ ]:
+ if object_ is None:
+ return None
+ if "kind" in object_:
+ if object_["kind"] == "create":
+ return converter.structure(object_, lsp_types.CreateFile)
+ elif object_["kind"] == "rename":
+ return converter.structure(object_, lsp_types.RenameFile)
+ elif object_["kind"] == "delete":
+ return converter.structure(object_, lsp_types.DeleteFile)
+ else:
+ raise ValueError("Unknown edit kind: ", object_)
+ else:
+ return converter.structure(object_, lsp_types.TextDocumentEdit)
+
+ def _semantic_tokens_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.SemanticTokensOptionsFullType1]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.SemanticTokensOptionsFullType1)
+
+ def _semantic_tokens_capabilities_hook(
+ object_: Any, _: type
+ ) -> Union[
+ OptionalPrimitive,
+ lsp_types.SemanticTokensClientCapabilitiesRequestsTypeFullType1,
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(
+ object_, lsp_types.SemanticTokensClientCapabilitiesRequestsTypeFullType1
+ )
+
+ def _code_action_kind_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.CodeActionKind]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.CodeActionKind)
+
+ def _position_encoding_kind_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.PositionEncodingKind]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.PositionEncodingKind)
+
+ def _folding_range_kind_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.FoldingRangeKind]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.FoldingRangeKind)
+
+ def _semantic_token_types_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.SemanticTokenTypes]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.SemanticTokenTypes)
+
+ def _semantic_token_modifiers_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.SemanticTokenModifiers]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.SemanticTokenModifiers)
+
+ def _watch_kind_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.WatchKind]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.WatchKind)
+
+ def _notebook_sync_option_selector_hook(
+ object_: Any, _: type
+ ) -> Union[
+ lsp_types.NotebookDocumentSyncOptionsNotebookSelectorType1,
+ lsp_types.NotebookDocumentSyncOptionsNotebookSelectorType2,
+ ]:
+ if "notebook" in object_:
+ return converter.structure(
+ object_, lsp_types.NotebookDocumentSyncOptionsNotebookSelectorType1
+ )
+ else:
+ return converter.structure(
+ object_, lsp_types.NotebookDocumentSyncOptionsNotebookSelectorType2
+ )
+
+ def _semantic_token_registration_options_hook(
+ object_: Any, _: type
+ ) -> Optional[
+ Union[OptionalPrimitive, lsp_types.SemanticTokensRegistrationOptionsFullType1]
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(
+ object_, lsp_types.SemanticTokensRegistrationOptionsFullType1
+ )
+
+ def _inline_completion_provider_hook(
+ object_: Any, _: type
+ ) -> Optional[Union[OptionalPrimitive, lsp_types.InlineCompletionOptions]]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.InlineCompletionOptions)
+
+ def _inline_completion_list_hook(
+ object_: Any, _: type
+ ) -> Optional[
+ Union[lsp_types.InlineCompletionList, List[lsp_types.InlineCompletionItem]]
+ ]:
+ if object_ is None:
+ return None
+ if isinstance(object_, list):
+ return [
+ converter.structure(item, lsp_types.InlineCompletionItem)
+ for item in object_
+ ]
+ return converter.structure(object_, lsp_types.InlineCompletionList)
+
+ def _string_value_hook(
+ object_: Any, _: type
+ ) -> Union[OptionalPrimitive, lsp_types.StringValue]:
+ if object_ is None:
+ return None
+ if isinstance(object_, (bool, int, str, float)):
+ return object_
+ return converter.structure(object_, lsp_types.StringValue)
+
+ def _symbol_list_hook(
+ object_: Any, _: type
+ ) -> Optional[
+ Union[List[lsp_types.SymbolInformation], List[lsp_types.WorkspaceSymbol]]
+ ]:
+ if object_ is None:
+ return None
+ assert isinstance(object_, list)
+ if len(object_) == 0:
+ return [] # type: ignore[return-value]
+ if "location" in object_[0]:
+ return [
+ converter.structure(item, lsp_types.SymbolInformation)
+ for item in object_
+ ]
+ else:
+ return [
+ converter.structure(item, lsp_types.WorkspaceSymbol) for item in object_
+ ]
+
+ def _notebook_sync_registration_option_selector_hook(
+ object_: Any, _: type
+ ) -> Union[
+ lsp_types.NotebookDocumentSyncRegistrationOptionsNotebookSelectorType1,
+ lsp_types.NotebookDocumentSyncRegistrationOptionsNotebookSelectorType2,
+ ]:
+ if "notebook" in object_:
+ return converter.structure(
+ object_,
+ lsp_types.NotebookDocumentSyncRegistrationOptionsNotebookSelectorType1,
+ )
+ else:
+ return converter.structure(
+ object_,
+ lsp_types.NotebookDocumentSyncRegistrationOptionsNotebookSelectorType2,
+ )
+
+ structure_hooks = [
+ (
+ Optional[
+ Union[lsp_types.TextDocumentSyncOptions, lsp_types.TextDocumentSyncKind]
+ ],
+ _text_document_sync_hook,
+ ),
+ (
+ Optional[
+ Union[
+ lsp_types.NotebookDocumentSyncOptions,
+ lsp_types.NotebookDocumentSyncRegistrationOptions,
+ ]
+ ],
+ _notebook_document_sync_hook,
+ ),
+ (Optional[Union[bool, lsp_types.HoverOptions]], _hover_provider_hook),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.DeclarationOptions,
+ lsp_types.DeclarationRegistrationOptions,
+ ]
+ ],
+ _declaration_provider_hook,
+ ),
+ (Optional[Union[bool, lsp_types.DefinitionOptions]], _definition_provider_hook),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.TypeDefinitionOptions,
+ lsp_types.TypeDefinitionRegistrationOptions,
+ ]
+ ],
+ _type_definition_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.ImplementationOptions,
+ lsp_types.ImplementationRegistrationOptions,
+ ]
+ ],
+ _implementation_provider_hook,
+ ),
+ (Optional[Union[bool, lsp_types.ReferenceOptions]], _references_provider_hook),
+ (
+ Optional[Union[bool, lsp_types.DocumentHighlightOptions]],
+ _document_highlight_provider_hook,
+ ),
+ (
+ Optional[Union[bool, lsp_types.DocumentSymbolOptions]],
+ _document_symbol_provider_hook,
+ ),
+ (
+ Optional[Union[bool, lsp_types.CodeActionOptions]],
+ _code_action_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.DocumentColorOptions,
+ lsp_types.DocumentColorRegistrationOptions,
+ ]
+ ],
+ _color_provider_hook,
+ ),
+ (
+ Optional[Union[bool, lsp_types.WorkspaceSymbolOptions]],
+ _workspace_symbol_provider_hook,
+ ),
+ (
+ Optional[Union[bool, lsp_types.DocumentFormattingOptions]],
+ _document_formatting_provider_hook,
+ ),
+ (
+ Optional[Union[bool, lsp_types.DocumentRangeFormattingOptions]],
+ _document_range_formatting_provider_hook,
+ ),
+ (Optional[Union[bool, lsp_types.RenameOptions]], _rename_provider_hook),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.FoldingRangeOptions,
+ lsp_types.FoldingRangeRegistrationOptions,
+ ]
+ ],
+ _folding_range_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.SelectionRangeOptions,
+ lsp_types.SelectionRangeRegistrationOptions,
+ ]
+ ],
+ _selection_range_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.CallHierarchyOptions,
+ lsp_types.CallHierarchyRegistrationOptions,
+ ]
+ ],
+ _call_hierarchy_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.LinkedEditingRangeOptions,
+ lsp_types.LinkedEditingRangeRegistrationOptions,
+ ]
+ ],
+ _linked_editing_range_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ lsp_types.SemanticTokensOptions,
+ lsp_types.SemanticTokensRegistrationOptions,
+ ]
+ ],
+ _semantic_tokens_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool, lsp_types.MonikerOptions, lsp_types.MonikerRegistrationOptions
+ ]
+ ],
+ _moniker_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.TypeHierarchyOptions,
+ lsp_types.TypeHierarchyRegistrationOptions,
+ ]
+ ],
+ _type_hierarchy_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.InlineValueOptions,
+ lsp_types.InlineValueRegistrationOptions,
+ ]
+ ],
+ _inline_value_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.InlayHintOptions,
+ lsp_types.InlayHintRegistrationOptions,
+ ]
+ ],
+ _inlay_hint_provider_hook,
+ ),
+ (
+ Union[str, List[lsp_types.InlayHintLabelPart]],
+ _inlay_hint_label_part_hook,
+ ),
+ (
+ Optional[
+ Union[
+ lsp_types.DiagnosticOptions, lsp_types.DiagnosticRegistrationOptions
+ ]
+ ],
+ _diagnostic_provider_hook,
+ ),
+ (
+ Optional[Union[lsp_types.SaveOptions, bool]],
+ _save_hook,
+ ),
+ (
+ Union[lsp_types.Command, lsp_types.CodeAction],
+ _code_action_hook,
+ ),
+ (
+ Optional[Union[List[lsp_types.CompletionItem], lsp_types.CompletionList]],
+ _completion_list_hook,
+ ),
+ (
+ Optional[
+ Union[
+ lsp_types.Location,
+ List[lsp_types.Location],
+ List[lsp_types.LocationLink],
+ ]
+ ],
+ _location_hook,
+ ),
+ (
+ Optional[
+ Union[List[lsp_types.SymbolInformation], List[lsp_types.DocumentSymbol]]
+ ],
+ _symbol_hook,
+ ),
+ (
+ Union[
+ lsp_types.MarkupContent,
+ str,
+ lsp_types.MarkedString_Type1,
+ List[Union[str, lsp_types.MarkedString_Type1]],
+ ],
+ _markup_content_hook,
+ ),
+ (
+ Union[
+ lsp_types.TextDocumentEdit,
+ lsp_types.CreateFile,
+ lsp_types.RenameFile,
+ lsp_types.DeleteFile,
+ ],
+ _document_edit_hook,
+ ),
+ (
+ Optional[Union[bool, lsp_types.SemanticTokensOptionsFullType1]],
+ _semantic_tokens_hook,
+ ),
+ (
+ Optional[
+ Union[
+ bool,
+ lsp_types.SemanticTokensClientCapabilitiesRequestsTypeFullType1,
+ ]
+ ],
+ _semantic_tokens_capabilities_hook,
+ ),
+ (
+ Optional[Union[str, lsp_types.MarkupContent]],
+ _markup_content_hook,
+ ),
+ (
+ Optional[Union[lsp_types.CodeActionKind, str]],
+ _code_action_kind_hook,
+ ),
+ (
+ Union[lsp_types.CodeActionKind, str],
+ _code_action_kind_hook,
+ ),
+ (
+ Union[lsp_types.PositionEncodingKind, str],
+ _position_encoding_kind_hook,
+ ),
+ (
+ Optional[Union[lsp_types.FoldingRangeKind, str]],
+ _folding_range_kind_hook,
+ ),
+ (
+ Union[lsp_types.FoldingRangeKind, str],
+ _folding_range_kind_hook,
+ ),
+ (
+ Union[lsp_types.SemanticTokenTypes, str],
+ _semantic_token_types_hook,
+ ),
+ (
+ Optional[Union[lsp_types.SemanticTokenTypes, str]],
+ _semantic_token_types_hook,
+ ),
+ (
+ Union[lsp_types.SemanticTokenModifiers, str],
+ _semantic_token_modifiers_hook,
+ ),
+ (
+ Optional[Union[lsp_types.SemanticTokenModifiers, str]],
+ _semantic_token_modifiers_hook,
+ ),
+ (
+ Union[lsp_types.WatchKind, int],
+ _watch_kind_hook,
+ ),
+ (
+ Optional[Union[lsp_types.WatchKind, int]],
+ _watch_kind_hook,
+ ),
+ (
+ Union[
+ lsp_types.NotebookDocumentSyncOptionsNotebookSelectorType1,
+ lsp_types.NotebookDocumentSyncOptionsNotebookSelectorType2,
+ ],
+ _notebook_sync_option_selector_hook,
+ ),
+ (
+ Optional[
+ Union[
+ lsp_types.PositionEncodingKind,
+ str,
+ ]
+ ],
+ _position_encoding_hook,
+ ),
+ (
+ Optional[Union[bool, lsp_types.SemanticTokensRegistrationOptionsFullType1]],
+ _semantic_token_registration_options_hook,
+ ),
+ (
+ Optional[Union[bool, lsp_types.InlineCompletionOptions]],
+ _inline_completion_provider_hook,
+ ),
+ (
+ Optional[
+ Union[
+ lsp_types.InlineCompletionList, List[lsp_types.InlineCompletionItem]
+ ]
+ ],
+ _inline_completion_list_hook,
+ ),
+ (
+ Union[str, lsp_types.StringValue],
+ _string_value_hook,
+ ),
+ (
+ Optional[
+ Union[
+ List[lsp_types.SymbolInformation], List[lsp_types.WorkspaceSymbol]
+ ]
+ ],
+ _symbol_list_hook,
+ ),
+ (
+ Union[
+ lsp_types.NotebookDocumentSyncRegistrationOptionsNotebookSelectorType1,
+ lsp_types.NotebookDocumentSyncRegistrationOptionsNotebookSelectorType2,
+ ],
+ _notebook_sync_registration_option_selector_hook,
+ ),
+ ]
+ for type_, hook in structure_hooks:
+ converter.register_structure_hook(type_, hook)
+ return converter
+
+
+def _register_required_structure_hooks(
+ converter: cattrs.Converter,
+) -> cattrs.Converter:
+ def _lsp_object_hook(object_: Any, type_: type) -> Any:
+ return object_
+
+ def _parameter_information_label_hook(
+ object_: Any, type: type
+ ) -> Union[str, Tuple[int, int]]:
+ if isinstance(object_, str):
+ return object_
+ else:
+ return (int(object_[0]), int(object_[1]))
+
+ def _text_document_filter_hook(
+ object_: Any, _: type
+ ) -> Union[
+ str,
+ lsp_types.TextDocumentFilter_Type1,
+ lsp_types.TextDocumentFilter_Type2,
+ lsp_types.TextDocumentFilter_Type3,
+ lsp_types.NotebookCellTextDocumentFilter,
+ ]:
+ if isinstance(object_, str):
+ return str(object_)
+ elif "notebook" in object_:
+ return converter.structure(
+ object_, lsp_types.NotebookCellTextDocumentFilter
+ )
+ elif "language" in object_:
+ return converter.structure(object_, lsp_types.TextDocumentFilter_Type1)
+ elif "scheme" in object_:
+ return converter.structure(object_, lsp_types.TextDocumentFilter_Type2)
+ else:
+ return converter.structure(object_, lsp_types.TextDocumentFilter_Type3)
+
+ def _notebook_filter_hook(
+ object_: Any, _: type
+ ) -> Union[
+ str,
+ lsp_types.NotebookDocumentFilter_Type1,
+ lsp_types.NotebookDocumentFilter_Type2,
+ lsp_types.NotebookDocumentFilter_Type3,
+ ]:
+ if isinstance(object_, str):
+ return str(object_)
+ elif "notebookType" in object_:
+ return converter.structure(object_, lsp_types.NotebookDocumentFilter_Type1)
+ elif "scheme" in object_:
+ return converter.structure(object_, lsp_types.NotebookDocumentFilter_Type2)
+ else:
+ return converter.structure(object_, lsp_types.NotebookDocumentFilter_Type3)
+
+ # TODO: Remove the ignore after this issue with attrs is addressed in either attrs or mypy
+ NotebookSelectorItem = attrs.fields(
+ lsp_types.NotebookCellTextDocumentFilter
+ ).notebook.type
+ STRUCTURE_HOOKS = [
+ (type(None), lambda object_, _type: object_),
+ (Optional[Union[int, str]], lambda object_, _type: object_),
+ (Union[int, str], lambda object_, _type: object_),
+ (lsp_types.LSPAny, _lsp_object_hook),
+ (Optional[Union[str, bool]], lambda object_, _type: object_),
+ (Optional[Union[bool, Any]], lambda object_, _type: object_),
+ (
+ Union[
+ lsp_types.TextDocumentFilter_Type1,
+ lsp_types.TextDocumentFilter_Type2,
+ lsp_types.TextDocumentFilter_Type3,
+ lsp_types.NotebookCellTextDocumentFilter,
+ ],
+ _text_document_filter_hook,
+ ),
+ (lsp_types.DocumentFilter, _text_document_filter_hook),
+ (
+ Union[
+ str,
+ lsp_types.NotebookDocumentFilter_Type1,
+ lsp_types.NotebookDocumentFilter_Type2,
+ lsp_types.NotebookDocumentFilter_Type3,
+ ],
+ _notebook_filter_hook,
+ ),
+ (NotebookSelectorItem, _notebook_filter_hook),
+ (
+ Union[lsp_types.LSPObject, List["LSPAny"], str, int, float, bool, None],
+ _lsp_object_hook,
+ ),
+ (
+ Union[
+ lsp_types.LSPObject, List[lsp_types.LSPAny], str, int, float, bool, None
+ ],
+ _lsp_object_hook,
+ ),
+ (
+ Union[str, Tuple[int, int]],
+ _parameter_information_label_hook,
+ ),
+ (lsp_types.LSPObject, _lsp_object_hook),
+ ]
+
+ if sys.version_info > (3, 8):
+ STRUCTURE_HOOKS += [
+ (
+ Union[
+ lsp_types.LSPObject,
+ List[
+ Union[
+ lsp_types.LSPObject,
+ List["LSPAny"],
+ str,
+ int,
+ float,
+ bool,
+ None,
+ ]
+ ],
+ str,
+ int,
+ float,
+ bool,
+ None,
+ ],
+ _lsp_object_hook,
+ )
+ ]
+
+ for type_, hook in STRUCTURE_HOOKS:
+ converter.register_structure_hook(type_, hook)
+
+ return converter
+
+
+def _register_custom_property_hooks(converter: cattrs.Converter) -> cattrs.Converter:
+ def _to_camel_case(name: str) -> str:
+ # TODO: when min Python becomes >= 3.9, then update this to:
+ # `return name.removesuffix("_")`.
+ new_name = name[:-1] if name.endswith("_") else name
+ parts = new_name.split("_")
+ return parts[0] + "".join(p.title() for p in parts[1:])
+
+ def _omit(cls: type, prop: str) -> bool:
+ special = lsp_types.is_special_property(cls, prop)
+ return not special
+
+ def _with_custom_unstructure(cls: type) -> Any:
+ attributes = {
+ a.name: cattrs.gen.override(
+ rename=_to_camel_case(a.name),
+ omit_if_default=_omit(cls, a.name),
+ )
+ for a in attrs.fields(cls) # type: ignore
+ }
+ return cattrs.gen.make_dict_unstructure_fn(cls, converter, **attributes)
+
+ def _with_custom_structure(cls: type) -> Any:
+ attributes = {
+ a.name: cattrs.gen.override(
+ rename=_to_camel_case(a.name),
+ omit_if_default=_omit(cls, a.name),
+ )
+ for a in attrs.fields(cls) # type: ignore
+ }
+ return cattrs.gen.make_dict_structure_fn(cls, converter, **attributes)
+
+ converter.register_unstructure_hook_factory(attrs.has, _with_custom_unstructure)
+ converter.register_structure_hook_factory(attrs.has, _with_custom_structure)
+ return converter