@@ -9,7 +9,7 @@ use lsp_types::{
99} ;
1010use rust_analyzer:: req:: {
1111 CodeActionParams , CodeActionRequest , Completion , CompletionParams , DidOpenTextDocument ,
12- Formatting , GotoDefinition , OnEnter , Runnables , RunnablesParams ,
12+ Formatting , GotoDefinition , HoverRequest , OnEnter , Runnables , RunnablesParams ,
1313} ;
1414use serde_json:: json;
1515use 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