about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAmos Wenger <amoswenger@gmail.com>2022-07-20 19:13:06 +0200
committerAmos Wenger <amoswenger@gmail.com>2022-07-20 19:18:39 +0200
commitd25b61030e97c2bb95f7dece2c6cf3cf271b6fe6 (patch)
tree8d0ec1a7da785bf53703f76c6aaed109c79ebd74
parent191db9fed4df1ed72fde44bbc8e6f988478db9f5 (diff)
downloadrust-d25b61030e97c2bb95f7dece2c6cf3cf271b6fe6.tar.gz
rust-d25b61030e97c2bb95f7dece2c6cf3cf271b6fe6.zip
Add literal/ident conversion, tests pass
-rw-r--r--Cargo.lock5
-rw-r--r--crates/proc-macro-srv/Cargo.toml1
-rw-r--r--crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs63
-rw-r--r--crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs22
-rw-r--r--crates/proc-macro-srv/src/abis/mod.rs16
5 files changed, 71 insertions, 36 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a960012c8cf..5d313b93083 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1022,9 +1022,9 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.12.0"
+version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
+checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
 
 [[package]]
 name = "oorandom"
@@ -1167,6 +1167,7 @@ dependencies = [
  "mbe",
  "memmap2",
  "object 0.29.0",
+ "once_cell",
  "paths",
  "proc-macro-api",
  "proc-macro-test",
diff --git a/crates/proc-macro-srv/Cargo.toml b/crates/proc-macro-srv/Cargo.toml
index e39026ac70b..06348afdede 100644
--- a/crates/proc-macro-srv/Cargo.toml
+++ b/crates/proc-macro-srv/Cargo.toml
@@ -24,6 +24,7 @@ tt = { path = "../tt", version = "0.0.0" }
 mbe = { path = "../mbe", version = "0.0.0" }
 paths = { path = "../paths", version = "0.0.0" }
 proc-macro-api = { path = "../proc-macro-api", version = "0.0.0" }
+once_cell = "1.13.0"
 
 [dev-dependencies]
 expect-test = "1.4.0"
diff --git a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
index 26766878304..55649ab8101 100644
--- a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
+++ b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
@@ -115,20 +115,29 @@ impl server::TokenStream for RustAnalyzer {
                 Self::TokenStream::from_iter(vec![tree])
             }
 
-            bridge::TokenTree::Ident(_symbol) => {
-                todo!("convert Ident bridge=>TokenStream");
-                // let IdentData(ident) = self.ident_interner.get(index).clone();
-                // let ident: tt::Ident = ident;
-                // let leaf = tt::Leaf::from(ident);
-                // let tree = TokenTree::from(leaf);
-                // Self::TokenStream::from_iter(vec![tree])
+            bridge::TokenTree::Ident(ident) => {
+                // FIXME: handle raw idents
+                let text = SYMBOL_INTERNER.lock().unwrap().get(&ident.sym).clone();
+                let ident: tt::Ident = tt::Ident { text, id: ident.span };
+                let leaf = tt::Leaf::from(ident);
+                let tree = TokenTree::from(leaf);
+                Self::TokenStream::from_iter(vec![tree])
             }
 
-            bridge::TokenTree::Literal(_literal) => {
-                todo!("convert Literal bridge=>TokenStream");
-                // let leaf = tt::Leaf::from(literal);
-                // let tree = TokenTree::from(leaf);
-                // Self::TokenStream::from_iter(vec![tree])
+            bridge::TokenTree::Literal(literal) => {
+                let symbol = SYMBOL_INTERNER.lock().unwrap().get(&literal.symbol).clone();
+
+                let text: tt::SmolStr = if let Some(suffix) = literal.suffix {
+                    let suffix = SYMBOL_INTERNER.lock().unwrap().get(&suffix).clone();
+                    format!("{symbol}{suffix}").into()
+                } else {
+                    symbol
+                };
+
+                let literal = tt::Literal { text, id: literal.span };
+                let leaf = tt::Leaf::from(literal);
+                let tree = TokenTree::from(leaf);
+                Self::TokenStream::from_iter(vec![tree])
             }
 
             bridge::TokenTree::Punct(p) => {
@@ -185,13 +194,23 @@ impl server::TokenStream for RustAnalyzer {
         stream
             .into_iter()
             .map(|tree| match tree {
-                tt::TokenTree::Leaf(tt::Leaf::Ident(_ident)) => {
-                    todo!("convert Ident tt=>bridge");
-                    // bridge::TokenTree::Ident(Symbol(self.ident_interner.intern(&IdentData(ident))))
+                tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
+                    bridge::TokenTree::Ident(bridge::Ident {
+                        sym: SYMBOL_INTERNER.lock().unwrap().intern(&ident.text),
+                        // FIXME: handle raw idents
+                        is_raw: false,
+                        span: ident.id,
+                    })
                 }
-                tt::TokenTree::Leaf(tt::Leaf::Literal(_lit)) => {
-                    todo!("convert Literal tt=>bridge");
-                    // bridge::TokenTree::Literal(lit)
+                tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
+                    bridge::TokenTree::Literal(bridge::Literal {
+                        // FIXME: handle literal kinds
+                        kind: bridge::LitKind::Err,
+                        symbol: SYMBOL_INTERNER.lock().unwrap().intern(&lit.text),
+                        // FIXME: handle suffixes
+                        suffix: None,
+                        span: lit.id,
+                    })
                 }
                 tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => {
                     bridge::TokenTree::Punct(bridge::Punct {
@@ -379,12 +398,12 @@ impl server::Server for RustAnalyzer {
         }
     }
 
-    fn intern_symbol(_ident: &str) -> Self::Symbol {
-        todo!("intern_symbol")
+    fn intern_symbol(ident: &str) -> Self::Symbol {
+        SYMBOL_INTERNER.lock().unwrap().intern(&tt::SmolStr::from(ident))
     }
 
-    fn with_symbol_string(_symbol: &Self::Symbol, _f: impl FnOnce(&str)) {
-        todo!("with_symbol_string")
+    fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
+        f(SYMBOL_INTERNER.lock().unwrap().get(symbol).as_str())
     }
 }
 
diff --git a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs
index b045f762b88..5bfc62a301b 100644
--- a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs
+++ b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs
@@ -1,18 +1,21 @@
-use std::collections::HashMap;
+use once_cell::sync::Lazy;
+use std::{collections::HashMap, sync::Mutex};
 use tt::SmolStr;
 
-// Identifier for an interned symbol.
+pub(super) static SYMBOL_INTERNER: Lazy<Mutex<SymbolInterner>> = Lazy::new(|| Default::default());
+
+// ID for an interned symbol.
 #[derive(Hash, Eq, PartialEq, Copy, Clone)]
 pub struct Symbol(u32);
 
 #[derive(Default)]
-struct IdentInterner {
+pub(super) struct SymbolInterner {
     idents: HashMap<SmolStr, u32>,
     ident_data: Vec<SmolStr>,
 }
 
-impl IdentInterner {
-    fn intern(&mut self, data: &str) -> Symbol {
+impl SymbolInterner {
+    pub(super) fn intern(&mut self, data: &str) -> Symbol {
         if let Some(index) = self.idents.get(data) {
             return Symbol(*index);
         }
@@ -24,12 +27,7 @@ impl IdentInterner {
         Symbol(index)
     }
 
-    fn get(&self, index: u32) -> &SmolStr {
-        &self.ident_data[index as usize]
-    }
-
-    #[allow(unused)]
-    fn get_mut(&mut self, index: u32) -> &mut SmolStr {
-        self.ident_data.get_mut(index as usize).expect("Should be consistent")
+    pub(super) fn get(&self, index: &Symbol) -> &SmolStr {
+        &self.ident_data[index.0 as usize]
     }
 }
diff --git a/crates/proc-macro-srv/src/abis/mod.rs b/crates/proc-macro-srv/src/abis/mod.rs
index 62479b7ccd6..f1083a9284b 100644
--- a/crates/proc-macro-srv/src/abis/mod.rs
+++ b/crates/proc-macro-srv/src/abis/mod.rs
@@ -37,6 +37,8 @@ use super::dylib::LoadProcMacroDylibError;
 pub(crate) use abi_1_58::Abi as Abi_1_58;
 pub(crate) use abi_1_63::Abi as Abi_1_63;
 pub(crate) use abi_1_64::Abi as Abi_1_64;
+#[cfg(feature = "sysroot-abi")]
+pub(crate) use abi_sysroot::Abi as Abi_Sysroot;
 use libloading::Library;
 use proc_macro_api::{ProcMacroKind, RustCInfo};
 
@@ -54,6 +56,8 @@ pub(crate) enum Abi {
     Abi1_58(Abi_1_58),
     Abi1_63(Abi_1_63),
     Abi1_64(Abi_1_64),
+    #[cfg(feature = "sysroot-abi")]
+    AbiSysroot(Abi_Sysroot),
 }
 
 impl Abi {
@@ -71,6 +75,14 @@ impl Abi {
         symbol_name: String,
         info: RustCInfo,
     ) -> Result<Abi, LoadProcMacroDylibError> {
+        // Gated behind an env var for now to avoid a change in behavior for
+        // rustup-installed rust-analyzer
+        #[cfg(feature = "sysroot-abi")]
+        if std::env::var("PROC_MACRO_SRV_SYSROOT_ABI").is_ok() {
+            let inner = unsafe { Abi_Sysroot::from_lib(lib, symbol_name) }?;
+            return Ok(Abi::AbiSysroot(inner));
+        }
+
         // FIXME: this should use exclusive ranges when they're stable
         // https://github.com/rust-lang/rust/issues/37854
         match (info.version.0, info.version.1) {
@@ -100,6 +112,8 @@ impl Abi {
             Self::Abi1_58(abi) => abi.expand(macro_name, macro_body, attributes),
             Self::Abi1_63(abi) => abi.expand(macro_name, macro_body, attributes),
             Self::Abi1_64(abi) => abi.expand(macro_name, macro_body, attributes),
+            #[cfg(feature = "sysroot-abi")]
+            Self::AbiSysroot(abi) => abi.expand(macro_name, macro_body, attributes),
         }
     }
 
@@ -108,6 +122,8 @@ impl Abi {
             Self::Abi1_58(abi) => abi.list_macros(),
             Self::Abi1_63(abi) => abi.list_macros(),
             Self::Abi1_64(abi) => abi.list_macros(),
+            #[cfg(feature = "sysroot-abi")]
+            Self::AbiSysroot(abi) => abi.list_macros(),
         }
     }
 }