Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax-bridge/src/lib.rs')
-rw-r--r--crates/syntax-bridge/src/lib.rs71
1 files changed, 42 insertions, 29 deletions
diff --git a/crates/syntax-bridge/src/lib.rs b/crates/syntax-bridge/src/lib.rs
index 4e525be3fe..1ded2b4113 100644
--- a/crates/syntax-bridge/src/lib.rs
+++ b/crates/syntax-bridge/src/lib.rs
@@ -1,6 +1,6 @@
//! Conversions between [`SyntaxNode`] and [`tt::TokenTree`].
-use std::{fmt, hash::Hash};
+use std::{collections::VecDeque, fmt, hash::Hash};
use intern::Symbol;
use rustc_hash::{FxHashMap, FxHashSet};
@@ -102,26 +102,34 @@ where
SpanData<Ctx>: Copy + fmt::Debug,
SpanMap: SpanMapper<SpanData<Ctx>>,
{
- let mut c = Converter::new(node, map, Default::default(), Default::default(), span, mode);
+ let mut c =
+ Converter::new(node, map, Default::default(), Default::default(), span, mode, |_, _| {
+ (true, Vec::new())
+ });
convert_tokens(&mut c)
}
/// Converts a syntax tree to a [`tt::Subtree`] using the provided span map to populate the
/// subtree's spans. Additionally using the append and remove parameters, the additional tokens can
/// be injected or hidden from the output.
-pub fn syntax_node_to_token_tree_modified<Ctx, SpanMap>(
+pub fn syntax_node_to_token_tree_modified<Ctx, SpanMap, OnEvent>(
node: &SyntaxNode,
map: SpanMap,
append: FxHashMap<SyntaxElement, Vec<tt::Leaf<SpanData<Ctx>>>>,
remove: FxHashSet<SyntaxElement>,
call_site: SpanData<Ctx>,
mode: DocCommentDesugarMode,
+ on_enter: OnEvent,
) -> tt::TopSubtree<SpanData<Ctx>>
where
SpanMap: SpanMapper<SpanData<Ctx>>,
SpanData<Ctx>: Copy + fmt::Debug,
+ OnEvent: FnMut(
+ &mut PreorderWithTokens,
+ &WalkEvent<SyntaxElement>,
+ ) -> (bool, Vec<tt::Leaf<SpanData<Ctx>>>),
{
- let mut c = Converter::new(node, map, append, remove, call_site, mode);
+ let mut c = Converter::new(node, map, append, remove, call_site, mode, on_enter);
convert_tokens(&mut c)
}
@@ -143,7 +151,6 @@ pub fn token_tree_to_syntax_node<Ctx>(
tt: &tt::TopSubtree<SpanData<Ctx>>,
entry_point: parser::TopEntryPoint,
span_to_edition: &mut dyn FnMut(Ctx) -> Edition,
- top_edition: Edition,
) -> (Parse<SyntaxNode>, SpanMap<Ctx>)
where
Ctx: Copy + fmt::Debug + PartialEq + PartialEq + Eq + Hash,
@@ -151,7 +158,7 @@ where
let buffer = tt.view().strip_invisible();
let parser_input = to_parser_input(buffer, span_to_edition);
// It matters what edition we parse with even when we escape all identifiers correctly.
- let parser_output = entry_point.parse(&parser_input, top_edition);
+ let parser_output = entry_point.parse(&parser_input);
let mut tree_sink = TtTreeSink::new(buffer.cursor());
for event in parser_output.iter() {
match event {
@@ -624,9 +631,9 @@ where
}
}
-struct Converter<SpanMap, S> {
+struct Converter<SpanMap, S, OnEvent> {
current: Option<SyntaxToken>,
- current_leaves: Vec<tt::Leaf<S>>,
+ current_leaves: VecDeque<tt::Leaf<S>>,
preorder: PreorderWithTokens,
range: TextRange,
punct_offset: Option<(SyntaxToken, TextSize)>,
@@ -636,9 +643,13 @@ struct Converter<SpanMap, S> {
remove: FxHashSet<SyntaxElement>,
call_site: S,
mode: DocCommentDesugarMode,
+ on_event: OnEvent,
}
-impl<SpanMap, S> Converter<SpanMap, S> {
+impl<SpanMap, S, OnEvent> Converter<SpanMap, S, OnEvent>
+where
+ OnEvent: FnMut(&mut PreorderWithTokens, &WalkEvent<SyntaxElement>) -> (bool, Vec<tt::Leaf<S>>),
+{
fn new(
node: &SyntaxNode,
map: SpanMap,
@@ -646,8 +657,9 @@ impl<SpanMap, S> Converter<SpanMap, S> {
remove: FxHashSet<SyntaxElement>,
call_site: S,
mode: DocCommentDesugarMode,
+ on_enter: OnEvent,
) -> Self {
- let mut this = Converter {
+ let mut converter = Converter {
current: None,
preorder: node.preorder_with_tokens(),
range: node.text_range(),
@@ -656,16 +668,21 @@ impl<SpanMap, S> Converter<SpanMap, S> {
append,
remove,
call_site,
- current_leaves: vec![],
+ current_leaves: VecDeque::new(),
mode,
+ on_event: on_enter,
};
- let first = this.next_token();
- this.current = first;
- this
+ converter.current = converter.next_token();
+ converter
}
fn next_token(&mut self) -> Option<SyntaxToken> {
while let Some(ev) = self.preorder.next() {
+ let (keep_event, insert_leaves) = (self.on_event)(&mut self.preorder, &ev);
+ self.current_leaves.extend(insert_leaves);
+ if !keep_event {
+ continue;
+ }
match ev {
WalkEvent::Enter(token) => {
if self.remove.contains(&token) {
@@ -675,10 +692,9 @@ impl<SpanMap, S> Converter<SpanMap, S> {
}
node => {
self.preorder.skip_subtree();
- if let Some(mut v) = self.append.remove(&node) {
- v.reverse();
+ if let Some(v) = self.append.remove(&node) {
self.current_leaves.extend(v);
- return None;
+ continue;
}
}
}
@@ -687,10 +703,9 @@ impl<SpanMap, S> Converter<SpanMap, S> {
}
}
WalkEvent::Leave(ele) => {
- if let Some(mut v) = self.append.remove(&ele) {
- v.reverse();
+ if let Some(v) = self.append.remove(&ele) {
self.current_leaves.extend(v);
- return None;
+ continue;
}
}
}
@@ -715,8 +730,8 @@ impl<S> SynToken<S> {
}
}
-impl<SpanMap, S> SrcToken<Converter<SpanMap, S>, S> for SynToken<S> {
- fn kind(&self, _ctx: &Converter<SpanMap, S>) -> SyntaxKind {
+impl<SpanMap, S, OnEvent> SrcToken<Converter<SpanMap, S, OnEvent>, S> for SynToken<S> {
+ fn kind(&self, _ctx: &Converter<SpanMap, S, OnEvent>) -> SyntaxKind {
match self {
SynToken::Ordinary(token) => token.kind(),
SynToken::Punct { token, offset: i } => {
@@ -728,14 +743,14 @@ impl<SpanMap, S> SrcToken<Converter<SpanMap, S>, S> for SynToken<S> {
}
}
}
- fn to_char(&self, _ctx: &Converter<SpanMap, S>) -> Option<char> {
+ fn to_char(&self, _ctx: &Converter<SpanMap, S, OnEvent>) -> Option<char> {
match self {
SynToken::Ordinary(_) => None,
SynToken::Punct { token: it, offset: i } => it.text().chars().nth(*i),
SynToken::Leaf(_) => None,
}
}
- fn to_text(&self, _ctx: &Converter<SpanMap, S>) -> SmolStr {
+ fn to_text(&self, _ctx: &Converter<SpanMap, S, OnEvent>) -> SmolStr {
match self {
SynToken::Ordinary(token) | SynToken::Punct { token, offset: _ } => token.text().into(),
SynToken::Leaf(_) => {
@@ -752,10 +767,11 @@ impl<SpanMap, S> SrcToken<Converter<SpanMap, S>, S> for SynToken<S> {
}
}
-impl<S, SpanMap> TokenConverter<S> for Converter<SpanMap, S>
+impl<S, SpanMap, OnEvent> TokenConverter<S> for Converter<SpanMap, S, OnEvent>
where
S: Copy,
SpanMap: SpanMapper<S>,
+ OnEvent: FnMut(&mut PreorderWithTokens, &WalkEvent<SyntaxElement>) -> (bool, Vec<tt::Leaf<S>>),
{
type Token = SynToken<S>;
fn convert_doc_comment(
@@ -781,10 +797,7 @@ where
));
}
- if let Some(leaf) = self.current_leaves.pop() {
- if self.current_leaves.is_empty() {
- self.current = self.next_token();
- }
+ if let Some(leaf) = self.current_leaves.pop_front() {
return Some((SynToken::Leaf(leaf), TextRange::empty(TextSize::new(0))));
}