diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/doc_tests/generated.rs | 17 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/remove_mut.rs | 32 | ||||
-rw-r--r-- | crates/ra_assists/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/expr.rs | 18 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide/src/diagnostics.rs | 29 | ||||
-rw-r--r-- | crates/ra_ide/src/extend_selection.rs | 27 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 18 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs | 63 | ||||
-rw-r--r-- | crates/ra_ide/src/references.rs | 32 | ||||
-rw-r--r-- | crates/ra_ide/src/references/classify.rs | 42 | ||||
-rw-r--r-- | crates/ra_ide/src/references/search_scope.rs | 21 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 44 | ||||
-rw-r--r-- | crates/ra_ide_db/src/defs.rs | 134 | ||||
-rw-r--r-- | crates/ra_ide_db/src/imports_locator.rs | 8 | ||||
-rw-r--r-- | crates/ra_mbe/src/subtree_source.rs | 2 | ||||
-rw-r--r-- | crates/ra_prof/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_prof/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/traits.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/caps.rs | 1 |
21 files changed, 333 insertions, 201 deletions
diff --git a/crates/ra_assists/src/doc_tests/generated.rs b/crates/ra_assists/src/doc_tests/generated.rs index 4ab09b167..3f56dd508 100644 --- a/crates/ra_assists/src/doc_tests/generated.rs +++ b/crates/ra_assists/src/doc_tests/generated.rs | |||
@@ -549,6 +549,23 @@ fn main() { | |||
549 | } | 549 | } |
550 | 550 | ||
551 | #[test] | 551 | #[test] |
552 | fn doctest_remove_mut() { | ||
553 | check( | ||
554 | "remove_mut", | ||
555 | r#####" | ||
556 | impl Walrus { | ||
557 | fn feed(&mut<|> self, amount: u32) {} | ||
558 | } | ||
559 | "#####, | ||
560 | r#####" | ||
561 | impl Walrus { | ||
562 | fn feed(&self, amount: u32) {} | ||
563 | } | ||
564 | "#####, | ||
565 | ) | ||
566 | } | ||
567 | |||
568 | #[test] | ||
552 | fn doctest_replace_if_let_with_match() { | 569 | fn doctest_replace_if_let_with_match() { |
553 | check( | 570 | check( |
554 | "replace_if_let_with_match", | 571 | "replace_if_let_with_match", |
diff --git a/crates/ra_assists/src/handlers/remove_mut.rs b/crates/ra_assists/src/handlers/remove_mut.rs new file mode 100644 index 000000000..6884830eb --- /dev/null +++ b/crates/ra_assists/src/handlers/remove_mut.rs | |||
@@ -0,0 +1,32 @@ | |||
1 | use ra_syntax::{SyntaxKind, TextRange, T}; | ||
2 | |||
3 | use crate::{Assist, AssistCtx, AssistId}; | ||
4 | |||
5 | // Assist: remove_mut | ||
6 | // | ||
7 | // Removes the `mut` keyword. | ||
8 | // | ||
9 | // ``` | ||
10 | // impl Walrus { | ||
11 | // fn feed(&mut<|> self, amount: u32) {} | ||
12 | // } | ||
13 | // ``` | ||
14 | // -> | ||
15 | // ``` | ||
16 | // impl Walrus { | ||
17 | // fn feed(&self, amount: u32) {} | ||
18 | // } | ||
19 | // ``` | ||
20 | pub(crate) fn remove_mut(ctx: AssistCtx) -> Option<Assist> { | ||
21 | let mut_token = ctx.find_token_at_offset(T![mut])?; | ||
22 | let delete_from = mut_token.text_range().start(); | ||
23 | let delete_to = match mut_token.next_token() { | ||
24 | Some(it) if it.kind() == SyntaxKind::WHITESPACE => it.text_range().end(), | ||
25 | _ => mut_token.text_range().end(), | ||
26 | }; | ||
27 | |||
28 | ctx.add_assist(AssistId("remove_mut"), "Remove `mut` keyword", |edit| { | ||
29 | edit.set_cursor(delete_from); | ||
30 | edit.delete(TextRange::from_to(delete_from, delete_to)); | ||
31 | }) | ||
32 | } | ||
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index a0e7fe17e..d7998b0d1 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -38,7 +38,7 @@ pub struct GroupLabel(pub String); | |||
38 | impl AssistLabel { | 38 | impl AssistLabel { |
39 | pub(crate) fn new(label: String, id: AssistId) -> AssistLabel { | 39 | pub(crate) fn new(label: String, id: AssistId) -> AssistLabel { |
40 | // FIXME: make fields private, so that this invariant can't be broken | 40 | // FIXME: make fields private, so that this invariant can't be broken |
41 | assert!(label.chars().next().unwrap().is_uppercase()); | 41 | assert!(label.starts_with(|c: char| c.is_uppercase())); |
42 | AssistLabel { label, id } | 42 | AssistLabel { label, id } |
43 | } | 43 | } |
44 | } | 44 | } |
@@ -108,6 +108,7 @@ mod handlers { | |||
108 | mod introduce_variable; | 108 | mod introduce_variable; |
109 | mod inline_local_variable; | 109 | mod inline_local_variable; |
110 | mod raw_string; | 110 | mod raw_string; |
111 | mod remove_mut; | ||
111 | mod replace_if_let_with_match; | 112 | mod replace_if_let_with_match; |
112 | mod split_import; | 113 | mod split_import; |
113 | mod remove_dbg; | 114 | mod remove_dbg; |
@@ -147,6 +148,7 @@ mod handlers { | |||
147 | raw_string::make_raw_string, | 148 | raw_string::make_raw_string, |
148 | raw_string::make_usual_string, | 149 | raw_string::make_usual_string, |
149 | raw_string::remove_hash, | 150 | raw_string::remove_hash, |
151 | remove_mut::remove_mut, | ||
150 | early_return::convert_to_guarded_return, | 152 | early_return::convert_to_guarded_return, |
151 | auto_import::auto_import, | 153 | auto_import::auto_import, |
152 | ] | 154 | ] |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 1bdcda069..efc3502d0 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -30,6 +30,7 @@ use ra_syntax::{ | |||
30 | ast::{self, AttrsOwner}, | 30 | ast::{self, AttrsOwner}, |
31 | AstNode, | 31 | AstNode, |
32 | }; | 32 | }; |
33 | use rustc_hash::FxHashSet; | ||
33 | 34 | ||
34 | use crate::{ | 35 | use crate::{ |
35 | db::{DefDatabase, HirDatabase}, | 36 | db::{DefDatabase, HirDatabase}, |
@@ -123,10 +124,25 @@ impl_froms!( | |||
123 | BuiltinType | 124 | BuiltinType |
124 | ); | 125 | ); |
125 | 126 | ||
127 | impl ModuleDef { | ||
128 | pub fn module(self, db: &impl HirDatabase) -> Option<Module> { | ||
129 | match self { | ||
130 | ModuleDef::Module(it) => it.parent(db), | ||
131 | ModuleDef::Function(it) => Some(it.module(db)), | ||
132 | ModuleDef::Adt(it) => Some(it.module(db)), | ||
133 | ModuleDef::EnumVariant(it) => Some(it.module(db)), | ||
134 | ModuleDef::Const(it) => Some(it.module(db)), | ||
135 | ModuleDef::Static(it) => Some(it.module(db)), | ||
136 | ModuleDef::Trait(it) => Some(it.module(db)), | ||
137 | ModuleDef::TypeAlias(it) => Some(it.module(db)), | ||
138 | ModuleDef::BuiltinType(_) => None, | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
126 | pub use hir_def::{ | 143 | pub use hir_def::{ |
127 | attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId, AssocItemLoc, | 144 | attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId, AssocItemLoc, |
128 | }; | 145 | }; |
129 | use rustc_hash::FxHashSet; | ||
130 | 146 | ||
131 | impl Module { | 147 | impl Module { |
132 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 148 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
@@ -649,6 +665,17 @@ pub struct MacroDef { | |||
649 | pub(crate) id: MacroDefId, | 665 | pub(crate) id: MacroDefId, |
650 | } | 666 | } |
651 | 667 | ||
668 | impl MacroDef { | ||
669 | /// FIXME: right now, this just returns the root module of the crate that | ||
670 | /// defines this macro. The reasons for this is that macros are expanded | ||
671 | /// early, in `ra_hir_expand`, where modules simply do not exist yet. | ||
672 | pub fn module(self, db: &impl HirDatabase) -> Option<Module> { | ||
673 | let krate = self.id.krate?; | ||
674 | let module_id = db.crate_def_map(krate).root; | ||
675 | Some(Module::new(Crate { id: krate }, module_id)) | ||
676 | } | ||
677 | } | ||
678 | |||
652 | /// Invariant: `inner.as_assoc_item(db).is_some()` | 679 | /// Invariant: `inner.as_assoc_item(db).is_some()` |
653 | /// We do not actively enforce this invariant. | 680 | /// We do not actively enforce this invariant. |
654 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 681 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs index 0d11b537c..22f24890d 100644 --- a/crates/ra_hir_ty/src/expr.rs +++ b/crates/ra_hir_ty/src/expr.rs | |||
@@ -15,6 +15,7 @@ use rustc_hash::FxHashSet; | |||
15 | use crate::{ | 15 | use crate::{ |
16 | db::HirDatabase, | 16 | db::HirDatabase, |
17 | diagnostics::{MissingFields, MissingOkInTailExpr}, | 17 | diagnostics::{MissingFields, MissingOkInTailExpr}, |
18 | utils::variant_data, | ||
18 | ApplicationTy, InferenceResult, Ty, TypeCtor, | 19 | ApplicationTy, InferenceResult, Ty, TypeCtor, |
19 | }; | 20 | }; |
20 | 21 | ||
@@ -27,6 +28,7 @@ pub use hir_def::{ | |||
27 | ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, | 28 | ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, |
28 | MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp, | 29 | MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp, |
29 | }, | 30 | }, |
31 | VariantId, | ||
30 | }; | 32 | }; |
31 | 33 | ||
32 | pub struct ExprValidator<'a, 'b: 'a> { | 34 | pub struct ExprValidator<'a, 'b: 'a> { |
@@ -69,17 +71,19 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
69 | ) { | 71 | ) { |
70 | if spread.is_some() { | 72 | if spread.is_some() { |
71 | return; | 73 | return; |
74 | }; | ||
75 | let variant_def: VariantId = match self.infer.variant_resolution_for_expr(id) { | ||
76 | Some(VariantId::UnionId(_)) | None => return, | ||
77 | Some(it) => it, | ||
78 | }; | ||
79 | if let VariantId::UnionId(_) = variant_def { | ||
80 | return; | ||
72 | } | 81 | } |
73 | 82 | ||
74 | let struct_def = match self.infer[id].as_adt() { | 83 | let variant_data = variant_data(db, variant_def); |
75 | Some((AdtId::StructId(s), _)) => s, | ||
76 | _ => return, | ||
77 | }; | ||
78 | let struct_data = db.struct_data(struct_def); | ||
79 | 84 | ||
80 | let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); | 85 | let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); |
81 | let missed_fields: Vec<Name> = struct_data | 86 | let missed_fields: Vec<Name> = variant_data |
82 | .variant_data | ||
83 | .fields() | 87 | .fields() |
84 | .iter() | 88 | .iter() |
85 | .filter_map(|(_f, d)| { | 89 | .filter_map(|(_f, d)| { |
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 1a3bcffae..a524987fd 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -135,11 +135,7 @@ impl Completions { | |||
135 | let (before, after) = (&docs[..idx], &docs[idx + s.len()..]); | 135 | let (before, after) = (&docs[..idx], &docs[idx + s.len()..]); |
136 | // Ensure to match the full word | 136 | // Ensure to match the full word |
137 | if after.starts_with('!') | 137 | if after.starts_with('!') |
138 | && before | 138 | && !before.ends_with(|c: char| c == '_' || c.is_ascii_alphanumeric()) |
139 | .chars() | ||
140 | .rev() | ||
141 | .next() | ||
142 | .map_or(true, |c| c != '_' && !c.is_ascii_alphanumeric()) | ||
143 | { | 139 | { |
144 | // It may have spaces before the braces like `foo! {}` | 140 | // It may have spaces before the braces like `foo! {}` |
145 | match after[1..].chars().find(|&c| !c.is_whitespace()) { | 141 | match after[1..].chars().find(|&c| !c.is_whitespace()) { |
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index 82596c665..9cf86b26d 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs | |||
@@ -470,6 +470,35 @@ mod tests { | |||
470 | } | 470 | } |
471 | 471 | ||
472 | #[test] | 472 | #[test] |
473 | fn test_fill_struct_fields_enum() { | ||
474 | let before = r" | ||
475 | enum Expr { | ||
476 | Bin { lhs: Box<Expr>, rhs: Box<Expr> } | ||
477 | } | ||
478 | |||
479 | impl Expr { | ||
480 | fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr { | ||
481 | Expr::Bin { <|> } | ||
482 | } | ||
483 | } | ||
484 | |||
485 | "; | ||
486 | let after = r" | ||
487 | enum Expr { | ||
488 | Bin { lhs: Box<Expr>, rhs: Box<Expr> } | ||
489 | } | ||
490 | |||
491 | impl Expr { | ||
492 | fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr { | ||
493 | Expr::Bin { lhs: (), rhs: () <|> } | ||
494 | } | ||
495 | } | ||
496 | |||
497 | "; | ||
498 | check_apply_diagnostic_fix(before, after); | ||
499 | } | ||
500 | |||
501 | #[test] | ||
473 | fn test_fill_struct_fields_partial() { | 502 | fn test_fill_struct_fields_partial() { |
474 | let before = r" | 503 | let before = r" |
475 | struct TestStruct { | 504 | struct TestStruct { |
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs index 726963a33..4757d8e22 100644 --- a/crates/ra_ide/src/extend_selection.rs +++ b/crates/ra_ide/src/extend_selection.rs | |||
@@ -44,6 +44,7 @@ fn try_extend_selection( | |||
44 | ARRAY_EXPR, | 44 | ARRAY_EXPR, |
45 | TUPLE_EXPR, | 45 | TUPLE_EXPR, |
46 | TUPLE_TYPE, | 46 | TUPLE_TYPE, |
47 | TUPLE_PAT, | ||
47 | WHERE_CLAUSE, | 48 | WHERE_CLAUSE, |
48 | ]; | 49 | ]; |
49 | 50 | ||
@@ -612,6 +613,32 @@ fn main() { let var = ( | |||
612 | } | 613 | } |
613 | 614 | ||
614 | #[test] | 615 | #[test] |
616 | fn test_extend_selection_on_tuple_pat() { | ||
617 | do_check( | ||
618 | r#"fn main() { let (krate, _crate_def_map<|>, module_id) = var; }"#, | ||
619 | &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"], | ||
620 | ); | ||
621 | // white space variations | ||
622 | do_check( | ||
623 | r#"fn main() { let (krate,_crate<|>_def_map,module_id) = var; }"#, | ||
624 | &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"], | ||
625 | ); | ||
626 | do_check( | ||
627 | r#" | ||
628 | fn main() { let ( | ||
629 | krate, | ||
630 | _crate_def_map<|>, | ||
631 | module_id | ||
632 | ) = var; }"#, | ||
633 | &[ | ||
634 | "_crate_def_map", | ||
635 | "_crate_def_map,", | ||
636 | "(\n krate,\n _crate_def_map,\n module_id\n)", | ||
637 | ], | ||
638 | ); | ||
639 | } | ||
640 | |||
641 | #[test] | ||
615 | fn extend_selection_inside_macros() { | 642 | fn extend_selection_inside_macros() { |
616 | do_check( | 643 | do_check( |
617 | r#"macro_rules! foo { ($item:item) => {$item} } | 644 | r#"macro_rules! foo { ($item:item) => {$item} } |
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index de5551a4c..cce539e56 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{db::AstDatabase, InFile, SourceBinder}; | 3 | use hir::{db::AstDatabase, InFile, SourceBinder}; |
4 | use ra_ide_db::{symbol_index, RootDatabase}; | 4 | use ra_ide_db::{defs::NameDefinition, symbol_index, RootDatabase}; |
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | ast::{self, DocCommentsOwner}, | 6 | ast::{self, DocCommentsOwner}, |
7 | match_ast, AstNode, | 7 | match_ast, AstNode, |
@@ -12,7 +12,7 @@ use ra_syntax::{ | |||
12 | use crate::{ | 12 | use crate::{ |
13 | display::{ShortLabel, ToNav}, | 13 | display::{ShortLabel, ToNav}, |
14 | expand::descend_into_macros, | 14 | expand::descend_into_macros, |
15 | references::{classify_name_ref, NameKind::*}, | 15 | references::classify_name_ref, |
16 | FilePosition, NavigationTarget, RangeInfo, | 16 | FilePosition, NavigationTarget, RangeInfo, |
17 | }; | 17 | }; |
18 | 18 | ||
@@ -73,17 +73,17 @@ pub(crate) fn reference_definition( | |||
73 | ) -> ReferenceResult { | 73 | ) -> ReferenceResult { |
74 | use self::ReferenceResult::*; | 74 | use self::ReferenceResult::*; |
75 | 75 | ||
76 | let name_kind = classify_name_ref(sb, name_ref).map(|d| d.kind); | 76 | let name_kind = classify_name_ref(sb, name_ref); |
77 | match name_kind { | 77 | match name_kind { |
78 | Some(Macro(it)) => return Exact(it.to_nav(sb.db)), | 78 | Some(NameDefinition::Macro(it)) => return Exact(it.to_nav(sb.db)), |
79 | Some(StructField(it)) => return Exact(it.to_nav(sb.db)), | 79 | Some(NameDefinition::StructField(it)) => return Exact(it.to_nav(sb.db)), |
80 | Some(TypeParam(it)) => return Exact(it.to_nav(sb.db)), | 80 | Some(NameDefinition::TypeParam(it)) => return Exact(it.to_nav(sb.db)), |
81 | Some(Local(it)) => return Exact(it.to_nav(sb.db)), | 81 | Some(NameDefinition::Local(it)) => return Exact(it.to_nav(sb.db)), |
82 | Some(ModuleDef(def)) => match NavigationTarget::from_def(sb.db, def) { | 82 | Some(NameDefinition::ModuleDef(def)) => match NavigationTarget::from_def(sb.db, def) { |
83 | Some(nav) => return Exact(nav), | 83 | Some(nav) => return Exact(nav), |
84 | None => return Approximate(vec![]), | 84 | None => return Approximate(vec![]), |
85 | }, | 85 | }, |
86 | Some(SelfType(imp)) => { | 86 | Some(NameDefinition::SelfType(imp)) => { |
87 | // FIXME: ideally, this should point to the type in the impl, and | 87 | // FIXME: ideally, this should point to the type in the impl, and |
88 | // not at the whole impl. And goto **type** definition should bring | 88 | // not at the whole impl. And goto **type** definition should bring |
89 | // us to the actual type | 89 | // us to the actual type |
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 3f88bb260..1c6ca36df 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use hir::{db::AstDatabase, Adt, HasSource, HirDisplay, SourceBinder}; | 3 | use hir::{db::AstDatabase, Adt, HasSource, HirDisplay, SourceBinder}; |
4 | use ra_db::SourceDatabase; | 4 | use ra_db::SourceDatabase; |
5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::{defs::NameDefinition, RootDatabase}; |
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
7 | algo::find_covering_element, | 7 | algo::find_covering_element, |
8 | ast::{self, DocCommentsOwner}, | 8 | ast::{self, DocCommentsOwner}, |
@@ -13,8 +13,8 @@ use ra_syntax::{ | |||
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel}, | 15 | display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel}, |
16 | expand::descend_into_macros, | 16 | expand::{descend_into_macros, original_range}, |
17 | references::{classify_name, classify_name_ref, NameKind, NameKind::*}, | 17 | references::{classify_name, classify_name_ref}, |
18 | FilePosition, FileRange, RangeInfo, | 18 | FilePosition, FileRange, RangeInfo, |
19 | }; | 19 | }; |
20 | 20 | ||
@@ -92,20 +92,20 @@ fn hover_text(docs: Option<String>, desc: Option<String>) -> Option<String> { | |||
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | fn hover_text_from_name_kind(db: &RootDatabase, name_kind: NameKind) -> Option<String> { | 95 | fn hover_text_from_name_kind(db: &RootDatabase, def: NameDefinition) -> Option<String> { |
96 | return match name_kind { | 96 | return match def { |
97 | Macro(it) => { | 97 | NameDefinition::Macro(it) => { |
98 | let src = it.source(db); | 98 | let src = it.source(db); |
99 | hover_text(src.value.doc_comment_text(), Some(macro_label(&src.value))) | 99 | hover_text(src.value.doc_comment_text(), Some(macro_label(&src.value))) |
100 | } | 100 | } |
101 | StructField(it) => { | 101 | NameDefinition::StructField(it) => { |
102 | let src = it.source(db); | 102 | let src = it.source(db); |
103 | match src.value { | 103 | match src.value { |
104 | hir::FieldSource::Named(it) => hover_text(it.doc_comment_text(), it.short_label()), | 104 | hir::FieldSource::Named(it) => hover_text(it.doc_comment_text(), it.short_label()), |
105 | _ => None, | 105 | _ => None, |
106 | } | 106 | } |
107 | } | 107 | } |
108 | ModuleDef(it) => match it { | 108 | NameDefinition::ModuleDef(it) => match it { |
109 | hir::ModuleDef::Module(it) => match it.definition_source(db).value { | 109 | hir::ModuleDef::Module(it) => match it.definition_source(db).value { |
110 | hir::ModuleSource::Module(it) => { | 110 | hir::ModuleSource::Module(it) => { |
111 | hover_text(it.doc_comment_text(), it.short_label()) | 111 | hover_text(it.doc_comment_text(), it.short_label()) |
@@ -123,8 +123,10 @@ fn hover_text_from_name_kind(db: &RootDatabase, name_kind: NameKind) -> Option<S | |||
123 | hir::ModuleDef::TypeAlias(it) => from_def_source(db, it), | 123 | hir::ModuleDef::TypeAlias(it) => from_def_source(db, it), |
124 | hir::ModuleDef::BuiltinType(it) => Some(it.to_string()), | 124 | hir::ModuleDef::BuiltinType(it) => Some(it.to_string()), |
125 | }, | 125 | }, |
126 | Local(it) => Some(rust_code_markup(it.ty(db).display_truncated(db, None).to_string())), | 126 | NameDefinition::Local(it) => { |
127 | TypeParam(_) | SelfType(_) => { | 127 | Some(rust_code_markup(it.ty(db).display_truncated(db, None).to_string())) |
128 | } | ||
129 | NameDefinition::TypeParam(_) | NameDefinition::SelfType(_) => { | ||
128 | // FIXME: Hover for generic param | 130 | // FIXME: Hover for generic param |
129 | None | 131 | None |
130 | } | 132 | } |
@@ -148,17 +150,18 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
148 | let mut res = HoverResult::new(); | 150 | let mut res = HoverResult::new(); |
149 | 151 | ||
150 | let mut sb = SourceBinder::new(db); | 152 | let mut sb = SourceBinder::new(db); |
151 | if let Some((range, name_kind)) = match_ast! { | 153 | if let Some((node, name_kind)) = match_ast! { |
152 | match (token.value.parent()) { | 154 | match (token.value.parent()) { |
153 | ast::NameRef(name_ref) => { | 155 | ast::NameRef(name_ref) => { |
154 | classify_name_ref(&mut sb, token.with_value(&name_ref)).map(|d| (name_ref.syntax().text_range(), d.kind)) | 156 | classify_name_ref(&mut sb, token.with_value(&name_ref)).map(|d| (name_ref.syntax().clone(), d)) |
155 | }, | 157 | }, |
156 | ast::Name(name) => { | 158 | ast::Name(name) => { |
157 | classify_name(&mut sb, token.with_value(&name)).map(|d| (name.syntax().text_range(), d.kind)) | 159 | classify_name(&mut sb, token.with_value(&name)).map(|d| (name.syntax().clone(), d)) |
158 | }, | 160 | }, |
159 | _ => None, | 161 | _ => None, |
160 | } | 162 | } |
161 | } { | 163 | } { |
164 | let range = original_range(db, token.with_value(&node)).range; | ||
162 | res.extend(hover_text_from_name_kind(db, name_kind)); | 165 | res.extend(hover_text_from_name_kind(db, name_kind)); |
163 | 166 | ||
164 | if !res.is_empty() { | 167 | if !res.is_empty() { |
@@ -171,8 +174,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
171 | .ancestors() | 174 | .ancestors() |
172 | .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?; | 175 | .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?; |
173 | 176 | ||
174 | // The following logic will not work if token is coming from a macro | 177 | let frange = original_range(db, token.with_value(&node)); |
175 | let frange = FileRange { file_id: position.file_id, range: node.text_range() }; | ||
176 | res.extend(type_of(db, frange).map(rust_code_markup)); | 178 | res.extend(type_of(db, frange).map(rust_code_markup)); |
177 | if res.is_empty() { | 179 | if res.is_empty() { |
178 | return None; | 180 | return None; |
@@ -220,6 +222,7 @@ mod tests { | |||
220 | use crate::mock_analysis::{ | 222 | use crate::mock_analysis::{ |
221 | analysis_and_position, single_file_with_position, single_file_with_range, | 223 | analysis_and_position, single_file_with_position, single_file_with_range, |
222 | }; | 224 | }; |
225 | use ra_db::FileLoader; | ||
223 | use ra_syntax::TextRange; | 226 | use ra_syntax::TextRange; |
224 | 227 | ||
225 | fn trim_markup(s: &str) -> &str { | 228 | fn trim_markup(s: &str) -> &str { |
@@ -230,7 +233,7 @@ mod tests { | |||
230 | s.map(trim_markup) | 233 | s.map(trim_markup) |
231 | } | 234 | } |
232 | 235 | ||
233 | fn check_hover_result(fixture: &str, expected: &[&str]) { | 236 | fn check_hover_result(fixture: &str, expected: &[&str]) -> String { |
234 | let (analysis, position) = analysis_and_position(fixture); | 237 | let (analysis, position) = analysis_and_position(fixture); |
235 | let hover = analysis.hover(position).unwrap().unwrap(); | 238 | let hover = analysis.hover(position).unwrap().unwrap(); |
236 | let mut results = Vec::from(hover.info.results()); | 239 | let mut results = Vec::from(hover.info.results()); |
@@ -243,6 +246,9 @@ mod tests { | |||
243 | } | 246 | } |
244 | 247 | ||
245 | assert_eq!(hover.info.len(), expected.len()); | 248 | assert_eq!(hover.info.len(), expected.len()); |
249 | |||
250 | let content = analysis.db.file_text(position.file_id); | ||
251 | content[hover.range].to_string() | ||
246 | } | 252 | } |
247 | 253 | ||
248 | #[test] | 254 | #[test] |
@@ -711,7 +717,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
711 | 717 | ||
712 | #[test] | 718 | #[test] |
713 | fn test_hover_through_macro() { | 719 | fn test_hover_through_macro() { |
714 | check_hover_result( | 720 | let hover_on = check_hover_result( |
715 | " | 721 | " |
716 | //- /lib.rs | 722 | //- /lib.rs |
717 | macro_rules! id { | 723 | macro_rules! id { |
@@ -726,11 +732,13 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
726 | ", | 732 | ", |
727 | &["fn foo()"], | 733 | &["fn foo()"], |
728 | ); | 734 | ); |
735 | |||
736 | assert_eq!(hover_on, "foo") | ||
729 | } | 737 | } |
730 | 738 | ||
731 | #[test] | 739 | #[test] |
732 | fn test_hover_through_expr_in_macro() { | 740 | fn test_hover_through_expr_in_macro() { |
733 | check_hover_result( | 741 | let hover_on = check_hover_result( |
734 | " | 742 | " |
735 | //- /lib.rs | 743 | //- /lib.rs |
736 | macro_rules! id { | 744 | macro_rules! id { |
@@ -742,5 +750,24 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
742 | ", | 750 | ", |
743 | &["u32"], | 751 | &["u32"], |
744 | ); | 752 | ); |
753 | |||
754 | assert_eq!(hover_on, "bar") | ||
755 | } | ||
756 | |||
757 | #[test] | ||
758 | fn test_hover_non_ascii_space_doc() { | ||
759 | check_hover_result( | ||
760 | " | ||
761 | //- /lib.rs | ||
762 | /// <- `\u{3000}` here | ||
763 | fn foo() { | ||
764 | } | ||
765 | |||
766 | fn bar() { | ||
767 | fo<|>o(); | ||
768 | } | ||
769 | ", | ||
770 | &["fn foo()\n```\n\n<- `\u{3000}` here"], | ||
771 | ); | ||
745 | } | 772 | } |
746 | } | 773 | } |
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index 97c08ade5..7f790a62d 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs | |||
@@ -31,7 +31,7 @@ pub(crate) use self::{ | |||
31 | classify::{classify_name, classify_name_ref}, | 31 | classify::{classify_name, classify_name_ref}, |
32 | rename::rename, | 32 | rename::rename, |
33 | }; | 33 | }; |
34 | pub(crate) use ra_ide_db::defs::{NameDefinition, NameKind}; | 34 | pub(crate) use ra_ide_db::defs::NameDefinition; |
35 | 35 | ||
36 | pub use self::search_scope::SearchScope; | 36 | pub use self::search_scope::SearchScope; |
37 | 37 | ||
@@ -126,13 +126,13 @@ pub(crate) fn find_all_refs( | |||
126 | 126 | ||
127 | let RangeInfo { range, info: (name, def) } = find_name(db, &syntax, position, opt_name)?; | 127 | let RangeInfo { range, info: (name, def) } = find_name(db, &syntax, position, opt_name)?; |
128 | 128 | ||
129 | let declaration = match def.kind { | 129 | let declaration = match def { |
130 | NameKind::Macro(mac) => mac.to_nav(db), | 130 | NameDefinition::Macro(mac) => mac.to_nav(db), |
131 | NameKind::StructField(field) => field.to_nav(db), | 131 | NameDefinition::StructField(field) => field.to_nav(db), |
132 | NameKind::ModuleDef(def) => NavigationTarget::from_def(db, def)?, | 132 | NameDefinition::ModuleDef(def) => NavigationTarget::from_def(db, def)?, |
133 | NameKind::SelfType(imp) => imp.to_nav(db), | 133 | NameDefinition::SelfType(imp) => imp.to_nav(db), |
134 | NameKind::Local(local) => local.to_nav(db), | 134 | NameDefinition::Local(local) => local.to_nav(db), |
135 | NameKind::TypeParam(_) => return None, | 135 | NameDefinition::TypeParam(_) => return None, |
136 | }; | 136 | }; |
137 | 137 | ||
138 | let search_scope = { | 138 | let search_scope = { |
@@ -148,7 +148,7 @@ pub(crate) fn find_all_refs( | |||
148 | let declaration = Declaration { | 148 | let declaration = Declaration { |
149 | nav: declaration, | 149 | nav: declaration, |
150 | kind: ReferenceKind::Other, | 150 | kind: ReferenceKind::Other, |
151 | access: decl_access(&def.kind, &name, &syntax, decl_range), | 151 | access: decl_access(&def, &name, &syntax, decl_range), |
152 | }; | 152 | }; |
153 | 153 | ||
154 | let references = process_definition(db, def, name, search_scope) | 154 | let references = process_definition(db, def, name, search_scope) |
@@ -247,7 +247,7 @@ fn process_definition( | |||
247 | refs.push(Reference { | 247 | refs.push(Reference { |
248 | file_range: FileRange { file_id, range }, | 248 | file_range: FileRange { file_id, range }, |
249 | kind, | 249 | kind, |
250 | access: reference_access(&d.kind, &name_ref.value), | 250 | access: reference_access(&d, &name_ref.value), |
251 | }); | 251 | }); |
252 | } | 252 | } |
253 | } | 253 | } |
@@ -257,13 +257,13 @@ fn process_definition( | |||
257 | } | 257 | } |
258 | 258 | ||
259 | fn decl_access( | 259 | fn decl_access( |
260 | kind: &NameKind, | 260 | def: &NameDefinition, |
261 | name: &str, | 261 | name: &str, |
262 | syntax: &SyntaxNode, | 262 | syntax: &SyntaxNode, |
263 | range: TextRange, | 263 | range: TextRange, |
264 | ) -> Option<ReferenceAccess> { | 264 | ) -> Option<ReferenceAccess> { |
265 | match kind { | 265 | match def { |
266 | NameKind::Local(_) | NameKind::StructField(_) => {} | 266 | NameDefinition::Local(_) | NameDefinition::StructField(_) => {} |
267 | _ => return None, | 267 | _ => return None, |
268 | }; | 268 | }; |
269 | 269 | ||
@@ -280,10 +280,10 @@ fn decl_access( | |||
280 | None | 280 | None |
281 | } | 281 | } |
282 | 282 | ||
283 | fn reference_access(kind: &NameKind, name_ref: &ast::NameRef) -> Option<ReferenceAccess> { | 283 | fn reference_access(def: &NameDefinition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> { |
284 | // Only Locals and Fields have accesses for now. | 284 | // Only Locals and Fields have accesses for now. |
285 | match kind { | 285 | match def { |
286 | NameKind::Local(_) | NameKind::StructField(_) => {} | 286 | NameDefinition::Local(_) | NameDefinition::StructField(_) => {} |
287 | _ => return None, | 287 | _ => return None, |
288 | }; | 288 | }; |
289 | 289 | ||
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs index d0f03d8a8..478e18871 100644 --- a/crates/ra_ide/src/references/classify.rs +++ b/crates/ra_ide/src/references/classify.rs | |||
@@ -5,7 +5,7 @@ use ra_prof::profile; | |||
5 | use ra_syntax::{ast, AstNode}; | 5 | use ra_syntax::{ast, AstNode}; |
6 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
7 | 7 | ||
8 | use super::{NameDefinition, NameKind}; | 8 | use super::NameDefinition; |
9 | use ra_ide_db::RootDatabase; | 9 | use ra_ide_db::RootDatabase; |
10 | 10 | ||
11 | pub use ra_ide_db::defs::{classify_name, from_module_def, from_struct_field}; | 11 | pub use ra_ide_db::defs::{classify_name, from_module_def, from_struct_field}; |
@@ -22,14 +22,14 @@ pub(crate) fn classify_name_ref( | |||
22 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { | 22 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { |
23 | tested_by!(goto_def_for_methods); | 23 | tested_by!(goto_def_for_methods); |
24 | if let Some(func) = analyzer.resolve_method_call(&method_call) { | 24 | if let Some(func) = analyzer.resolve_method_call(&method_call) { |
25 | return Some(from_module_def(sb.db, func.into(), None)); | 25 | return Some(from_module_def(func.into())); |
26 | } | 26 | } |
27 | } | 27 | } |
28 | 28 | ||
29 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { | 29 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { |
30 | tested_by!(goto_def_for_fields); | 30 | tested_by!(goto_def_for_fields); |
31 | if let Some(field) = analyzer.resolve_field(&field_expr) { | 31 | if let Some(field) = analyzer.resolve_field(&field_expr) { |
32 | return Some(from_struct_field(sb.db, field)); | 32 | return Some(from_struct_field(field)); |
33 | } | 33 | } |
34 | } | 34 | } |
35 | 35 | ||
@@ -37,55 +37,35 @@ pub(crate) fn classify_name_ref( | |||
37 | tested_by!(goto_def_for_record_fields); | 37 | tested_by!(goto_def_for_record_fields); |
38 | tested_by!(goto_def_for_field_init_shorthand); | 38 | tested_by!(goto_def_for_field_init_shorthand); |
39 | if let Some(field_def) = analyzer.resolve_record_field(&record_field) { | 39 | if let Some(field_def) = analyzer.resolve_record_field(&record_field) { |
40 | return Some(from_struct_field(sb.db, field_def)); | 40 | return Some(from_struct_field(field_def)); |
41 | } | 41 | } |
42 | } | 42 | } |
43 | 43 | ||
44 | // FIXME: find correct container and visibility for each case | ||
45 | let visibility = None; | ||
46 | let container = sb.to_module_def(name_ref.file_id.original_file(sb.db))?; | ||
47 | |||
48 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { | 44 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { |
49 | tested_by!(goto_def_for_macros); | 45 | tested_by!(goto_def_for_macros); |
50 | if let Some(macro_def) = | 46 | if let Some(macro_def) = |
51 | analyzer.resolve_macro_call(sb.db, name_ref.with_value(¯o_call)) | 47 | analyzer.resolve_macro_call(sb.db, name_ref.with_value(¯o_call)) |
52 | { | 48 | { |
53 | let kind = NameKind::Macro(macro_def); | 49 | return Some(NameDefinition::Macro(macro_def)); |
54 | return Some(NameDefinition { kind, container, visibility }); | ||
55 | } | 50 | } |
56 | } | 51 | } |
57 | 52 | ||
58 | let path = name_ref.value.syntax().ancestors().find_map(ast::Path::cast)?; | 53 | let path = name_ref.value.syntax().ancestors().find_map(ast::Path::cast)?; |
59 | let resolved = analyzer.resolve_path(sb.db, &path)?; | 54 | let resolved = analyzer.resolve_path(sb.db, &path)?; |
60 | let res = match resolved { | 55 | let res = match resolved { |
61 | PathResolution::Def(def) => from_module_def(sb.db, def, Some(container)), | 56 | PathResolution::Def(def) => from_module_def(def), |
62 | PathResolution::AssocItem(item) => { | 57 | PathResolution::AssocItem(item) => { |
63 | let def = match item { | 58 | let def = match item { |
64 | hir::AssocItem::Function(it) => it.into(), | 59 | hir::AssocItem::Function(it) => it.into(), |
65 | hir::AssocItem::Const(it) => it.into(), | 60 | hir::AssocItem::Const(it) => it.into(), |
66 | hir::AssocItem::TypeAlias(it) => it.into(), | 61 | hir::AssocItem::TypeAlias(it) => it.into(), |
67 | }; | 62 | }; |
68 | from_module_def(sb.db, def, Some(container)) | 63 | from_module_def(def) |
69 | } | ||
70 | PathResolution::Local(local) => { | ||
71 | let kind = NameKind::Local(local); | ||
72 | let container = local.module(sb.db); | ||
73 | NameDefinition { kind, container, visibility: None } | ||
74 | } | ||
75 | PathResolution::TypeParam(par) => { | ||
76 | let kind = NameKind::TypeParam(par); | ||
77 | let container = par.module(sb.db); | ||
78 | NameDefinition { kind, container, visibility } | ||
79 | } | ||
80 | PathResolution::Macro(def) => { | ||
81 | let kind = NameKind::Macro(def); | ||
82 | NameDefinition { kind, container, visibility } | ||
83 | } | ||
84 | PathResolution::SelfType(impl_block) => { | ||
85 | let kind = NameKind::SelfType(impl_block); | ||
86 | let container = impl_block.module(sb.db); | ||
87 | NameDefinition { kind, container, visibility } | ||
88 | } | 64 | } |
65 | PathResolution::Local(local) => NameDefinition::Local(local), | ||
66 | PathResolution::TypeParam(par) => NameDefinition::TypeParam(par), | ||
67 | PathResolution::Macro(def) => NameDefinition::Macro(def), | ||
68 | PathResolution::SelfType(impl_block) => NameDefinition::SelfType(impl_block), | ||
89 | }; | 69 | }; |
90 | Some(res) | 70 | Some(res) |
91 | } | 71 | } |
diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs index 279f57be0..27d483233 100644 --- a/crates/ra_ide/src/references/search_scope.rs +++ b/crates/ra_ide/src/references/search_scope.rs | |||
@@ -12,20 +12,27 @@ use rustc_hash::FxHashMap; | |||
12 | 12 | ||
13 | use ra_ide_db::RootDatabase; | 13 | use ra_ide_db::RootDatabase; |
14 | 14 | ||
15 | use super::{NameDefinition, NameKind}; | 15 | use super::NameDefinition; |
16 | 16 | ||
17 | pub struct SearchScope { | 17 | pub struct SearchScope { |
18 | entries: FxHashMap<FileId, Option<TextRange>>, | 18 | entries: FxHashMap<FileId, Option<TextRange>>, |
19 | } | 19 | } |
20 | 20 | ||
21 | impl SearchScope { | 21 | impl SearchScope { |
22 | fn empty() -> SearchScope { | ||
23 | SearchScope { entries: FxHashMap::default() } | ||
24 | } | ||
25 | |||
22 | pub(crate) fn for_def(def: &NameDefinition, db: &RootDatabase) -> SearchScope { | 26 | pub(crate) fn for_def(def: &NameDefinition, db: &RootDatabase) -> SearchScope { |
23 | let _p = profile("search_scope"); | 27 | let _p = profile("search_scope"); |
24 | 28 | let module = match def.module(db) { | |
25 | let module_src = def.container.definition_source(db); | 29 | Some(it) => it, |
30 | None => return SearchScope::empty(), | ||
31 | }; | ||
32 | let module_src = module.definition_source(db); | ||
26 | let file_id = module_src.file_id.original_file(db); | 33 | let file_id = module_src.file_id.original_file(db); |
27 | 34 | ||
28 | if let NameKind::Local(var) = def.kind { | 35 | if let NameDefinition::Local(var) = def { |
29 | let range = match var.parent(db) { | 36 | let range = match var.parent(db) { |
30 | DefWithBody::Function(f) => f.source(db).value.syntax().text_range(), | 37 | DefWithBody::Function(f) => f.source(db).value.syntax().text_range(), |
31 | DefWithBody::Const(c) => c.source(db).value.syntax().text_range(), | 38 | DefWithBody::Const(c) => c.source(db).value.syntax().text_range(), |
@@ -36,10 +43,10 @@ impl SearchScope { | |||
36 | return SearchScope::new(res); | 43 | return SearchScope::new(res); |
37 | } | 44 | } |
38 | 45 | ||
39 | let vis = def.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or_default(); | 46 | let vis = def.visibility(db).as_ref().map(|v| v.syntax().to_string()).unwrap_or_default(); |
40 | 47 | ||
41 | if vis.as_str() == "pub(super)" { | 48 | if vis.as_str() == "pub(super)" { |
42 | if let Some(parent_module) = def.container.parent(db) { | 49 | if let Some(parent_module) = module.parent(db) { |
43 | let mut res = FxHashMap::default(); | 50 | let mut res = FxHashMap::default(); |
44 | let parent_src = parent_module.definition_source(db); | 51 | let parent_src = parent_module.definition_source(db); |
45 | let file_id = parent_src.file_id.original_file(db); | 52 | let file_id = parent_src.file_id.original_file(db); |
@@ -72,7 +79,7 @@ impl SearchScope { | |||
72 | return SearchScope::new(res); | 79 | return SearchScope::new(res); |
73 | } | 80 | } |
74 | if vis.as_str() == "pub" { | 81 | if vis.as_str() == "pub" { |
75 | let krate = def.container.krate(); | 82 | let krate = module.krate(); |
76 | for rev_dep in krate.reverse_dependencies(db) { | 83 | for rev_dep in krate.reverse_dependencies(db) { |
77 | let root_file = rev_dep.root_file(db); | 84 | let root_file = rev_dep.root_file(db); |
78 | let source_root_id = db.file_source_root(root_file); | 85 | let source_root_id = db.file_source_root(root_file); |
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 8e793e479..d873f153e 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use hir::{HirFileId, InFile, Name, SourceAnalyzer, SourceBinder}; | 3 | use hir::{HirFileId, InFile, Name, SourceAnalyzer, SourceBinder}; |
4 | use ra_db::SourceDatabase; | 4 | use ra_db::SourceDatabase; |
5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::{defs::NameDefinition, RootDatabase}; |
6 | use ra_prof::profile; | 6 | use ra_prof::profile; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, SyntaxToken, TextRange, | 8 | ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, SyntaxToken, TextRange, |
@@ -12,7 +12,7 @@ use rustc_hash::FxHashMap; | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | expand::descend_into_macros_with_analyzer, | 14 | expand::descend_into_macros_with_analyzer, |
15 | references::{classify_name, classify_name_ref, NameKind}, | 15 | references::{classify_name, classify_name_ref}, |
16 | FileId, | 16 | FileId, |
17 | }; | 17 | }; |
18 | 18 | ||
@@ -186,10 +186,10 @@ fn highlight_node( | |||
186 | NAME_REF if node.value.ancestors().any(|it| it.kind() == ATTR) => return None, | 186 | NAME_REF if node.value.ancestors().any(|it| it.kind() == ATTR) => return None, |
187 | NAME_REF => { | 187 | NAME_REF => { |
188 | let name_ref = node.value.as_node().cloned().and_then(ast::NameRef::cast).unwrap(); | 188 | let name_ref = node.value.as_node().cloned().and_then(ast::NameRef::cast).unwrap(); |
189 | let name_kind = classify_name_ref(sb, node.with_value(&name_ref)).map(|d| d.kind); | 189 | let name_kind = classify_name_ref(sb, node.with_value(&name_ref)); |
190 | match name_kind { | 190 | match name_kind { |
191 | Some(name_kind) => { | 191 | Some(name_kind) => { |
192 | if let NameKind::Local(local) = &name_kind { | 192 | if let NameDefinition::Local(local) = &name_kind { |
193 | if let Some(name) = local.name(db) { | 193 | if let Some(name) = local.name(db) { |
194 | let shadow_count = | 194 | let shadow_count = |
195 | bindings_shadow_count.entry(name.clone()).or_default(); | 195 | bindings_shadow_count.entry(name.clone()).or_default(); |
@@ -205,9 +205,9 @@ fn highlight_node( | |||
205 | } | 205 | } |
206 | NAME => { | 206 | NAME => { |
207 | let name = node.value.as_node().cloned().and_then(ast::Name::cast).unwrap(); | 207 | let name = node.value.as_node().cloned().and_then(ast::Name::cast).unwrap(); |
208 | let name_kind = classify_name(sb, node.with_value(&name)).map(|d| d.kind); | 208 | let name_kind = classify_name(sb, node.with_value(&name)); |
209 | 209 | ||
210 | if let Some(NameKind::Local(local)) = &name_kind { | 210 | if let Some(NameDefinition::Local(local)) = &name_kind { |
211 | if let Some(name) = local.name(db) { | 211 | if let Some(name) = local.name(db) { |
212 | let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); | 212 | let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); |
213 | *shadow_count += 1; | 213 | *shadow_count += 1; |
@@ -310,22 +310,22 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo | |||
310 | buf | 310 | buf |
311 | } | 311 | } |
312 | 312 | ||
313 | fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str { | 313 | fn highlight_name(db: &RootDatabase, def: NameDefinition) -> &'static str { |
314 | match name_kind { | 314 | match def { |
315 | NameKind::Macro(_) => tags::MACRO, | 315 | NameDefinition::Macro(_) => tags::MACRO, |
316 | NameKind::StructField(_) => tags::FIELD, | 316 | NameDefinition::StructField(_) => tags::FIELD, |
317 | NameKind::ModuleDef(hir::ModuleDef::Module(_)) => tags::MODULE, | 317 | NameDefinition::ModuleDef(hir::ModuleDef::Module(_)) => tags::MODULE, |
318 | NameKind::ModuleDef(hir::ModuleDef::Function(_)) => tags::FUNCTION, | 318 | NameDefinition::ModuleDef(hir::ModuleDef::Function(_)) => tags::FUNCTION, |
319 | NameKind::ModuleDef(hir::ModuleDef::Adt(_)) => tags::TYPE, | 319 | NameDefinition::ModuleDef(hir::ModuleDef::Adt(_)) => tags::TYPE, |
320 | NameKind::ModuleDef(hir::ModuleDef::EnumVariant(_)) => tags::CONSTANT, | 320 | NameDefinition::ModuleDef(hir::ModuleDef::EnumVariant(_)) => tags::CONSTANT, |
321 | NameKind::ModuleDef(hir::ModuleDef::Const(_)) => tags::CONSTANT, | 321 | NameDefinition::ModuleDef(hir::ModuleDef::Const(_)) => tags::CONSTANT, |
322 | NameKind::ModuleDef(hir::ModuleDef::Static(_)) => tags::CONSTANT, | 322 | NameDefinition::ModuleDef(hir::ModuleDef::Static(_)) => tags::CONSTANT, |
323 | NameKind::ModuleDef(hir::ModuleDef::Trait(_)) => tags::TYPE, | 323 | NameDefinition::ModuleDef(hir::ModuleDef::Trait(_)) => tags::TYPE, |
324 | NameKind::ModuleDef(hir::ModuleDef::TypeAlias(_)) => tags::TYPE, | 324 | NameDefinition::ModuleDef(hir::ModuleDef::TypeAlias(_)) => tags::TYPE, |
325 | NameKind::ModuleDef(hir::ModuleDef::BuiltinType(_)) => tags::TYPE_BUILTIN, | 325 | NameDefinition::ModuleDef(hir::ModuleDef::BuiltinType(_)) => tags::TYPE_BUILTIN, |
326 | NameKind::SelfType(_) => tags::TYPE_SELF, | 326 | NameDefinition::SelfType(_) => tags::TYPE_SELF, |
327 | NameKind::TypeParam(_) => tags::TYPE_PARAM, | 327 | NameDefinition::TypeParam(_) => tags::TYPE_PARAM, |
328 | NameKind::Local(local) => { | 328 | NameDefinition::Local(local) => { |
329 | if local.is_mut(db) || local.ty(db).is_mutable_reference() { | 329 | if local.is_mut(db) || local.ty(db).is_mutable_reference() { |
330 | tags::VARIABLE_MUT | 330 | tags::VARIABLE_MUT |
331 | } else { | 331 | } else { |
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 030f44f86..04c214624 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs | |||
@@ -6,8 +6,8 @@ | |||
6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). | 6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). |
7 | 7 | ||
8 | use hir::{ | 8 | use hir::{ |
9 | Adt, HasSource, ImplBlock, InFile, Local, MacroDef, Module, ModuleDef, SourceBinder, | 9 | Adt, FieldSource, HasSource, ImplBlock, InFile, Local, MacroDef, Module, ModuleDef, |
10 | StructField, TypeParam, VariantDef, | 10 | SourceBinder, StructField, TypeParam, |
11 | }; | 11 | }; |
12 | use ra_prof::profile; | 12 | use ra_prof::profile; |
13 | use ra_syntax::{ | 13 | use ra_syntax::{ |
@@ -18,7 +18,7 @@ use ra_syntax::{ | |||
18 | use crate::RootDatabase; | 18 | use crate::RootDatabase; |
19 | 19 | ||
20 | #[derive(Debug, PartialEq, Eq)] | 20 | #[derive(Debug, PartialEq, Eq)] |
21 | pub enum NameKind { | 21 | pub enum NameDefinition { |
22 | Macro(MacroDef), | 22 | Macro(MacroDef), |
23 | StructField(StructField), | 23 | StructField(StructField), |
24 | ModuleDef(ModuleDef), | 24 | ModuleDef(ModuleDef), |
@@ -27,13 +27,45 @@ pub enum NameKind { | |||
27 | TypeParam(TypeParam), | 27 | TypeParam(TypeParam), |
28 | } | 28 | } |
29 | 29 | ||
30 | #[derive(PartialEq, Eq)] | 30 | impl NameDefinition { |
31 | pub struct NameDefinition { | 31 | pub fn module(&self, db: &RootDatabase) -> Option<Module> { |
32 | pub visibility: Option<ast::Visibility>, | 32 | match self { |
33 | /// FIXME: this doesn't really make sense. For example, builtin types don't | 33 | NameDefinition::Macro(it) => it.module(db), |
34 | /// really have a module. | 34 | NameDefinition::StructField(it) => Some(it.parent_def(db).module(db)), |
35 | pub container: Module, | 35 | NameDefinition::ModuleDef(it) => it.module(db), |
36 | pub kind: NameKind, | 36 | NameDefinition::SelfType(it) => Some(it.module(db)), |
37 | NameDefinition::Local(it) => Some(it.module(db)), | ||
38 | NameDefinition::TypeParam(it) => Some(it.module(db)), | ||
39 | } | ||
40 | } | ||
41 | |||
42 | pub fn visibility(&self, db: &RootDatabase) -> Option<ast::Visibility> { | ||
43 | match self { | ||
44 | NameDefinition::Macro(_) => None, | ||
45 | NameDefinition::StructField(sf) => match sf.source(db).value { | ||
46 | FieldSource::Named(it) => it.visibility(), | ||
47 | FieldSource::Pos(it) => it.visibility(), | ||
48 | }, | ||
49 | NameDefinition::ModuleDef(def) => match def { | ||
50 | ModuleDef::Module(it) => it.declaration_source(db)?.value.visibility(), | ||
51 | ModuleDef::Function(it) => it.source(db).value.visibility(), | ||
52 | ModuleDef::Adt(adt) => match adt { | ||
53 | Adt::Struct(it) => it.source(db).value.visibility(), | ||
54 | Adt::Union(it) => it.source(db).value.visibility(), | ||
55 | Adt::Enum(it) => it.source(db).value.visibility(), | ||
56 | }, | ||
57 | ModuleDef::Const(it) => it.source(db).value.visibility(), | ||
58 | ModuleDef::Static(it) => it.source(db).value.visibility(), | ||
59 | ModuleDef::Trait(it) => it.source(db).value.visibility(), | ||
60 | ModuleDef::TypeAlias(it) => it.source(db).value.visibility(), | ||
61 | ModuleDef::EnumVariant(_) => None, | ||
62 | ModuleDef::BuiltinType(_) => None, | ||
63 | }, | ||
64 | NameDefinition::SelfType(_) => None, | ||
65 | NameDefinition::Local(_) => None, | ||
66 | NameDefinition::TypeParam(_) => None, | ||
67 | } | ||
68 | } | ||
37 | } | 69 | } |
38 | 70 | ||
39 | pub fn classify_name( | 71 | pub fn classify_name( |
@@ -48,125 +80,77 @@ pub fn classify_name( | |||
48 | ast::BindPat(it) => { | 80 | ast::BindPat(it) => { |
49 | let src = name.with_value(it); | 81 | let src = name.with_value(it); |
50 | let local = sb.to_def(src)?; | 82 | let local = sb.to_def(src)?; |
51 | Some(NameDefinition { | 83 | Some(NameDefinition::Local(local)) |
52 | visibility: None, | ||
53 | container: local.module(sb.db), | ||
54 | kind: NameKind::Local(local), | ||
55 | }) | ||
56 | }, | 84 | }, |
57 | ast::RecordFieldDef(it) => { | 85 | ast::RecordFieldDef(it) => { |
58 | let src = name.with_value(it); | 86 | let src = name.with_value(it); |
59 | let field: hir::StructField = sb.to_def(src)?; | 87 | let field: hir::StructField = sb.to_def(src)?; |
60 | Some(from_struct_field(sb.db, field)) | 88 | Some(from_struct_field(field)) |
61 | }, | 89 | }, |
62 | ast::Module(it) => { | 90 | ast::Module(it) => { |
63 | let def = sb.to_def(name.with_value(it))?; | 91 | let def = sb.to_def(name.with_value(it))?; |
64 | Some(from_module_def(sb.db, def.into(), None)) | 92 | Some(from_module_def(def.into())) |
65 | }, | 93 | }, |
66 | ast::StructDef(it) => { | 94 | ast::StructDef(it) => { |
67 | let src = name.with_value(it); | 95 | let src = name.with_value(it); |
68 | let def: hir::Struct = sb.to_def(src)?; | 96 | let def: hir::Struct = sb.to_def(src)?; |
69 | Some(from_module_def(sb.db, def.into(), None)) | 97 | Some(from_module_def(def.into())) |
70 | }, | 98 | }, |
71 | ast::EnumDef(it) => { | 99 | ast::EnumDef(it) => { |
72 | let src = name.with_value(it); | 100 | let src = name.with_value(it); |
73 | let def: hir::Enum = sb.to_def(src)?; | 101 | let def: hir::Enum = sb.to_def(src)?; |
74 | Some(from_module_def(sb.db, def.into(), None)) | 102 | Some(from_module_def(def.into())) |
75 | }, | 103 | }, |
76 | ast::TraitDef(it) => { | 104 | ast::TraitDef(it) => { |
77 | let src = name.with_value(it); | 105 | let src = name.with_value(it); |
78 | let def: hir::Trait = sb.to_def(src)?; | 106 | let def: hir::Trait = sb.to_def(src)?; |
79 | Some(from_module_def(sb.db, def.into(), None)) | 107 | Some(from_module_def(def.into())) |
80 | }, | 108 | }, |
81 | ast::StaticDef(it) => { | 109 | ast::StaticDef(it) => { |
82 | let src = name.with_value(it); | 110 | let src = name.with_value(it); |
83 | let def: hir::Static = sb.to_def(src)?; | 111 | let def: hir::Static = sb.to_def(src)?; |
84 | Some(from_module_def(sb.db, def.into(), None)) | 112 | Some(from_module_def(def.into())) |
85 | }, | 113 | }, |
86 | ast::EnumVariant(it) => { | 114 | ast::EnumVariant(it) => { |
87 | let src = name.with_value(it); | 115 | let src = name.with_value(it); |
88 | let def: hir::EnumVariant = sb.to_def(src)?; | 116 | let def: hir::EnumVariant = sb.to_def(src)?; |
89 | Some(from_module_def(sb.db, def.into(), None)) | 117 | Some(from_module_def(def.into())) |
90 | }, | 118 | }, |
91 | ast::FnDef(it) => { | 119 | ast::FnDef(it) => { |
92 | let src = name.with_value(it); | 120 | let src = name.with_value(it); |
93 | let def: hir::Function = sb.to_def(src)?; | 121 | let def: hir::Function = sb.to_def(src)?; |
94 | Some(from_module_def(sb.db, def.into(), None)) | 122 | Some(from_module_def(def.into())) |
95 | }, | 123 | }, |
96 | ast::ConstDef(it) => { | 124 | ast::ConstDef(it) => { |
97 | let src = name.with_value(it); | 125 | let src = name.with_value(it); |
98 | let def: hir::Const = sb.to_def(src)?; | 126 | let def: hir::Const = sb.to_def(src)?; |
99 | Some(from_module_def(sb.db, def.into(), None)) | 127 | Some(from_module_def(def.into())) |
100 | }, | 128 | }, |
101 | ast::TypeAliasDef(it) => { | 129 | ast::TypeAliasDef(it) => { |
102 | let src = name.with_value(it); | 130 | let src = name.with_value(it); |
103 | let def: hir::TypeAlias = sb.to_def(src)?; | 131 | let def: hir::TypeAlias = sb.to_def(src)?; |
104 | Some(from_module_def(sb.db, def.into(), None)) | 132 | Some(from_module_def(def.into())) |
105 | }, | 133 | }, |
106 | ast::MacroCall(it) => { | 134 | ast::MacroCall(it) => { |
107 | let src = name.with_value(it); | 135 | let src = name.with_value(it); |
108 | let def = sb.to_def(src.clone())?; | 136 | let def = sb.to_def(src.clone())?; |
109 | 137 | ||
110 | let module = sb.to_module_def(src.file_id.original_file(sb.db))?; | 138 | Some(NameDefinition::Macro(def)) |
111 | |||
112 | Some(NameDefinition { | ||
113 | visibility: None, | ||
114 | container: module, | ||
115 | kind: NameKind::Macro(def), | ||
116 | }) | ||
117 | }, | 139 | }, |
118 | ast::TypeParam(it) => { | 140 | ast::TypeParam(it) => { |
119 | let src = name.with_value(it); | 141 | let src = name.with_value(it); |
120 | let def = sb.to_def(src)?; | 142 | let def = sb.to_def(src)?; |
121 | Some(NameDefinition { | 143 | Some(NameDefinition::TypeParam(def)) |
122 | visibility: None, | ||
123 | container: def.module(sb.db), | ||
124 | kind: NameKind::TypeParam(def), | ||
125 | }) | ||
126 | }, | 144 | }, |
127 | _ => None, | 145 | _ => None, |
128 | } | 146 | } |
129 | } | 147 | } |
130 | } | 148 | } |
131 | 149 | ||
132 | pub fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDefinition { | 150 | pub fn from_struct_field(field: StructField) -> NameDefinition { |
133 | let kind = NameKind::StructField(field); | 151 | NameDefinition::StructField(field) |
134 | let parent = field.parent_def(db); | ||
135 | let container = parent.module(db); | ||
136 | let visibility = match parent { | ||
137 | VariantDef::Struct(s) => s.source(db).value.visibility(), | ||
138 | VariantDef::Union(e) => e.source(db).value.visibility(), | ||
139 | VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), | ||
140 | }; | ||
141 | NameDefinition { kind, container, visibility } | ||
142 | } | 152 | } |
143 | 153 | ||
144 | pub fn from_module_def( | 154 | pub fn from_module_def(def: ModuleDef) -> NameDefinition { |
145 | db: &RootDatabase, | 155 | NameDefinition::ModuleDef(def) |
146 | def: ModuleDef, | ||
147 | module: Option<Module>, | ||
148 | ) -> NameDefinition { | ||
149 | let kind = NameKind::ModuleDef(def); | ||
150 | let (container, visibility) = match def { | ||
151 | ModuleDef::Module(it) => { | ||
152 | let container = it.parent(db).or_else(|| Some(it)).unwrap(); | ||
153 | let visibility = it.declaration_source(db).and_then(|s| s.value.visibility()); | ||
154 | (container, visibility) | ||
155 | } | ||
156 | ModuleDef::EnumVariant(it) => { | ||
157 | let container = it.module(db); | ||
158 | let visibility = it.source(db).value.parent_enum().visibility(); | ||
159 | (container, visibility) | ||
160 | } | ||
161 | ModuleDef::Function(it) => (it.module(db), it.source(db).value.visibility()), | ||
162 | ModuleDef::Const(it) => (it.module(db), it.source(db).value.visibility()), | ||
163 | ModuleDef::Static(it) => (it.module(db), it.source(db).value.visibility()), | ||
164 | ModuleDef::Trait(it) => (it.module(db), it.source(db).value.visibility()), | ||
165 | ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).value.visibility()), | ||
166 | ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).value.visibility()), | ||
167 | ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).value.visibility()), | ||
168 | ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).value.visibility()), | ||
169 | ModuleDef::BuiltinType(..) => (module.unwrap(), None), | ||
170 | }; | ||
171 | NameDefinition { kind, container, visibility } | ||
172 | } | 156 | } |
diff --git a/crates/ra_ide_db/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs index 86383bcd0..b8dd358a9 100644 --- a/crates/ra_ide_db/src/imports_locator.rs +++ b/crates/ra_ide_db/src/imports_locator.rs | |||
@@ -6,8 +6,7 @@ use ra_prof::profile; | |||
6 | use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; | 6 | use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | defs::classify_name, | 9 | defs::{classify_name, NameDefinition}, |
10 | defs::NameKind, | ||
11 | symbol_index::{self, FileSymbol, Query}, | 10 | symbol_index::{self, FileSymbol, Query}, |
12 | RootDatabase, | 11 | RootDatabase, |
13 | }; | 12 | }; |
@@ -44,7 +43,7 @@ impl<'a> ImportsLocator<'a> { | |||
44 | .chain(lib_results.into_iter()) | 43 | .chain(lib_results.into_iter()) |
45 | .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate)) | 44 | .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate)) |
46 | .filter_map(|name_definition_to_import| match name_definition_to_import { | 45 | .filter_map(|name_definition_to_import| match name_definition_to_import { |
47 | NameKind::ModuleDef(module_def) => Some(module_def), | 46 | NameDefinition::ModuleDef(module_def) => Some(module_def), |
48 | _ => None, | 47 | _ => None, |
49 | }) | 48 | }) |
50 | .collect() | 49 | .collect() |
@@ -54,7 +53,7 @@ impl<'a> ImportsLocator<'a> { | |||
54 | &mut self, | 53 | &mut self, |
55 | db: &impl HirDatabase, | 54 | db: &impl HirDatabase, |
56 | import_candidate: &FileSymbol, | 55 | import_candidate: &FileSymbol, |
57 | ) -> Option<NameKind> { | 56 | ) -> Option<NameDefinition> { |
58 | let _p = profile("get_name_definition"); | 57 | let _p = profile("get_name_definition"); |
59 | let file_id = import_candidate.file_id.into(); | 58 | let file_id = import_candidate.file_id.into(); |
60 | let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); | 59 | let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); |
@@ -67,6 +66,5 @@ impl<'a> ImportsLocator<'a> { | |||
67 | &mut self.source_binder, | 66 | &mut self.source_binder, |
68 | hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? }, | 67 | hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? }, |
69 | ) | 68 | ) |
70 | .map(|it| it.kind) | ||
71 | } | 69 | } |
72 | } | 70 | } |
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs index eb8b79e9a..dacca8279 100644 --- a/crates/ra_mbe/src/subtree_source.rs +++ b/crates/ra_mbe/src/subtree_source.rs | |||
@@ -141,7 +141,7 @@ fn convert_literal(l: &tt::Literal) -> TtToken { | |||
141 | } | 141 | } |
142 | 142 | ||
143 | fn convert_ident(ident: &tt::Ident) -> TtToken { | 143 | fn convert_ident(ident: &tt::Ident) -> TtToken { |
144 | let kind = if let Some('\'') = ident.text.chars().next() { | 144 | let kind = if ident.text.starts_with('\'') { |
145 | LIFETIME | 145 | LIFETIME |
146 | } else { | 146 | } else { |
147 | SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT) | 147 | SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT) |
diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index e06a6d7d2..823745795 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml | |||
@@ -11,7 +11,7 @@ doctest = false | |||
11 | [dependencies] | 11 | [dependencies] |
12 | once_cell = "1.3.1" | 12 | once_cell = "1.3.1" |
13 | itertools = "0.8.2" | 13 | itertools = "0.8.2" |
14 | backtrace = "0.3.44" | 14 | backtrace = { version = "0.3.44", optional = true } |
15 | 15 | ||
16 | [target.'cfg(not(target_env = "msvc"))'.dependencies] | 16 | [target.'cfg(not(target_env = "msvc"))'.dependencies] |
17 | jemallocator = { version = "0.3.2", optional = true } | 17 | jemallocator = { version = "0.3.2", optional = true } |
diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index 660d85b42..6853a4794 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs | |||
@@ -315,6 +315,7 @@ fn idx_to_children(msgs: &[Message]) -> Vec<Vec<usize>> { | |||
315 | } | 315 | } |
316 | 316 | ||
317 | /// Prints backtrace to stderr, useful for debugging. | 317 | /// Prints backtrace to stderr, useful for debugging. |
318 | #[cfg(feature = "backtrace")] | ||
318 | pub fn print_backtrace() { | 319 | pub fn print_backtrace() { |
319 | let bt = backtrace::Backtrace::new(); | 320 | let bt = backtrace::Backtrace::new(); |
320 | eprintln!("{:?}", bt); | 321 | eprintln!("{:?}", bt); |
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs index f99984fe0..f8cf1e3eb 100644 --- a/crates/ra_syntax/src/ast/traits.rs +++ b/crates/ra_syntax/src/ast/traits.rs | |||
@@ -126,8 +126,8 @@ pub trait DocCommentsOwner: AstNode { | |||
126 | 126 | ||
127 | // Determine if the prefix or prefix + 1 char is stripped | 127 | // Determine if the prefix or prefix + 1 char is stripped |
128 | let pos = | 128 | let pos = |
129 | if line.chars().nth(prefix_len).map(|c| c.is_whitespace()).unwrap_or(false) { | 129 | if let Some(ws) = line.chars().nth(prefix_len).filter(|c| c.is_whitespace()) { |
130 | prefix_len + 1 | 130 | prefix_len + ws.len_utf8() |
131 | } else { | 131 | } else { |
132 | prefix_len | 132 | prefix_len |
133 | }; | 133 | }; |
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index c4711076c..c9fd645f1 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs | |||
@@ -57,6 +57,7 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
57 | execute_command_provider: None, | 57 | execute_command_provider: None, |
58 | workspace: None, | 58 | workspace: None, |
59 | call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), | 59 | call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), |
60 | semantic_tokens_provider: None, | ||
60 | experimental: Default::default(), | 61 | experimental: Default::default(), |
61 | } | 62 | } |
62 | } | 63 | } |