diff options
Diffstat (limited to 'src/source.rs')
| -rw-r--r-- | src/source.rs | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/src/source.rs b/src/source.rs index 82b54550..eaf94001 100644 --- a/src/source.rs +++ b/src/source.rs @@ -20,24 +20,24 @@ use codespan_reporting::files::{self, Files}; /// A unique identifier for a loaded source file. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct SourceId(u32); +pub struct SourceId(u16); impl SourceId { /// Create a new source id for a file that is not part of a store. pub const fn detached() -> Self { - Self(u32::MAX) + Self(u16::MAX) } /// Create a source id from the raw underlying value. /// /// This should only be called with values returned by /// [`into_raw`](Self::into_raw). - pub const fn from_raw(v: u32) -> Self { + pub const fn from_raw(v: u16) -> Self { Self(v) } /// Convert into the raw underlying value. - pub const fn into_raw(self) -> u32 { + pub const fn into_raw(self) -> u16 { self.0 } } @@ -108,7 +108,7 @@ impl SourceStore { } // No existing file yet. - let id = SourceId(self.sources.len() as u32); + let id = SourceId(self.sources.len() as u16); self.sources.push(SourceFile::new(id, path, src)); // Register in file map if the path was known to the loader. @@ -140,6 +140,13 @@ impl SourceStore { ) -> Range<usize> { self.sources[id.0 as usize].edit(replace, with) } + + /// Map a span that points into this source store to a byte range. + /// + /// Panics if the span does not point into this source store. + pub fn range(&self, span: Span) -> Range<usize> { + self.get(span.source()).range(span) + } } /// A single source file. @@ -160,10 +167,14 @@ impl SourceFile { pub fn new(id: SourceId, path: &Path, src: String) -> Self { let mut lines = vec![Line { byte_idx: 0, utf16_idx: 0 }]; lines.extend(Line::iter(0, 0, &src)); + + let mut root = parse(&src); + root.number(id, 1); + Self { id, path: path.normalize(), - root: parse(&src), + root, src, lines, rev: 0, @@ -178,8 +189,8 @@ impl SourceFile { /// Create a source file with the same synthetic span for all nodes. pub fn synthesized(src: impl Into<String>, span: Span) -> Self { let mut file = Self::detached(src); - file.root.synthesize(Arc::new(span)); - file.id = span.source; + file.root.synthesize(span); + file.id = span.source(); file } @@ -232,6 +243,7 @@ impl SourceFile { self.lines = vec![Line { byte_idx: 0, utf16_idx: 0 }]; self.lines.extend(Line::iter(0, 0, &self.src)); self.root = parse(&self.src); + self.root.number(self.id(), 1); self.rev = self.rev.wrapping_add(1); } @@ -265,7 +277,9 @@ impl SourceFile { )); // Incrementally reparse the replaced range. - reparse(&mut self.root, &self.src, replace, with.len()) + let range = reparse(&mut self.root, &self.src, replace, with.len()); + self.root.number(self.id(), 1); + range } /// Get the length of the file in bytes. @@ -284,6 +298,15 @@ impl SourceFile { self.lines.len() } + /// Map a span that points into this source file to a byte range. + /// + /// Panics if the span does not point into this source file. + pub fn range(&self, span: Span) -> Range<usize> { + self.root + .range(span, 0) + .expect("span does not point into this source file") + } + /// Return the index of the UTF-16 code unit at the byte index. pub fn byte_to_utf16(&self, byte_idx: usize) -> Option<usize> { let line_idx = self.byte_to_line(byte_idx)?; |
