aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/cfg/Cargo.toml (renamed from crates/ra_cfg/Cargo.toml)12
-rw-r--r--crates/cfg/src/cfg_expr.rs (renamed from crates/ra_cfg/src/cfg_expr.rs)16
-rw-r--r--crates/cfg/src/lib.rs (renamed from crates/ra_cfg/src/lib.rs)4
-rw-r--r--crates/mbe/Cargo.toml (renamed from crates/ra_mbe/Cargo.toml)15
-rw-r--r--crates/mbe/src/lib.rs (renamed from crates/ra_mbe/src/lib.rs)0
-rw-r--r--crates/mbe/src/mbe_expander.rs (renamed from crates/ra_mbe/src/mbe_expander.rs)0
-rw-r--r--crates/mbe/src/mbe_expander/matcher.rs (renamed from crates/ra_mbe/src/mbe_expander/matcher.rs)0
-rw-r--r--crates/mbe/src/mbe_expander/transcriber.rs (renamed from crates/ra_mbe/src/mbe_expander/transcriber.rs)0
-rw-r--r--crates/mbe/src/parser.rs (renamed from crates/ra_mbe/src/parser.rs)0
-rw-r--r--crates/mbe/src/subtree_source.rs (renamed from crates/ra_mbe/src/subtree_source.rs)0
-rw-r--r--crates/mbe/src/syntax_bridge.rs (renamed from crates/ra_mbe/src/syntax_bridge.rs)0
-rw-r--r--crates/mbe/src/tests.rs (renamed from crates/ra_mbe/src/tests.rs)0
-rw-r--r--crates/mbe/src/tt_iter.rs (renamed from crates/ra_mbe/src/tt_iter.rs)0
-rw-r--r--crates/proc_macro_srv/Cargo.toml (renamed from crates/ra_proc_macro_srv/Cargo.toml)17
-rw-r--r--crates/proc_macro_srv/src/cli.rs (renamed from crates/ra_proc_macro_srv/src/cli.rs)0
-rw-r--r--crates/proc_macro_srv/src/dylib.rs (renamed from crates/ra_proc_macro_srv/src/dylib.rs)0
-rw-r--r--crates/proc_macro_srv/src/lib.rs (renamed from crates/ra_proc_macro_srv/src/lib.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/bridge/buffer.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/bridge/buffer.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/bridge/client.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/bridge/client.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/bridge/closure.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/bridge/closure.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/bridge/handle.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/bridge/handle.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/bridge/mod.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/bridge/mod.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/bridge/rpc.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/bridge/rpc.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/bridge/scoped_cell.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/bridge/scoped_cell.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/bridge/server.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/bridge/server.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/diagnostic.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/diagnostic.rs)0
-rw-r--r--crates/proc_macro_srv/src/proc_macro/mod.rs (renamed from crates/ra_proc_macro_srv/src/proc_macro/mod.rs)0
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs (renamed from crates/ra_proc_macro_srv/src/rustc_server.rs)2
-rw-r--r--crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt (renamed from crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt)0
-rw-r--r--crates/proc_macro_srv/src/tests/mod.rs (renamed from crates/ra_proc_macro_srv/src/tests/mod.rs)0
-rw-r--r--crates/proc_macro_srv/src/tests/utils.rs (renamed from crates/ra_proc_macro_srv/src/tests/utils.rs)0
-rw-r--r--crates/project_model/Cargo.toml (renamed from crates/ra_project_model/Cargo.toml)19
-rw-r--r--crates/project_model/src/cargo_workspace.rs (renamed from crates/ra_project_model/src/cargo_workspace.rs)0
-rw-r--r--crates/project_model/src/cfg_flag.rs (renamed from crates/ra_project_model/src/cfg_flag.rs)2
-rw-r--r--crates/project_model/src/lib.rs (renamed from crates/ra_project_model/src/lib.rs)2
-rw-r--r--crates/project_model/src/project_json.rs (renamed from crates/ra_project_model/src/project_json.rs)0
-rw-r--r--crates/project_model/src/sysroot.rs (renamed from crates/ra_project_model/src/sysroot.rs)0
-rw-r--r--crates/ra_assists/Cargo.toml1
-rw-r--r--crates/ra_assists/src/assist_context.rs17
-rw-r--r--crates/ra_assists/src/handlers/change_return_type_to_result.rs73
-rw-r--r--crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs16
-rw-r--r--crates/ra_assists/src/handlers/move_guard.rs222
-rw-r--r--crates/ra_assists/src/handlers/replace_if_let_with_match.rs6
-rw-r--r--crates/ra_assists/src/handlers/unwrap_block.rs3
-rw-r--r--crates/ra_assists/src/tests/generated.rs4
-rw-r--r--crates/ra_assists/src/utils.rs38
-rw-r--r--crates/ra_assists/src/utils/insert_use.rs27
-rw-r--r--crates/ra_db/Cargo.toml2
-rw-r--r--crates/ra_db/src/fixture.rs2
-rw-r--r--crates/ra_db/src/input.rs2
-rw-r--r--crates/ra_fmt/Cargo.toml15
-rw-r--r--crates/ra_fmt/src/lib.rs96
-rw-r--r--crates/ra_hir_def/Cargo.toml4
-rw-r--r--crates/ra_hir_def/src/adt.rs2
-rw-r--r--crates/ra_hir_def/src/attr.rs2
-rw-r--r--crates/ra_hir_def/src/body.rs2
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs2
-rw-r--r--crates/ra_hir_expand/Cargo.toml2
-rw-r--r--crates/ra_ide/Cargo.toml3
-rw-r--r--crates/ra_ide/src/join_lines.rs27
-rw-r--r--crates/ra_ide/src/lib.rs2
-rw-r--r--crates/ra_ide/src/mock_analysis.rs2
-rw-r--r--crates/ra_ide/src/parent_module.rs2
-rw-r--r--crates/ra_ide/src/runnables.rs2
-rw-r--r--crates/ra_ide/src/typing.rs5
-rw-r--r--crates/rust-analyzer/Cargo.toml8
-rw-r--r--crates/rust-analyzer/src/bin/main.rs4
-rw-r--r--crates/rust-analyzer/src/cargo_target_spec.rs6
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs2
-rw-r--r--crates/rust-analyzer/src/config.rs2
-rw-r--r--crates/rust-analyzer/src/global_state.rs2
-rw-r--r--crates/rust-analyzer/src/handlers.rs2
-rw-r--r--crates/rust-analyzer/src/main_loop.rs2
-rw-r--r--crates/rust-analyzer/src/reload.rs8
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/support.rs2
-rw-r--r--crates/syntax/src/ast/edit.rs3
-rw-r--r--crates/syntax/src/ast/make.rs7
77 files changed, 337 insertions, 381 deletions
diff --git a/crates/ra_cfg/Cargo.toml b/crates/cfg/Cargo.toml
index cb0d2b9d7..d2ea551d1 100644
--- a/crates/ra_cfg/Cargo.toml
+++ b/crates/cfg/Cargo.toml
@@ -1,9 +1,9 @@
1[package] 1[package]
2edition = "2018" 2name = "cfg"
3name = "ra_cfg" 3version = "0.0.0"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6license = "MIT OR Apache-2.0" 4license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"]
6edition = "2018"
7 7
8[lib] 8[lib]
9doctest = false 9doctest = false
@@ -11,8 +11,8 @@ doctest = false
11[dependencies] 11[dependencies]
12rustc-hash = "1.1.0" 12rustc-hash = "1.1.0"
13 13
14syntax = { path = "../syntax" }
15tt = { path = "../tt" } 14tt = { path = "../tt" }
16 15
17[dev-dependencies] 16[dev-dependencies]
18mbe = { path = "../ra_mbe", package = "ra_mbe" } 17mbe = { path = "../mbe" }
18syntax = { path = "../syntax" }
diff --git a/crates/ra_cfg/src/cfg_expr.rs b/crates/cfg/src/cfg_expr.rs
index 940091465..336fe25bc 100644
--- a/crates/ra_cfg/src/cfg_expr.rs
+++ b/crates/cfg/src/cfg_expr.rs
@@ -4,7 +4,7 @@
4 4
5use std::slice::Iter as SliceIter; 5use std::slice::Iter as SliceIter;
6 6
7use syntax::SmolStr; 7use tt::SmolStr;
8 8
9#[derive(Debug, Clone, PartialEq, Eq)] 9#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum CfgExpr { 10pub enum CfgExpr {
@@ -86,17 +86,15 @@ fn next_cfg_expr(it: &mut SliceIter<tt::TokenTree>) -> Option<CfgExpr> {
86mod tests { 86mod tests {
87 use super::*; 87 use super::*;
88 88
89 use mbe::{ast_to_token_tree, TokenMap}; 89 use mbe::ast_to_token_tree;
90 use syntax::ast::{self, AstNode}; 90 use syntax::ast::{self, AstNode};
91 91
92 fn get_token_tree_generated(input: &str) -> (tt::Subtree, TokenMap) {
93 let source_file = ast::SourceFile::parse(input).ok().unwrap();
94 let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
95 ast_to_token_tree(&tt).unwrap()
96 }
97
98 fn assert_parse_result(input: &str, expected: CfgExpr) { 92 fn assert_parse_result(input: &str, expected: CfgExpr) {
99 let (tt, _) = get_token_tree_generated(input); 93 let (tt, _) = {
94 let source_file = ast::SourceFile::parse(input).ok().unwrap();
95 let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
96 ast_to_token_tree(&tt).unwrap()
97 };
100 let cfg = CfgExpr::parse(&tt); 98 let cfg = CfgExpr::parse(&tt);
101 assert_eq!(cfg, expected); 99 assert_eq!(cfg, expected);
102 } 100 }
diff --git a/crates/ra_cfg/src/lib.rs b/crates/cfg/src/lib.rs
index 7e025143b..a9d50e698 100644
--- a/crates/ra_cfg/src/lib.rs
+++ b/crates/cfg/src/lib.rs
@@ -1,9 +1,9 @@
1//! ra_cfg defines conditional compiling options, `cfg` attibute parser and evaluator 1//! cfg defines conditional compiling options, `cfg` attibute parser and evaluator
2 2
3mod cfg_expr; 3mod cfg_expr;
4 4
5use rustc_hash::FxHashSet; 5use rustc_hash::FxHashSet;
6use syntax::SmolStr; 6use tt::SmolStr;
7 7
8pub use cfg_expr::CfgExpr; 8pub use cfg_expr::CfgExpr;
9 9
diff --git a/crates/ra_mbe/Cargo.toml b/crates/mbe/Cargo.toml
index 4a4be65eb..1aba8b7c4 100644
--- a/crates/ra_mbe/Cargo.toml
+++ b/crates/mbe/Cargo.toml
@@ -1,20 +1,21 @@
1[package] 1[package]
2edition = "2018" 2name = "mbe"
3name = "ra_mbe" 3version = "0.0.0"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6license = "MIT OR Apache-2.0" 4license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"]
6edition = "2018"
7 7
8[lib] 8[lib]
9doctest = false 9doctest = false
10 10
11[dependencies] 11[dependencies]
12syntax = { path = "../syntax" }
13parser = { path = "../parser" }
14tt = { path = "../tt" }
15rustc-hash = "1.1.0" 12rustc-hash = "1.1.0"
16smallvec = "1.2.0" 13smallvec = "1.2.0"
17log = "0.4.8" 14log = "0.4.8"
18 15
16syntax = { path = "../syntax" }
17parser = { path = "../parser" }
18tt = { path = "../tt" }
19
19[dev-dependencies] 20[dev-dependencies]
20test_utils = { path = "../test_utils" } 21test_utils = { path = "../test_utils" }
diff --git a/crates/ra_mbe/src/lib.rs b/crates/mbe/src/lib.rs
index f854ca09a..f854ca09a 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/mbe/src/lib.rs
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/mbe/src/mbe_expander.rs
index 1ad8b9f8a..1ad8b9f8a 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/mbe/src/mbe_expander.rs
diff --git a/crates/ra_mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs
index b698b9832..b698b9832 100644
--- a/crates/ra_mbe/src/mbe_expander/matcher.rs
+++ b/crates/mbe/src/mbe_expander/matcher.rs
diff --git a/crates/ra_mbe/src/mbe_expander/transcriber.rs b/crates/mbe/src/mbe_expander/transcriber.rs
index c9525c5bf..c9525c5bf 100644
--- a/crates/ra_mbe/src/mbe_expander/transcriber.rs
+++ b/crates/mbe/src/mbe_expander/transcriber.rs
diff --git a/crates/ra_mbe/src/parser.rs b/crates/mbe/src/parser.rs
index 6b46a1673..6b46a1673 100644
--- a/crates/ra_mbe/src/parser.rs
+++ b/crates/mbe/src/parser.rs
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/mbe/src/subtree_source.rs
index 41461b315..41461b315 100644
--- a/crates/ra_mbe/src/subtree_source.rs
+++ b/crates/mbe/src/subtree_source.rs
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index a8ad917fb..a8ad917fb 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
diff --git a/crates/ra_mbe/src/tests.rs b/crates/mbe/src/tests.rs
index 0796ceee1..0796ceee1 100644
--- a/crates/ra_mbe/src/tests.rs
+++ b/crates/mbe/src/tests.rs
diff --git a/crates/ra_mbe/src/tt_iter.rs b/crates/mbe/src/tt_iter.rs
index 46c420718..46c420718 100644
--- a/crates/ra_mbe/src/tt_iter.rs
+++ b/crates/mbe/src/tt_iter.rs
diff --git a/crates/ra_proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml
index 1c25e7229..0954ffb66 100644
--- a/crates/ra_proc_macro_srv/Cargo.toml
+++ b/crates/proc_macro_srv/Cargo.toml
@@ -1,21 +1,21 @@
1[package] 1[package]
2edition = "2018" 2name = "proc_macro_srv"
3name = "ra_proc_macro_srv" 3version = "0.0.0"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6publish = false
7license = "MIT OR Apache-2.0" 4license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"]
6edition = "2018"
8 7
9[lib] 8[lib]
10doctest = false 9doctest = false
11 10
12[dependencies] 11[dependencies]
13tt = { path = "../tt" }
14ra_mbe = { path = "../ra_mbe" }
15ra_proc_macro = { path = "../ra_proc_macro" }
16goblin = "0.2.1" 12goblin = "0.2.1"
17libloading = "0.6.0" 13libloading = "0.6.0"
18memmap = "0.7" 14memmap = "0.7"
15
16tt = { path = "../tt" }
17mbe = { path = "../mbe" }
18ra_proc_macro = { path = "../ra_proc_macro" }
19test_utils = { path = "../test_utils" } 19test_utils = { path = "../test_utils" }
20 20
21[dev-dependencies] 21[dev-dependencies]
@@ -23,4 +23,5 @@ cargo_metadata = "0.11.1"
23difference = "2.0.0" 23difference = "2.0.0"
24# used as proc macro test target 24# used as proc macro test target
25serde_derive = "1.0.106" 25serde_derive = "1.0.106"
26
26toolchain = { path = "../toolchain" } 27toolchain = { path = "../toolchain" }
diff --git a/crates/ra_proc_macro_srv/src/cli.rs b/crates/proc_macro_srv/src/cli.rs
index 1437794c9..1437794c9 100644
--- a/crates/ra_proc_macro_srv/src/cli.rs
+++ b/crates/proc_macro_srv/src/cli.rs
diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/proc_macro_srv/src/dylib.rs
index 9b6cc91ef..9b6cc91ef 100644
--- a/crates/ra_proc_macro_srv/src/dylib.rs
+++ b/crates/proc_macro_srv/src/dylib.rs
diff --git a/crates/ra_proc_macro_srv/src/lib.rs b/crates/proc_macro_srv/src/lib.rs
index 1fc2eef82..1fc2eef82 100644
--- a/crates/ra_proc_macro_srv/src/lib.rs
+++ b/crates/proc_macro_srv/src/lib.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/bridge/buffer.rs b/crates/proc_macro_srv/src/proc_macro/bridge/buffer.rs
index dae6ff1d1..dae6ff1d1 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/bridge/buffer.rs
+++ b/crates/proc_macro_srv/src/proc_macro/bridge/buffer.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/bridge/client.rs b/crates/proc_macro_srv/src/proc_macro/bridge/client.rs
index cb4b3bdb0..cb4b3bdb0 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/bridge/client.rs
+++ b/crates/proc_macro_srv/src/proc_macro/bridge/client.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/bridge/closure.rs b/crates/proc_macro_srv/src/proc_macro/bridge/closure.rs
index 273a97715..273a97715 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/bridge/closure.rs
+++ b/crates/proc_macro_srv/src/proc_macro/bridge/closure.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/bridge/handle.rs b/crates/proc_macro_srv/src/proc_macro/bridge/handle.rs
index a2f77b5ac..a2f77b5ac 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/bridge/handle.rs
+++ b/crates/proc_macro_srv/src/proc_macro/bridge/handle.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/bridge/mod.rs b/crates/proc_macro_srv/src/proc_macro/bridge/mod.rs
index aeb05aad4..aeb05aad4 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/bridge/mod.rs
+++ b/crates/proc_macro_srv/src/proc_macro/bridge/mod.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/bridge/rpc.rs b/crates/proc_macro_srv/src/proc_macro/bridge/rpc.rs
index 3528d5c99..3528d5c99 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/bridge/rpc.rs
+++ b/crates/proc_macro_srv/src/proc_macro/bridge/rpc.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/bridge/scoped_cell.rs b/crates/proc_macro_srv/src/proc_macro/bridge/scoped_cell.rs
index 6ef7ea43c..6ef7ea43c 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/bridge/scoped_cell.rs
+++ b/crates/proc_macro_srv/src/proc_macro/bridge/scoped_cell.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/bridge/server.rs b/crates/proc_macro_srv/src/proc_macro/bridge/server.rs
index 45d41ac02..45d41ac02 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/bridge/server.rs
+++ b/crates/proc_macro_srv/src/proc_macro/bridge/server.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/diagnostic.rs b/crates/proc_macro_srv/src/proc_macro/diagnostic.rs
index 55d93917c..55d93917c 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/diagnostic.rs
+++ b/crates/proc_macro_srv/src/proc_macro/diagnostic.rs
diff --git a/crates/ra_proc_macro_srv/src/proc_macro/mod.rs b/crates/proc_macro_srv/src/proc_macro/mod.rs
index ee0dc9722..ee0dc9722 100644
--- a/crates/ra_proc_macro_srv/src/proc_macro/mod.rs
+++ b/crates/proc_macro_srv/src/proc_macro/mod.rs
diff --git a/crates/ra_proc_macro_srv/src/rustc_server.rs b/crates/proc_macro_srv/src/rustc_server.rs
index d534d1337..7d1695c86 100644
--- a/crates/ra_proc_macro_srv/src/rustc_server.rs
+++ b/crates/proc_macro_srv/src/rustc_server.rs
@@ -182,7 +182,7 @@ pub mod token_stream {
182 182
183 fn from_str(src: &str) -> Result<TokenStream, LexError> { 183 fn from_str(src: &str) -> Result<TokenStream, LexError> {
184 let (subtree, _token_map) = 184 let (subtree, _token_map) =
185 ra_mbe::parse_to_token_tree(src).ok_or("Failed to parse from mbe")?; 185 mbe::parse_to_token_tree(src).ok_or("Failed to parse from mbe")?;
186 186
187 let tt: tt::TokenTree = subtree.into(); 187 let tt: tt::TokenTree = subtree.into();
188 Ok(tt.into()) 188 Ok(tt.into())
diff --git a/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt b/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt
index e6fd21610..e6fd21610 100644
--- a/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt
+++ b/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt
diff --git a/crates/ra_proc_macro_srv/src/tests/mod.rs b/crates/proc_macro_srv/src/tests/mod.rs
index 8e6f28abd..8e6f28abd 100644
--- a/crates/ra_proc_macro_srv/src/tests/mod.rs
+++ b/crates/proc_macro_srv/src/tests/mod.rs
diff --git a/crates/ra_proc_macro_srv/src/tests/utils.rs b/crates/proc_macro_srv/src/tests/utils.rs
index 1b6a0b6fb..1b6a0b6fb 100644
--- a/crates/ra_proc_macro_srv/src/tests/utils.rs
+++ b/crates/proc_macro_srv/src/tests/utils.rs
diff --git a/crates/ra_project_model/Cargo.toml b/crates/project_model/Cargo.toml
index 171fe8626..8d8d09387 100644
--- a/crates/ra_project_model/Cargo.toml
+++ b/crates/project_model/Cargo.toml
@@ -1,9 +1,9 @@
1[package] 1[package]
2edition = "2018" 2name = "project_model"
3name = "ra_project_model" 3version = "0.0.0"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6license = "MIT OR Apache-2.0" 4license = "MIT OR Apache-2.0"
5authors = ["rust-analyzer developers"]
6edition = "2018"
7 7
8[lib] 8[lib]
9doctest = false 9doctest = false
@@ -11,18 +11,15 @@ doctest = false
11[dependencies] 11[dependencies]
12log = "0.4.8" 12log = "0.4.8"
13rustc-hash = "1.1.0" 13rustc-hash = "1.1.0"
14
15cargo_metadata = "0.11.1" 14cargo_metadata = "0.11.1"
15serde = { version = "1.0.106", features = ["derive"] }
16serde_json = "1.0.48"
17anyhow = "1.0.26"
16 18
17arena = { path = "../arena" } 19arena = { path = "../arena" }
18ra_cfg = { path = "../ra_cfg" } 20cfg = { path = "../cfg" }
19ra_db = { path = "../ra_db" } 21ra_db = { path = "../ra_db" }
20toolchain = { path = "../toolchain" } 22toolchain = { path = "../toolchain" }
21ra_proc_macro = { path = "../ra_proc_macro" } 23ra_proc_macro = { path = "../ra_proc_macro" }
22paths = { path = "../paths" } 24paths = { path = "../paths" }
23stdx = { path = "../stdx" } 25stdx = { path = "../stdx" }
24
25serde = { version = "1.0.106", features = ["derive"] }
26serde_json = "1.0.48"
27
28anyhow = "1.0.26"
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs
index abf8dca96..abf8dca96 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/project_model/src/cargo_workspace.rs
diff --git a/crates/ra_project_model/src/cfg_flag.rs b/crates/project_model/src/cfg_flag.rs
index bd50056c6..e92962cf6 100644
--- a/crates/ra_project_model/src/cfg_flag.rs
+++ b/crates/project_model/src/cfg_flag.rs
@@ -3,7 +3,7 @@
3//! rustc main.rs --cfg foo --cfg 'feature="bar"' 3//! rustc main.rs --cfg foo --cfg 'feature="bar"'
4use std::str::FromStr; 4use std::str::FromStr;
5 5
6use ra_cfg::CfgOptions; 6use cfg::CfgOptions;
7use stdx::split_once; 7use stdx::split_once;
8 8
9#[derive(Clone, Eq, PartialEq, Debug)] 9#[derive(Clone, Eq, PartialEq, Debug)]
diff --git a/crates/ra_project_model/src/lib.rs b/crates/project_model/src/lib.rs
index 46f44910c..ee42198f3 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/project_model/src/lib.rs
@@ -12,8 +12,8 @@ use std::{
12}; 12};
13 13
14use anyhow::{bail, Context, Result}; 14use anyhow::{bail, Context, Result};
15use cfg::CfgOptions;
15use paths::{AbsPath, AbsPathBuf}; 16use paths::{AbsPath, AbsPathBuf};
16use ra_cfg::CfgOptions;
17use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; 17use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId};
18use rustc_hash::{FxHashMap, FxHashSet}; 18use rustc_hash::{FxHashMap, FxHashSet};
19 19
diff --git a/crates/ra_project_model/src/project_json.rs b/crates/project_model/src/project_json.rs
index e3f3163f6..e3f3163f6 100644
--- a/crates/ra_project_model/src/project_json.rs
+++ b/crates/project_model/src/project_json.rs
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs
index 8239797b6..8239797b6 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/project_model/src/sysroot.rs
diff --git a/crates/ra_assists/Cargo.toml b/crates/ra_assists/Cargo.toml
index abc290463..83e44c124 100644
--- a/crates/ra_assists/Cargo.toml
+++ b/crates/ra_assists/Cargo.toml
@@ -17,7 +17,6 @@ stdx = { path = "../stdx" }
17 17
18syntax = { path = "../syntax" } 18syntax = { path = "../syntax" }
19text_edit = { path = "../text_edit" } 19text_edit = { path = "../text_edit" }
20ra_fmt = { path = "../ra_fmt" }
21profile = { path = "../profile" } 20profile = { path = "../profile" }
22ra_db = { path = "../ra_db" } 21ra_db = { path = "../ra_db" }
23ra_ide_db = { path = "../ra_ide_db" } 22ra_ide_db = { path = "../ra_ide_db" }
diff --git a/crates/ra_assists/src/assist_context.rs b/crates/ra_assists/src/assist_context.rs
index 217f692a4..368d48a71 100644
--- a/crates/ra_assists/src/assist_context.rs
+++ b/crates/ra_assists/src/assist_context.rs
@@ -5,14 +5,13 @@ use std::mem;
5use algo::find_covering_element; 5use algo::find_covering_element;
6use hir::Semantics; 6use hir::Semantics;
7use ra_db::{FileId, FileRange}; 7use ra_db::{FileId, FileRange};
8use ra_fmt::{leading_indent, reindent};
9use ra_ide_db::{ 8use ra_ide_db::{
10 source_change::{SourceChange, SourceFileEdit}, 9 source_change::{SourceChange, SourceFileEdit},
11 RootDatabase, 10 RootDatabase,
12}; 11};
13use syntax::{ 12use syntax::{
14 algo::{self, find_node_at_offset, SyntaxRewriter}, 13 algo::{self, find_node_at_offset, SyntaxRewriter},
15 AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize, 14 AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxToken, TextRange, TextSize,
16 TokenAtOffset, 15 TokenAtOffset,
17}; 16};
18use text_edit::{TextEdit, TextEditBuilder}; 17use text_edit::{TextEdit, TextEditBuilder};
@@ -269,20 +268,6 @@ impl AssistBuilder {
269 pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) { 268 pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
270 algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit) 269 algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
271 } 270 }
272 /// Replaces specified `node` of text with a given string, reindenting the
273 /// string to maintain `node`'s existing indent.
274 // FIXME: remove in favor of syntax::edit::IndentLevel::increase_indent
275 pub(crate) fn replace_node_and_indent(
276 &mut self,
277 node: &SyntaxNode,
278 replace_with: impl Into<String>,
279 ) {
280 let mut replace_with = replace_with.into();
281 if let Some(indent) = leading_indent(node) {
282 replace_with = reindent(&replace_with, &indent)
283 }
284 self.replace(node.text_range(), replace_with)
285 }
286 pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) { 271 pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) {
287 let node = rewriter.rewrite_root().unwrap(); 272 let node = rewriter.rewrite_root().unwrap();
288 let new = rewriter.rewrite(&node); 273 let new = rewriter.rewrite(&node);
diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
index d5a68a24c..be480943c 100644
--- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs
+++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
@@ -1,10 +1,12 @@
1use std::iter;
2
1use syntax::{ 3use syntax::{
2 ast::{self, BlockExpr, Expr, LoopBodyOwner}, 4 ast::{self, make, BlockExpr, Expr, LoopBodyOwner},
3 AstNode, SyntaxNode, 5 AstNode, SyntaxNode,
4}; 6};
7use test_utils::mark;
5 8
6use crate::{AssistContext, AssistId, AssistKind, Assists}; 9use crate::{AssistContext, AssistId, AssistKind, Assists};
7use test_utils::mark;
8 10
9// Assist: change_return_type_to_result 11// Assist: change_return_type_to_result
10// 12//
@@ -44,7 +46,13 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex
44 tail_return_expr_collector.collect_tail_exprs(block_expr); 46 tail_return_expr_collector.collect_tail_exprs(block_expr);
45 47
46 for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { 48 for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap {
47 builder.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); 49 let ok_wrapped = make::expr_call(
50 make::expr_path(make::path_unqualified(make::path_segment(make::name_ref(
51 "Ok",
52 )))),
53 make::arg_list(iter::once(ret_expr_arg.clone())),
54 );
55 builder.replace_ast(ret_expr_arg, ok_wrapped);
48 } 56 }
49 57
50 match ctx.config.snippet_cap { 58 match ctx.config.snippet_cap {
@@ -60,7 +68,7 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex
60} 68}
61 69
62struct TailReturnCollector { 70struct TailReturnCollector {
63 exprs_to_wrap: Vec<SyntaxNode>, 71 exprs_to_wrap: Vec<ast::Expr>,
64} 72}
65 73
66impl TailReturnCollector { 74impl TailReturnCollector {
@@ -86,7 +94,8 @@ impl TailReturnCollector {
86 if let Some(last_exprs) = get_tail_expr_from_block(&expr) { 94 if let Some(last_exprs) = get_tail_expr_from_block(&expr) {
87 for last_expr in last_exprs { 95 for last_expr in last_exprs {
88 let last_expr = match last_expr { 96 let last_expr = match last_expr {
89 NodeType::Node(expr) | NodeType::Leaf(expr) => expr, 97 NodeType::Node(expr) => expr,
98 NodeType::Leaf(expr) => expr.syntax().clone(),
90 }; 99 };
91 100
92 if let Some(last_expr) = Expr::cast(last_expr.clone()) { 101 if let Some(last_expr) = Expr::cast(last_expr.clone()) {
@@ -113,12 +122,12 @@ impl TailReturnCollector {
113 } 122 }
114 Expr::ReturnExpr(ret_expr) => { 123 Expr::ReturnExpr(ret_expr) => {
115 if let Some(ret_expr_arg) = &ret_expr.expr() { 124 if let Some(ret_expr_arg) = &ret_expr.expr() {
116 self.exprs_to_wrap.push(ret_expr_arg.syntax().clone()); 125 self.exprs_to_wrap.push(ret_expr_arg.clone());
117 } 126 }
118 } 127 }
119 Expr::BreakExpr(break_expr) if collect_break => { 128 Expr::BreakExpr(break_expr) if collect_break => {
120 if let Some(break_expr_arg) = &break_expr.expr() { 129 if let Some(break_expr_arg) = &break_expr.expr() {
121 self.exprs_to_wrap.push(break_expr_arg.syntax().clone()); 130 self.exprs_to_wrap.push(break_expr_arg.clone());
122 } 131 }
123 } 132 }
124 Expr::IfExpr(if_expr) => { 133 Expr::IfExpr(if_expr) => {
@@ -166,14 +175,11 @@ impl TailReturnCollector {
166 NodeType::Leaf(expr) => { 175 NodeType::Leaf(expr) => {
167 self.exprs_to_wrap.push(expr.clone()); 176 self.exprs_to_wrap.push(expr.clone());
168 } 177 }
169 NodeType::Node(expr) => match &Expr::cast(expr.clone()) { 178 NodeType::Node(expr) => {
170 Some(last_expr) => { 179 if let Some(last_expr) = Expr::cast(expr.clone()) {
171 self.fetch_tail_exprs(last_expr); 180 self.fetch_tail_exprs(&last_expr);
172 }
173 None => {
174 self.exprs_to_wrap.push(expr.clone());
175 } 181 }
176 }, 182 }
177 } 183 }
178 } 184 }
179 } 185 }
@@ -182,7 +188,7 @@ impl TailReturnCollector {
182 188
183#[derive(Debug)] 189#[derive(Debug)]
184enum NodeType { 190enum NodeType {
185 Leaf(SyntaxNode), 191 Leaf(ast::Expr),
186 Node(SyntaxNode), 192 Node(SyntaxNode),
187} 193}
188 194
@@ -233,25 +239,26 @@ fn get_tail_expr_from_block(expr: &Expr) -> Option<Vec<NodeType>> {
233 239
234 Some(arms) 240 Some(arms)
235 } 241 }
236 Expr::BreakExpr(expr) => expr.expr().map(|e| vec![NodeType::Leaf(e.syntax().clone())]), 242 Expr::BreakExpr(expr) => expr.expr().map(|e| vec![NodeType::Leaf(e)]),
237 Expr::ReturnExpr(ret_expr) => Some(vec![NodeType::Node(ret_expr.syntax().clone())]), 243 Expr::ReturnExpr(ret_expr) => Some(vec![NodeType::Node(ret_expr.syntax().clone())]),
238 Expr::CallExpr(call_expr) => Some(vec![NodeType::Leaf(call_expr.syntax().clone())]), 244
239 Expr::Literal(lit_expr) => Some(vec![NodeType::Leaf(lit_expr.syntax().clone())]), 245 Expr::CallExpr(_)
240 Expr::TupleExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 246 | Expr::Literal(_)
241 Expr::ArrayExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 247 | Expr::TupleExpr(_)
242 Expr::ParenExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 248 | Expr::ArrayExpr(_)
243 Expr::PathExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 249 | Expr::ParenExpr(_)
244 Expr::RecordExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 250 | Expr::PathExpr(_)
245 Expr::IndexExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 251 | Expr::RecordExpr(_)
246 Expr::MethodCallExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 252 | Expr::IndexExpr(_)
247 Expr::AwaitExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 253 | Expr::MethodCallExpr(_)
248 Expr::CastExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 254 | Expr::AwaitExpr(_)
249 Expr::RefExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 255 | Expr::CastExpr(_)
250 Expr::PrefixExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 256 | Expr::RefExpr(_)
251 Expr::RangeExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 257 | Expr::PrefixExpr(_)
252 Expr::BinExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 258 | Expr::RangeExpr(_)
253 Expr::MacroCall(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 259 | Expr::BinExpr(_)
254 Expr::BoxExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 260 | Expr::MacroCall(_)
261 | Expr::BoxExpr(_) => Some(vec![NodeType::Leaf(expr.clone())]),
255 _ => None, 262 _ => None,
256 } 263 }
257} 264}
diff --git a/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs
index 6e9f2d0fc..497f887cd 100644
--- a/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -1,12 +1,11 @@
1use hir::{EnumVariant, Module, ModuleDef, Name}; 1use hir::{EnumVariant, Module, ModuleDef, Name};
2use ra_db::FileId; 2use ra_db::FileId;
3use ra_fmt::leading_indent;
4use ra_ide_db::{defs::Definition, search::Reference, RootDatabase}; 3use ra_ide_db::{defs::Definition, search::Reference, RootDatabase};
5use rustc_hash::FxHashSet; 4use rustc_hash::FxHashSet;
6use syntax::{ 5use syntax::{
7 algo::find_node_at_offset, 6 algo::find_node_at_offset,
8 ast::{self, ArgListOwner, AstNode, NameOwner, VisibilityOwner}, 7 ast::{self, edit::IndentLevel, ArgListOwner, AstNode, NameOwner, VisibilityOwner},
9 SourceFile, SyntaxNode, TextRange, TextSize, 8 SourceFile, TextRange, TextSize,
10}; 9};
11 10
12use crate::{ 11use crate::{
@@ -72,7 +71,7 @@ pub(crate) fn extract_struct_from_enum_variant(
72 } 71 }
73 extract_struct_def( 72 extract_struct_def(
74 builder, 73 builder,
75 enum_ast.syntax(), 74 &enum_ast,
76 &variant_name, 75 &variant_name,
77 &field_list.to_string(), 76 &field_list.to_string(),
78 start_offset, 77 start_offset,
@@ -112,9 +111,10 @@ fn insert_import(
112 Some(()) 111 Some(())
113} 112}
114 113
114// FIXME: this should use strongly-typed `make`, rather than string manipulation.
115fn extract_struct_def( 115fn extract_struct_def(
116 builder: &mut AssistBuilder, 116 builder: &mut AssistBuilder,
117 enum_ast: &SyntaxNode, 117 enum_: &ast::Enum,
118 variant_name: &str, 118 variant_name: &str,
119 variant_list: &str, 119 variant_list: &str,
120 start_offset: TextSize, 120 start_offset: TextSize,
@@ -126,11 +126,7 @@ fn extract_struct_def(
126 } else { 126 } else {
127 "".to_string() 127 "".to_string()
128 }; 128 };
129 let indent = if let Some(indent) = leading_indent(enum_ast) { 129 let indent = IndentLevel::from_node(enum_.syntax());
130 indent.to_string()
131 } else {
132 "".to_string()
133 };
134 let struct_def = format!( 130 let struct_def = format!(
135 r#"{}struct {}{}; 131 r#"{}struct {}{};
136 132
diff --git a/crates/ra_assists/src/handlers/move_guard.rs b/crates/ra_assists/src/handlers/move_guard.rs
index c62ebc306..452115fe6 100644
--- a/crates/ra_assists/src/handlers/move_guard.rs
+++ b/crates/ra_assists/src/handlers/move_guard.rs
@@ -1,5 +1,5 @@
1use syntax::{ 1use syntax::{
2 ast::{AstNode, IfExpr, MatchArm}, 2 ast::{edit::AstNodeEdit, make, AstNode, IfExpr, MatchArm},
3 SyntaxKind::WHITESPACE, 3 SyntaxKind::WHITESPACE,
4}; 4};
5 5
@@ -25,7 +25,9 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
25// 25//
26// fn handle(action: Action) { 26// fn handle(action: Action) {
27// match action { 27// match action {
28// Action::Move { distance } => if distance > 10 { foo() }, 28// Action::Move { distance } => if distance > 10 {
29// foo()
30// },
29// _ => (), 31// _ => (),
30// } 32// }
31// } 33// }
@@ -35,9 +37,13 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) ->
35 let guard = match_arm.guard()?; 37 let guard = match_arm.guard()?;
36 let space_before_guard = guard.syntax().prev_sibling_or_token(); 38 let space_before_guard = guard.syntax().prev_sibling_or_token();
37 39
38 let guard_conditions = guard.expr()?; 40 let guard_condition = guard.expr()?;
39 let arm_expr = match_arm.expr()?; 41 let arm_expr = match_arm.expr()?;
40 let buf = format!("if {} {{ {} }}", guard_conditions.syntax().text(), arm_expr.syntax().text()); 42 let if_expr = make::expr_if(
43 make::condition(guard_condition, None),
44 make::block_expr(None, Some(arm_expr.clone())),
45 )
46 .indent(arm_expr.indent_level());
41 47
42 let target = guard.syntax().text_range(); 48 let target = guard.syntax().text_range();
43 acc.add( 49 acc.add(
@@ -53,7 +59,7 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) ->
53 }; 59 };
54 60
55 edit.delete(guard.syntax().text_range()); 61 edit.delete(guard.syntax().text_range());
56 edit.replace_node_and_indent(arm_expr.syntax(), buf); 62 edit.replace_ast(arm_expr, if_expr);
57 }, 63 },
58 ) 64 )
59} 65}
@@ -134,16 +140,14 @@ mod tests {
134 check_assist_target( 140 check_assist_target(
135 move_guard_to_arm_body, 141 move_guard_to_arm_body,
136 r#" 142 r#"
137 fn f() { 143fn main() {
138 let t = 'a'; 144 match 92 {
139 let chars = "abcd"; 145 x <|>if x > 10 => false,
140 match t { 146 _ => true
141 '\r' <|>if chars.clone().next() == Some('\n') => false, 147 }
142 _ => true 148}
143 } 149"#,
144 } 150 r#"if x > 10"#,
145 "#,
146 r#"if chars.clone().next() == Some('\n')"#,
147 ); 151 );
148 } 152 }
149 153
@@ -152,25 +156,23 @@ mod tests {
152 check_assist( 156 check_assist(
153 move_guard_to_arm_body, 157 move_guard_to_arm_body,
154 r#" 158 r#"
155 fn f() { 159fn main() {
156 let t = 'a'; 160 match 92 {
157 let chars = "abcd"; 161 x <|>if x > 10 => false,
158 match t { 162 _ => true
159 '\r' <|>if chars.clone().next() == Some('\n') => false, 163 }
160 _ => true 164}
161 } 165"#,
162 }
163 "#,
164 r#" 166 r#"
165 fn f() { 167fn main() {
166 let t = 'a'; 168 match 92 {
167 let chars = "abcd"; 169 x => if x > 10 {
168 match t { 170 false
169 '\r' => if chars.clone().next() == Some('\n') { false }, 171 },
170 _ => true 172 _ => true
171 } 173 }
172 } 174}
173 "#, 175"#,
174 ); 176 );
175 } 177 }
176 178
@@ -179,21 +181,23 @@ mod tests {
179 check_assist( 181 check_assist(
180 move_guard_to_arm_body, 182 move_guard_to_arm_body,
181 r#" 183 r#"
182 fn f() { 184fn main() {
183 match x { 185 match 92 {
184 <|>y @ 4 | y @ 5 if y > 5 => true, 186 <|>x @ 4 | x @ 5 if x > 5 => true,
185 _ => false 187 _ => false
186 } 188 }
187 } 189}
188 "#, 190"#,
189 r#" 191 r#"
190 fn f() { 192fn main() {
191 match x { 193 match 92 {
192 y @ 4 | y @ 5 => if y > 5 { true }, 194 x @ 4 | x @ 5 => if x > 5 {
193 _ => false 195 true
194 } 196 },
195 } 197 _ => false
196 "#, 198 }
199}
200"#,
197 ); 201 );
198 } 202 }
199 203
@@ -202,25 +206,21 @@ mod tests {
202 check_assist( 206 check_assist(
203 move_arm_cond_to_match_guard, 207 move_arm_cond_to_match_guard,
204 r#" 208 r#"
205 fn f() { 209fn main() {
206 let t = 'a'; 210 match 92 {
207 let chars = "abcd"; 211 x => if x > 10 { <|>false },
208 match t { 212 _ => true
209 '\r' => if chars.clone().next() == Some('\n') { <|>false }, 213 }
210 _ => true 214}
211 } 215"#,
212 }
213 "#,
214 r#" 216 r#"
215 fn f() { 217fn main() {
216 let t = 'a'; 218 match 92 {
217 let chars = "abcd"; 219 x if x > 10 => false,
218 match t { 220 _ => true
219 '\r' if chars.clone().next() == Some('\n') => false, 221 }
220 _ => true 222}
221 } 223"#,
222 }
223 "#,
224 ); 224 );
225 } 225 }
226 226
@@ -229,15 +229,13 @@ mod tests {
229 check_assist_not_applicable( 229 check_assist_not_applicable(
230 move_arm_cond_to_match_guard, 230 move_arm_cond_to_match_guard,
231 r#" 231 r#"
232 fn f() { 232fn main() {
233 let t = 'a'; 233 match 92 {
234 let chars = "abcd"; 234 x => if let 62 = x { <|>false },
235 match t { 235 _ => true
236 '\r' => if let Some(_) = chars.clone().next() { <|>false }, 236 }
237 _ => true 237}
238 } 238"#,
239 }
240 "#,
241 ); 239 );
242 } 240 }
243 241
@@ -246,25 +244,21 @@ mod tests {
246 check_assist( 244 check_assist(
247 move_arm_cond_to_match_guard, 245 move_arm_cond_to_match_guard,
248 r#" 246 r#"
249 fn f() { 247fn main() {
250 let t = 'a'; 248 match 92 {
251 let chars = "abcd"; 249 x => if x > 10 { <|> },
252 match t { 250 _ => true
253 '\r' => if chars.clone().next().is_some() { <|> }, 251 }
254 _ => true 252}
255 } 253"#,
256 }
257 "#,
258 r#" 254 r#"
259 fn f() { 255fn main() {
260 let t = 'a'; 256 match 92 {
261 let chars = "abcd"; 257 x if x > 10 => { },
262 match t { 258 _ => true
263 '\r' if chars.clone().next().is_some() => { }, 259 }
264 _ => true 260}
265 } 261"#,
266 }
267 "#,
268 ); 262 );
269 } 263 }
270 264
@@ -273,31 +267,27 @@ mod tests {
273 check_assist( 267 check_assist(
274 move_arm_cond_to_match_guard, 268 move_arm_cond_to_match_guard,
275 r#" 269 r#"
276 fn f() { 270fn main() {
277 let mut t = 'a'; 271 match 92 {
278 let chars = "abcd"; 272 x => if x > 10 {
279 match t { 273 92;<|>
280 '\r' => if chars.clone().next().is_some() { 274 false
281 t = 'e';<|> 275 },
282 false 276 _ => true
283 }, 277 }
284 _ => true 278}
285 } 279"#,
286 }
287 "#,
288 r#" 280 r#"
289 fn f() { 281fn main() {
290 let mut t = 'a'; 282 match 92 {
291 let chars = "abcd"; 283 x if x > 10 => {
292 match t { 284 92;
293 '\r' if chars.clone().next().is_some() => { 285 false
294 t = 'e'; 286 },
295 false 287 _ => true
296 }, 288 }
297 _ => true 289}
298 } 290"#,
299 }
300 "#,
301 ); 291 );
302 } 292 }
303} 293}
diff --git a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs
index 2442f049b..79097621e 100644
--- a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs
+++ b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs
@@ -1,4 +1,3 @@
1use ra_fmt::unwrap_trivial_block;
2use syntax::{ 1use syntax::{
3 ast::{ 2 ast::{
4 self, 3 self,
@@ -8,7 +7,10 @@ use syntax::{
8 AstNode, 7 AstNode,
9}; 8};
10 9
11use crate::{utils::TryEnum, AssistContext, AssistId, AssistKind, Assists}; 10use crate::{
11 utils::{unwrap_trivial_block, TryEnum},
12 AssistContext, AssistId, AssistKind, Assists,
13};
12 14
13// Assist: replace_if_let_with_match 15// Assist: replace_if_let_with_match
14// 16//
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs
index 2879090b8..3851aeb3e 100644
--- a/crates/ra_assists/src/handlers/unwrap_block.rs
+++ b/crates/ra_assists/src/handlers/unwrap_block.rs
@@ -1,4 +1,3 @@
1use ra_fmt::unwrap_trivial_block;
2use syntax::{ 1use syntax::{
3 ast::{ 2 ast::{
4 self, 3 self,
@@ -7,7 +6,7 @@ use syntax::{
7 AstNode, TextRange, T, 6 AstNode, TextRange, T,
8}; 7};
9 8
10use crate::{AssistContext, AssistId, AssistKind, Assists}; 9use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, Assists};
11 10
12// Assist: unwrap_block 11// Assist: unwrap_block
13// 12//
diff --git a/crates/ra_assists/src/tests/generated.rs b/crates/ra_assists/src/tests/generated.rs
index 97978e7a2..d16e6fb0a 100644
--- a/crates/ra_assists/src/tests/generated.rs
+++ b/crates/ra_assists/src/tests/generated.rs
@@ -690,7 +690,9 @@ enum Action { Move { distance: u32 }, Stop }
690 690
691fn handle(action: Action) { 691fn handle(action: Action) {
692 match action { 692 match action {
693 Action::Move { distance } => if distance > 10 { foo() }, 693 Action::Move { distance } => if distance > 10 {
694 foo()
695 },
694 _ => (), 696 _ => (),
695 } 697 }
696} 698}
diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs
index 6d85661c4..a20453dd8 100644
--- a/crates/ra_assists/src/utils.rs
+++ b/crates/ra_assists/src/utils.rs
@@ -4,6 +4,7 @@ pub(crate) mod insert_use;
4use std::{iter, ops}; 4use std::{iter, ops};
5 5
6use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type}; 6use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type};
7use itertools::Itertools;
7use ra_ide_db::RootDatabase; 8use ra_ide_db::RootDatabase;
8use rustc_hash::FxHashSet; 9use rustc_hash::FxHashSet;
9use syntax::{ 10use syntax::{
@@ -17,6 +18,43 @@ use crate::assist_config::SnippetCap;
17 18
18pub(crate) use insert_use::{find_insert_use_container, insert_use_statement}; 19pub(crate) use insert_use::{find_insert_use_container, insert_use_statement};
19 20
21pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
22 extract_trivial_expression(&block)
23 .filter(|expr| !expr.syntax().text().contains_char('\n'))
24 .unwrap_or_else(|| block.into())
25}
26
27pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
28 let has_anything_else = |thing: &SyntaxNode| -> bool {
29 let mut non_trivial_children =
30 block.syntax().children_with_tokens().filter(|it| match it.kind() {
31 WHITESPACE | T!['{'] | T!['}'] => false,
32 _ => it.as_node() != Some(thing),
33 });
34 non_trivial_children.next().is_some()
35 };
36
37 if let Some(expr) = block.expr() {
38 if has_anything_else(expr.syntax()) {
39 return None;
40 }
41 return Some(expr);
42 }
43 // Unwrap `{ continue; }`
44 let (stmt,) = block.statements().next_tuple()?;
45 if let ast::Stmt::ExprStmt(expr_stmt) = stmt {
46 if has_anything_else(expr_stmt.syntax()) {
47 return None;
48 }
49 let expr = expr_stmt.expr()?;
50 match expr.syntax().kind() {
51 CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr),
52 _ => (),
53 }
54 }
55 None
56}
57
20#[derive(Clone, Copy, Debug)] 58#[derive(Clone, Copy, Debug)]
21pub(crate) enum Cursor<'a> { 59pub(crate) enum Cursor<'a> {
22 Replace(&'a SyntaxNode), 60 Replace(&'a SyntaxNode),
diff --git a/crates/ra_assists/src/utils/insert_use.rs b/crates/ra_assists/src/utils/insert_use.rs
index f89c288da..50a62ee82 100644
--- a/crates/ra_assists/src/utils/insert_use.rs
+++ b/crates/ra_assists/src/utils/insert_use.rs
@@ -2,13 +2,15 @@
2// FIXME: rewrite according to the plan, outlined in 2// FIXME: rewrite according to the plan, outlined in
3// https://github.com/rust-analyzer/rust-analyzer/issues/3301#issuecomment-592931553 3// https://github.com/rust-analyzer/rust-analyzer/issues/3301#issuecomment-592931553
4 4
5use std::iter::successors;
6
5use either::Either; 7use either::Either;
6use hir::{self, ModPath}; 8use hir::{self, ModPath};
7use syntax::{ 9use syntax::{
8 ast::{self, NameOwner, VisibilityOwner}, 10 ast::{self, NameOwner, VisibilityOwner},
9 AstNode, Direction, SmolStr, 11 AstNode, AstToken, Direction, SmolStr,
10 SyntaxKind::{PATH, PATH_SEGMENT}, 12 SyntaxKind::{PATH, PATH_SEGMENT},
11 SyntaxNode, T, 13 SyntaxNode, SyntaxToken, T,
12}; 14};
13use text_edit::TextEditBuilder; 15use text_edit::TextEditBuilder;
14 16
@@ -442,7 +444,7 @@ fn make_assist_add_new_use(
442 edit: &mut TextEditBuilder, 444 edit: &mut TextEditBuilder,
443) { 445) {
444 if let Some(anchor) = anchor { 446 if let Some(anchor) = anchor {
445 let indent = ra_fmt::leading_indent(anchor); 447 let indent = leading_indent(anchor);
446 let mut buf = String::new(); 448 let mut buf = String::new();
447 if after { 449 if after {
448 buf.push_str("\n"); 450 buf.push_str("\n");
@@ -524,3 +526,22 @@ fn make_assist_add_nested_import(
524 edit.insert(end, "}".to_string()); 526 edit.insert(end, "}".to_string());
525 } 527 }
526} 528}
529
530/// If the node is on the beginning of the line, calculate indent.
531fn leading_indent(node: &SyntaxNode) -> Option<SmolStr> {
532 for token in prev_tokens(node.first_token()?) {
533 if let Some(ws) = ast::Whitespace::cast(token.clone()) {
534 let ws_text = ws.text();
535 if let Some(pos) = ws_text.rfind('\n') {
536 return Some(ws_text[pos + 1..].into());
537 }
538 }
539 if token.text().contains('\n') {
540 break;
541 }
542 }
543 return None;
544 fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> {
545 successors(token.prev_token(), |token| token.prev_token())
546 }
547}
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml
index 156ea1ee4..ad432f096 100644
--- a/crates/ra_db/Cargo.toml
+++ b/crates/ra_db/Cargo.toml
@@ -13,7 +13,7 @@ salsa = "0.15.2"
13rustc-hash = "1.1.0" 13rustc-hash = "1.1.0"
14 14
15syntax = { path = "../syntax" } 15syntax = { path = "../syntax" }
16ra_cfg = { path = "../ra_cfg" } 16cfg = { path = "../cfg" }
17profile = { path = "../profile" } 17profile = { path = "../profile" }
18tt = { path = "../tt" } 18tt = { path = "../tt" }
19test_utils = { path = "../test_utils" } 19test_utils = { path = "../test_utils" }
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index 2aafb9965..5ff8ead0e 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -59,7 +59,7 @@
59//! ``` 59//! ```
60use std::{str::FromStr, sync::Arc}; 60use std::{str::FromStr, sync::Arc};
61 61
62use ra_cfg::CfgOptions; 62use cfg::CfgOptions;
63use rustc_hash::FxHashMap; 63use rustc_hash::FxHashMap;
64use test_utils::{extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER}; 64use test_utils::{extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER};
65use vfs::{file_set::FileSet, VfsPath}; 65use vfs::{file_set::FileSet, VfsPath};
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index 12a863499..f3d65cdf0 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -8,7 +8,7 @@
8 8
9use std::{fmt, iter::FromIterator, ops, str::FromStr, sync::Arc}; 9use std::{fmt, iter::FromIterator, ops, str::FromStr, sync::Arc};
10 10
11use ra_cfg::CfgOptions; 11use cfg::CfgOptions;
12use rustc_hash::{FxHashMap, FxHashSet}; 12use rustc_hash::{FxHashMap, FxHashSet};
13use syntax::SmolStr; 13use syntax::SmolStr;
14use tt::TokenExpander; 14use tt::TokenExpander;
diff --git a/crates/ra_fmt/Cargo.toml b/crates/ra_fmt/Cargo.toml
deleted file mode 100644
index d42ca62be..000000000
--- a/crates/ra_fmt/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
1[package]
2edition = "2018"
3name = "ra_fmt"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6publish = false
7license = "MIT OR Apache-2.0"
8
9[lib]
10doctest = false
11
12[dependencies]
13itertools = "0.9.0"
14
15syntax = { path = "../syntax" }
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs
deleted file mode 100644
index d0bf0593f..000000000
--- a/crates/ra_fmt/src/lib.rs
+++ /dev/null
@@ -1,96 +0,0 @@
1//! This crate provides some utilities for indenting rust code.
2
3use std::iter::successors;
4
5use itertools::Itertools;
6use syntax::{
7 ast::{self, AstNode, AstToken},
8 SmolStr, SyntaxKind,
9 SyntaxKind::*,
10 SyntaxNode, SyntaxToken, T,
11};
12
13pub fn reindent(text: &str, indent: &str) -> String {
14 let indent = format!("\n{}", indent);
15 text.lines().intersperse(&indent).collect()
16}
17
18/// If the node is on the beginning of the line, calculate indent.
19pub fn leading_indent(node: &SyntaxNode) -> Option<SmolStr> {
20 for token in prev_tokens(node.first_token()?) {
21 if let Some(ws) = ast::Whitespace::cast(token.clone()) {
22 let ws_text = ws.text();
23 if let Some(pos) = ws_text.rfind('\n') {
24 return Some(ws_text[pos + 1..].into());
25 }
26 }
27 if token.text().contains('\n') {
28 break;
29 }
30 }
31 None
32}
33
34fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> {
35 successors(token.prev_token(), |token| token.prev_token())
36}
37
38pub fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
39 extract_trivial_expression(&block)
40 .filter(|expr| !expr.syntax().text().contains_char('\n'))
41 .unwrap_or_else(|| block.into())
42}
43
44pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
45 let has_anything_else = |thing: &SyntaxNode| -> bool {
46 let mut non_trivial_children =
47 block.syntax().children_with_tokens().filter(|it| match it.kind() {
48 WHITESPACE | T!['{'] | T!['}'] => false,
49 _ => it.as_node() != Some(thing),
50 });
51 non_trivial_children.next().is_some()
52 };
53
54 if let Some(expr) = block.expr() {
55 if has_anything_else(expr.syntax()) {
56 return None;
57 }
58 return Some(expr);
59 }
60 // Unwrap `{ continue; }`
61 let (stmt,) = block.statements().next_tuple()?;
62 if let ast::Stmt::ExprStmt(expr_stmt) = stmt {
63 if has_anything_else(expr_stmt.syntax()) {
64 return None;
65 }
66 let expr = expr_stmt.expr()?;
67 match expr.syntax().kind() {
68 CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr),
69 _ => (),
70 }
71 }
72 None
73}
74
75pub fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str {
76 match left {
77 T!['('] | T!['['] => return "",
78 T!['{'] => {
79 if let USE_TREE = right {
80 return "";
81 }
82 }
83 _ => (),
84 }
85 match right {
86 T![')'] | T![']'] => return "",
87 T!['}'] => {
88 if let USE_TREE = left {
89 return "";
90 }
91 }
92 T![.] => return "",
93 _ => (),
94 }
95 " "
96}
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml
index 38129782f..e7d3c4d5b 100644
--- a/crates/ra_hir_def/Cargo.toml
+++ b/crates/ra_hir_def/Cargo.toml
@@ -28,8 +28,8 @@ syntax = { path = "../syntax" }
28profile = { path = "../profile" } 28profile = { path = "../profile" }
29hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } 29hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
30test_utils = { path = "../test_utils" } 30test_utils = { path = "../test_utils" }
31mbe = { path = "../ra_mbe", package = "ra_mbe" } 31mbe = { path = "../mbe" }
32ra_cfg = { path = "../ra_cfg" } 32cfg = { path = "../cfg" }
33tt = { path = "../tt" } 33tt = { path = "../tt" }
34 34
35[dev-dependencies] 35[dev-dependencies]
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index c83219d77..d69ff2fc7 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -23,7 +23,7 @@ use crate::{
23 EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, 23 EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId,
24 VariantId, 24 VariantId,
25}; 25};
26use ra_cfg::CfgOptions; 26use cfg::CfgOptions;
27 27
28/// Note that we use `StructData` for unions as well! 28/// Note that we use `StructData` for unions as well!
29#[derive(Debug, Clone, PartialEq, Eq)] 29#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 36dc8b816..dea552a60 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -2,10 +2,10 @@
2 2
3use std::{ops, sync::Arc}; 3use std::{ops, sync::Arc};
4 4
5use cfg::{CfgExpr, CfgOptions};
5use either::Either; 6use either::Either;
6use hir_expand::{hygiene::Hygiene, AstId, InFile}; 7use hir_expand::{hygiene::Hygiene, AstId, InFile};
7use mbe::ast_to_token_tree; 8use mbe::ast_to_token_tree;
8use ra_cfg::{CfgExpr, CfgOptions};
9use syntax::{ 9use syntax::{
10 ast::{self, AstNode, AttrsOwner}, 10 ast::{self, AstNode, AttrsOwner},
11 SmolStr, 11 SmolStr,
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 7c33966a7..fe659386a 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -6,10 +6,10 @@ pub mod scope;
6use std::{mem, ops::Index, sync::Arc}; 6use std::{mem, ops::Index, sync::Arc};
7 7
8use arena::{map::ArenaMap, Arena}; 8use arena::{map::ArenaMap, Arena};
9use cfg::CfgOptions;
9use drop_bomb::DropBomb; 10use drop_bomb::DropBomb;
10use either::Either; 11use either::Either;
11use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId}; 12use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId};
12use ra_cfg::CfgOptions;
13use ra_db::CrateId; 13use ra_db::CrateId;
14use rustc_hash::FxHashMap; 14use rustc_hash::FxHashMap;
15use syntax::{ast, AstNode, AstPtr}; 15use syntax::{ast, AstNode, AstPtr};
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index f7270ec91..6a5891936 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -3,6 +3,7 @@
3//! `DefCollector::collect` contains the fixed-point iteration loop which 3//! `DefCollector::collect` contains the fixed-point iteration loop which
4//! resolves imports and expands macros. 4//! resolves imports and expands macros.
5 5
6use cfg::CfgOptions;
6use hir_expand::{ 7use hir_expand::{
7 ast_id_map::FileAstId, 8 ast_id_map::FileAstId,
8 builtin_derive::find_builtin_derive, 9 builtin_derive::find_builtin_derive,
@@ -11,7 +12,6 @@ use hir_expand::{
11 proc_macro::ProcMacroExpander, 12 proc_macro::ProcMacroExpander,
12 HirFileId, MacroCallId, MacroDefId, MacroDefKind, 13 HirFileId, MacroCallId, MacroDefId, MacroDefKind,
13}; 14};
14use ra_cfg::CfgOptions;
15use ra_db::{CrateId, FileId, ProcMacroId}; 15use ra_db::{CrateId, FileId, ProcMacroId};
16use rustc_hash::FxHashMap; 16use rustc_hash::FxHashMap;
17use syntax::ast; 17use syntax::ast;
diff --git a/crates/ra_hir_expand/Cargo.toml b/crates/ra_hir_expand/Cargo.toml
index 153a70bdf..cbb0ac29b 100644
--- a/crates/ra_hir_expand/Cargo.toml
+++ b/crates/ra_hir_expand/Cargo.toml
@@ -19,5 +19,5 @@ syntax = { path = "../syntax" }
19parser = { path = "../parser" } 19parser = { path = "../parser" }
20profile = { path = "../profile" } 20profile = { path = "../profile" }
21tt = { path = "../tt" } 21tt = { path = "../tt" }
22mbe = { path = "../ra_mbe", package = "ra_mbe" } 22mbe = { path = "../mbe" }
23test_utils = { path = "../test_utils"} 23test_utils = { path = "../test_utils"}
diff --git a/crates/ra_ide/Cargo.toml b/crates/ra_ide/Cargo.toml
index 8e0fa5917..938398a41 100644
--- a/crates/ra_ide/Cargo.toml
+++ b/crates/ra_ide/Cargo.toml
@@ -25,8 +25,7 @@ syntax = { path = "../syntax" }
25text_edit = { path = "../text_edit" } 25text_edit = { path = "../text_edit" }
26ra_db = { path = "../ra_db" } 26ra_db = { path = "../ra_db" }
27ra_ide_db = { path = "../ra_ide_db" } 27ra_ide_db = { path = "../ra_ide_db" }
28ra_cfg = { path = "../ra_cfg" } 28cfg = { path = "../cfg" }
29ra_fmt = { path = "../ra_fmt" }
30profile = { path = "../profile" } 29profile = { path = "../profile" }
31test_utils = { path = "../test_utils" } 30test_utils = { path = "../test_utils" }
32ra_assists = { path = "../ra_assists" } 31ra_assists = { path = "../ra_assists" }
diff --git a/crates/ra_ide/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs
index 35cec87f6..f5c310701 100644
--- a/crates/ra_ide/src/join_lines.rs
+++ b/crates/ra_ide/src/join_lines.rs
@@ -1,10 +1,10 @@
1use itertools::Itertools; 1use itertools::Itertools;
2use ra_fmt::{compute_ws, extract_trivial_expression}; 2use ra_assists::utils::extract_trivial_expression;
3use syntax::{ 3use syntax::{
4 algo::{find_covering_element, non_trivia_sibling}, 4 algo::{find_covering_element, non_trivia_sibling},
5 ast::{self, AstNode, AstToken}, 5 ast::{self, AstNode, AstToken},
6 Direction, NodeOrToken, SourceFile, 6 Direction, NodeOrToken, SourceFile,
7 SyntaxKind::{self, WHITESPACE}, 7 SyntaxKind::{self, USE_TREE, WHITESPACE},
8 SyntaxNode, SyntaxToken, TextRange, TextSize, T, 8 SyntaxNode, SyntaxToken, TextRange, TextSize, T,
9}; 9};
10use text_edit::{TextEdit, TextEditBuilder}; 10use text_edit::{TextEdit, TextEditBuilder};
@@ -168,6 +168,29 @@ fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool {
168 matches!((left, right), (T![,], T![')']) | (T![,], T![']'])) 168 matches!((left, right), (T![,], T![')']) | (T![,], T![']']))
169} 169}
170 170
171fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str {
172 match left {
173 T!['('] | T!['['] => return "",
174 T!['{'] => {
175 if let USE_TREE = right {
176 return "";
177 }
178 }
179 _ => (),
180 }
181 match right {
182 T![')'] | T![']'] => return "",
183 T!['}'] => {
184 if let USE_TREE = left {
185 return "";
186 }
187 }
188 T![.] => return "",
189 _ => (),
190 }
191 " "
192}
193
171#[cfg(test)] 194#[cfg(test)]
172mod tests { 195mod tests {
173 use syntax::SourceFile; 196 use syntax::SourceFile;
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 20967ba99..1fdf17800 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -47,7 +47,7 @@ mod typing;
47 47
48use std::sync::Arc; 48use std::sync::Arc;
49 49
50use ra_cfg::CfgOptions; 50use cfg::CfgOptions;
51use ra_db::{ 51use ra_db::{
52 salsa::{self, ParallelDatabase}, 52 salsa::{self, ParallelDatabase},
53 CheckCanceled, Env, FileLoader, FileSet, SourceDatabase, VfsPath, 53 CheckCanceled, Env, FileLoader, FileSet, SourceDatabase, VfsPath,
diff --git a/crates/ra_ide/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs
index c7e0f4b58..a4691f028 100644
--- a/crates/ra_ide/src/mock_analysis.rs
+++ b/crates/ra_ide/src/mock_analysis.rs
@@ -1,7 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use ra_cfg::CfgOptions; 4use cfg::CfgOptions;
5use ra_db::{CrateName, FileSet, SourceRoot, VfsPath}; 5use ra_db::{CrateName, FileSet, SourceRoot, VfsPath};
6use test_utils::{ 6use test_utils::{
7 extract_annotations, extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER, 7 extract_annotations, extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER,
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs
index 69af0c86a..b78388e6b 100644
--- a/crates/ra_ide/src/parent_module.rs
+++ b/crates/ra_ide/src/parent_module.rs
@@ -63,7 +63,7 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
63 63
64#[cfg(test)] 64#[cfg(test)]
65mod tests { 65mod tests {
66 use ra_cfg::CfgOptions; 66 use cfg::CfgOptions;
67 use ra_db::Env; 67 use ra_db::Env;
68 use test_utils::mark; 68 use test_utils::mark;
69 69
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs
index 54cb3b309..fb40762cf 100644
--- a/crates/ra_ide/src/runnables.rs
+++ b/crates/ra_ide/src/runnables.rs
@@ -1,8 +1,8 @@
1use std::fmt; 1use std::fmt;
2 2
3use cfg::CfgExpr;
3use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics}; 4use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics};
4use itertools::Itertools; 5use itertools::Itertools;
5use ra_cfg::CfgExpr;
6use ra_ide_db::RootDatabase; 6use ra_ide_db::RootDatabase;
7use syntax::{ 7use syntax::{
8 ast::{self, AstNode, AttrsOwner, DocCommentsOwner, ModuleItemOwner, NameOwner}, 8 ast::{self, AstNode, AttrsOwner, DocCommentsOwner, ModuleItemOwner, NameOwner},
diff --git a/crates/ra_ide/src/typing.rs b/crates/ra_ide/src/typing.rs
index c408b1d52..7897c57b7 100644
--- a/crates/ra_ide/src/typing.rs
+++ b/crates/ra_ide/src/typing.rs
@@ -16,11 +16,10 @@
16mod on_enter; 16mod on_enter;
17 17
18use ra_db::{FilePosition, SourceDatabase}; 18use ra_db::{FilePosition, SourceDatabase};
19use ra_fmt::leading_indent;
20use ra_ide_db::{source_change::SourceFileEdit, RootDatabase}; 19use ra_ide_db::{source_change::SourceFileEdit, RootDatabase};
21use syntax::{ 20use syntax::{
22 algo::find_node_at_offset, 21 algo::find_node_at_offset,
23 ast::{self, AstToken}, 22 ast::{self, edit::IndentLevel, AstToken},
24 AstNode, SourceFile, 23 AstNode, SourceFile,
25 SyntaxKind::{FIELD_EXPR, METHOD_CALL_EXPR}, 24 SyntaxKind::{FIELD_EXPR, METHOD_CALL_EXPR},
26 TextRange, TextSize, 25 TextRange, TextSize,
@@ -104,7 +103,7 @@ fn on_dot_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
104 if !matches!(parent.kind(), FIELD_EXPR | METHOD_CALL_EXPR) { 103 if !matches!(parent.kind(), FIELD_EXPR | METHOD_CALL_EXPR) {
105 return None; 104 return None;
106 } 105 }
107 let prev_indent = leading_indent(&parent)?; 106 let prev_indent = IndentLevel::from_node(&parent);
108 let target_indent = format!(" {}", prev_indent); 107 let target_indent = format!(" {}", prev_indent);
109 let target_indent_len = TextSize::of(&target_indent); 108 let target_indent_len = TextSize::of(&target_indent);
110 if current_indent_len == target_indent_len { 109 if current_indent_len == target_indent_len {
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 86c786e25..c6102bf27 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -37,12 +37,12 @@ lsp-server = "0.3.3"
37flycheck = { path = "../flycheck" } 37flycheck = { path = "../flycheck" }
38ra_ide = { path = "../ra_ide" } 38ra_ide = { path = "../ra_ide" }
39profile = { path = "../profile" } 39profile = { path = "../profile" }
40ra_project_model = { path = "../ra_project_model" } 40project_model = { path = "../project_model" }
41syntax = { path = "../syntax" } 41syntax = { path = "../syntax" }
42text_edit = { path = "../text_edit" } 42text_edit = { path = "../text_edit" }
43vfs = { path = "../vfs" } 43vfs = { path = "../vfs" }
44vfs-notify = { path = "../vfs-notify" } 44vfs-notify = { path = "../vfs-notify" }
45ra_cfg = { path = "../ra_cfg" } 45cfg = { path = "../cfg" }
46toolchain = { path = "../toolchain" } 46toolchain = { path = "../toolchain" }
47 47
48# This should only be used in CLI 48# This should only be used in CLI
@@ -52,7 +52,7 @@ ra_ssr = { path = "../ra_ssr" }
52hir = { path = "../ra_hir", package = "ra_hir" } 52hir = { path = "../ra_hir", package = "ra_hir" }
53hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } 53hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
54hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } 54hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
55ra_proc_macro_srv = { path = "../ra_proc_macro_srv" } 55proc_macro_srv = { path = "../proc_macro_srv" }
56 56
57[target.'cfg(windows)'.dependencies] 57[target.'cfg(windows)'.dependencies]
58winapi = "0.3.8" 58winapi = "0.3.8"
@@ -60,5 +60,5 @@ winapi = "0.3.8"
60[dev-dependencies] 60[dev-dependencies]
61expect = { path = "../expect" } 61expect = { path = "../expect" }
62test_utils = { path = "../test_utils" } 62test_utils = { path = "../test_utils" }
63mbe = { path = "../ra_mbe", package = "ra_mbe" } 63mbe = { path = "../mbe" }
64tt = { path = "../tt" } 64tt = { path = "../tt" }
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 9622d71c0..bade31ca2 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -6,7 +6,7 @@ mod args;
6use std::{convert::TryFrom, process}; 6use std::{convert::TryFrom, process};
7 7
8use lsp_server::Connection; 8use lsp_server::Connection;
9use ra_project_model::ProjectManifest; 9use project_model::ProjectManifest;
10use rust_analyzer::{ 10use rust_analyzer::{
11 cli, 11 cli,
12 config::{Config, LinkedProject}, 12 config::{Config, LinkedProject},
@@ -30,7 +30,7 @@ fn try_main() -> Result<()> {
30 let args = args::Args::parse()?; 30 let args = args::Args::parse()?;
31 match args.command { 31 match args.command {
32 args::Command::RunServer => run_server()?, 32 args::Command::RunServer => run_server()?,
33 args::Command::ProcMacro => ra_proc_macro_srv::cli::run()?, 33 args::Command::ProcMacro => proc_macro_srv::cli::run()?,
34 34
35 args::Command::Parse { no_dump } => cli::parse(no_dump)?, 35 args::Command::Parse { no_dump } => cli::parse(no_dump)?,
36 args::Command::Symbols => cli::symbols()?, 36 args::Command::Symbols => cli::symbols()?,
diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs
index 7929368c0..5ba30dbad 100644
--- a/crates/rust-analyzer/src/cargo_target_spec.rs
+++ b/crates/rust-analyzer/src/cargo_target_spec.rs
@@ -1,8 +1,8 @@
1//! See `CargoTargetSpec` 1//! See `CargoTargetSpec`
2 2
3use ra_cfg::CfgExpr; 3use cfg::CfgExpr;
4use project_model::{self, TargetKind};
4use ra_ide::{FileId, RunnableKind, TestId}; 5use ra_ide::{FileId, RunnableKind, TestId};
5use ra_project_model::{self, TargetKind};
6use vfs::AbsPathBuf; 6use vfs::AbsPathBuf;
7 7
8use crate::{global_state::GlobalStateSnapshot, Result}; 8use crate::{global_state::GlobalStateSnapshot, Result};
@@ -177,8 +177,8 @@ fn required_features(cfg_expr: &CfgExpr, features: &mut Vec<String>) {
177mod tests { 177mod tests {
178 use super::*; 178 use super::*;
179 179
180 use cfg::CfgExpr;
180 use mbe::ast_to_token_tree; 181 use mbe::ast_to_token_tree;
181 use ra_cfg::CfgExpr;
182 use syntax::{ 182 use syntax::{
183 ast::{self, AstNode}, 183 ast::{self, AstNode},
184 SmolStr, 184 SmolStr,
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index a43bf2244..f6cb144c6 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -4,9 +4,9 @@ use std::{path::Path, sync::Arc};
4 4
5use anyhow::Result; 5use anyhow::Result;
6use crossbeam_channel::{unbounded, Receiver}; 6use crossbeam_channel::{unbounded, Receiver};
7use project_model::{CargoConfig, ProcMacroClient, ProjectManifest, ProjectWorkspace};
7use ra_db::CrateGraph; 8use ra_db::CrateGraph;
8use ra_ide::{AnalysisChange, AnalysisHost}; 9use ra_ide::{AnalysisChange, AnalysisHost};
9use ra_project_model::{CargoConfig, ProcMacroClient, ProjectManifest, ProjectWorkspace};
10use vfs::{loader::Handle, AbsPath, AbsPathBuf}; 10use vfs::{loader::Handle, AbsPath, AbsPathBuf};
11 11
12use crate::reload::{ProjectFolders, SourceRootConfig}; 12use crate::reload::{ProjectFolders, SourceRootConfig};
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 70b4512d0..bfc84147c 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -11,8 +11,8 @@ use std::{ffi::OsString, path::PathBuf};
11 11
12use flycheck::FlycheckConfig; 12use flycheck::FlycheckConfig;
13use lsp_types::ClientCapabilities; 13use lsp_types::ClientCapabilities;
14use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest};
14use ra_ide::{AssistConfig, CompletionConfig, HoverConfig, InlayHintsConfig}; 15use ra_ide::{AssistConfig, CompletionConfig, HoverConfig, InlayHintsConfig};
15use ra_project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest};
16use serde::Deserialize; 16use serde::Deserialize;
17use vfs::AbsPathBuf; 17use vfs::AbsPathBuf;
18 18
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index 8c115c8a6..2e8b708d0 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -9,9 +9,9 @@ use crossbeam_channel::{unbounded, Receiver, Sender};
9use flycheck::FlycheckHandle; 9use flycheck::FlycheckHandle;
10use lsp_types::{SemanticTokens, Url}; 10use lsp_types::{SemanticTokens, Url};
11use parking_lot::{Mutex, RwLock}; 11use parking_lot::{Mutex, RwLock};
12use project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target};
12use ra_db::{CrateId, VfsPath}; 13use ra_db::{CrateId, VfsPath};
13use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FileId}; 14use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FileId};
14use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target};
15use rustc_hash::FxHashMap; 15use rustc_hash::FxHashMap;
16 16
17use crate::{ 17use crate::{
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 86e7833f2..4b5ca7eec 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -18,11 +18,11 @@ use lsp_types::{
18 SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, SymbolTag, 18 SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, SymbolTag,
19 TextDocumentIdentifier, Url, WorkspaceEdit, 19 TextDocumentIdentifier, Url, WorkspaceEdit,
20}; 20};
21use project_model::TargetKind;
21use ra_ide::{ 22use ra_ide::{
22 FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, NavigationTarget, Query, 23 FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, NavigationTarget, Query,
23 RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit, 24 RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit,
24}; 25};
25use ra_project_model::TargetKind;
26use serde::{Deserialize, Serialize}; 26use serde::{Deserialize, Serialize};
27use serde_json::to_value; 27use serde_json::to_value;
28use stdx::{format_to, split_once}; 28use stdx::{format_to, split_once};
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 32962b088..9a779cb14 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -21,7 +21,7 @@ use crate::{
21 lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress}, 21 lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress},
22 Result, 22 Result,
23}; 23};
24use ra_project_model::ProjectWorkspace; 24use project_model::ProjectWorkspace;
25use vfs::ChangeKind; 25use vfs::ChangeKind;
26 26
27pub fn main_loop(config: Config, connection: Connection) -> Result<()> { 27pub fn main_loop(config: Config, connection: Connection) -> Result<()> {
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index f74f2c02c..640417dc6 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -2,9 +2,9 @@
2use std::{mem, sync::Arc}; 2use std::{mem, sync::Arc};
3 3
4use flycheck::FlycheckHandle; 4use flycheck::FlycheckHandle;
5use project_model::{ProcMacroClient, ProjectWorkspace};
5use ra_db::{CrateGraph, SourceRoot, VfsPath}; 6use ra_db::{CrateGraph, SourceRoot, VfsPath};
6use ra_ide::AnalysisChange; 7use ra_ide::AnalysisChange;
7use ra_project_model::{ProcMacroClient, ProjectWorkspace};
8use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; 8use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
9 9
10use crate::{ 10use crate::{
@@ -98,14 +98,14 @@ impl GlobalState {
98 .iter() 98 .iter()
99 .map(|project| match project { 99 .map(|project| match project {
100 LinkedProject::ProjectManifest(manifest) => { 100 LinkedProject::ProjectManifest(manifest) => {
101 ra_project_model::ProjectWorkspace::load( 101 project_model::ProjectWorkspace::load(
102 manifest.clone(), 102 manifest.clone(),
103 &cargo_config, 103 &cargo_config,
104 with_sysroot, 104 with_sysroot,
105 ) 105 )
106 } 106 }
107 LinkedProject::InlineJsonProject(it) => { 107 LinkedProject::InlineJsonProject(it) => {
108 Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() }) 108 Ok(project_model::ProjectWorkspace::Json { project: it.clone() })
109 } 109 }
110 }) 110 })
111 .collect::<Vec<_>>(); 111 .collect::<Vec<_>>();
@@ -176,7 +176,7 @@ impl GlobalState {
176 Ok(it) => it, 176 Ok(it) => it,
177 Err(err) => { 177 Err(err) => {
178 log::error!( 178 log::error!(
179 "Failed to run ra_proc_macro_srv from path {}, error: {:?}", 179 "Failed to run proc_macro_srv from path {}, error: {:?}",
180 path.display(), 180 path.display(),
181 err 181 err
182 ); 182 );
diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs
index 15866fbb1..5bafeba79 100644
--- a/crates/rust-analyzer/tests/heavy_tests/support.rs
+++ b/crates/rust-analyzer/tests/heavy_tests/support.rs
@@ -12,7 +12,7 @@ use lsp_types::{
12 notification::Exit, request::Shutdown, TextDocumentIdentifier, Url, WorkDoneProgress, 12 notification::Exit, request::Shutdown, TextDocumentIdentifier, Url, WorkDoneProgress,
13}; 13};
14use lsp_types::{ProgressParams, ProgressParamsValue}; 14use lsp_types::{ProgressParams, ProgressParamsValue};
15use ra_project_model::ProjectManifest; 15use project_model::ProjectManifest;
16use rust_analyzer::{ 16use rust_analyzer::{
17 config::{ClientCapsConfig, Config, FilesConfig, FilesWatcher, LinkedProject}, 17 config::{ClientCapsConfig, Config, FilesConfig, FilesWatcher, LinkedProject},
18 main_loop, 18 main_loop,
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index 2667d9af4..190746e09 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -601,6 +601,9 @@ pub trait AstNodeEdit: AstNode + Clone + Sized {
601 } 601 }
602 rewriter.rewrite_ast(self) 602 rewriter.rewrite_ast(self)
603 } 603 }
604 fn indent_level(&self) -> IndentLevel {
605 IndentLevel::from_node(self.syntax())
606 }
604 #[must_use] 607 #[must_use]
605 fn indent(&self, level: IndentLevel) -> Self { 608 fn indent(&self, level: IndentLevel) -> Self {
606 Self::cast(level.increase_indent(self.syntax().clone())).unwrap() 609 Self::cast(level.increase_indent(self.syntax().clone())).unwrap()
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index 3009faed7..d20c085aa 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -134,6 +134,9 @@ pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr {
134 let token = token(op); 134 let token = token(op);
135 expr_from_text(&format!("{}{}", token, expr)) 135 expr_from_text(&format!("{}{}", token, expr))
136} 136}
137pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
138 expr_from_text(&format!("{}{}", f, arg_list))
139}
137fn expr_from_text(text: &str) -> ast::Expr { 140fn expr_from_text(text: &str) -> ast::Expr {
138 ast_from_text(&format!("const C: () = {};", text)) 141 ast_from_text(&format!("const C: () = {};", text))
139} 142}
@@ -151,6 +154,10 @@ pub fn condition(expr: ast::Expr, pattern: Option<ast::Pat>) -> ast::Condition {
151 } 154 }
152} 155}
153 156
157pub fn arg_list(args: impl IntoIterator<Item = ast::Expr>) -> ast::ArgList {
158 ast_from_text(&format!("fn main() {{ ()({}) }}", args.into_iter().format(", ")))
159}
160
154pub fn ident_pat(name: ast::Name) -> ast::IdentPat { 161pub fn ident_pat(name: ast::Name) -> ast::IdentPat {
155 return from_text(name.text()); 162 return from_text(name.text());
156 163