diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-04-11 12:49:07 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-04-11 12:49:07 +0100 |
commit | 0ecdba20df41a800222d0fd864843843feb6e875 (patch) | |
tree | f8c96eaece90cd0630075e2693f833e4385404f7 /crates/ra_proc_macro_srv/src/tests | |
parent | 54bdb9c78b012c560efc142971dc3e724989e807 (diff) | |
parent | 31d163aa3be9c938ffe713534e4f648550a35f6c (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')
-rw-r--r-- | crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt | 188 | ||||
-rw-r--r-- | crates/ra_proc_macro_srv/src/tests/mod.rs | 47 | ||||
-rw-r--r-- | crates/ra_proc_macro_srv/src/tests/utils.rs | 65 |
3 files changed, 300 insertions, 0 deletions
diff --git a/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt b/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt new file mode 100644 index 000000000..24507d98d --- /dev/null +++ b/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt | |||
@@ -0,0 +1,188 @@ | |||
1 | SUBTREE $ | ||
2 | PUNCH # [alone] 4294967295 | ||
3 | SUBTREE [] 4294967295 | ||
4 | IDENT allow 4294967295 | ||
5 | SUBTREE () 4294967295 | ||
6 | IDENT non_upper_case_globals 4294967295 | ||
7 | PUNCH , [alone] 4294967295 | ||
8 | IDENT unused_attributes 4294967295 | ||
9 | PUNCH , [alone] 4294967295 | ||
10 | IDENT unused_qualifications 4294967295 | ||
11 | IDENT const 4294967295 | ||
12 | IDENT _IMPL_SERIALIZE_FOR_Foo 4294967295 | ||
13 | PUNCH : [alone] 4294967295 | ||
14 | SUBTREE () 4294967295 | ||
15 | PUNCH = [alone] 4294967295 | ||
16 | SUBTREE {} 4294967295 | ||
17 | PUNCH # [alone] 4294967295 | ||
18 | SUBTREE [] 4294967295 | ||
19 | IDENT allow 4294967295 | ||
20 | SUBTREE () 4294967295 | ||
21 | IDENT unknown_lints 4294967295 | ||
22 | PUNCH # [alone] 4294967295 | ||
23 | SUBTREE [] 4294967295 | ||
24 | IDENT cfg_attr 4294967295 | ||
25 | SUBTREE () 4294967295 | ||
26 | IDENT feature 4294967295 | ||
27 | PUNCH = [alone] 4294967295 | ||
28 | SUBTREE $ | ||
29 | LITERAL "cargo-clippy" 0 | ||
30 | PUNCH , [alone] 4294967295 | ||
31 | IDENT allow 4294967295 | ||
32 | SUBTREE () 4294967295 | ||
33 | IDENT useless_attribute 4294967295 | ||
34 | PUNCH # [alone] 4294967295 | ||
35 | SUBTREE [] 4294967295 | ||
36 | IDENT allow 4294967295 | ||
37 | SUBTREE () 4294967295 | ||
38 | IDENT rust_2018_idioms 4294967295 | ||
39 | IDENT extern 4294967295 | ||
40 | IDENT crate 4294967295 | ||
41 | IDENT serde 4294967295 | ||
42 | IDENT as 4294967295 | ||
43 | IDENT _serde 4294967295 | ||
44 | PUNCH ; [alone] 4294967295 | ||
45 | PUNCH # [alone] 4294967295 | ||
46 | SUBTREE [] 4294967295 | ||
47 | IDENT allow 4294967295 | ||
48 | SUBTREE () 4294967295 | ||
49 | IDENT unused_macros 4294967295 | ||
50 | IDENT macro_rules 4294967295 | ||
51 | PUNCH ! [alone] 4294967295 | ||
52 | IDENT try 4294967295 | ||
53 | SUBTREE {} 4294967295 | ||
54 | SUBTREE () 4294967295 | ||
55 | PUNCH $ [alone] 4294967295 | ||
56 | IDENT __expr 4294967295 | ||
57 | PUNCH : [alone] 4294967295 | ||
58 | IDENT expr 4294967295 | ||
59 | PUNCH = [joint] 4294967295 | ||
60 | PUNCH > [alone] 4294967295 | ||
61 | SUBTREE {} 4294967295 | ||
62 | IDENT match 4294967295 | ||
63 | PUNCH $ [alone] 4294967295 | ||
64 | IDENT __expr 4294967295 | ||
65 | SUBTREE {} 4294967295 | ||
66 | IDENT _serde 4294967295 | ||
67 | PUNCH : [joint] 4294967295 | ||
68 | PUNCH : [alone] 4294967295 | ||
69 | IDENT export 4294967295 | ||
70 | PUNCH : [joint] 4294967295 | ||
71 | PUNCH : [alone] 4294967295 | ||
72 | IDENT Ok 4294967295 | ||
73 | SUBTREE () 4294967295 | ||
74 | IDENT __val 4294967295 | ||
75 | PUNCH = [joint] 4294967295 | ||
76 | PUNCH > [alone] 4294967295 | ||
77 | IDENT __val 4294967295 | ||
78 | PUNCH , [alone] 4294967295 | ||
79 | IDENT _serde 4294967295 | ||
80 | PUNCH : [joint] 4294967295 | ||
81 | PUNCH : [alone] 4294967295 | ||
82 | IDENT export 4294967295 | ||
83 | PUNCH : [joint] 4294967295 | ||
84 | PUNCH : [alone] 4294967295 | ||
85 | IDENT Err 4294967295 | ||
86 | SUBTREE () 4294967295 | ||
87 | IDENT __err 4294967295 | ||
88 | PUNCH = [joint] 4294967295 | ||
89 | PUNCH > [alone] 4294967295 | ||
90 | SUBTREE {} 4294967295 | ||
91 | IDENT return 4294967295 | ||
92 | IDENT _serde 4294967295 | ||
93 | PUNCH : [joint] 4294967295 | ||
94 | PUNCH : [alone] 4294967295 | ||
95 | IDENT export 4294967295 | ||
96 | PUNCH : [joint] 4294967295 | ||
97 | PUNCH : [alone] 4294967295 | ||
98 | IDENT Err 4294967295 | ||
99 | SUBTREE () 4294967295 | ||
100 | IDENT __err 4294967295 | ||
101 | PUNCH ; [alone] 4294967295 | ||
102 | PUNCH # [alone] 4294967295 | ||
103 | SUBTREE [] 4294967295 | ||
104 | IDENT automatically_derived 4294967295 | ||
105 | IDENT impl 4294967295 | ||
106 | IDENT _serde 4294967295 | ||
107 | PUNCH : [joint] 4294967295 | ||
108 | PUNCH : [alone] 4294967295 | ||
109 | IDENT Serialize 4294967295 | ||
110 | IDENT for 4294967295 | ||
111 | IDENT Foo 1 | ||
112 | SUBTREE {} 4294967295 | ||
113 | IDENT fn 4294967295 | ||
114 | IDENT serialize 4294967295 | ||
115 | PUNCH < [alone] 4294967295 | ||
116 | IDENT __S 4294967295 | ||
117 | PUNCH > [alone] 4294967295 | ||
118 | SUBTREE () 4294967295 | ||
119 | PUNCH & [alone] 4294967295 | ||
120 | IDENT self 4294967295 | ||
121 | PUNCH , [alone] 4294967295 | ||
122 | IDENT __serializer 4294967295 | ||
123 | PUNCH : [alone] 4294967295 | ||
124 | IDENT __S 4294967295 | ||
125 | PUNCH - [joint] 4294967295 | ||
126 | PUNCH > [alone] 4294967295 | ||
127 | IDENT _serde 4294967295 | ||
128 | PUNCH : [joint] 4294967295 | ||
129 | PUNCH : [alone] 4294967295 | ||
130 | IDENT export 4294967295 | ||
131 | PUNCH : [joint] 4294967295 | ||
132 | PUNCH : [alone] 4294967295 | ||
133 | IDENT Result 4294967295 | ||
134 | PUNCH < [alone] 4294967295 | ||
135 | IDENT __S 4294967295 | ||
136 | PUNCH : [joint] 4294967295 | ||
137 | PUNCH : [alone] 4294967295 | ||
138 | IDENT Ok 4294967295 | ||
139 | PUNCH , [alone] 4294967295 | ||
140 | IDENT __S 4294967295 | ||
141 | PUNCH : [joint] 4294967295 | ||
142 | PUNCH : [alone] 4294967295 | ||
143 | IDENT Error 4294967295 | ||
144 | PUNCH > [alone] 4294967295 | ||
145 | IDENT where 4294967295 | ||
146 | IDENT __S 4294967295 | ||
147 | PUNCH : [alone] 4294967295 | ||
148 | IDENT _serde 4294967295 | ||
149 | PUNCH : [joint] 4294967295 | ||
150 | PUNCH : [alone] 4294967295 | ||
151 | IDENT Serializer 4294967295 | ||
152 | PUNCH , [alone] 4294967295 | ||
153 | SUBTREE {} 4294967295 | ||
154 | IDENT let 4294967295 | ||
155 | IDENT __serde_state 4294967295 | ||
156 | PUNCH = [alone] 4294967295 | ||
157 | IDENT try 4294967295 | ||
158 | PUNCH ! [alone] 4294967295 | ||
159 | SUBTREE () 4294967295 | ||
160 | IDENT _serde 4294967295 | ||
161 | PUNCH : [joint] 4294967295 | ||
162 | PUNCH : [alone] 4294967295 | ||
163 | IDENT Serializer 4294967295 | ||
164 | PUNCH : [joint] 4294967295 | ||
165 | PUNCH : [alone] 4294967295 | ||
166 | IDENT serialize_struct 4294967295 | ||
167 | SUBTREE () 4294967295 | ||
168 | IDENT __serializer 4294967295 | ||
169 | PUNCH , [alone] 4294967295 | ||
170 | LITERAL "Foo" 4294967295 | ||
171 | PUNCH , [alone] 4294967295 | ||
172 | IDENT false 4294967295 | ||
173 | IDENT as 4294967295 | ||
174 | IDENT usize 4294967295 | ||
175 | PUNCH ; [alone] 4294967295 | ||
176 | IDENT _serde 4294967295 | ||
177 | PUNCH : [joint] 4294967295 | ||
178 | PUNCH : [alone] 4294967295 | ||
179 | IDENT ser 4294967295 | ||
180 | PUNCH : [joint] 4294967295 | ||
181 | PUNCH : [alone] 4294967295 | ||
182 | IDENT SerializeStruct 4294967295 | ||
183 | PUNCH : [joint] 4294967295 | ||
184 | PUNCH : [alone] 4294967295 | ||
185 | IDENT end 4294967295 | ||
186 | SUBTREE () 4294967295 | ||
187 | IDENT __serde_state 4294967295 | ||
188 | PUNCH ; [alone] 4294967295 \ No newline at end of file | ||
diff --git a/crates/ra_proc_macro_srv/src/tests/mod.rs b/crates/ra_proc_macro_srv/src/tests/mod.rs new file mode 100644 index 000000000..03f79bc5d --- /dev/null +++ b/crates/ra_proc_macro_srv/src/tests/mod.rs | |||
@@ -0,0 +1,47 @@ | |||
1 | //! proc-macro tests | ||
2 | |||
3 | #[macro_use] | ||
4 | mod utils; | ||
5 | use test_utils::assert_eq_text; | ||
6 | use utils::*; | ||
7 | |||
8 | #[test] | ||
9 | fn test_derive_serialize_proc_macro() { | ||
10 | assert_expand( | ||
11 | "serde_derive", | ||
12 | "Serialize", | ||
13 | "1.0.104", | ||
14 | r##"struct Foo {}"##, | ||
15 | include_str!("fixtures/test_serialize_proc_macro.txt"), | ||
16 | ); | ||
17 | } | ||
18 | |||
19 | #[test] | ||
20 | fn test_derive_serialize_proc_macro_failed() { | ||
21 | assert_expand( | ||
22 | "serde_derive", | ||
23 | "Serialize", | ||
24 | "1.0.104", | ||
25 | r##" | ||
26 | struct {} | ||
27 | "##, | ||
28 | r##" | ||
29 | SUBTREE $ | ||
30 | IDENT compile_error 4294967295 | ||
31 | PUNCH ! [alone] 4294967295 | ||
32 | SUBTREE {} 4294967295 | ||
33 | LITERAL "expected identifier" 4294967295 | ||
34 | "##, | ||
35 | ); | ||
36 | } | ||
37 | |||
38 | #[test] | ||
39 | fn test_derive_proc_macro_list() { | ||
40 | let res = list("serde_derive", "1.0.104").join("\n"); | ||
41 | |||
42 | assert_eq_text!( | ||
43 | &res, | ||
44 | r#"Serialize [CustomDerive] | ||
45 | Deserialize [CustomDerive]"# | ||
46 | ); | ||
47 | } | ||
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 | |||
3 | use crate::dylib; | ||
4 | use crate::list_macros; | ||
5 | pub use difference::Changeset as __Changeset; | ||
6 | use ra_proc_macro::ListMacrosTask; | ||
7 | use std::str::FromStr; | ||
8 | use test_utils::assert_eq_text; | ||
9 | |||
10 | mod 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 | |||
40 | fn parse_string(code: &str) -> Option<crate::rustc_server::TokenStream> { | ||
41 | Some(crate::rustc_server::TokenStream::from_str(code).unwrap()) | ||
42 | } | ||
43 | |||
44 | pub 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 | |||
59 | pub 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 | } | ||