slang_ir/
location.rs

1/// Represents a location in the source code (position, line, column, length)
2#[derive(Debug, Clone, Copy)]
3pub struct Location {
4    /// The position in the source code (byte offset)
5    pub position: usize,
6    /// The line number (1-based)
7    pub line: usize,
8    /// The column number (1-based)
9    pub column: usize,
10    /// The length of the token/node in characters
11    pub length: usize,
12}
13
14impl Location {
15    /// Creates a new SourceLocation
16    ///
17    /// ### Arguments
18    /// * `position` - Position in the source (byte offset)
19    /// * `line` - Line number (1-based)
20    /// * `column` - Column number (1-based)
21    /// * `length` - Length of the token/node in characters
22    ///
23    /// ### Returns
24    /// A new SourceLocation
25    pub fn new(position: usize, line: usize, column: usize, length: usize) -> Self {
26        Self {
27            position,
28            line,
29            column,
30            length,
31        }
32    }
33
34    /// Creates a new SourceLocation with the old 3-parameter signature for backward compatibility
35    ///
36    /// ### Arguments
37    /// * `position` - Position in the source (byte offset)
38    /// * `line` - Line number (1-based)
39    /// * `column` - Column number (1-based)
40    ///
41    /// ### Returns
42    /// A new SourceLocation with length = 1 (default for single character tokens)
43    pub fn new_simple(position: usize, line: usize, column: usize) -> Self {
44        Self {
45            position,
46            line,
47            column,
48            length: 1,
49        }
50    }
51
52    /// Get the end position of this location
53    ///
54    /// ### Returns
55    /// The byte offset position at the end of this location
56    pub fn end_position(&self) -> usize {
57        self.position + self.length
58    }
59
60    /// Get the end column of this location (assuming single line)
61    ///
62    /// ### Returns
63    /// The column number at the end of this location
64    pub fn end_column(&self) -> usize {
65        self.column + self.length
66    }
67
68    /// Create a span from this location to another location
69    ///
70    /// ### Arguments
71    ///
72    /// * `other` - The other SourceLocation to create a span to
73    ///
74    /// ### Returns
75    /// A new SourceLocation representing the span from this location to the other
76    pub fn span_to(&self, other: &Location) -> Location {
77        let start_pos = self.position.min(other.position);
78        let end_pos = self.end_position().max(other.end_position());
79
80        Location {
81            position: start_pos,
82            line: self.line.min(other.line),
83            column: if self.line == other.line {
84                self.column.min(other.column)
85            } else {
86                self.column
87            },
88            length: end_pos - start_pos,
89        }
90    }
91}
92
93impl Default for Location {
94    /// Creates a default SourceLocation at the start of the source code
95    fn default() -> Self {
96        Self {
97            position: 0,
98            line: 1,
99            column: 1,
100            length: 1,
101        }
102    }
103}