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

use {
  crate::{
    TRACER,
    Uri,
    database::PartitionWriteContextRef,
    protocol::{
      jsonrpc,
      lsp::{
        DynamicRegistrationClientCapabilities,
        PartialResultParams,
        Range,
        SymbolKind,
        SymbolTag,
        TextDocumentPositionParams,
        WorkDoneProgressOptions,
        WorkDoneProgressParams,
      },
    },
    scheduler::{
      lanes::{
        self,
        Lane,
      },
      task::TaskContext,
    },
  },
  serde::{
    Deserialize,
    Serialize,
  },
  serde_json::Value,
};

pub type CallHierarchyClientCapabilities =
  DynamicRegistrationClientCapabilities;

#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyOptions {
  #[serde(flatten)]
  pub work_done_progress_options: WorkDoneProgressOptions,
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum CallHierarchyServerCapability {
  Simple(bool),
  Options(CallHierarchyOptions),
}

impl From<CallHierarchyOptions> for CallHierarchyServerCapability {
  fn from(from: CallHierarchyOptions) -> Self {
    Self::Options(from)
  }
}

impl From<bool> for CallHierarchyServerCapability {
  fn from(from: bool) -> Self {
    Self::Simple(from)
  }
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyPrepareParams {
  #[serde(flatten)]
  pub text_document_position_params: TextDocumentPositionParams,

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

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyItem {
  /// 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<Vec<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: Uri,

  /// 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`](#CallHierarchyItem.range).
  pub selection_range: Range,

  /// A data entry field that is preserved between a call hierarchy prepare and
  /// incoming calls or outgoing calls requests.
  #[serde(skip_serializing_if = "Option::is_none")]
  pub data: Option<Value>,
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyIncomingCallsParams {
  pub item: CallHierarchyItem,

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

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

/// Represents an incoming call, e.g. a caller of a method or constructor.
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyIncomingCall {
  /// The item that makes the call.
  pub from: CallHierarchyItem,

  /// The range at which at which the calls appears. This is relative to the
  /// caller denoted by [`this.from`](#CallHierarchyIncomingCall.from).
  pub from_ranges: Vec<Range>,
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyOutgoingCallsParams {
  pub item: CallHierarchyItem,

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

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

/// Represents an outgoing call, e.g. calling a getter from a method or a method
/// from a constructor etc.
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyOutgoingCall {
  /// The item that is called.
  pub to: CallHierarchyItem,

  /// The range at which this item is called. This is the range relative to the
  /// caller, e.g the item passed to [`provideCallHierarchyOutgoingCalls`](#
  /// CallHierarchyItemProvider.provideCallHierarchyOutgoingCalls)
  /// and not [`this.to`](#CallHierarchyOutgoingCall.to).
  pub from_ranges: Vec<Range>,
}

pub trait CallHierarchyService<
  P: crate::database::storage::Partitions,
  T: crate::protocol::lsp::LanguageServer<P>,
>: Send + Sync + 'static
{
  /// The [`textDocument/prepareCallHierarchy`] request is sent from the client
  /// to the server to return a call hierarchy for the language element of
  /// given text document positions.
  ///
  /// [`textDocument/prepareCallHierarchy`]: https://microsoft.github.io/language-server-protocol/specification#textDocument_prepareCallHierarchy
  ///
  /// The call hierarchy requests are executed in two steps:
  ///
  /// 1. First, a call hierarchy item is resolved for the given text document
  ///    position (this method).
  /// 2. For a call hierarchy item, the incoming or outgoing call hierarchy
  ///    items are resolved inside [`incoming_calls`] and [`outgoing_calls`],
  ///    respectively.
  ///
  /// [`incoming_calls`]: Self::incoming_calls
  /// [`outgoing_calls`]: Self::outgoing_calls
  ///
  /// # Compatibility
  ///
  /// This request was introduced in specification version 3.16.0.
  fn prepare_call_hierarchy(
    &self,
    params: CallHierarchyPrepareParams,
    ctx: &mut TaskContext<P, T>,
    writer: &mut PartitionWriteContextRef<'_, P>,
  ) -> impl std::future::Future<
    Output = jsonrpc::Result<Option<Vec<CallHierarchyItem>>>,
  > + Send {
    async move {
      otel::span!(
        "laburnum.lsp.prepare_call_hierarchy",
        "document.uri" = params
          .text_document_position_params
          .text_document
          .uri
          .to_string(),
        "position.line" =
          params.text_document_position_params.position.line as i64,
        "position.character" =
          params.text_document_position_params.position.character as i64
      );

      let _ = (params, ctx, writer);

      Err(jsonrpc::Error::method_not_found())
    }
  }
  const PREPARE_CALL_HIERARCHY_LANE: Lane = lanes::DEFAULT_LANE;

  /// The [`callHierarchy/incomingCalls`] request is sent from the client to the
  /// server to resolve **incoming** calls for a given call hierarchy item.
  ///
  /// The request doesn't define its own client and server capabilities. It is
  /// only issued if a server registers for the
  /// [`textDocument/prepareCallHierarchy`] request.
  ///
  /// [`callHierarchy/incomingCalls`]: https://microsoft.github.io/language-server-protocol/specification#callHierarchy_incomingCalls
  /// [`textDocument/prepareCallHierarchy`]: Self::prepare_call_hierarchy
  ///
  /// # Compatibility
  ///
  /// This request was introduced in specification version 3.16.0.
  fn incoming_calls(
    &self,
    params: CallHierarchyIncomingCallsParams,
    ctx: &mut TaskContext<P, T>,
    writer: &mut PartitionWriteContextRef<'_, P>,
  ) -> impl std::future::Future<
    Output = jsonrpc::Result<Option<Vec<CallHierarchyIncomingCall>>>,
  > + Send {
    async move {
      otel::span!("laburnum.lsp.incoming_calls");

      let _ = (params, ctx, writer);

      Err(jsonrpc::Error::method_not_found())
    }
  }
  const INCOMING_CALLS_LANE: Lane = lanes::DEFAULT_LANE;

  /// The [`callHierarchy/outgoingCalls`] request is sent from the client to the
  /// server to resolve **outgoing** calls for a given call hierarchy item.
  ///
  /// The request doesn't define its own client and server capabilities. It is
  /// only issued if a server registers for the
  /// [`textDocument/prepareCallHierarchy`] request.
  ///
  /// [`callHierarchy/outgoingCalls`]: https://microsoft.github.io/language-server-protocol/specification#callHierarchy_outgoingCalls
  /// [`textDocument/prepareCallHierarchy`]: Self::prepare_call_hierarchy
  ///
  /// # Compatibility
  ///
  /// This request was introduced in specification version 3.16.0.
  fn outgoing_calls(
    &self,
    params: CallHierarchyOutgoingCallsParams,
    ctx: &mut TaskContext<P, T>,
    writer: &mut PartitionWriteContextRef<'_, P>,
  ) -> impl std::future::Future<
    Output = jsonrpc::Result<Option<Vec<CallHierarchyOutgoingCall>>>,
  > + Send {
    async move {
      otel::span!("laburnum.lsp.outgoing_calls");

      let _ = (params, ctx, writer);
      Err(jsonrpc::Error::method_not_found())
    }
  }
  const OUTGOING_CALLS_LANE: Lane = lanes::DEFAULT_LANE;
}