Files
nx_post_support/server/libs/lsprotocol/_hooks.py
T
2025-07-16 17:14:09 +02:00

1238 lines
41 KiB
Python

# 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 []
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 []
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 []
if "deprecated" in object_[0]:
return [
converter.structure(item, lsp_types.SymbolInformation)
for item in object_
]
elif ("data" in object_[0]) or ("range" not in object_[0]["location"]):
return [
converter.structure(item, lsp_types.WorkspaceSymbol) for item in object_
]
return [
converter.structure(item, lsp_types.SymbolInformation) 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)
}
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)
}
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