mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 04:23:25 +00:00
Build test-macros in a build script
This commit is contained in:
parent
5f592f4f58
commit
05b3a4bc93
9 changed files with 133 additions and 75 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -1158,6 +1158,15 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc_macro_test"
|
name = "proc_macro_test"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"cargo_metadata",
|
||||||
|
"proc_macro_test_impl",
|
||||||
|
"toolchain",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc_macro_test_impl"
|
||||||
|
version = "0.0.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "profile"
|
name = "profile"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = ["xtask/", "lib/*", "crates/*"]
|
members = ["xtask/", "lib/*", "crates/*"]
|
||||||
|
exclude = ["crates/proc_macro_test/imp"]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
# Disabling debug info speeds up builds a bunch,
|
# Disabling debug info speeds up builds a bunch,
|
||||||
|
|
|
@ -7,35 +7,8 @@ use proc_macro_api::ListMacrosTask;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub mod fixtures {
|
pub mod fixtures {
|
||||||
use cargo_metadata::Message;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
// Use current project metadata to get the proc-macro dylib path
|
|
||||||
pub fn proc_macro_test_dylib_path() -> std::path::PathBuf {
|
pub fn proc_macro_test_dylib_path() -> std::path::PathBuf {
|
||||||
let name = "proc_macro_test";
|
proc_macro_test::PROC_MACRO_TEST_LOCATION.into()
|
||||||
let version = "0.0.0";
|
|
||||||
let command = Command::new(toolchain::cargo())
|
|
||||||
.args(&["check", "--tests", "--message-format", "json"])
|
|
||||||
.output()
|
|
||||||
.unwrap()
|
|
||||||
.stdout;
|
|
||||||
|
|
||||||
for message in Message::parse_stream(command.as_slice()) {
|
|
||||||
match message.unwrap() {
|
|
||||||
Message::CompilerArtifact(artifact) => {
|
|
||||||
if artifact.target.kind.contains(&"proc-macro".to_string()) {
|
|
||||||
let repr = format!("{} {}", name, version);
|
|
||||||
if artifact.package_id.repr.starts_with(&repr) {
|
|
||||||
return PathBuf::from(&artifact.filenames[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (), // Unknown message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panic!("No proc-macro dylib for {} found!", name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,4 +8,8 @@ publish = false
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
doctest = false
|
doctest = false
|
||||||
proc-macro = true
|
|
||||||
|
[build-dependencies]
|
||||||
|
proc_macro_test_impl = { path = "imp", version = "0.0.0" }
|
||||||
|
toolchain = { path = "../toolchain", version = "0.0.0" }
|
||||||
|
cargo_metadata = "0.13"
|
||||||
|
|
48
crates/proc_macro_test/build.rs
Normal file
48
crates/proc_macro_test/build.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
//! This will build the proc macro in `imp`, and copy the resulting dylib artifact into the
|
||||||
|
//! `OUT_DIR`.
|
||||||
|
//!
|
||||||
|
//! `proc_macro_test` itself contains only a path to that artifact.
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
env, fs,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
process::Command,
|
||||||
|
};
|
||||||
|
|
||||||
|
use cargo_metadata::Message;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
let out_dir = Path::new(&out_dir);
|
||||||
|
|
||||||
|
let name = "proc_macro_test_impl";
|
||||||
|
let version = "0.0.0";
|
||||||
|
let output = Command::new(toolchain::cargo())
|
||||||
|
.current_dir("imp")
|
||||||
|
.args(&["build", "-p", "proc_macro_test_impl", "--message-format", "json"])
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
assert!(output.status.success());
|
||||||
|
|
||||||
|
let mut artifact_path = None;
|
||||||
|
for message in Message::parse_stream(output.stdout.as_slice()) {
|
||||||
|
match message.unwrap() {
|
||||||
|
Message::CompilerArtifact(artifact) => {
|
||||||
|
if artifact.target.kind.contains(&"proc-macro".to_string()) {
|
||||||
|
let repr = format!("{} {}", name, version);
|
||||||
|
if artifact.package_id.repr.starts_with(&repr) {
|
||||||
|
artifact_path = Some(PathBuf::from(&artifact.filenames[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (), // Unknown message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let src_path = artifact_path.expect("no dylib for proc_macro_test_impl found");
|
||||||
|
let dest_path = out_dir.join(src_path.file_name().unwrap());
|
||||||
|
fs::copy(src_path, &dest_path).unwrap();
|
||||||
|
|
||||||
|
let info_path = out_dir.join("proc_macro_test_location.txt");
|
||||||
|
fs::write(info_path, dest_path.to_str().unwrap()).unwrap();
|
||||||
|
}
|
2
crates/proc_macro_test/imp/.gitignore
vendored
Normal file
2
crates/proc_macro_test/imp/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
target/
|
||||||
|
Cargo.lock
|
17
crates/proc_macro_test/imp/Cargo.toml
Normal file
17
crates/proc_macro_test/imp/Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
name = "proc_macro_test_impl"
|
||||||
|
version = "0.0.0"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
authors = ["rust-analyzer developers"]
|
||||||
|
edition = "2018"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
doctest = false
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# this crate should not have any dependencies, since it uses its own workspace,
|
||||||
|
# and its own `Cargo.lock`
|
48
crates/proc_macro_test/imp/src/lib.rs
Normal file
48
crates/proc_macro_test/imp/src/lib.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
//! Exports a few trivial procedural macros for testing.
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn fn_like_noop(args: TokenStream) -> TokenStream {
|
||||||
|
args
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn fn_like_panic(args: TokenStream) -> TokenStream {
|
||||||
|
panic!("fn_like_panic!({})", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn fn_like_error(args: TokenStream) -> TokenStream {
|
||||||
|
format!("compile_error!(\"fn_like_error!({})\");", args).parse().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
|
item
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn attr_panic(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
|
panic!("#[attr_panic {}] {}", args, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn attr_error(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
|
format!("compile_error!(\"#[attr_error({})] {}\");", args, item).parse().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(DeriveEmpty)]
|
||||||
|
pub fn derive_empty(_item: TokenStream) -> TokenStream {
|
||||||
|
TokenStream::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(DerivePanic)]
|
||||||
|
pub fn derive_panic(item: TokenStream) -> TokenStream {
|
||||||
|
panic!("#[derive(DerivePanic)] {}", item);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(DeriveError)]
|
||||||
|
pub fn derive_error(item: TokenStream) -> TokenStream {
|
||||||
|
format!("compile_error!(\"#[derive(DeriveError)] {}\");", item).parse().unwrap()
|
||||||
|
}
|
|
@ -1,48 +1,4 @@
|
||||||
//! Exports a few trivial procedural macros for testing.
|
//! Exports a few trivial procedural macros for testing.
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
pub static PROC_MACRO_TEST_LOCATION: &str =
|
||||||
|
include_str!(concat!(env!("OUT_DIR"), "/proc_macro_test_location.txt"));
|
||||||
#[proc_macro]
|
|
||||||
pub fn fn_like_noop(args: TokenStream) -> TokenStream {
|
|
||||||
args
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn fn_like_panic(args: TokenStream) -> TokenStream {
|
|
||||||
panic!("fn_like_panic!({})", args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn fn_like_error(args: TokenStream) -> TokenStream {
|
|
||||||
format!("compile_error!(\"fn_like_error!({})\");", args).parse().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
|
||||||
pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream {
|
|
||||||
item
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
|
||||||
pub fn attr_panic(args: TokenStream, item: TokenStream) -> TokenStream {
|
|
||||||
panic!("#[attr_panic {}] {}", args, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
|
||||||
pub fn attr_error(args: TokenStream, item: TokenStream) -> TokenStream {
|
|
||||||
format!("compile_error!(\"#[attr_error({})] {}\");", args, item).parse().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro_derive(DeriveEmpty)]
|
|
||||||
pub fn derive_empty(_item: TokenStream) -> TokenStream {
|
|
||||||
TokenStream::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro_derive(DerivePanic)]
|
|
||||||
pub fn derive_panic(item: TokenStream) -> TokenStream {
|
|
||||||
panic!("#[derive(DerivePanic)] {}", item);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro_derive(DeriveError)]
|
|
||||||
pub fn derive_error(item: TokenStream) -> TokenStream {
|
|
||||||
format!("compile_error!(\"#[derive(DeriveError)] {}\");", item).parse().unwrap()
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue