@@ -8,7 +8,7 @@ mod diagnostics;
88
99use std:: ptr:: NonNull ;
1010
11- use ruby_prism_sys:: { pm_arena_free, pm_arena_t, pm_comment_t, pm_diagnostic_t, pm_location_t, pm_magic_comment_t, pm_node_t, pm_parser_free, pm_parser_t} ;
11+ use ruby_prism_sys:: { pm_arena_free, pm_arena_t, pm_comment_t, pm_diagnostic_t, pm_line_offset_list_line_column , pm_location_t, pm_magic_comment_t, pm_node_t, pm_parser_free, pm_parser_t} ;
1212
1313pub use self :: comments:: { Comment , CommentType , Comments , MagicComment , MagicComments } ;
1414pub use self :: diagnostics:: { Diagnostic , Diagnostics } ;
@@ -66,6 +66,56 @@ impl<'pr> Location<'pr> {
6666 } )
6767 }
6868 }
69+
70+ /// Returns a new location that is the result of chopping off the last byte.
71+ #[ must_use]
72+ pub const fn chop ( & self ) -> Self {
73+ Location {
74+ parser : self . parser ,
75+ start : self . start ,
76+ length : if self . length == 0 { 0 } else { self . length - 1 } ,
77+ marker : std:: marker:: PhantomData ,
78+ }
79+ }
80+ }
81+
82+ impl Location < ' _ > {
83+ /// Returns the line number where this location starts.
84+ #[ must_use]
85+ pub fn start_line ( & self ) -> i32 {
86+ self . line_column ( self . start ) . 0
87+ }
88+
89+ /// Returns the column number in bytes where this location starts from the
90+ /// start of the line.
91+ #[ must_use]
92+ pub fn start_column ( & self ) -> u32 {
93+ self . line_column ( self . start ) . 1
94+ }
95+
96+ /// Returns the line number where this location ends.
97+ #[ must_use]
98+ pub fn end_line ( & self ) -> i32 {
99+ self . line_column ( self . end ( ) ) . 0
100+ }
101+
102+ /// Returns the column number in bytes where this location ends from the
103+ /// start of the line.
104+ #[ must_use]
105+ pub fn end_column ( & self ) -> u32 {
106+ self . line_column ( self . end ( ) ) . 1
107+ }
108+
109+ /// Returns the line and column number for the given byte offset.
110+ fn line_column ( & self , cursor : u32 ) -> ( i32 , u32 ) {
111+ // SAFETY: We read the line_offsets and start_line from the parser,
112+ // which is valid for the lifetime of this Location.
113+ unsafe {
114+ let parser = self . parser . as_ptr ( ) ;
115+ let result = pm_line_offset_list_line_column ( & raw const ( * parser) . line_offsets , cursor, ( * parser) . start_line ) ;
116+ ( result. line , result. column )
117+ }
118+ }
69119}
70120
71121impl std:: fmt:: Debug for Location < ' _ > {
0 commit comments