Skip to content

Commit d25b610

Browse files
Add literal/ident conversion, tests pass
1 parent 191db9f commit d25b610

File tree

5 files changed

+71
-36
lines changed

5 files changed

+71
-36
lines changed

Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/proc-macro-srv/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ tt = { path = "../tt", version = "0.0.0" }
2424
mbe = { path = "../mbe", version = "0.0.0" }
2525
paths = { path = "../paths", version = "0.0.0" }
2626
proc-macro-api = { path = "../proc-macro-api", version = "0.0.0" }
27+
once_cell = "1.13.0"
2728

2829
[dev-dependencies]
2930
expect-test = "1.4.0"

crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -115,20 +115,29 @@ impl server::TokenStream for RustAnalyzer {
115115
Self::TokenStream::from_iter(vec![tree])
116116
}
117117

118-
bridge::TokenTree::Ident(_symbol) => {
119-
todo!("convert Ident bridge=>TokenStream");
120-
// let IdentData(ident) = self.ident_interner.get(index).clone();
121-
// let ident: tt::Ident = ident;
122-
// let leaf = tt::Leaf::from(ident);
123-
// let tree = TokenTree::from(leaf);
124-
// Self::TokenStream::from_iter(vec![tree])
118+
bridge::TokenTree::Ident(ident) => {
119+
// FIXME: handle raw idents
120+
let text = SYMBOL_INTERNER.lock().unwrap().get(&ident.sym).clone();
121+
let ident: tt::Ident = tt::Ident { text, id: ident.span };
122+
let leaf = tt::Leaf::from(ident);
123+
let tree = TokenTree::from(leaf);
124+
Self::TokenStream::from_iter(vec![tree])
125125
}
126126

127-
bridge::TokenTree::Literal(_literal) => {
128-
todo!("convert Literal bridge=>TokenStream");
129-
// let leaf = tt::Leaf::from(literal);
130-
// let tree = TokenTree::from(leaf);
131-
// Self::TokenStream::from_iter(vec![tree])
127+
bridge::TokenTree::Literal(literal) => {
128+
let symbol = SYMBOL_INTERNER.lock().unwrap().get(&literal.symbol).clone();
129+
130+
let text: tt::SmolStr = if let Some(suffix) = literal.suffix {
131+
let suffix = SYMBOL_INTERNER.lock().unwrap().get(&suffix).clone();
132+
format!("{symbol}{suffix}").into()
133+
} else {
134+
symbol
135+
};
136+
137+
let literal = tt::Literal { text, id: literal.span };
138+
let leaf = tt::Leaf::from(literal);
139+
let tree = TokenTree::from(leaf);
140+
Self::TokenStream::from_iter(vec![tree])
132141
}
133142

134143
bridge::TokenTree::Punct(p) => {
@@ -185,13 +194,23 @@ impl server::TokenStream for RustAnalyzer {
185194
stream
186195
.into_iter()
187196
.map(|tree| match tree {
188-
tt::TokenTree::Leaf(tt::Leaf::Ident(_ident)) => {
189-
todo!("convert Ident tt=>bridge");
190-
// bridge::TokenTree::Ident(Symbol(self.ident_interner.intern(&IdentData(ident))))
197+
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
198+
bridge::TokenTree::Ident(bridge::Ident {
199+
sym: SYMBOL_INTERNER.lock().unwrap().intern(&ident.text),
200+
// FIXME: handle raw idents
201+
is_raw: false,
202+
span: ident.id,
203+
})
191204
}
192-
tt::TokenTree::Leaf(tt::Leaf::Literal(_lit)) => {
193-
todo!("convert Literal tt=>bridge");
194-
// bridge::TokenTree::Literal(lit)
205+
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
206+
bridge::TokenTree::Literal(bridge::Literal {
207+
// FIXME: handle literal kinds
208+
kind: bridge::LitKind::Err,
209+
symbol: SYMBOL_INTERNER.lock().unwrap().intern(&lit.text),
210+
// FIXME: handle suffixes
211+
suffix: None,
212+
span: lit.id,
213+
})
195214
}
196215
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => {
197216
bridge::TokenTree::Punct(bridge::Punct {
@@ -379,12 +398,12 @@ impl server::Server for RustAnalyzer {
379398
}
380399
}
381400

382-
fn intern_symbol(_ident: &str) -> Self::Symbol {
383-
todo!("intern_symbol")
401+
fn intern_symbol(ident: &str) -> Self::Symbol {
402+
SYMBOL_INTERNER.lock().unwrap().intern(&tt::SmolStr::from(ident))
384403
}
385404

386-
fn with_symbol_string(_symbol: &Self::Symbol, _f: impl FnOnce(&str)) {
387-
todo!("with_symbol_string")
405+
fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
406+
f(SYMBOL_INTERNER.lock().unwrap().get(symbol).as_str())
388407
}
389408
}
390409

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
use std::collections::HashMap;
1+
use once_cell::sync::Lazy;
2+
use std::{collections::HashMap, sync::Mutex};
23
use tt::SmolStr;
34

4-
// Identifier for an interned symbol.
5+
pub(super) static SYMBOL_INTERNER: Lazy<Mutex<SymbolInterner>> = Lazy::new(|| Default::default());
6+
7+
// ID for an interned symbol.
58
#[derive(Hash, Eq, PartialEq, Copy, Clone)]
69
pub struct Symbol(u32);
710

811
#[derive(Default)]
9-
struct IdentInterner {
12+
pub(super) struct SymbolInterner {
1013
idents: HashMap<SmolStr, u32>,
1114
ident_data: Vec<SmolStr>,
1215
}
1316

14-
impl IdentInterner {
15-
fn intern(&mut self, data: &str) -> Symbol {
17+
impl SymbolInterner {
18+
pub(super) fn intern(&mut self, data: &str) -> Symbol {
1619
if let Some(index) = self.idents.get(data) {
1720
return Symbol(*index);
1821
}
@@ -24,12 +27,7 @@ impl IdentInterner {
2427
Symbol(index)
2528
}
2629

27-
fn get(&self, index: u32) -> &SmolStr {
28-
&self.ident_data[index as usize]
29-
}
30-
31-
#[allow(unused)]
32-
fn get_mut(&mut self, index: u32) -> &mut SmolStr {
33-
self.ident_data.get_mut(index as usize).expect("Should be consistent")
30+
pub(super) fn get(&self, index: &Symbol) -> &SmolStr {
31+
&self.ident_data[index.0 as usize]
3432
}
3533
}

crates/proc-macro-srv/src/abis/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ use super::dylib::LoadProcMacroDylibError;
3737
pub(crate) use abi_1_58::Abi as Abi_1_58;
3838
pub(crate) use abi_1_63::Abi as Abi_1_63;
3939
pub(crate) use abi_1_64::Abi as Abi_1_64;
40+
#[cfg(feature = "sysroot-abi")]
41+
pub(crate) use abi_sysroot::Abi as Abi_Sysroot;
4042
use libloading::Library;
4143
use proc_macro_api::{ProcMacroKind, RustCInfo};
4244

@@ -54,6 +56,8 @@ pub(crate) enum Abi {
5456
Abi1_58(Abi_1_58),
5557
Abi1_63(Abi_1_63),
5658
Abi1_64(Abi_1_64),
59+
#[cfg(feature = "sysroot-abi")]
60+
AbiSysroot(Abi_Sysroot),
5761
}
5862

5963
impl Abi {
@@ -71,6 +75,14 @@ impl Abi {
7175
symbol_name: String,
7276
info: RustCInfo,
7377
) -> Result<Abi, LoadProcMacroDylibError> {
78+
// Gated behind an env var for now to avoid a change in behavior for
79+
// rustup-installed rust-analyzer
80+
#[cfg(feature = "sysroot-abi")]
81+
if std::env::var("PROC_MACRO_SRV_SYSROOT_ABI").is_ok() {
82+
let inner = unsafe { Abi_Sysroot::from_lib(lib, symbol_name) }?;
83+
return Ok(Abi::AbiSysroot(inner));
84+
}
85+
7486
// FIXME: this should use exclusive ranges when they're stable
7587
// https://github.com/rust-lang/rust/issues/37854
7688
match (info.version.0, info.version.1) {
@@ -100,6 +112,8 @@ impl Abi {
100112
Self::Abi1_58(abi) => abi.expand(macro_name, macro_body, attributes),
101113
Self::Abi1_63(abi) => abi.expand(macro_name, macro_body, attributes),
102114
Self::Abi1_64(abi) => abi.expand(macro_name, macro_body, attributes),
115+
#[cfg(feature = "sysroot-abi")]
116+
Self::AbiSysroot(abi) => abi.expand(macro_name, macro_body, attributes),
103117
}
104118
}
105119

@@ -108,6 +122,8 @@ impl Abi {
108122
Self::Abi1_58(abi) => abi.list_macros(),
109123
Self::Abi1_63(abi) => abi.list_macros(),
110124
Self::Abi1_64(abi) => abi.list_macros(),
125+
#[cfg(feature = "sysroot-abi")]
126+
Self::AbiSysroot(abi) => abi.list_macros(),
111127
}
112128
}
113129
}

0 commit comments

Comments
 (0)