Skip to content

Commit cacb1f3

Browse files
committed
WIP: to_string and more
1 parent e321cb0 commit cacb1f3

File tree

1 file changed

+77
-5
lines changed

1 file changed

+77
-5
lines changed

library/proc_macro/src/bridge/standalone.rs

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#![allow(unused_variables)]
2+
#![warn(warnings)]
23
use std::cell::RefCell;
34
use std::ops::{Bound, Range};
45

6+
use crate::Delimiter;
57
use crate::bridge::client::Symbol;
6-
use crate::bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree, server};
8+
use crate::bridge::fxhash::FxHashMap;
9+
use crate::bridge::{Diagnostic, ExpnGlobals, LitKind, Literal, TokenTree, server};
710

811
pub struct NoRustc;
912

@@ -21,7 +24,7 @@ impl server::Span for NoRustc {
2124
}
2225

2326
fn byte_range(&mut self, span: Self::Span) -> Range<usize> {
24-
todo!()
27+
span.lo as usize..span.hi as usize
2528
}
2629

2730
fn start(&mut self, span: Self::Span) -> Self::Span {
@@ -111,14 +114,18 @@ impl server::Span for NoRustc {
111114

112115
thread_local! {
113116
static SAVED_SPANS: RefCell<Vec<Span>> = const { RefCell::new(Vec::new()) };
117+
static TRACKED_ENV_VARS: RefCell<FxHashMap<String, Option<String>>> = RefCell::new(FxHashMap::default());
114118
}
115119

116120
impl server::FreeFunctions for NoRustc {
117121
fn injected_env_var(&mut self, var: &str) -> Option<String> {
118-
todo!()
122+
TRACKED_ENV_VARS.with_borrow(|vars| vars.get(var)?.clone())
119123
}
120124

121-
fn track_env_var(&mut self, _var: &str, _value: Option<&str>) {}
125+
fn track_env_var(&mut self, var: &str, value: Option<&str>) {
126+
TRACKED_ENV_VARS
127+
.with_borrow_mut(|vars| vars.insert(var.to_string(), value.map(ToString::to_string)));
128+
}
122129

123130
fn track_path(&mut self, _path: &str) {}
124131

@@ -145,7 +152,72 @@ impl server::TokenStream for NoRustc {
145152
}
146153

147154
fn to_string(&mut self, tokens: &Self::TokenStream) -> String {
148-
todo!()
155+
/// Returns a string containing exactly `num` '#' characters.
156+
/// Uses a 256-character source string literal which is always safe to
157+
/// index with a `u8` index.
158+
fn get_hashes_str(num: u8) -> &'static str {
159+
const HASHES: &str = "\
160+
################################################################\
161+
################################################################\
162+
################################################################\
163+
################################################################\
164+
";
165+
const _: () = assert!(HASHES.len() == 256);
166+
&HASHES[..num as usize]
167+
}
168+
169+
let mut s = String::new();
170+
for tree in &tokens.0 {
171+
s.push_str(&match tree {
172+
TokenTree::Group(group) => {
173+
let inner = if let Some(stream) = &group.stream {
174+
self.to_string(stream)
175+
} else {
176+
String::new()
177+
};
178+
match group.delimiter {
179+
Delimiter::Parenthesis => format!("({inner})"),
180+
Delimiter::Brace => format!("{{{inner}}}"),
181+
Delimiter::Bracket => format!("[{inner}]"),
182+
Delimiter::None => inner,
183+
}
184+
}
185+
TokenTree::Ident(ident) => {
186+
if ident.is_raw {
187+
format!("r#{}", ident.sym)
188+
} else {
189+
ident.sym.to_string()
190+
}
191+
}
192+
TokenTree::Literal(lit) => {
193+
let inner = if let Some(suffix) = lit.suffix {
194+
format!("{}{suffix}", lit.symbol)
195+
} else {
196+
lit.symbol.to_string()
197+
};
198+
match lit.kind {
199+
LitKind::Byte => todo!(),
200+
LitKind::ByteStr => format!("b\"{inner}\""),
201+
LitKind::ByteStrRaw(raw) => {
202+
format!("br{0}\"{inner}\"{0}", get_hashes_str(raw))
203+
}
204+
LitKind::CStr => format!("c\"{inner}\""),
205+
LitKind::CStrRaw(raw) => {
206+
format!("cr{0}\"{inner}\"{0}", get_hashes_str(raw))
207+
}
208+
LitKind::Char => format!("'{inner}'"),
209+
LitKind::ErrWithGuar => unreachable!(),
210+
LitKind::Float | LitKind::Integer => inner,
211+
LitKind::Str => format!("\"{inner}\""),
212+
LitKind::StrRaw(raw) => format!("r{0}\"{inner}\"{0}", get_hashes_str(raw)),
213+
}
214+
}
215+
TokenTree::Punct(punct) => (punct.ch as char).to_string(),
216+
});
217+
s.push(' ');
218+
}
219+
s.pop();
220+
s
149221
}
150222

151223
fn from_token_tree(

0 commit comments

Comments
 (0)