laburnum 1.17.0

An LSP framework for building language servers and compilers, powered by an incremental query tree with content-addressed storage, task-based dataflow, and parallel queries.
Documentation
// Copyright Two Neutron Stars Incorporated and contributors
// SPDX-License-Identifier: BlueOak-1.0.0

//! `goto_definition`, `goto_declaration`, `goto_type_definition`,
//! `goto_implementation`.

use crate::{
  connect::lsp::{
    LspClient,
    request::{
      GotoDeclaration,
      GotoDefinition,
      GotoImplementation,
      GotoTypeDefinition,
    },
  },
  connect::mcp::{
    schema,
    tool::{
      Tool,
      ToolError,
      ToolRegistry,
    },
  },
  protocol::lsp::{
    GotoDefinitionParams,
    GotoDefinitionResponse,
  },
};

pub fn register(registry: &mut ToolRegistry) {
  registry.register::<GotoDefinitionTool>();
  registry.register::<GotoDeclarationTool>();
  registry.register::<GotoTypeDefinitionTool>();
  registry.register::<GotoImplementationTool>();
}

pub enum GotoDefinitionTool {}

impl Tool for GotoDefinitionTool {
  type Input = GotoDefinitionParams;
  type Output = Option<GotoDefinitionResponse>;

  const NAME: &'static str = "goto_definition";
  const DESCRIPTION: &'static str =
    "Find the source location where the symbol at the given position is \
     defined. Wraps LSP `textDocument/definition`.";

  fn input_schema() -> serde_json::Value {
    schema::text_document_position()
  }

  async fn call(
    client: &LspClient,
    input: Self::Input,
  ) -> Result<Self::Output, ToolError> {
    Ok(client.send_request::<GotoDefinition>(input).await?)
  }
}

pub enum GotoDeclarationTool {}

impl Tool for GotoDeclarationTool {
  type Input = GotoDefinitionParams;
  type Output = Option<GotoDefinitionResponse>;

  const NAME: &'static str = "goto_declaration";
  const DESCRIPTION: &'static str =
    "Find the source location of the declaration (which may differ from the \
     definition in languages with split declarations) of the symbol at the \
     given position. Wraps LSP `textDocument/declaration`.";

  fn input_schema() -> serde_json::Value {
    schema::text_document_position()
  }

  async fn call(
    client: &LspClient,
    input: Self::Input,
  ) -> Result<Self::Output, ToolError> {
    Ok(client.send_request::<GotoDeclaration>(input).await?)
  }
}

pub enum GotoTypeDefinitionTool {}

impl Tool for GotoTypeDefinitionTool {
  type Input = GotoDefinitionParams;
  type Output = Option<GotoDefinitionResponse>;

  const NAME: &'static str = "goto_type_definition";
  const DESCRIPTION: &'static str =
    "Find the source location where the type of the symbol at the given \
     position is defined. Wraps LSP `textDocument/typeDefinition`.";

  fn input_schema() -> serde_json::Value {
    schema::text_document_position()
  }

  async fn call(
    client: &LspClient,
    input: Self::Input,
  ) -> Result<Self::Output, ToolError> {
    Ok(client.send_request::<GotoTypeDefinition>(input).await?)
  }
}

pub enum GotoImplementationTool {}

impl Tool for GotoImplementationTool {
  type Input = GotoDefinitionParams;
  type Output = Option<GotoDefinitionResponse>;

  const NAME: &'static str = "goto_implementation";
  const DESCRIPTION: &'static str =
    "Find source locations that implement the symbol at the given position \
     (e.g. concrete impls of a trait/interface). Wraps LSP \
     `textDocument/implementation`.";

  fn input_schema() -> serde_json::Value {
    schema::text_document_position()
  }

  async fn call(
    client: &LspClient,
    input: Self::Input,
  ) -> Result<Self::Output, ToolError> {
    Ok(client.send_request::<GotoImplementation>(input).await?)
  }
}