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::{
  Ident,
  SourceKey,
  protocol::lsp::PositionEncodingKind,
  source::Span,
};

crate::define_dyn_partition!(
  /// To write text document references, create a wrapper partition with
  /// [`impl_partition_for_dyn!`]:
  ///
  /// ```rust,ignore
  /// use laburnum::{impl_partition_for_dyn, partitions::TextDocumentReferences};
  ///
  /// // Your record type must implement TextDocumentReferenceRecord + Record
  /// impl_partition_for_dyn!(MyReferencesPartition, TextDocumentReferences, MyReference);
  ///
  /// // Then write using the wrapper partition
  /// let sort_key = TextDocumentReferenceSortKey::Reference { source_key, ident, span };
  /// writer.write::<MyReferencesPartition>(sort_key, reference.into());
  /// ```
  ///
  /// [`impl_partition_for_dyn!`]: crate::impl_partition_for_dyn
  TextDocumentReferences,
  "laburnum::symbol_references",
  TextDocumentReferenceSortKey,
  TextDocumentReferenceRecord
);

#[derive(Debug, Clone)]
pub enum TextDocumentReferenceSortKey {
  Reference {
    source_key: SourceKey,
    ident:      Ident,
    span:       Span,
  },
  All,
  SourcePrefix {
    source_key: SourceKey,
  },
  SymbolPrefix {
    source_key: SourceKey,
    ident:      Ident,
  },
}

impl std::fmt::Display for TextDocumentReferenceSortKey {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
      | TextDocumentReferenceSortKey::Reference {
        source_key,
        ident,
        span,
      } => write!(f, "{}|{}|>{:?}", source_key, ident, span),
      | TextDocumentReferenceSortKey::All => Ok(()),
      | TextDocumentReferenceSortKey::SourcePrefix { source_key } => {
        write!(f, "{}|", source_key)
      },
      | TextDocumentReferenceSortKey::SymbolPrefix { source_key, ident } => {
        write!(f, "{}|{}|>", source_key, ident)
      },
    }
  }
}

pub trait TextDocumentReferenceRecord: Send + Sync + std::fmt::Debug {
  fn reference_source_key(&self) -> SourceKey;

  fn reference_span(&self) -> Span;

  fn target_source_key(&self) -> SourceKey;

  fn target_ident(&self) -> Ident;

  fn location(
    &self,
    source_cache: &crate::source::cache::reporter::SourceCacheReader,
    encoding: &PositionEncodingKind,
  ) -> Option<crate::protocol::lsp::Location> {
    let source = source_cache.get_source(self.reference_source_key())?;
    let uri = source.uri().clone();
    let span_cache = source.span_cache();
    let range = self
      .reference_span()
      .to_lsp_range(span_cache, &*source, encoding)?;
    Some(crate::protocol::lsp::Location { uri, range })
  }
}