Skip to content

Commit ca7dc69

Browse files
committed
Add tests for proc_macro
1 parent a4b0ce0 commit ca7dc69

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

.github/workflows/ci.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ jobs:
8585
- name: Compile
8686
run: cargo test --no-run
8787

88+
# We have to build ra_proc_macro_srv first for running related heavy tests
89+
- name: Build ra_proc_macro_srv
90+
run: cargo build -p ra_proc_macro_srv
91+
8892
- name: Test
8993
run: cargo test
9094

crates/rust-analyzer/tests/heavy_tests/main.rs

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use lsp_types::{
99
};
1010
use rust_analyzer::req::{
1111
CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument,
12-
Formatting, GotoDefinition, OnEnter, Runnables, RunnablesParams,
12+
Formatting, GotoDefinition, HoverRequest, OnEnter, Runnables, RunnablesParams,
1313
};
1414
use serde_json::json;
1515
use tempfile::TempDir;
@@ -625,3 +625,90 @@ fn main() { message(); }
625625
));
626626
assert!(format!("{}", res).contains("hello.rs"));
627627
}
628+
629+
#[test]
630+
fn resolve_proc_macro() {
631+
if skip_slow_tests() {
632+
return;
633+
}
634+
let server = Project::with_fixture(
635+
r###"
636+
//- foo/Cargo.toml
637+
[package]
638+
name = "foo"
639+
version = "0.0.0"
640+
edition = "2018"
641+
[dependencies]
642+
bar = {path = "../bar"}
643+
644+
//- foo/src/main.rs
645+
use bar::Bar;
646+
trait Bar {
647+
fn bar();
648+
}
649+
#[derive(Bar)]
650+
struct Foo {}
651+
fn main() {
652+
Foo::bar();
653+
}
654+
655+
//- bar/Cargo.toml
656+
[package]
657+
name = "bar"
658+
version = "0.0.0"
659+
edition = "2018"
660+
661+
[lib]
662+
proc-macro = true
663+
664+
//- bar/src/lib.rs
665+
extern crate proc_macro;
666+
use proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
667+
macro_rules! t {
668+
($n:literal) => {
669+
TokenTree::from(Ident::new($n, Span::call_site()))
670+
};
671+
({}) => {
672+
TokenTree::from(Group::new(Delimiter::Brace, TokenStream::new()))
673+
};
674+
(()) => {
675+
TokenTree::from(Group::new(Delimiter::Parenthesis, TokenStream::new()))
676+
};
677+
}
678+
#[proc_macro_derive(Bar)]
679+
pub fn foo(_input: TokenStream) -> TokenStream {
680+
// We hard code the output here for preventing to use any deps
681+
let mut res = TokenStream::new();
682+
683+
// impl Bar for Foo { fn bar() {} }
684+
let mut tokens = vec![t!("impl"), t!("Bar"), t!("for"), t!("Foo")];
685+
let mut fn_stream = TokenStream::new();
686+
fn_stream.extend(vec![t!("fn"), t!("bar"), t!(()), t!({})]);
687+
tokens.push(Group::new(Delimiter::Brace, fn_stream).into());
688+
res.extend(tokens);
689+
res
690+
}
691+
692+
"###,
693+
)
694+
.with_config(|config| {
695+
let macro_srv_path = std::path::Path::new(std::env!("CARGO_MANIFEST_DIR"))
696+
.join("../../target/debug/ra_proc_macro_srv")
697+
.to_string_lossy()
698+
.to_string();
699+
700+
config.cargo.load_out_dirs_from_check = true;
701+
config.proc_macro_srv = Some(macro_srv_path)
702+
})
703+
.root("foo")
704+
.root("bar")
705+
.server();
706+
server.wait_until_workspace_is_loaded();
707+
let res = server.send_request::<HoverRequest>(TextDocumentPositionParams::new(
708+
server.doc_id("foo/src/main.rs"),
709+
Position::new(7, 9),
710+
));
711+
712+
let value = res.get("contents").unwrap().get("value").unwrap().to_string();
713+
assert_eq!(value, r#""```rust\nfoo::Bar\nfn bar()\n```""#)
714+
}

0 commit comments

Comments
 (0)