Skip to content

Commit 634596e

Browse files
authored
Merge pull request #19928 from Veykril/push-kznpuqllrvvq
Deduplicate code in proc-macro-srv
2 parents 55b7331 + 02a788b commit 634596e

File tree

6 files changed

+160
-297
lines changed

6 files changed

+160
-297
lines changed

crates/proc-macro-srv/src/server_impl.rs

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
1111
use std::fmt;
1212

13+
use intern::Symbol;
1314
use proc_macro::bridge;
1415

1516
mod token_stream;
@@ -112,3 +113,135 @@ fn literal_kind_to_internal(kind: bridge::LitKind) -> tt::LitKind {
112113
bridge::LitKind::ErrWithGuar => tt::LitKind::Err(()),
113114
}
114115
}
116+
117+
pub(super) fn literal_from_str<Span: Copy>(
118+
s: &str,
119+
span: Span,
120+
) -> Result<bridge::Literal<Span, Symbol>, ()> {
121+
use proc_macro::bridge::LitKind;
122+
use rustc_lexer::{LiteralKind, Token, TokenKind};
123+
124+
let mut tokens = rustc_lexer::tokenize(s);
125+
let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
126+
127+
let lit = if minus_or_lit.kind == TokenKind::Minus {
128+
let lit = tokens.next().ok_or(())?;
129+
if !matches!(
130+
lit.kind,
131+
TokenKind::Literal { kind: LiteralKind::Int { .. } | LiteralKind::Float { .. }, .. }
132+
) {
133+
return Err(());
134+
}
135+
lit
136+
} else {
137+
minus_or_lit
138+
};
139+
140+
if tokens.next().is_some() {
141+
return Err(());
142+
}
143+
144+
let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
145+
let (kind, start_offset, end_offset) = match kind {
146+
LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
147+
LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
148+
LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
149+
LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
150+
LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
151+
LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
152+
LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
153+
LiteralKind::RawStr { n_hashes } => (
154+
LitKind::StrRaw(n_hashes.unwrap_or_default()),
155+
2 + n_hashes.unwrap_or_default() as usize,
156+
1 + n_hashes.unwrap_or_default() as usize,
157+
),
158+
LiteralKind::RawByteStr { n_hashes } => (
159+
LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
160+
3 + n_hashes.unwrap_or_default() as usize,
161+
1 + n_hashes.unwrap_or_default() as usize,
162+
),
163+
LiteralKind::RawCStr { n_hashes } => (
164+
LitKind::CStrRaw(n_hashes.unwrap_or_default()),
165+
3 + n_hashes.unwrap_or_default() as usize,
166+
1 + n_hashes.unwrap_or_default() as usize,
167+
),
168+
};
169+
170+
let (lit, suffix) = s.split_at(suffix_start as usize);
171+
let lit = &lit[start_offset..lit.len() - end_offset];
172+
let suffix = match suffix {
173+
"" | "_" => None,
174+
suffix => Some(Symbol::intern(suffix)),
175+
};
176+
177+
Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span })
178+
}
179+
180+
pub(super) fn from_token_tree<Span: Copy>(
181+
tree: bridge::TokenTree<TokenStream<Span>, Span, Symbol>,
182+
) -> TokenStream<Span> {
183+
match tree {
184+
bridge::TokenTree::Group(group) => {
185+
let group = TopSubtree::from_bridge(group);
186+
TokenStream { token_trees: group.0 }
187+
}
188+
189+
bridge::TokenTree::Ident(ident) => {
190+
let text = ident.sym;
191+
let ident: tt::Ident<Span> = tt::Ident {
192+
sym: text,
193+
span: ident.span,
194+
is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
195+
};
196+
let leaf = tt::Leaf::from(ident);
197+
let tree = tt::TokenTree::from(leaf);
198+
TokenStream { token_trees: vec![tree] }
199+
}
200+
201+
bridge::TokenTree::Literal(literal) => {
202+
let token_trees =
203+
if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
204+
let punct = tt::Punct {
205+
spacing: tt::Spacing::Alone,
206+
span: literal.span,
207+
char: '-' as char,
208+
};
209+
let leaf: tt::Leaf<Span> = tt::Leaf::from(punct);
210+
let minus_tree = tt::TokenTree::from(leaf);
211+
212+
let literal = tt::Literal {
213+
symbol: Symbol::intern(symbol),
214+
suffix: literal.suffix,
215+
span: literal.span,
216+
kind: literal_kind_to_internal(literal.kind),
217+
};
218+
let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
219+
let tree = tt::TokenTree::from(leaf);
220+
vec![minus_tree, tree]
221+
} else {
222+
let literal = tt::Literal {
223+
symbol: literal.symbol,
224+
suffix: literal.suffix,
225+
span: literal.span,
226+
kind: literal_kind_to_internal(literal.kind),
227+
};
228+
229+
let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
230+
let tree = tt::TokenTree::from(leaf);
231+
vec![tree]
232+
};
233+
TokenStream { token_trees }
234+
}
235+
236+
bridge::TokenTree::Punct(p) => {
237+
let punct = tt::Punct {
238+
char: p.ch as char,
239+
spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone },
240+
span: p.span,
241+
};
242+
let leaf = tt::Leaf::from(punct);
243+
let tree = tt::TokenTree::from(leaf);
244+
TokenStream { token_trees: vec![tree] }
245+
}
246+
}
247+
}

crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs

Lines changed: 3 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,7 @@ use proc_macro::bridge::{self, server};
1414
use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
1515
use tt::{TextRange, TextSize};
1616

17-
use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder};
18-
mod tt {
19-
pub use tt::*;
20-
21-
pub type TokenTree = ::tt::TokenTree<super::Span>;
22-
pub type Leaf = ::tt::Leaf<super::Span>;
23-
pub type Literal = ::tt::Literal<super::Span>;
24-
pub type Punct = ::tt::Punct<super::Span>;
25-
pub type Ident = ::tt::Ident<super::Span>;
26-
}
17+
use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder};
2718

2819
type TokenStream = crate::server_impl::TokenStream<Span>;
2920

@@ -62,66 +53,7 @@ impl server::FreeFunctions for RaSpanServer {
6253
&mut self,
6354
s: &str,
6455
) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
65-
use proc_macro::bridge::LitKind;
66-
use rustc_lexer::{LiteralKind, Token, TokenKind};
67-
68-
let mut tokens = rustc_lexer::tokenize(s);
69-
let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
70-
71-
let lit = if minus_or_lit.kind == TokenKind::Minus {
72-
let lit = tokens.next().ok_or(())?;
73-
if !matches!(
74-
lit.kind,
75-
TokenKind::Literal {
76-
kind: LiteralKind::Int { .. } | LiteralKind::Float { .. },
77-
..
78-
}
79-
) {
80-
return Err(());
81-
}
82-
lit
83-
} else {
84-
minus_or_lit
85-
};
86-
87-
if tokens.next().is_some() {
88-
return Err(());
89-
}
90-
91-
let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
92-
let (kind, start_offset, end_offset) = match kind {
93-
LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
94-
LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
95-
LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
96-
LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
97-
LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
98-
LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
99-
LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
100-
LiteralKind::RawStr { n_hashes } => (
101-
LitKind::StrRaw(n_hashes.unwrap_or_default()),
102-
2 + n_hashes.unwrap_or_default() as usize,
103-
1 + n_hashes.unwrap_or_default() as usize,
104-
),
105-
LiteralKind::RawByteStr { n_hashes } => (
106-
LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
107-
3 + n_hashes.unwrap_or_default() as usize,
108-
1 + n_hashes.unwrap_or_default() as usize,
109-
),
110-
LiteralKind::RawCStr { n_hashes } => (
111-
LitKind::CStrRaw(n_hashes.unwrap_or_default()),
112-
3 + n_hashes.unwrap_or_default() as usize,
113-
1 + n_hashes.unwrap_or_default() as usize,
114-
),
115-
};
116-
117-
let (lit, suffix) = s.split_at(suffix_start as usize);
118-
let lit = &lit[start_offset..lit.len() - end_offset];
119-
let suffix = match suffix {
120-
"" | "_" => None,
121-
suffix => Some(Symbol::intern(suffix)),
122-
};
123-
124-
Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site })
56+
literal_from_str(s, self.call_site)
12557
}
12658

12759
fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {
@@ -149,70 +81,7 @@ impl server::TokenStream for RaSpanServer {
14981
&mut self,
15082
tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
15183
) -> Self::TokenStream {
152-
match tree {
153-
bridge::TokenTree::Group(group) => {
154-
let group = TopSubtree::from_bridge(group);
155-
TokenStream { token_trees: group.0 }
156-
}
157-
158-
bridge::TokenTree::Ident(ident) => {
159-
let text = ident.sym;
160-
let ident: tt::Ident = tt::Ident {
161-
sym: text,
162-
span: ident.span,
163-
is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
164-
};
165-
let leaf = tt::Leaf::from(ident);
166-
let tree = tt::TokenTree::from(leaf);
167-
TokenStream { token_trees: vec![tree] }
168-
}
169-
170-
bridge::TokenTree::Literal(literal) => {
171-
let token_trees =
172-
if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
173-
let punct = tt::Punct {
174-
spacing: tt::Spacing::Alone,
175-
span: literal.span,
176-
char: '-' as char,
177-
};
178-
let leaf: tt::Leaf = tt::Leaf::from(punct);
179-
let minus_tree = tt::TokenTree::from(leaf);
180-
181-
let literal = tt::Literal {
182-
symbol: Symbol::intern(symbol),
183-
suffix: literal.suffix,
184-
span: literal.span,
185-
kind: literal_kind_to_internal(literal.kind),
186-
};
187-
let leaf: tt::Leaf = tt::Leaf::from(literal);
188-
let tree = tt::TokenTree::from(leaf);
189-
vec![minus_tree, tree]
190-
} else {
191-
let literal = tt::Literal {
192-
symbol: literal.symbol,
193-
suffix: literal.suffix,
194-
span: literal.span,
195-
kind: literal_kind_to_internal(literal.kind),
196-
};
197-
198-
let leaf: tt::Leaf = tt::Leaf::from(literal);
199-
let tree = tt::TokenTree::from(leaf);
200-
vec![tree]
201-
};
202-
TokenStream { token_trees }
203-
}
204-
205-
bridge::TokenTree::Punct(p) => {
206-
let punct = tt::Punct {
207-
char: p.ch as char,
208-
spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone },
209-
span: p.span,
210-
};
211-
let leaf = tt::Leaf::from(punct);
212-
let tree = tt::TokenTree::from(leaf);
213-
TokenStream { token_trees: vec![tree] }
214-
}
215-
}
84+
from_token_tree(tree)
21685
}
21786

21887
fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {

0 commit comments

Comments
 (0)