Skip to content

Commit

Permalink
Add support for type hierarchies
Browse files Browse the repository at this point in the history
  • Loading branch information
ebkalderon committed Jan 23, 2023
1 parent df4ded4 commit 6eeacd6
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ pub use semantic_tokens::*;
mod signature_help;
pub use signature_help::*;

mod type_hierarchy;
pub use type_hierarchy::*;

mod linked_editing;
pub use linked_editing::*;

Expand Down Expand Up @@ -1515,6 +1518,12 @@ pub struct TextDocumentClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub moniker: Option<MonikerClientCapabilities>,

/// Capabilities specific to the various type hierarchy requests.
///
/// @since 3.17.0
#[serde(skip_serializing_if = "Option::is_none")]
pub type_hierarchy: Option<TypeHierarchyClientCapabilities>,

/// Capabilities specific to the `textDocument/inlineValue` request.
///
/// @since 3.17.0
Expand Down
51 changes: 51 additions & 0 deletions src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ macro_rules! lsp_request {
("textDocument/prepareCallHierarchy") => {
$crate::request::CallHierarchyPrepare
};
("textDocument/prepareTypeHierarchy") => {
$crate::request::TypeHierarchyPrepare
};
("textDocument/semanticTokens/full") => {
$crate::request::SemanticTokensFullRequest
};
Expand All @@ -156,6 +159,12 @@ macro_rules! lsp_request {
("textDocument/inlineValue") => {
$crate::request::InlineValueRequest
};
("typeHierarchy/supertypes") => {
$crate::request::TypeHierarchySupertypes
};
("typeHierarchy/subtypes") => {
$crate::request::TypeHierarchySubtypes
};
("workspace/willCreateFiles") => {
$crate::request::WillCreateFiles
};
Expand Down Expand Up @@ -857,6 +866,45 @@ impl Request for InlineValueRefreshRequest {
const METHOD: &'static str = "workspace/inlineValue/refresh";
}

/// The type hierarchy request is sent from the client to the server to return a type hierarchy for
/// the language element of given text document positions. Will return null if the server couldn’t
/// infer a valid type from the position. The type hierarchy requests are executed in two steps:
///
/// 1. first a type hierarchy item is prepared for the given text document position.
/// 2. for a type hierarchy item the supertype or subtype type hierarchy items are resolved.
pub enum TypeHierarchyPrepare {}

impl Request for TypeHierarchyPrepare {
type Params = TypeHierarchyPrepareParams;
type Result = Option<Vec<TypeHierarchyItem>>;
const METHOD: &'static str = "textDocument/prepareTypeHierarchy";
}

/// The `typeHierarchy/supertypes` request is sent from the client to the server to resolve the
/// supertypes for a given type hierarchy item. Will return null if the server couldn’t infer a
/// valid type from item in the params. The request doesn’t define its own client and server
/// capabilities. It is only issued if a server registers for the
/// `textDocument/prepareTypeHierarchy` request.
pub enum TypeHierarchySupertypes {}

impl Request for TypeHierarchySupertypes {
type Params = TypeHierarchySupertypesParams;
type Result = Option<Vec<TypeHierarchyItem>>;
const METHOD: &'static str = "typeHierarchy/supertypes";
}

/// The `typeHierarchy/subtypes` request is sent from the client to the server to resolve the
/// subtypes for a given type hierarchy item. Will return null if the server couldn’t infer a valid
/// type from item in the params. The request doesn’t define its own client and server capabilities.
/// It is only issued if a server registers for the textDocument/prepareTypeHierarchy request.
pub enum TypeHierarchySubtypes {}

impl Request for TypeHierarchySubtypes {
type Params = TypeHierarchySubtypesParams;
type Result = Option<Vec<TypeHierarchyItem>>;
const METHOD: &'static str = "typeHierarchy/subtypes";
}

#[cfg(test)]
mod test {
use super::*;
Expand Down Expand Up @@ -916,6 +964,7 @@ mod test {
check_macro!("textDocument/moniker");
check_macro!("textDocument/linkedEditingRange");
check_macro!("textDocument/prepareCallHierarchy");
check_macro!("textDocument/prepareTypeHierarchy");
check_macro!("textDocument/semanticTokens/full");
check_macro!("textDocument/semanticTokens/full/delta");
check_macro!("textDocument/semanticTokens/range");
Expand All @@ -942,6 +991,8 @@ mod test {
check_macro!("completionItem/resolve");
check_macro!("documentLink/resolve");
check_macro!("inlayHint/resolve");
check_macro!("typeHierarchy/subtypes");
check_macro!("typeHierarchy/supertypes");
}

#[test]
Expand Down
90 changes: 90 additions & 0 deletions src/type_hierarchy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use crate::{
DynamicRegistrationClientCapabilities, LSPAny, PartialResultParams, Range,
StaticRegistrationOptions, SymbolKind, SymbolTag, TextDocumentPositionParams,
TextDocumentRegistrationOptions, Url, WorkDoneProgressOptions, WorkDoneProgressParams,
};

use serde::{Deserialize, Serialize};

pub type TypeHierarchyClientCapabilities = DynamicRegistrationClientCapabilities;

#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct TypeHierarchyOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,
}

#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct TypeHierarchyRegistrationOptions {
#[serde(flatten)]
pub text_document_registration_options: TextDocumentRegistrationOptions,
#[serde(flatten)]
pub type_hierarchy_options: TypeHierarchyOptions,
#[serde(flatten)]
pub static_registration_options: StaticRegistrationOptions,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct TypeHierarchyPrepareParams {
#[serde(flatten)]
pub text_document_position_params: TextDocumentPositionParams,
#[serde(flatten)]
pub work_done_progress_params: WorkDoneProgressParams,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct TypeHierarchySupertypesParams {
pub item: TypeHierarchyItem,

#[serde(flatten)]
pub work_done_progress_params: WorkDoneProgressParams,
#[serde(flatten)]
pub partial_result_params: PartialResultParams,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct TypeHierarchySubtypesParams {
pub item: TypeHierarchyItem,

#[serde(flatten)]
pub work_done_progress_params: WorkDoneProgressParams,
#[serde(flatten)]
pub partial_result_params: PartialResultParams,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TypeHierarchyItem {
/// The name of this item.
pub name: String,

/// The kind of this item.
pub kind: SymbolKind,

/// Tags for this item.
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<SymbolTag>,

/// More detail for this item, e.g. the signature of a function.
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<String>,

/// The resource identifier of this item.
pub uri: Url,

/// The range enclosing this symbol not including leading/trailing whitespace
/// but everything else, e.g. comments and code.
pub range: Range,

/// The range that should be selected and revealed when this symbol is being
/// picked, e.g. the name of a function. Must be contained by the
/// [`range`](#TypeHierarchyItem.range).
pub selection_range: Range,

/// A data entry field that is preserved between a type hierarchy prepare and
/// supertypes or subtypes requests. It could also be used to identify the
/// type hierarchy in the server, helping improve the performance on
/// resolving supertypes and subtypes.
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<LSPAny>,
}

0 comments on commit 6eeacd6

Please sign in to comment.