tasks: Fix runnables retrieval to not bail when a single tag can't be matched (#12113)
This can happen with queries without `@run` indicator. Release Notes: - N/A
This commit is contained in:
parent
e68ef944d9
commit
c440f3a71b
1 changed files with 46 additions and 42 deletions
|
@ -3005,52 +3005,56 @@ impl BufferSnapshot {
|
||||||
.map(|grammar| grammar.runnable_config.as_ref())
|
.map(|grammar| grammar.runnable_config.as_ref())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
iter::from_fn(move || {
|
iter::from_fn(move || loop {
|
||||||
let test_range = syntax_matches.peek().and_then(|mat| {
|
let mat = syntax_matches.peek()?;
|
||||||
test_configs[mat.grammar_index].and_then(|test_configs| {
|
let test_range = test_configs[mat.grammar_index].and_then(|test_configs| {
|
||||||
let mut tags: SmallVec<[(Range<usize>, RunnableTag); 1]> =
|
let mut tags: SmallVec<[(Range<usize>, RunnableTag); 1]> =
|
||||||
SmallVec::from_iter(mat.captures.iter().filter_map(|capture| {
|
SmallVec::from_iter(mat.captures.iter().filter_map(|capture| {
|
||||||
test_configs
|
test_configs
|
||||||
.runnable_tags
|
.runnable_tags
|
||||||
.get(&capture.index)
|
.get(&capture.index)
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|tag_name| (capture.node.byte_range(), tag_name))
|
.map(|tag_name| (capture.node.byte_range(), tag_name))
|
||||||
}));
|
}));
|
||||||
let maximum_range = tags
|
let maximum_range = tags
|
||||||
.iter()
|
.iter()
|
||||||
.max_by_key(|(byte_range, _)| byte_range.len())
|
.max_by_key(|(byte_range, _)| byte_range.len())
|
||||||
.map(|(range, _)| range)?
|
.map(|(range, _)| range)?
|
||||||
.clone();
|
.clone();
|
||||||
tags.sort_by_key(|(range, _)| range == &maximum_range);
|
tags.sort_by_key(|(range, _)| range == &maximum_range);
|
||||||
let split_point = tags.partition_point(|(range, _)| range != &maximum_range);
|
let split_point = tags.partition_point(|(range, _)| range != &maximum_range);
|
||||||
let (extra_captures, tags) = tags.split_at(split_point);
|
let (extra_captures, tags) = tags.split_at(split_point);
|
||||||
let extra_captures = extra_captures
|
let extra_captures = extra_captures
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(range, name)| {
|
.map(|(range, name)| {
|
||||||
(
|
(
|
||||||
name.0.to_string(),
|
name.0.to_string(),
|
||||||
self.text_for_range(range.clone()).collect::<String>(),
|
self.text_for_range(range.clone()).collect::<String>(),
|
||||||
)
|
)
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
Some(RunnableRange {
|
|
||||||
run_range: mat
|
|
||||||
.captures
|
|
||||||
.iter()
|
|
||||||
.find(|capture| capture.index == test_configs.run_capture_ix)
|
|
||||||
.map(|mat| mat.node.byte_range())?,
|
|
||||||
runnable: Runnable {
|
|
||||||
tags: tags.into_iter().cloned().map(|(_, tag)| tag).collect(),
|
|
||||||
language: mat.language,
|
|
||||||
buffer: self.remote_id(),
|
|
||||||
},
|
|
||||||
extra_captures,
|
|
||||||
buffer_id: self.remote_id(),
|
|
||||||
})
|
})
|
||||||
|
.collect();
|
||||||
|
Some(RunnableRange {
|
||||||
|
run_range: mat
|
||||||
|
.captures
|
||||||
|
.iter()
|
||||||
|
.find(|capture| capture.index == test_configs.run_capture_ix)
|
||||||
|
.map(|mat| mat.node.byte_range())?,
|
||||||
|
runnable: Runnable {
|
||||||
|
tags: tags.into_iter().cloned().map(|(_, tag)| tag).collect(),
|
||||||
|
language: mat.language,
|
||||||
|
buffer: self.remote_id(),
|
||||||
|
},
|
||||||
|
extra_captures,
|
||||||
|
buffer_id: self.remote_id(),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
syntax_matches.advance();
|
syntax_matches.advance();
|
||||||
test_range
|
if test_range.is_some() {
|
||||||
|
// It's fine for us to short-circuit on .peek()? returning None. We don't want to return None from this iter if we
|
||||||
|
// had a capture that did not contain a run marker, hence we'll just loop around for the next capture.
|
||||||
|
return test_range;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue