diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-23 10:54:25 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-23 12:00:06 +0100 |
| commit | b2a3d3f235fb5a23322435b854460f52db772114 (patch) | |
| tree | 441ded5e4fcc0a702fe877fc6a3e3fedaaacabb5 /src/syntax | |
| parent | 65aa27014d090628cfef14b0679d86dd611188b9 (diff) | |
More general evaluation interface
Diffstat (limited to 'src/syntax')
| -rw-r--r-- | src/syntax/source.rs | 49 | ||||
| -rw-r--r-- | src/syntax/span.rs | 37 |
2 files changed, 49 insertions, 37 deletions
diff --git a/src/syntax/source.rs b/src/syntax/source.rs index 08b52685..6144d524 100644 --- a/src/syntax/source.rs +++ b/src/syntax/source.rs @@ -21,26 +21,21 @@ use crate::util::{PathExt, StrExt}; pub struct Source { id: SourceId, path: PathBuf, - text: Prehashed<String>, lines: Vec<Line>, + text: Prehashed<String>, root: Prehashed<SyntaxNode>, } impl Source { /// Create a new source file. pub fn new(id: SourceId, path: &Path, text: String) -> Self { - let lines = std::iter::once(Line { byte_idx: 0, utf16_idx: 0 }) - .chain(lines(0, 0, &text)) - .collect(); - let mut root = parse(&text); root.numberize(id, Span::FULL).unwrap(); - Self { id, path: path.normalize(), + lines: lines(&text), text: Prehashed::new(text), - lines, root: Prehashed::new(root), } } @@ -51,13 +46,16 @@ impl Source { } /// Create a source file with the same synthetic span for all nodes. - pub fn synthesized(text: impl Into<String>, span: Span) -> Self { - let mut file = Self::detached(text); - let mut root = file.root.into_inner(); + pub fn synthesized(text: String, span: Span) -> Self { + let mut root = parse(&text); root.synthesize(span); - file.root = Prehashed::new(root); - file.id = span.source(); - file + Self { + id: SourceId::detached(), + path: PathBuf::new(), + lines: lines(&text), + text: Prehashed::new(text), + root: Prehashed::new(root), + } } /// The root node of the file's untyped syntax tree. @@ -98,10 +96,9 @@ impl Source { /// Fully replace the source text. pub fn replace(&mut self, text: String) { self.text = Prehashed::new(text); - self.lines = vec![Line { byte_idx: 0, utf16_idx: 0 }]; - self.lines.extend(lines(0, 0, &self.text)); + self.lines = lines(&self.text); let mut root = parse(&self.text); - root.numberize(self.id(), Span::FULL).unwrap(); + root.numberize(self.id, Span::FULL).unwrap(); self.root = Prehashed::new(root); } @@ -128,7 +125,7 @@ impl Source { // Recalculate the line starts after the edit. self.lines - .extend(lines(start_byte, start_utf16, &self.text[start_byte..])); + .extend(lines_from(start_byte, start_utf16, &self.text[start_byte..])); // Incrementally reparse the replaced range. let mut root = std::mem::take(&mut self.root).into_inner(); @@ -262,11 +259,16 @@ impl Hash for Source { pub struct SourceId(u16); impl SourceId { - /// Create a new source id for a file that is not part of a store. + /// Create a new source id for a file that is not part of the world. pub const fn detached() -> Self { Self(u16::MAX) } + /// Whether the source id is the detached. + pub const fn is_detached(self) -> bool { + self.0 == Self::detached().0 + } + /// Create a source id from a number. pub const fn from_u16(v: u16) -> Self { Self(v) @@ -287,8 +289,15 @@ struct Line { utf16_idx: usize, } -/// Iterate over the lines in the string. -fn lines( +/// Create a line vector. +fn lines(text: &str) -> Vec<Line> { + std::iter::once(Line { byte_idx: 0, utf16_idx: 0 }) + .chain(lines_from(0, 0, &text)) + .collect() +} + +/// Compute a line iterator from an offset. +fn lines_from( byte_offset: usize, utf16_offset: usize, text: &str, diff --git a/src/syntax/span.rs b/src/syntax/span.rs index 7fbb7305..22ada359 100644 --- a/src/syntax/span.rs +++ b/src/syntax/span.rs @@ -27,15 +27,13 @@ use super::SourceId; pub struct Span(NonZeroU64); impl Span { + /// The full range of numbers available for span numbering. + pub const FULL: Range<u64> = 2..(1 << Self::BITS); + const DETACHED: u64 = 1; + // Data layout: // | 16 bits source id | 48 bits number | - - // Number of bits for and minimum and maximum numbers assignable to spans. const BITS: usize = 48; - const DETACHED: u64 = 1; - - /// The full range of numbers available for span numbering. - pub const FULL: Range<u64> = 2..(1 << Self::BITS); /// Create a new span from a source id and a unique number. /// @@ -46,13 +44,26 @@ impl Span { "span number outside valid range" ); - let bits = ((id.into_u16() as u64) << Self::BITS) | number; - Self(to_non_zero(bits)) + Self::pack(id, number) } /// A span that does not point into any source file. pub const fn detached() -> Self { - Self(to_non_zero(Self::DETACHED)) + Self::pack(SourceId::detached(), Self::DETACHED) + } + + /// Pack the components into a span. + const fn pack(id: SourceId, number: u64) -> Span { + let bits = ((id.into_u16() as u64) << Self::BITS) | number; + match NonZeroU64::new(bits) { + Some(v) => Self(v), + None => panic!("span encoding is zero"), + } + } + + /// Whether the span is detached. + pub const fn is_detached(self) -> bool { + self.source().is_detached() } /// The id of the source file the span points into. @@ -66,14 +77,6 @@ impl Span { } } -/// Convert to a non zero u64. -const fn to_non_zero(v: u64) -> NonZeroU64 { - match NonZeroU64::new(v) { - Some(v) => v, - None => panic!("span encoding is zero"), - } -} - /// A value with a span locating it in the source code. #[derive(Copy, Clone, Eq, PartialEq, Hash)] pub struct Spanned<T> { |
