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::{
  ContentHash,
  Ident,
  SourceKey,
  database::{
    DynPartition,
    PartitionKey,
  },
  protocol::lsp::Position,
};

pub struct TextDocumentPosition;

impl PartitionKey for TextDocumentPosition {
  const KEY: Ident = Ident::new("laburnum::text_document_position_index");
}
/// To write text document positions, create a wrapper partition with
/// [`impl_partition_for_dyn!`]:
///
/// ```rust,ignore
/// use laburnum::{impl_partition_for_dyn, partitions::TextDocumentPosition};
///
/// // Your record type must implement TextDocumentPositionRecord + Record
/// impl_partition_for_dyn!(MyPositionPartition, TextDocumentPosition, MyPosition);
///
/// // Then write using the wrapper partition
/// let sort_key = TextDocumentPositionSortKey::Position {
///   source_key, line, character, kind
/// };
/// writer.write::<MyPositionPartition>(sort_key, position.into());
/// ```
///
/// [`impl_partition_for_dyn!`]: crate::impl_partition_for_dyn
impl DynPartition for TextDocumentPosition {
  type DynSortKey = TextDocumentPositionSortKey;
  type RecordConstraint = dyn TextDocumentPositionRecord;
}

impl<R: TextDocumentPositionRecord + crate::record::Record>
  crate::database::DynPartitionRecord<TextDocumentPosition> for R
{
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum PositionKind {
  Unknown   = 0,
  Ident     = 1,
  Symbol    = 2,
  Reference = 3,
}

#[derive(Debug, Clone)]
pub enum TextDocumentPositionSortKey {
  Position {
    source_key: SourceKey,
    line:       u32,
    character:  u32,
    kind:       PositionKind,
  },
  All,
  FilePrefix {
    source_key: SourceKey,
  },
}

impl std::fmt::Display for TextDocumentPositionSortKey {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
      | TextDocumentPositionSortKey::Position {
        source_key,
        line,
        character,
        kind,
      } => {
        write!(
          f,
          "{}|{:010}|{:010}|{}",
          source_key, line, character, *kind as u8
        )
      },
      | TextDocumentPositionSortKey::All => Ok(()),
      | TextDocumentPositionSortKey::FilePrefix { source_key } => {
        write!(f, "{}", source_key)
      },
    }
  }
}

pub trait TextDocumentPositionRecord: Send + Sync + std::fmt::Debug {
  fn source_key(&self) -> SourceKey;
  fn position(&self) -> Position;
  fn kind(&self) -> PositionKind;

  /// Content hash of the DocumentSymbolRecord for this position.
  ///
  /// Resolve via `query_client.get_by_hash::<DocumentSymbols>(hash)`
  /// then downcast with `.as_document_symbol()`.
  fn symbol_hash(&self) -> ContentHash;

  /// Identifier of the symbol at this position.
  ///
  /// Stored inline for fast filtering (e.g. rename loop) without
  /// needing to resolve the full DocumentSymbolRecord.
  fn symbol_ident(&self) -> Ident;
}