aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_proc_macro_srv/src/tests/utils.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-11 12:49:07 +0100
committerGitHub <[email protected]>2020-04-11 12:49:07 +0100
commit0ecdba20df41a800222d0fd864843843feb6e875 (patch)
treef8c96eaece90cd0630075e2693f833e4385404f7 /crates/ra_proc_macro_srv/src/tests/utils.rs
parent54bdb9c78b012c560efc142971dc3e724989e807 (diff)
parent31d163aa3be9c938ffe713534e4f648550a35f6c (diff)
Merge #3920
3920: Implement expand_task and list_macros in proc_macro_srv r=matklad a=edwin0cheng This PR finish up the remain `proc_macro_srv` implementation : 1. Added dylib loading code for proc-macro crate dylib. Note that we have to add some special flags for unix loading because of a bug in old version of glibc, see https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1 and https://github.com/rust-lang/rust/issues/60593 for details. 2. Added tests for proc-macro expansion: We use a trick here by adding `serde_derive` to dev-dependencies and calling `cargo-metadata` for searching its dylib path, and expand it in our tests. [EDIT] Note that this PR **DO NOT** implement the final glue code with rust-analzyer and proc-macro-srv yet. Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_proc_macro_srv/src/tests/utils.rs')
-rw-r--r--crates/ra_proc_macro_srv/src/tests/utils.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/crates/ra_proc_macro_srv/src/tests/utils.rs b/crates/ra_proc_macro_srv/src/tests/utils.rs
new file mode 100644
index 000000000..1ee409449
--- /dev/null
+++ b/crates/ra_proc_macro_srv/src/tests/utils.rs
@@ -0,0 +1,65 @@
1//! utils used in proc-macro tests
2
3use crate::dylib;
4use crate::list_macros;
5pub use difference::Changeset as __Changeset;
6use ra_proc_macro::ListMacrosTask;
7use std::str::FromStr;
8use test_utils::assert_eq_text;
9
10mod fixtures {
11 use cargo_metadata::{parse_messages, Message};
12 use std::process::Command;
13
14 // Use current project metadata to get the proc-macro dylib path
15 pub fn dylib_path(crate_name: &str, version: &str) -> std::path::PathBuf {
16 let command = Command::new("cargo")
17 .args(&["check", "--message-format", "json"])
18 .output()
19 .unwrap()
20 .stdout;
21
22 for message in parse_messages(command.as_slice()) {
23 match message.unwrap() {
24 Message::CompilerArtifact(artifact) => {
25 if artifact.target.kind.contains(&"proc-macro".to_string()) {
26 let repr = format!("{} {}", crate_name, version);
27 if artifact.package_id.repr.starts_with(&repr) {
28 return artifact.filenames[0].clone();
29 }
30 }
31 }
32 _ => (), // Unknown message
33 }
34 }
35
36 panic!("No proc-macro dylib for {} found!", crate_name);
37 }
38}
39
40fn parse_string(code: &str) -> Option<crate::rustc_server::TokenStream> {
41 Some(crate::rustc_server::TokenStream::from_str(code).unwrap())
42}
43
44pub fn assert_expand(
45 crate_name: &str,
46 macro_name: &str,
47 version: &str,
48 fixture: &str,
49 expect: &str,
50) {
51 let path = fixtures::dylib_path(crate_name, version);
52 let expander = dylib::Expander::new(&path).unwrap();
53 let fixture = parse_string(fixture).unwrap();
54
55 let res = expander.expand(macro_name, &fixture.subtree, None).unwrap();
56 assert_eq_text!(&format!("{:?}", res), &expect.trim());
57}
58
59pub fn list(crate_name: &str, version: &str) -> Vec<String> {
60 let path = fixtures::dylib_path(crate_name, version);
61 let task = ListMacrosTask { lib: path };
62
63 let res = list_macros(&task).unwrap();
64 res.macros.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect()
65}