Document DiagnosticSet, SyntaxMap

This commit is contained in:
Max Brunsfeld 2024-01-18 15:34:04 -08:00
parent b65cf6d2d9
commit 058f39c180
4 changed files with 45 additions and 5 deletions

View file

@ -145,7 +145,7 @@ pub enum IndentKind {
/// An ASCII space character. /// An ASCII space character.
#[default] #[default]
Space, Space,
/// An ASCII tab chracter. /// An ASCII tab character.
Tab, Tab,
} }

View file

@ -9,20 +9,36 @@ use std::{
use sum_tree::{self, Bias, SumTree}; use sum_tree::{self, Bias, SumTree};
use text::{Anchor, FromAnchor, PointUtf16, ToOffset}; use text::{Anchor, FromAnchor, PointUtf16, ToOffset};
/// A set of diagnostics associated with a given buffer, provided
/// by a single language server.
///
/// The diagnostics are stored in a [SumTree], which allows this struct
/// to be cheaply copied, and allows for efficient retrieval of the
/// diagnostics that intersect a given range of the buffer.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct DiagnosticSet { pub struct DiagnosticSet {
diagnostics: SumTree<DiagnosticEntry<Anchor>>, diagnostics: SumTree<DiagnosticEntry<Anchor>>,
} }
/// A single diagnostic in a set. Generic over its range type, because
/// the diagnostics are stored internally as [Anchor]s, but can be
/// resolved to different coordinates types like [usize] byte offsets or
/// [Point]s.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct DiagnosticEntry<T> { pub struct DiagnosticEntry<T> {
/// The range of the buffer where the diagnostic applies.
pub range: Range<T>, pub range: Range<T>,
/// The information about the diagnostic.
pub diagnostic: Diagnostic, pub diagnostic: Diagnostic,
} }
/// A group of related diagnostics, ordered by their start position
/// in the buffer.
#[derive(Debug)] #[derive(Debug)]
pub struct DiagnosticGroup<T> { pub struct DiagnosticGroup<T> {
/// The diagnostics.
pub entries: Vec<DiagnosticEntry<T>>, pub entries: Vec<DiagnosticEntry<T>>,
/// The index into `entries` where the primary diagnostic is stored.
pub primary_ix: usize, pub primary_ix: usize,
} }
@ -36,7 +52,8 @@ pub struct Summary {
} }
impl<T> DiagnosticEntry<T> { impl<T> DiagnosticEntry<T> {
// Used to provide diagnostic context to lsp codeAction request /// Returns a raw LSP diagnostic ssed to provide diagnostic context to lsp
/// codeAction request
pub fn to_lsp_diagnostic_stub(&self) -> lsp::Diagnostic { pub fn to_lsp_diagnostic_stub(&self) -> lsp::Diagnostic {
let code = self let code = self
.diagnostic .diagnostic
@ -53,6 +70,8 @@ impl<T> DiagnosticEntry<T> {
} }
impl DiagnosticSet { impl DiagnosticSet {
/// Constructs a [DiagnosticSet] from a sequence of entries, ordered by
/// their position in the buffer.
pub fn from_sorted_entries<I>(iter: I, buffer: &text::BufferSnapshot) -> Self pub fn from_sorted_entries<I>(iter: I, buffer: &text::BufferSnapshot) -> Self
where where
I: IntoIterator<Item = DiagnosticEntry<Anchor>>, I: IntoIterator<Item = DiagnosticEntry<Anchor>>,
@ -62,6 +81,7 @@ impl DiagnosticSet {
} }
} }
/// Constructs a [DiagnosticSet] from a sequence of entries in an arbitrary order.
pub fn new<I>(iter: I, buffer: &text::BufferSnapshot) -> Self pub fn new<I>(iter: I, buffer: &text::BufferSnapshot) -> Self
where where
I: IntoIterator<Item = DiagnosticEntry<PointUtf16>>, I: IntoIterator<Item = DiagnosticEntry<PointUtf16>>,
@ -80,14 +100,18 @@ impl DiagnosticSet {
} }
} }
/// Returns the number of diagnostics in the set.
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.diagnostics.summary().count self.diagnostics.summary().count
} }
/// Returns an iterator over the diagnostic entries in the set.
pub fn iter(&self) -> impl Iterator<Item = &DiagnosticEntry<Anchor>> { pub fn iter(&self) -> impl Iterator<Item = &DiagnosticEntry<Anchor>> {
self.diagnostics.iter() self.diagnostics.iter()
} }
/// Returns an iterator over the diagnostic entries that intersect the
/// given range of the buffer.
pub fn range<'a, T, O>( pub fn range<'a, T, O>(
&'a self, &'a self,
range: Range<T>, range: Range<T>,
@ -134,6 +158,7 @@ impl DiagnosticSet {
}) })
} }
/// Adds all of this set's diagnostic groups to the given output vector.
pub fn groups( pub fn groups(
&self, &self,
language_server_id: LanguageServerId, language_server_id: LanguageServerId,
@ -173,6 +198,8 @@ impl DiagnosticSet {
}); });
} }
/// Returns all of the diagnostics in a particular diagnostic group,
/// in order of their position in the buffer.
pub fn group<'a, O: FromAnchor>( pub fn group<'a, O: FromAnchor>(
&'a self, &'a self,
group_id: usize, group_id: usize,
@ -183,6 +210,7 @@ impl DiagnosticSet {
.map(|entry| entry.resolve(buffer)) .map(|entry| entry.resolve(buffer))
} }
} }
impl sum_tree::Item for DiagnosticEntry<Anchor> { impl sum_tree::Item for DiagnosticEntry<Anchor> {
type Summary = Summary; type Summary = Summary;
@ -198,6 +226,7 @@ impl sum_tree::Item for DiagnosticEntry<Anchor> {
} }
impl DiagnosticEntry<Anchor> { impl DiagnosticEntry<Anchor> {
/// Converts the [DiagnosticEntry] to a different buffer coordinate type.
pub fn resolve<O: FromAnchor>(&self, buffer: &text::BufferSnapshot) -> DiagnosticEntry<O> { pub fn resolve<O: FromAnchor>(&self, buffer: &text::BufferSnapshot) -> DiagnosticEntry<O> {
DiagnosticEntry { DiagnosticEntry {
range: O::from_anchor(&self.range.start, buffer) range: O::from_anchor(&self.range.start, buffer)

View file

@ -114,10 +114,14 @@ lazy_static! {
)); ));
} }
/// Types that represent a position in a buffer, and can be converted into
/// an LSP position, to send to a language server.
pub trait ToLspPosition { pub trait ToLspPosition {
/// Converts the value into an LSP position.
fn to_lsp_position(self) -> lsp::Position; fn to_lsp_position(self) -> lsp::Position;
} }
/// A name of a language server.
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct LanguageServerName(pub Arc<str>); pub struct LanguageServerName(pub Arc<str>);

View file

@ -117,17 +117,22 @@ impl SyntaxLayerContent {
} }
} }
/// A layer of syntax highlighting, corresponding to a single syntax
/// tree in a particular language.
#[derive(Debug)] #[derive(Debug)]
pub struct SyntaxLayer<'a> { pub struct SyntaxLayer<'a> {
pub depth: usize, /// The language for this layer.
pub language: &'a Arc<Language>, pub language: &'a Arc<Language>,
depth: usize,
tree: &'a Tree, tree: &'a Tree,
offset: (usize, tree_sitter::Point), offset: (usize, tree_sitter::Point),
} }
/// A layer of syntax highlighting. Like [SyntaxLayer], but holding
/// owned data instead of references.
#[derive(Clone)] #[derive(Clone)]
pub struct OwnedSyntaxLayer { pub struct OwnedSyntaxLayer {
pub depth: usize, /// The language for this layer.
pub language: Arc<Language>, pub language: Arc<Language>,
tree: tree_sitter::Tree, tree: tree_sitter::Tree,
offset: (usize, tree_sitter::Point), offset: (usize, tree_sitter::Point),
@ -1437,6 +1442,7 @@ fn insert_newlines_between_ranges(
} }
impl OwnedSyntaxLayer { impl OwnedSyntaxLayer {
/// Returns the root syntax node for this layer.
pub fn node(&self) -> Node { pub fn node(&self) -> Node {
self.tree self.tree
.root_node_with_offset(self.offset.0, self.offset.1) .root_node_with_offset(self.offset.0, self.offset.1)
@ -1444,15 +1450,16 @@ impl OwnedSyntaxLayer {
} }
impl<'a> SyntaxLayer<'a> { impl<'a> SyntaxLayer<'a> {
/// Returns an owned version of this layer.
pub fn to_owned(&self) -> OwnedSyntaxLayer { pub fn to_owned(&self) -> OwnedSyntaxLayer {
OwnedSyntaxLayer { OwnedSyntaxLayer {
tree: self.tree.clone(), tree: self.tree.clone(),
offset: self.offset, offset: self.offset,
depth: self.depth,
language: self.language.clone(), language: self.language.clone(),
} }
} }
/// Returns the root node for this layer.
pub fn node(&self) -> Node<'a> { pub fn node(&self) -> Node<'a> {
self.tree self.tree
.root_node_with_offset(self.offset.0, self.offset.1) .root_node_with_offset(self.offset.0, self.offset.1)