laburnum 1.17.1

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

pub struct DocumentSymbols;

impl PartitionKey for DocumentSymbols {
  const KEY: Ident = Ident::new("laburnum::document_symbols");
}
/// To write document symbols, create a wrapper partition with
/// [`impl_partition_for_dyn!`]:
///
/// ```rust,ignore
/// use laburnum::{impl_partition_for_dyn, partitions::DocumentSymbols};
///
/// // Your record type must implement DocumentSymbolRecord + Record
/// impl_partition_for_dyn!(MyDocumentSymbolsPartition, DocumentSymbols, MySymbol);
///
/// // Then write using the wrapper partition
/// let sort_key = DocumentSymbolSortKey::Symbol { source_key, symbol_kind, ident };
/// writer.write::<MyDocumentSymbolsPartition>(sort_key, symbol.into());
/// ```
///
/// [`impl_partition_for_dyn!`]: crate::impl_partition_for_dyn
impl DynPartition for DocumentSymbols {
  type DynSortKey = DocumentSymbolSortKey;
  type RecordConstraint = dyn DocumentSymbolRecord;
}

impl<R: DocumentSymbolRecord + crate::record::Record>
  crate::database::DynPartitionRecord<DocumentSymbols> for R
{
}

#[derive(Debug, Clone)]
pub enum DocumentSymbolSortKey {
  Symbol {
    source_key:  SourceKey,
    symbol_kind: SymbolKind,
    ident:       Ident,
  },
  All,
  FilePrefix {
    source_key: SourceKey,
  },
}

impl std::fmt::Display for DocumentSymbolSortKey {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
      | DocumentSymbolSortKey::Symbol {
        source_key,
        symbol_kind,
        ident,
      } => write!(f, "{}|{}|{}", source_key, symbol_kind, ident),
      | DocumentSymbolSortKey::All => Ok(()),
      | DocumentSymbolSortKey::FilePrefix { source_key } => {
        write!(f, "{}", source_key)
      },
    }
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SymbolKindVariant {
  Symbol,
  Reference,
}

pub trait DocumentSymbolRecord: Send + Sync + std::fmt::Debug {
  fn get_ident(&self) -> Ident;

  fn get_ident_path(&self) -> Vec<Ident>;

  fn get_ident_range(&self) -> crate::protocol::lsp::Range;

  fn source_key(&self) -> SourceKey;

  fn span(&self) -> crate::source::Span;

  fn symbol_kind(&self) -> SymbolKind;

  fn target_source_key(&self) -> Option<SourceKey> {
    None
  }

  fn symbol_kind_variant(&self) -> SymbolKindVariant {
    SymbolKindVariant::Symbol
  }

  fn to_document_symbol(
    &self,
    source_cache: &crate::source::cache::reporter::SourceCacheReader,
    encoding: &crate::protocol::lsp::PositionEncodingKind,
  ) -> crate::protocol::lsp::DocumentSymbol;

  fn definition_location(
    &self,
    _source_cache: &crate::source::cache::reporter::SourceCacheReader,
    _encoding: &crate::protocol::lsp::PositionEncodingKind,
  ) -> Option<crate::protocol::lsp::Location> {
    None
  }

  fn hover_info(
    &self,
    _source_cache: &crate::source::cache::reporter::SourceCacheReader,
    _encoding: &crate::protocol::lsp::PositionEncodingKind,
  ) -> Option<crate::protocol::lsp::Hover> {
    None
  }

  fn rename_range(
    &self,
    _source_cache: &crate::source::cache::reporter::SourceCacheReader,
    _encoding: &crate::protocol::lsp::PositionEncodingKind,
  ) -> Option<crate::protocol::lsp::Range> {
    None
  }
}