diff options
-rw-r--r-- | .github/workflows/ci.yaml | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/tests/heavy_tests/main.rs | 89 |
2 files changed, 92 insertions, 1 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 00f299ff1..13a11c95b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml | |||
@@ -85,6 +85,10 @@ jobs: | |||
85 | - name: Compile | 85 | - name: Compile |
86 | run: cargo test --no-run | 86 | run: cargo test --no-run |
87 | 87 | ||
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 | |||
88 | - name: Test | 92 | - name: Test |
89 | run: cargo test | 93 | run: cargo test |
90 | 94 | ||
diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs index 638813311..26ab81a8f 100644 --- a/crates/rust-analyzer/tests/heavy_tests/main.rs +++ b/crates/rust-analyzer/tests/heavy_tests/main.rs | |||
@@ -9,7 +9,7 @@ use lsp_types::{ | |||
9 | }; | 9 | }; |
10 | use rust_analyzer::req::{ | 10 | use rust_analyzer::req::{ |
11 | CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument, | 11 | CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument, |
12 | Formatting, GotoDefinition, OnEnter, Runnables, RunnablesParams, | 12 | Formatting, GotoDefinition, HoverRequest, OnEnter, Runnables, RunnablesParams, |
13 | }; | 13 | }; |
14 | use serde_json::json; | 14 | use serde_json::json; |
15 | use tempfile::TempDir; | 15 | use tempfile::TempDir; |
@@ -625,3 +625,90 @@ fn main() { message(); } | |||
625 | )); | 625 | )); |
626 | assert!(format!("{}", res).contains("hello.rs")); | 626 | assert!(format!("{}", res).contains("hello.rs")); |
627 | } | 627 | } |
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 | } | ||