@ -1391,7 +1391,7 @@ impl Syntax {
range : Option < std ::ops ::Range < usize > > ,
range : Option < std ::ops ::Range < usize > > ,
cancellation_flag : Option < & ' a AtomicUsize > ,
cancellation_flag : Option < & ' a AtomicUsize > ,
) -> impl Iterator < Item = Result < HighlightEvent , Error > > + ' a {
) -> impl Iterator < Item = Result < HighlightEvent , Error > > + ' a {
let mut layers = self
let mut layers : Vec < _ > = self
. layers
. layers
. iter ( )
. iter ( )
. filter_map ( | ( _ , layer ) | {
. filter_map ( | ( _ , layer ) | {
@ -1438,11 +1438,13 @@ impl Syntax {
depth : layer . depth , // TODO: just reuse `layer`
depth : layer . depth , // TODO: just reuse `layer`
} )
} )
} )
} )
. collect ::< Vec < _ > > ( ) ;
. collect ( ) ;
layers . sort_unstable_by_key ( | layer | layer . sort_key ( ) ) ;
layers . sort_unstable_by_key ( | layer | layer . sort_key ( ) ) ;
let mut result = HighlightIter {
sort_layers ( & mut layers ) ;
HighlightIter {
source ,
source ,
byte_offset : range . map_or ( 0 , | r | r . start ) ,
byte_offset : range . map_or ( 0 , | r | r . start ) ,
cancellation_flag ,
cancellation_flag ,
@ -1450,9 +1452,7 @@ impl Syntax {
layers ,
layers ,
next_event : None ,
next_event : None ,
last_highlight_range : None ,
last_highlight_range : None ,
} ;
}
result . sort_layers ( ) ;
result
}
}
pub fn tree_for_byte_range ( & self , start : usize , end : usize ) -> & Tree {
pub fn tree_for_byte_range ( & self , start : usize , end : usize ) -> & Tree {
@ -2136,6 +2136,58 @@ impl<'a> IterLayer for QueryIterLayer<'a> {
self . cursor
self . cursor
}
}
}
}
/// Re-sort the given layers so that the next capture for the `layers[0]` is
/// the earliest capture in the document for all layers.
///
/// This function assumes that `layers` is already sorted except for the
/// first layer in the `Vec`. This function shifts the first layer later in
/// the `Vec` after any layers with earlier captures.
///
/// This is quicker than a regular full sort: it can only take as many
/// iterations as the number of layers and usually takes many fewer than
/// the full number of layers. The case when `layers[0]` is already the
/// layer with the earliest capture and the sort is a no-op is a fast-lane
/// which only takes one comparison operation.
///
/// This function also removes any layers which have no more query captures
/// to emit.
fn sort_layers < L : IterLayer > ( layers : & mut Vec < L > ) {
while ! layers . is_empty ( ) {
// If `Layer::sort_key` returns `None`, the layer has no more captures
// to emit and can be removed.
if let Some ( sort_key ) = layers [ 0 ] . sort_key ( ) {
let mut i = 0 ;
while i + 1 < layers . len ( ) {
if let Some ( next_offset ) = layers [ i + 1 ] . sort_key ( ) {
// Compare `0`'s sort key to `i + 1`'s. If `i + 1` comes
// before `0`, shift the `0` layer so it comes after the
// `i + 1` layers.
if next_offset < sort_key {
i + = 1 ;
continue ;
}
} else {
let layer = layers . remove ( i + 1 ) ;
PARSER . with ( | ts_parser | {
let highlighter = & mut ts_parser . borrow_mut ( ) ;
highlighter . cursors . push ( layer . cursor ( ) ) ;
} ) ;
}
break ;
}
if i > 0 {
layers [ 0 .. ( i + 1 ) ] . rotate_left ( 1 ) ;
}
break ;
} else {
let layer = layers . remove ( 0 ) ;
PARSER . with ( | ts_parser | {
let highlighter = & mut ts_parser . borrow_mut ( ) ;
highlighter . cursors . push ( layer . cursor ( ) ) ;
} ) ;
}
}
}
}
#[ derive(Clone) ]
#[ derive(Clone) ]
@ -2266,42 +2318,9 @@ impl<'a> HighlightIter<'a> {
} else {
} else {
result = event . map ( Ok ) ;
result = event . map ( Ok ) ;
}
}
self . sort_ layers( ) ;
sort_layers ( & mut self . layers) ;
result
result
}
}
fn sort_layers ( & mut self ) {
while ! self . layers . is_empty ( ) {
if let Some ( sort_key ) = self . layers [ 0 ] . sort_key ( ) {
let mut i = 0 ;
while i + 1 < self . layers . len ( ) {
if let Some ( next_offset ) = self . layers [ i + 1 ] . sort_key ( ) {
if next_offset < sort_key {
i + = 1 ;
continue ;
}
} else {
let layer = self . layers . remove ( i + 1 ) ;
PARSER . with ( | ts_parser | {
let highlighter = & mut ts_parser . borrow_mut ( ) ;
highlighter . cursors . push ( layer . cursor ) ;
} ) ;
}
break ;
}
if i > 0 {
self . layers [ 0 .. ( i + 1 ) ] . rotate_left ( 1 ) ;
}
break ;
} else {
let layer = self . layers . remove ( 0 ) ;
PARSER . with ( | ts_parser | {
let highlighter = & mut ts_parser . borrow_mut ( ) ;
highlighter . cursors . push ( layer . cursor ) ;
} ) ;
}
}
}
}
}
impl < ' a > Iterator for HighlightIter < ' a > {
impl < ' a > Iterator for HighlightIter < ' a > {
@ -2453,7 +2472,7 @@ impl<'a> Iterator for HighlightIter<'a> {
}
}
}
}
self . sort_ layers( ) ;
sort_layers ( & mut self . layers) ;
continue 'main ;
continue 'main ;
}
}
@ -2462,7 +2481,7 @@ impl<'a> Iterator for HighlightIter<'a> {
// a different layer, then skip over this one.
// a different layer, then skip over this one.
if let Some ( ( last_start , last_end , last_depth ) ) = self . last_highlight_range {
if let Some ( ( last_start , last_end , last_depth ) ) = self . last_highlight_range {
if range . start = = last_start & & range . end = = last_end & & layer . depth < last_depth {
if range . start = = last_start & & range . end = = last_end & & layer . depth < last_depth {
self . sort_ layers( ) ;
sort_layers ( & mut self . layers) ;
continue 'main ;
continue 'main ;
}
}
}
}
@ -2481,7 +2500,7 @@ impl<'a> Iterator for HighlightIter<'a> {
}
}
}
}
self . sort_ layers( ) ;
sort_layers ( & mut self . layers) ;
continue 'main ;
continue 'main ;
}
}
}
}
@ -2516,7 +2535,7 @@ impl<'a> Iterator for HighlightIter<'a> {
. emit_event ( range . start , Some ( HighlightEvent ::HighlightStart ( highlight ) ) ) ;
. emit_event ( range . start , Some ( HighlightEvent ::HighlightStart ( highlight ) ) ) ;
}
}
self . sort_ layers( ) ;
sort_layers ( & mut self . layers) ;
}
}
}
}
}
}
@ -2728,7 +2747,7 @@ fn pretty_print_tree_impl<W: fmt::Write>(
struct QueryIterLayer < ' a > {
struct QueryIterLayer < ' a > {
cursor : QueryCursor ,
cursor : QueryCursor ,
captures : iter::Peekable < QueryCaptures < ' a , ' a , RopeProvider < ' a > , & ' a [ u8 ] > > ,
captures : RefCell< iter::Peekable < QueryCaptures < ' a , ' a , RopeProvider < ' a > , & ' a [ u8 ] > > > ,
layer : & ' a LanguageLayer ,
layer : & ' a LanguageLayer ,
}
}
@ -2738,16 +2757,6 @@ impl<'a> fmt::Debug for QueryIterLayer<'a> {
}
}
}
}
impl < ' a > QueryIterLayer < ' a > {
fn sort_key ( & mut self ) -> Option < ( usize , isize ) > {
let depth = - ( self . layer . depth as isize ) ;
let ( match_ , capture_index ) = self . captures . peek ( ) ? ;
let start = match_ . captures [ * capture_index ] . node . start_byte ( ) ;
Some ( ( start , depth ) )
}
}
#[ derive(Debug) ]
#[ derive(Debug) ]
pub struct QueryIter < ' a > {
pub struct QueryIter < ' a > {
layers : Vec < QueryIterLayer < ' a > > ,
layers : Vec < QueryIterLayer < ' a > > ,
@ -2757,38 +2766,8 @@ impl<'a> Iterator for QueryIter<'a> {
type Item = ( & ' a LanguageLayer , QueryMatch < ' a , ' a > , usize ) ;
type Item = ( & ' a LanguageLayer , QueryMatch < ' a , ' a > , usize ) ;
fn next ( & mut self ) -> Option < Self ::Item > {
fn next ( & mut self ) -> Option < Self ::Item > {
// Sort the layers so that the first layer in the Vec has the next
// Sort the layers so that the first layer contains the next capture.
// capture ordered by start byte and depth (descending).
sort_layers ( & mut self . layers ) ;
while ! self . layers . is_empty ( ) {
if let Some ( sort_key ) = self . layers [ 0 ] . sort_key ( ) {
let mut i = 0 ;
while i + 1 < self . layers . len ( ) {
if let Some ( next_sort_key ) = self . layers [ i + 1 ] . sort_key ( ) {
if next_sort_key < sort_key {
i + = 1 ;
continue ;
}
} else {
let layer = self . layers . remove ( i + 1 ) ;
PARSER . with ( | ts_parser | {
let parser = & mut ts_parser . borrow_mut ( ) ;
parser . cursors . push ( layer . cursor ) ;
} ) ;
}
break ;
}
if i > 0 {
self . layers [ 0 .. ( i + 1 ) ] . rotate_left ( 1 ) ;
}
break ;
} else {
let layer = self . layers . remove ( 0 ) ;
PARSER . with ( | ts_parser | {
let parser = & mut ts_parser . borrow_mut ( ) ;
parser . cursors . push ( layer . cursor ) ;
} )
}
}
// Emit the next capture from the lowest layer. If there are no more
// Emit the next capture from the lowest layer. If there are no more
// layers, terminate.
// layers, terminate.