diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/handlers/early_return.rs | 2 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/replace_if_let_with_match.rs | 37 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/unwrap_block.rs | 164 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 12 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items.rs | 7 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/paths.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 8 | ||||
-rw-r--r-- | crates/ra_project_model/src/json_project.rs | 42 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/edit.rs | 13 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/err/0024_many_type_parens.rast | 74 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_fn.rast | 40 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_fn.rs | 3 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0164_type_path_in_pattern.rast | 38 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0164_type_path_in_pattern.rs | 1 |
16 files changed, 267 insertions, 184 deletions
diff --git a/crates/ra_assists/src/handlers/early_return.rs b/crates/ra_assists/src/handlers/early_return.rs index 4cc75a7ce..dfade7432 100644 --- a/crates/ra_assists/src/handlers/early_return.rs +++ b/crates/ra_assists/src/handlers/early_return.rs | |||
@@ -154,7 +154,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext) | |||
154 | parent_block: &ast::BlockExpr, | 154 | parent_block: &ast::BlockExpr, |
155 | if_expr: &ast::IfExpr, | 155 | if_expr: &ast::IfExpr, |
156 | ) -> SyntaxNode { | 156 | ) -> SyntaxNode { |
157 | let then_block_items = then_block.dedent(IndentLevel::from(1)); | 157 | let then_block_items = then_block.dedent(IndentLevel(1)); |
158 | let end_of_then = then_block_items.syntax().last_child_or_token().unwrap(); | 158 | let end_of_then = then_block_items.syntax().last_child_or_token().unwrap(); |
159 | let end_of_then = | 159 | let end_of_then = |
160 | if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) { | 160 | if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) { |
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 e016f51c3..dfcd787de 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 | |||
@@ -51,6 +51,7 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext) | |||
51 | acc.add(AssistId("replace_if_let_with_match"), "Replace with match", target, move |edit| { | 51 | acc.add(AssistId("replace_if_let_with_match"), "Replace with match", target, move |edit| { |
52 | let match_expr = { | 52 | let match_expr = { |
53 | let then_arm = { | 53 | let then_arm = { |
54 | let then_block = then_block.reset_indent().indent(IndentLevel(1)); | ||
54 | let then_expr = unwrap_trivial_block(then_block); | 55 | let then_expr = unwrap_trivial_block(then_block); |
55 | make::match_arm(vec![pat.clone()], then_expr) | 56 | make::match_arm(vec![pat.clone()], then_expr) |
56 | }; | 57 | }; |
@@ -64,8 +65,8 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext) | |||
64 | let else_expr = unwrap_trivial_block(else_block); | 65 | let else_expr = unwrap_trivial_block(else_block); |
65 | make::match_arm(vec![pattern], else_expr) | 66 | make::match_arm(vec![pattern], else_expr) |
66 | }; | 67 | }; |
67 | make::expr_match(expr, make::match_arm_list(vec![then_arm, else_arm])) | 68 | let match_expr = make::expr_match(expr, make::match_arm_list(vec![then_arm, else_arm])); |
68 | .indent(IndentLevel::from_node(if_expr.syntax())) | 69 | match_expr.indent(IndentLevel::from_node(if_expr.syntax())) |
69 | }; | 70 | }; |
70 | 71 | ||
71 | edit.replace_ast::<ast::Expr>(if_expr.into(), match_expr); | 72 | edit.replace_ast::<ast::Expr>(if_expr.into(), match_expr); |
@@ -213,4 +214,36 @@ fn foo(x: Result<i32, ()>) { | |||
213 | "#, | 214 | "#, |
214 | ); | 215 | ); |
215 | } | 216 | } |
217 | |||
218 | #[test] | ||
219 | fn nested_indent() { | ||
220 | check_assist( | ||
221 | replace_if_let_with_match, | ||
222 | r#" | ||
223 | fn main() { | ||
224 | if true { | ||
225 | <|>if let Ok(rel_path) = path.strip_prefix(root_path) { | ||
226 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | ||
227 | Some((*id, rel_path)) | ||
228 | } else { | ||
229 | None | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | "#, | ||
234 | r#" | ||
235 | fn main() { | ||
236 | if true { | ||
237 | match path.strip_prefix(root_path) { | ||
238 | Ok(rel_path) => { | ||
239 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | ||
240 | Some((*id, rel_path)) | ||
241 | } | ||
242 | _ => None, | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | "#, | ||
247 | ) | ||
248 | } | ||
216 | } | 249 | } |
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs index 8440c7d0f..1fb13f481 100644 --- a/crates/ra_assists/src/handlers/unwrap_block.rs +++ b/crates/ra_assists/src/handlers/unwrap_block.rs | |||
@@ -1,7 +1,10 @@ | |||
1 | use ra_fmt::unwrap_trivial_block; | 1 | use ra_fmt::unwrap_trivial_block; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | ast::{self, ElseBranch, Expr, LoopBodyOwner}, | 3 | ast::{ |
4 | match_ast, AstNode, TextRange, T, | 4 | self, |
5 | edit::{AstNodeEdit, IndentLevel}, | ||
6 | }, | ||
7 | AstNode, TextRange, T, | ||
5 | }; | 8 | }; |
6 | 9 | ||
7 | use crate::{AssistContext, AssistId, Assists}; | 10 | use crate::{AssistContext, AssistId, Assists}; |
@@ -24,94 +27,73 @@ use crate::{AssistContext, AssistId, Assists}; | |||
24 | // } | 27 | // } |
25 | // ``` | 28 | // ``` |
26 | pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 29 | pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
27 | let l_curly_token = ctx.find_token_at_offset(T!['{'])?; | ||
28 | let block = ast::BlockExpr::cast(l_curly_token.parent())?; | ||
29 | let parent = block.syntax().parent()?; | ||
30 | let assist_id = AssistId("unwrap_block"); | 30 | let assist_id = AssistId("unwrap_block"); |
31 | let assist_label = "Unwrap block"; | 31 | let assist_label = "Unwrap block"; |
32 | 32 | ||
33 | let (expr, expr_to_unwrap) = match_ast! { | 33 | let l_curly_token = ctx.find_token_at_offset(T!['{'])?; |
34 | match parent { | 34 | let mut block = ast::BlockExpr::cast(l_curly_token.parent())?; |
35 | ast::ForExpr(for_expr) => { | 35 | let mut parent = block.syntax().parent()?; |
36 | let block_expr = for_expr.loop_body()?; | 36 | if ast::MatchArm::can_cast(parent.kind()) { |
37 | let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?; | 37 | parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))? |
38 | (ast::Expr::ForExpr(for_expr), expr_to_unwrap) | 38 | } |
39 | }, | ||
40 | ast::WhileExpr(while_expr) => { | ||
41 | let block_expr = while_expr.loop_body()?; | ||
42 | let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?; | ||
43 | (ast::Expr::WhileExpr(while_expr), expr_to_unwrap) | ||
44 | }, | ||
45 | ast::LoopExpr(loop_expr) => { | ||
46 | let block_expr = loop_expr.loop_body()?; | ||
47 | let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?; | ||
48 | (ast::Expr::LoopExpr(loop_expr), expr_to_unwrap) | ||
49 | }, | ||
50 | ast::IfExpr(if_expr) => { | ||
51 | let mut resp = None; | ||
52 | |||
53 | let then_branch = if_expr.then_branch()?; | ||
54 | if then_branch.l_curly_token()?.text_range().contains_range(ctx.frange.range) { | ||
55 | if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) { | ||
56 | // For `else if` blocks | ||
57 | let ancestor_then_branch = ancestor.then_branch()?; | ||
58 | let l_curly_token = then_branch.l_curly_token()?; | ||
59 | |||
60 | let target = then_branch.syntax().text_range(); | ||
61 | return acc.add(assist_id, assist_label, target, |edit| { | ||
62 | let range_to_del_else_if = TextRange::new(ancestor_then_branch.syntax().text_range().end(), l_curly_token.text_range().start()); | ||
63 | let range_to_del_rest = TextRange::new(then_branch.syntax().text_range().end(), if_expr.syntax().text_range().end()); | ||
64 | |||
65 | edit.delete(range_to_del_rest); | ||
66 | edit.delete(range_to_del_else_if); | ||
67 | edit.replace(target, update_expr_string(then_branch.to_string(), &[' ', '{'])); | ||
68 | }); | ||
69 | } else { | ||
70 | resp = Some((ast::Expr::IfExpr(if_expr.clone()), Expr::BlockExpr(then_branch))); | ||
71 | } | ||
72 | } else if let Some(else_branch) = if_expr.else_branch() { | ||
73 | match else_branch { | ||
74 | ElseBranch::Block(else_block) => { | ||
75 | let l_curly_token = else_block.l_curly_token()?; | ||
76 | if l_curly_token.text_range().contains_range(ctx.frange.range) { | ||
77 | let target = else_block.syntax().text_range(); | ||
78 | return acc.add(assist_id, assist_label, target, |edit| { | ||
79 | let range_to_del = TextRange::new(then_branch.syntax().text_range().end(), l_curly_token.text_range().start()); | ||
80 | |||
81 | edit.delete(range_to_del); | ||
82 | edit.replace(target, update_expr_string(else_block.to_string(), &[' ', '{'])); | ||
83 | }); | ||
84 | } | ||
85 | }, | ||
86 | ElseBranch::IfExpr(_) => {}, | ||
87 | } | ||
88 | } | ||
89 | 39 | ||
90 | resp? | 40 | let parent = ast::Expr::cast(parent)?; |
91 | }, | 41 | |
92 | _ => return None, | 42 | match parent.clone() { |
43 | ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (), | ||
44 | ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)), | ||
45 | ast::Expr::IfExpr(if_expr) => { | ||
46 | let then_branch = if_expr.then_branch()?; | ||
47 | if then_branch == block { | ||
48 | if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) { | ||
49 | // For `else if` blocks | ||
50 | let ancestor_then_branch = ancestor.then_branch()?; | ||
51 | |||
52 | let target = then_branch.syntax().text_range(); | ||
53 | return acc.add(assist_id, assist_label, target, |edit| { | ||
54 | let range_to_del_else_if = TextRange::new( | ||
55 | ancestor_then_branch.syntax().text_range().end(), | ||
56 | l_curly_token.text_range().start(), | ||
57 | ); | ||
58 | let range_to_del_rest = TextRange::new( | ||
59 | then_branch.syntax().text_range().end(), | ||
60 | if_expr.syntax().text_range().end(), | ||
61 | ); | ||
62 | |||
63 | edit.delete(range_to_del_rest); | ||
64 | edit.delete(range_to_del_else_if); | ||
65 | edit.replace( | ||
66 | target, | ||
67 | update_expr_string(then_branch.to_string(), &[' ', '{']), | ||
68 | ); | ||
69 | }); | ||
70 | } | ||
71 | } else { | ||
72 | let target = block.syntax().text_range(); | ||
73 | return acc.add(assist_id, assist_label, target, |edit| { | ||
74 | let range_to_del = TextRange::new( | ||
75 | then_branch.syntax().text_range().end(), | ||
76 | l_curly_token.text_range().start(), | ||
77 | ); | ||
78 | |||
79 | edit.delete(range_to_del); | ||
80 | edit.replace(target, update_expr_string(block.to_string(), &[' ', '{'])); | ||
81 | }); | ||
82 | } | ||
93 | } | 83 | } |
84 | _ => return None, | ||
94 | }; | 85 | }; |
95 | 86 | ||
96 | let target = expr_to_unwrap.syntax().text_range(); | 87 | let unwrapped = unwrap_trivial_block(block); |
97 | acc.add(assist_id, assist_label, target, |edit| { | 88 | let target = unwrapped.syntax().text_range(); |
98 | edit.replace( | 89 | acc.add(assist_id, assist_label, target, |builder| { |
99 | expr.syntax().text_range(), | 90 | builder.replace( |
100 | update_expr_string(expr_to_unwrap.to_string(), &[' ', '{', '\n']), | 91 | parent.syntax().text_range(), |
92 | update_expr_string(unwrapped.to_string(), &[' ', '{', '\n']), | ||
101 | ); | 93 | ); |
102 | }) | 94 | }) |
103 | } | 95 | } |
104 | 96 | ||
105 | fn extract_expr(cursor_range: TextRange, block: ast::BlockExpr) -> Option<ast::Expr> { | ||
106 | let cursor_in_range = block.l_curly_token()?.text_range().contains_range(cursor_range); | ||
107 | |||
108 | if cursor_in_range { | ||
109 | Some(unwrap_trivial_block(block)) | ||
110 | } else { | ||
111 | None | ||
112 | } | ||
113 | } | ||
114 | |||
115 | fn update_expr_string(expr_str: String, trim_start_pat: &[char]) -> String { | 97 | fn update_expr_string(expr_str: String, trim_start_pat: &[char]) -> String { |
116 | let expr_string = expr_str.trim_start_matches(trim_start_pat); | 98 | let expr_string = expr_str.trim_start_matches(trim_start_pat); |
117 | let mut expr_string_lines: Vec<&str> = expr_string.lines().collect(); | 99 | let mut expr_string_lines: Vec<&str> = expr_string.lines().collect(); |
@@ -490,6 +472,30 @@ mod tests { | |||
490 | } | 472 | } |
491 | 473 | ||
492 | #[test] | 474 | #[test] |
475 | fn unwrap_match_arm() { | ||
476 | check_assist( | ||
477 | unwrap_block, | ||
478 | r#" | ||
479 | fn main() { | ||
480 | match rel_path { | ||
481 | Ok(rel_path) => {<|> | ||
482 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | ||
483 | Some((*id, rel_path)) | ||
484 | } | ||
485 | Err(_) => None, | ||
486 | } | ||
487 | } | ||
488 | "#, | ||
489 | r#" | ||
490 | fn main() { | ||
491 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | ||
492 | Some((*id, rel_path)) | ||
493 | } | ||
494 | "#, | ||
495 | ); | ||
496 | } | ||
497 | |||
498 | #[test] | ||
493 | fn simple_if_in_while_bad_cursor_position() { | 499 | fn simple_if_in_while_bad_cursor_position() { |
494 | check_assist_not_applicable( | 500 | check_assist_not_applicable( |
495 | unwrap_block, | 501 | unwrap_block, |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 4d2d3b48a..a8d6466ea 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -337,15 +337,11 @@ impl Env { | |||
337 | } | 337 | } |
338 | 338 | ||
339 | impl ExternSource { | 339 | impl ExternSource { |
340 | pub fn extern_path(&self, path: impl AsRef<Path>) -> Option<(ExternSourceId, RelativePathBuf)> { | 340 | pub fn extern_path(&self, path: &Path) -> Option<(ExternSourceId, RelativePathBuf)> { |
341 | let path = path.as_ref(); | ||
342 | self.extern_paths.iter().find_map(|(root_path, id)| { | 341 | self.extern_paths.iter().find_map(|(root_path, id)| { |
343 | if let Ok(rel_path) = path.strip_prefix(root_path) { | 342 | let rel_path = path.strip_prefix(root_path).ok()?; |
344 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | 343 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; |
345 | Some((*id, rel_path)) | 344 | Some((*id, rel_path)) |
346 | } else { | ||
347 | None | ||
348 | } | ||
349 | }) | 345 | }) |
350 | } | 346 | } |
351 | 347 | ||
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 91e0ee619..2ab314884 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -158,7 +158,7 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> { | |||
158 | if std::path::Path::new(path).is_absolute() { | 158 | if std::path::Path::new(path).is_absolute() { |
159 | let krate = *self.relevant_crates(anchor).get(0)?; | 159 | let krate = *self.relevant_crates(anchor).get(0)?; |
160 | let (extern_source_id, relative_file) = | 160 | let (extern_source_id, relative_file) = |
161 | self.0.crate_graph()[krate].extern_source.extern_path(path)?; | 161 | self.0.crate_graph()[krate].extern_source.extern_path(path.as_ref())?; |
162 | 162 | ||
163 | let source_root = self.0.source_root(SourceRootId(extern_source_id.0)); | 163 | let source_root = self.0.source_root(SourceRootId(extern_source_id.0)); |
164 | source_root.file_by_relative_path(&relative_file) | 164 | source_root.file_by_relative_path(&relative_file) |
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index 9c14b954a..97642bc24 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs | |||
@@ -121,7 +121,12 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul | |||
121 | T![unsafe] => { | 121 | T![unsafe] => { |
122 | // test default_unsafe_impl | 122 | // test default_unsafe_impl |
123 | // default unsafe impl Foo {} | 123 | // default unsafe impl Foo {} |
124 | if p.nth(2) == T![impl] { | 124 | |
125 | // test default_unsafe_fn | ||
126 | // impl T for Foo { | ||
127 | // default unsafe fn foo() {} | ||
128 | // } | ||
129 | if p.nth(2) == T![impl] || p.nth(2) == T![fn] { | ||
125 | p.bump_remap(T![default]); | 130 | p.bump_remap(T![default]); |
126 | p.bump(T![unsafe]); | 131 | p.bump(T![unsafe]); |
127 | has_mods = true; | 132 | has_mods = true; |
diff --git a/crates/ra_parser/src/grammar/paths.rs b/crates/ra_parser/src/grammar/paths.rs index 332acc1a0..428aa711e 100644 --- a/crates/ra_parser/src/grammar/paths.rs +++ b/crates/ra_parser/src/grammar/paths.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use super::*; | 3 | use super::*; |
4 | 4 | ||
5 | pub(super) const PATH_FIRST: TokenSet = | 5 | pub(super) const PATH_FIRST: TokenSet = |
6 | token_set![IDENT, SELF_KW, SUPER_KW, CRATE_KW, COLON, L_ANGLE]; | 6 | token_set![IDENT, T![self], T![super], T![crate], T![:], T![<]]; |
7 | 7 | ||
8 | pub(super) fn is_path_start(p: &Parser) -> bool { | 8 | pub(super) fn is_path_start(p: &Parser) -> bool { |
9 | is_use_path_start(p) || p.at(T![<]) | 9 | is_use_path_start(p) || p.at(T![<]) |
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs index 68fb2fc73..427c0eb49 100644 --- a/crates/ra_parser/src/grammar/patterns.rs +++ b/crates/ra_parser/src/grammar/patterns.rs | |||
@@ -4,7 +4,7 @@ use super::*; | |||
4 | 4 | ||
5 | pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST | 5 | pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST |
6 | .union(paths::PATH_FIRST) | 6 | .union(paths::PATH_FIRST) |
7 | .union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS, DOT]); | 7 | .union(token_set![T![box], T![ref], T![mut], T!['('], T!['['], T![&], T![_], T![-], T![.]]); |
8 | 8 | ||
9 | pub(crate) fn pattern(p: &mut Parser) { | 9 | pub(crate) fn pattern(p: &mut Parser) { |
10 | pattern_r(p, PAT_RECOVERY_SET); | 10 | pattern_r(p, PAT_RECOVERY_SET); |
@@ -88,7 +88,9 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { | |||
88 | _ => bind_pat(p, true), | 88 | _ => bind_pat(p, true), |
89 | }, | 89 | }, |
90 | 90 | ||
91 | _ if paths::is_use_path_start(p) => path_or_macro_pat(p), | 91 | // test type_path_in_pattern |
92 | // fn main() { let <_>::Foo = (); } | ||
93 | _ if paths::is_path_start(p) => path_or_macro_pat(p), | ||
92 | _ if is_literal_pat_start(p) => literal_pat(p), | 94 | _ if is_literal_pat_start(p) => literal_pat(p), |
93 | 95 | ||
94 | T![.] if p.at(T![..]) => dot_dot_pat(p), | 96 | T![.] if p.at(T![..]) => dot_dot_pat(p), |
@@ -138,7 +140,7 @@ fn literal_pat(p: &mut Parser) -> CompletedMarker { | |||
138 | // let Bar(..) = (); | 140 | // let Bar(..) = (); |
139 | // } | 141 | // } |
140 | fn path_or_macro_pat(p: &mut Parser) -> CompletedMarker { | 142 | fn path_or_macro_pat(p: &mut Parser) -> CompletedMarker { |
141 | assert!(paths::is_use_path_start(p)); | 143 | assert!(paths::is_path_start(p)); |
142 | let m = p.start(); | 144 | let m = p.start(); |
143 | paths::expr_path(p); | 145 | paths::expr_path(p); |
144 | let kind = match p.current() { | 146 | let kind = match p.current() { |
diff --git a/crates/ra_project_model/src/json_project.rs b/crates/ra_project_model/src/json_project.rs index 09c06fef9..ee2de4c25 100644 --- a/crates/ra_project_model/src/json_project.rs +++ b/crates/ra_project_model/src/json_project.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::path::PathBuf; | 3 | use std::path::PathBuf; |
4 | 4 | ||
5 | use rustc_hash::{FxHashMap, FxHashSet}; | 5 | use rustc_hash::FxHashSet; |
6 | use serde::Deserialize; | 6 | use serde::Deserialize; |
7 | 7 | ||
8 | /// Roots and crates that compose this Rust project. | 8 | /// Roots and crates that compose this Rust project. |
@@ -28,16 +28,9 @@ pub struct Crate { | |||
28 | pub(crate) edition: Edition, | 28 | pub(crate) edition: Edition, |
29 | pub(crate) deps: Vec<Dep>, | 29 | pub(crate) deps: Vec<Dep>, |
30 | 30 | ||
31 | // This is the preferred method of providing cfg options. | ||
32 | #[serde(default)] | 31 | #[serde(default)] |
33 | pub(crate) cfg: FxHashSet<String>, | 32 | pub(crate) cfg: FxHashSet<String>, |
34 | 33 | ||
35 | // These two are here for transition only. | ||
36 | #[serde(default)] | ||
37 | pub(crate) atom_cfgs: FxHashSet<String>, | ||
38 | #[serde(default)] | ||
39 | pub(crate) key_value_cfgs: FxHashMap<String, String>, | ||
40 | |||
41 | pub(crate) out_dir: Option<PathBuf>, | 34 | pub(crate) out_dir: Option<PathBuf>, |
42 | pub(crate) proc_macro_dylib_path: Option<PathBuf>, | 35 | pub(crate) proc_macro_dylib_path: Option<PathBuf>, |
43 | } | 36 | } |
@@ -99,37 +92,4 @@ mod tests { | |||
99 | assert!(krate.cfg.contains(&"feature=feature_2".to_string())); | 92 | assert!(krate.cfg.contains(&"feature=feature_2".to_string())); |
100 | assert!(krate.cfg.contains(&"other=value".to_string())); | 93 | assert!(krate.cfg.contains(&"other=value".to_string())); |
101 | } | 94 | } |
102 | |||
103 | #[test] | ||
104 | fn test_crate_deserialization_old_json() { | ||
105 | let raw_json = json!( { | ||
106 | "crate_id": 2, | ||
107 | "root_module": "this/is/a/file/path.rs", | ||
108 | "deps": [ | ||
109 | { | ||
110 | "crate": 1, | ||
111 | "name": "some_dep_crate" | ||
112 | }, | ||
113 | ], | ||
114 | "edition": "2015", | ||
115 | "atom_cfgs": [ | ||
116 | "atom_1", | ||
117 | "atom_2", | ||
118 | ], | ||
119 | "key_value_cfgs": { | ||
120 | "feature": "feature_1", | ||
121 | "feature": "feature_2", | ||
122 | "other": "value", | ||
123 | }, | ||
124 | }); | ||
125 | |||
126 | let krate: Crate = serde_json::from_value(raw_json).unwrap(); | ||
127 | |||
128 | assert!(krate.atom_cfgs.contains(&"atom_1".to_string())); | ||
129 | assert!(krate.atom_cfgs.contains(&"atom_2".to_string())); | ||
130 | assert!(krate.key_value_cfgs.contains_key(&"feature".to_string())); | ||
131 | assert_eq!(krate.key_value_cfgs.get("feature"), Some(&"feature_2".to_string())); | ||
132 | assert!(krate.key_value_cfgs.contains_key(&"other".to_string())); | ||
133 | assert_eq!(krate.key_value_cfgs.get("other"), Some(&"value".to_string())); | ||
134 | } | ||
135 | } | 95 | } |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 6604f5092..c1f7e3ac5 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -280,12 +280,6 @@ impl ProjectWorkspace { | |||
280 | } | 280 | } |
281 | } | 281 | } |
282 | } | 282 | } |
283 | for name in &krate.atom_cfgs { | ||
284 | opts.insert_atom(name.into()); | ||
285 | } | ||
286 | for (key, value) in &krate.key_value_cfgs { | ||
287 | opts.insert_key_value(key.into(), value.into()); | ||
288 | } | ||
289 | opts | 283 | opts |
290 | }; | 284 | }; |
291 | 285 | ||
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs index 29eb3fcb9..2ef173a03 100644 --- a/crates/ra_syntax/src/ast/edit.rs +++ b/crates/ra_syntax/src/ast/edit.rs | |||
@@ -579,12 +579,17 @@ pub trait AstNodeEdit: AstNode + Clone + Sized { | |||
579 | rewriter.rewrite_ast(self) | 579 | rewriter.rewrite_ast(self) |
580 | } | 580 | } |
581 | #[must_use] | 581 | #[must_use] |
582 | fn indent(&self, indent: IndentLevel) -> Self { | 582 | fn indent(&self, level: IndentLevel) -> Self { |
583 | Self::cast(indent.increase_indent(self.syntax().clone())).unwrap() | 583 | Self::cast(level.increase_indent(self.syntax().clone())).unwrap() |
584 | } | 584 | } |
585 | #[must_use] | 585 | #[must_use] |
586 | fn dedent(&self, indent: IndentLevel) -> Self { | 586 | fn dedent(&self, level: IndentLevel) -> Self { |
587 | Self::cast(indent.decrease_indent(self.syntax().clone())).unwrap() | 587 | Self::cast(level.decrease_indent(self.syntax().clone())).unwrap() |
588 | } | ||
589 | #[must_use] | ||
590 | fn reset_indent(&self) -> Self { | ||
591 | let level = IndentLevel::from_node(self.syntax()); | ||
592 | self.dedent(level) | ||
588 | } | 593 | } |
589 | } | 594 | } |
590 | 595 | ||
diff --git a/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.rast b/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.rast index 7c957fdde..48610a5eb 100644 --- a/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.rast +++ b/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.rast | |||
@@ -180,44 +180,45 @@ SOURCE_FILE@0..240 | |||
180 | EXPR_STMT@150..180 | 180 | EXPR_STMT@150..180 |
181 | TUPLE_EXPR@150..180 | 181 | TUPLE_EXPR@150..180 |
182 | L_PAREN@150..151 "(" | 182 | L_PAREN@150..151 "(" |
183 | BIN_EXPR@151..180 | 183 | FOR_EXPR@151..180 |
184 | BIN_EXPR@151..178 | 184 | FOR_KW@151..154 "for" |
185 | BIN_EXPR@151..169 | 185 | PATH_PAT@154..158 |
186 | BIN_EXPR@151..167 | 186 | PATH@154..158 |
187 | BIN_EXPR@151..164 | 187 | PATH_SEGMENT@154..158 |
188 | FOR_EXPR@151..157 | 188 | L_ANGLE@154..155 "<" |
189 | FOR_KW@151..154 "for" | 189 | ERROR@155..157 |
190 | ERROR@154..155 | 190 | LIFETIME@155..157 "\'a" |
191 | L_ANGLE@154..155 "<" | 191 | R_ANGLE@157..158 ">" |
192 | ERROR@155..157 | 192 | WHITESPACE@158..159 " " |
193 | LIFETIME@155..157 "\'a" | 193 | BIN_EXPR@159..180 |
194 | R_ANGLE@157..158 ">" | 194 | BIN_EXPR@159..178 |
195 | WHITESPACE@158..159 " " | 195 | BIN_EXPR@159..169 |
196 | BIN_EXPR@159..167 | ||
196 | PATH_EXPR@159..164 | 197 | PATH_EXPR@159..164 |
197 | PATH@159..164 | 198 | PATH@159..164 |
198 | PATH_SEGMENT@159..164 | 199 | PATH_SEGMENT@159..164 |
199 | NAME_REF@159..164 | 200 | NAME_REF@159..164 |
200 | IDENT@159..164 "Trait" | 201 | IDENT@159..164 "Trait" |
201 | L_ANGLE@164..165 "<" | 202 | L_ANGLE@164..165 "<" |
202 | ERROR@165..167 | 203 | ERROR@165..167 |
203 | LIFETIME@165..167 "\'a" | 204 | LIFETIME@165..167 "\'a" |
204 | R_ANGLE@167..168 ">" | 205 | R_ANGLE@167..168 ">" |
205 | ERROR@168..169 | 206 | ERROR@168..169 |
206 | R_PAREN@168..169 ")" | 207 | R_PAREN@168..169 ")" |
207 | WHITESPACE@169..170 " " | 208 | WHITESPACE@169..170 " " |
208 | PLUS@170..171 "+" | 209 | PLUS@170..171 "+" |
209 | WHITESPACE@171..172 " " | 210 | WHITESPACE@171..172 " " |
210 | PAREN_EXPR@172..178 | 211 | PAREN_EXPR@172..178 |
211 | L_PAREN@172..173 "(" | 212 | L_PAREN@172..173 "(" |
212 | PATH_EXPR@173..177 | 213 | PATH_EXPR@173..177 |
213 | PATH@173..177 | 214 | PATH@173..177 |
214 | PATH_SEGMENT@173..177 | 215 | PATH_SEGMENT@173..177 |
215 | NAME_REF@173..177 | 216 | NAME_REF@173..177 |
216 | IDENT@173..177 "Copy" | 217 | IDENT@173..177 "Copy" |
217 | R_PAREN@177..178 ")" | 218 | R_PAREN@177..178 ")" |
218 | R_ANGLE@178..179 ">" | 219 | R_ANGLE@178..179 ">" |
219 | ERROR@179..180 | 220 | ERROR@179..180 |
220 | SEMICOLON@179..180 ";" | 221 | SEMICOLON@179..180 ";" |
221 | WHITESPACE@180..185 "\n " | 222 | WHITESPACE@180..185 "\n " |
222 | LET_STMT@185..235 | 223 | LET_STMT@185..235 |
223 | LET_KW@185..188 "let" | 224 | LET_KW@185..188 "let" |
@@ -302,13 +303,12 @@ error 146..146: expected expression | |||
302 | error 147..147: expected SEMICOLON | 303 | error 147..147: expected SEMICOLON |
303 | error 148..148: expected expression | 304 | error 148..148: expected expression |
304 | error 149..149: expected SEMICOLON | 305 | error 149..149: expected SEMICOLON |
305 | error 154..154: expected pattern | 306 | error 155..155: expected type |
306 | error 155..155: expected IN_KW | 307 | error 158..158: expected IN_KW |
307 | error 155..155: expected expression | ||
308 | error 157..157: expected a block | ||
309 | error 165..165: expected expression | 308 | error 165..165: expected expression |
310 | error 168..168: expected expression | 309 | error 168..168: expected expression |
311 | error 179..179: expected expression | 310 | error 179..179: expected expression |
311 | error 180..180: expected a block | ||
312 | error 180..180: expected COMMA | 312 | error 180..180: expected COMMA |
313 | error 180..180: expected expression | 313 | error 180..180: expected expression |
314 | error 180..180: expected R_PAREN | 314 | error 180..180: expected R_PAREN |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_fn.rast b/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_fn.rast new file mode 100644 index 000000000..adb6159f4 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_fn.rast | |||
@@ -0,0 +1,40 @@ | |||
1 | SOURCE_FILE@0..50 | ||
2 | IMPL_DEF@0..49 | ||
3 | IMPL_KW@0..4 "impl" | ||
4 | WHITESPACE@4..5 " " | ||
5 | PATH_TYPE@5..6 | ||
6 | PATH@5..6 | ||
7 | PATH_SEGMENT@5..6 | ||
8 | NAME_REF@5..6 | ||
9 | IDENT@5..6 "T" | ||
10 | WHITESPACE@6..7 " " | ||
11 | FOR_KW@7..10 "for" | ||
12 | WHITESPACE@10..11 " " | ||
13 | PATH_TYPE@11..14 | ||
14 | PATH@11..14 | ||
15 | PATH_SEGMENT@11..14 | ||
16 | NAME_REF@11..14 | ||
17 | IDENT@11..14 "Foo" | ||
18 | WHITESPACE@14..15 " " | ||
19 | ITEM_LIST@15..49 | ||
20 | L_CURLY@15..16 "{" | ||
21 | WHITESPACE@16..21 "\n " | ||
22 | FN_DEF@21..47 | ||
23 | DEFAULT_KW@21..28 "default" | ||
24 | WHITESPACE@28..29 " " | ||
25 | UNSAFE_KW@29..35 "unsafe" | ||
26 | WHITESPACE@35..36 " " | ||
27 | FN_KW@36..38 "fn" | ||
28 | WHITESPACE@38..39 " " | ||
29 | NAME@39..42 | ||
30 | IDENT@39..42 "foo" | ||
31 | PARAM_LIST@42..44 | ||
32 | L_PAREN@42..43 "(" | ||
33 | R_PAREN@43..44 ")" | ||
34 | WHITESPACE@44..45 " " | ||
35 | BLOCK_EXPR@45..47 | ||
36 | L_CURLY@45..46 "{" | ||
37 | R_CURLY@46..47 "}" | ||
38 | WHITESPACE@47..48 "\n" | ||
39 | R_CURLY@48..49 "}" | ||
40 | WHITESPACE@49..50 "\n" | ||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_fn.rs b/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_fn.rs new file mode 100644 index 000000000..12926cd8a --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0163_default_unsafe_fn.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | impl T for Foo { | ||
2 | default unsafe fn foo() {} | ||
3 | } | ||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0164_type_path_in_pattern.rast b/crates/ra_syntax/test_data/parser/inline/ok/0164_type_path_in_pattern.rast new file mode 100644 index 000000000..868899275 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0164_type_path_in_pattern.rast | |||
@@ -0,0 +1,38 @@ | |||
1 | SOURCE_FILE@0..33 | ||
2 | FN_DEF@0..32 | ||
3 | FN_KW@0..2 "fn" | ||
4 | WHITESPACE@2..3 " " | ||
5 | NAME@3..7 | ||
6 | IDENT@3..7 "main" | ||
7 | PARAM_LIST@7..9 | ||
8 | L_PAREN@7..8 "(" | ||
9 | R_PAREN@8..9 ")" | ||
10 | WHITESPACE@9..10 " " | ||
11 | BLOCK_EXPR@10..32 | ||
12 | L_CURLY@10..11 "{" | ||
13 | WHITESPACE@11..12 " " | ||
14 | LET_STMT@12..30 | ||
15 | LET_KW@12..15 "let" | ||
16 | WHITESPACE@15..16 " " | ||
17 | PATH_PAT@16..24 | ||
18 | PATH@16..24 | ||
19 | PATH@16..19 | ||
20 | PATH_SEGMENT@16..19 | ||
21 | L_ANGLE@16..17 "<" | ||
22 | PLACEHOLDER_TYPE@17..18 | ||
23 | UNDERSCORE@17..18 "_" | ||
24 | R_ANGLE@18..19 ">" | ||
25 | COLON2@19..21 "::" | ||
26 | PATH_SEGMENT@21..24 | ||
27 | NAME_REF@21..24 | ||
28 | IDENT@21..24 "Foo" | ||
29 | WHITESPACE@24..25 " " | ||
30 | EQ@25..26 "=" | ||
31 | WHITESPACE@26..27 " " | ||
32 | TUPLE_EXPR@27..29 | ||
33 | L_PAREN@27..28 "(" | ||
34 | R_PAREN@28..29 ")" | ||
35 | SEMICOLON@29..30 ";" | ||
36 | WHITESPACE@30..31 " " | ||
37 | R_CURLY@31..32 "}" | ||
38 | WHITESPACE@32..33 "\n" | ||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0164_type_path_in_pattern.rs b/crates/ra_syntax/test_data/parser/inline/ok/0164_type_path_in_pattern.rs new file mode 100644 index 000000000..ebe26834d --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0164_type_path_in_pattern.rs | |||
@@ -0,0 +1 @@ | |||
fn main() { let <_>::Foo = (); } | |||