shape_ast/ast/span.rs
1//! Source span tracking for AST nodes
2
3use serde::{Deserialize, Serialize};
4
5/// Lightweight source span for AST nodes.
6/// Stores byte offsets from the beginning of the source text.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
8pub struct Span {
9 /// Start position (byte offset)
10 pub start: usize,
11 /// End position (byte offset)
12 pub end: usize,
13}
14
15impl Span {
16 /// A dummy span for AST nodes without source location
17 pub const DUMMY: Span = Span { start: 0, end: 0 };
18
19 /// Create a new span from start and end byte offsets
20 pub fn new(start: usize, end: usize) -> Self {
21 Self { start, end }
22 }
23
24 /// Merge two spans to create a span covering both
25 pub fn merge(self, other: Span) -> Span {
26 Span {
27 start: self.start.min(other.start),
28 end: self.end.max(other.end),
29 }
30 }
31
32 /// Get the length of the span in bytes
33 pub fn len(&self) -> usize {
34 self.end.saturating_sub(self.start)
35 }
36
37 /// Check if the span is empty
38 pub fn is_empty(&self) -> bool {
39 self.start >= self.end
40 }
41
42 /// Check if this is a dummy span
43 pub fn is_dummy(&self) -> bool {
44 self.start == 0 && self.end == 0
45 }
46}
47
48/// Trait for AST nodes that have source location information
49pub trait Spanned {
50 /// Get the source span for this node
51 fn span(&self) -> Span;
52}