Skip to main content

oak_core/tree/
metadata.rs

1use core::range::Range;
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4
5/// Represents the provenance of a token, describing how its text was composed.
6///
7/// This is used for advanced IDE features like renaming synthetic identifiers.
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10pub struct TokenProvenance {
11    /// The parts that compose this token's text.
12    pub parts: Vec<ProvenancePart>,
13}
14
15/// A single component of a token's provenance.
16#[derive(Debug, Clone, PartialEq, Eq, Hash)]
17#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
18pub enum ProvenancePart {
19    /// Part of the text comes directly from a source range.
20    Source(#[cfg_attr(feature = "serde", serde(with = "crate::serde_range"))] Range<usize>),
21    /// Part of the text is synthesized (e.g., by a macro).
22    /// The string is typically an interned ID or a small literal.
23    Synthesized(String),
24    /// An opaque tag for language-specific transformations (e.g., case conversion).
25    /// Oak doesn't understand these tags, but passes them to the LSP/IDE.
26    OpaqueTag(String),
27}
28
29impl TokenProvenance {
30    /// Creates a new provenance from a single source range.
31    pub fn from_source(range: Range<usize>) -> Self {
32        Self { parts: vec![ProvenancePart::Source(range)] }
33    }
34
35    /// Creates a new provenance from a synthesized string.
36    pub fn from_synthesized(s: impl Into<String>) -> Self {
37        Self { parts: vec![ProvenancePart::Synthesized(s.into())] }
38    }
39}