diff options
-rw-r--r-- | crates/ra_analysis/src/completion/complete_path.rs | 39 | ||||
-rw-r--r-- | crates/ra_analysis/src/completion/completion_item.rs | 1 | ||||
-rw-r--r-- | crates/ra_analysis/src/extend_selection.rs | 44 | ||||
-rw-r--r-- | crates/ra_analysis/src/macros.rs | 11 | ||||
-rw-r--r-- | crates/ra_analysis/src/mock_analysis.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/adt.rs | 45 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/module.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/name.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/query_definitions.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 24 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 1 |
12 files changed, 150 insertions, 78 deletions
diff --git a/crates/ra_analysis/src/completion/complete_path.rs b/crates/ra_analysis/src/completion/complete_path.rs index aaa2c7cee..c73a083a4 100644 --- a/crates/ra_analysis/src/completion/complete_path.rs +++ b/crates/ra_analysis/src/completion/complete_path.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use crate::{ | 1 | use crate::{ |
2 | Cancelable, | 2 | Cancelable, |
3 | completion::{CompletionItem, Completions, CompletionKind, CompletionContext}, | 3 | completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext}, |
4 | }; | 4 | }; |
5 | 5 | ||
6 | pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> { | 6 | pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> { |
@@ -12,16 +12,25 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) -> C | |||
12 | Some(it) => it, | 12 | Some(it) => it, |
13 | None => return Ok(()), | 13 | None => return Ok(()), |
14 | }; | 14 | }; |
15 | let target_module = match def_id.resolve(ctx.db)? { | 15 | match def_id.resolve(ctx.db)? { |
16 | hir::Def::Module(it) => it, | 16 | hir::Def::Module(module) => { |
17 | let module_scope = module.scope(ctx.db)?; | ||
18 | module_scope.entries().for_each(|(name, res)| { | ||
19 | CompletionItem::new(CompletionKind::Reference, name.to_string()) | ||
20 | .from_resolution(ctx.db, res) | ||
21 | .add_to(acc) | ||
22 | }); | ||
23 | } | ||
24 | hir::Def::Enum(e) => e | ||
25 | .variants(ctx.db)? | ||
26 | .into_iter() | ||
27 | .for_each(|(name, _variant)| { | ||
28 | CompletionItem::new(CompletionKind::Reference, name.to_string()) | ||
29 | .kind(CompletionItemKind::EnumVariant) | ||
30 | .add_to(acc) | ||
31 | }), | ||
17 | _ => return Ok(()), | 32 | _ => return Ok(()), |
18 | }; | 33 | }; |
19 | let module_scope = target_module.scope(ctx.db)?; | ||
20 | module_scope.entries().for_each(|(name, res)| { | ||
21 | CompletionItem::new(CompletionKind::Reference, name.to_string()) | ||
22 | .from_resolution(ctx.db, res) | ||
23 | .add_to(acc) | ||
24 | }); | ||
25 | Ok(()) | 34 | Ok(()) |
26 | } | 35 | } |
27 | 36 | ||
@@ -92,4 +101,16 @@ mod tests { | |||
92 | "Spam", | 101 | "Spam", |
93 | ); | 102 | ); |
94 | } | 103 | } |
104 | |||
105 | #[test] | ||
106 | fn completes_enum_variant() { | ||
107 | check_reference_completion( | ||
108 | " | ||
109 | //- /lib.rs | ||
110 | enum E { Foo, Bar(i32) } | ||
111 | fn foo() { let _ = E::<|> } | ||
112 | ", | ||
113 | "Foo;Bar", | ||
114 | ); | ||
115 | } | ||
95 | } | 116 | } |
diff --git a/crates/ra_analysis/src/completion/completion_item.rs b/crates/ra_analysis/src/completion/completion_item.rs index c9f9f495d..1d294c553 100644 --- a/crates/ra_analysis/src/completion/completion_item.rs +++ b/crates/ra_analysis/src/completion/completion_item.rs | |||
@@ -29,6 +29,7 @@ pub enum CompletionItemKind { | |||
29 | Function, | 29 | Function, |
30 | Struct, | 30 | Struct, |
31 | Enum, | 31 | Enum, |
32 | EnumVariant, | ||
32 | Binding, | 33 | Binding, |
33 | Field, | 34 | Field, |
34 | } | 35 | } |
diff --git a/crates/ra_analysis/src/extend_selection.rs b/crates/ra_analysis/src/extend_selection.rs index 5e1fbee18..cde6ee101 100644 --- a/crates/ra_analysis/src/extend_selection.rs +++ b/crates/ra_analysis/src/extend_selection.rs | |||
@@ -1,4 +1,8 @@ | |||
1 | use ra_db::SyntaxDatabase; | 1 | use ra_db::SyntaxDatabase; |
2 | use ra_syntax::{ | ||
3 | SyntaxNodeRef, AstNode, | ||
4 | ast, algo::find_covering_node, | ||
5 | }; | ||
2 | 6 | ||
3 | use crate::{ | 7 | use crate::{ |
4 | TextRange, FileRange, | 8 | TextRange, FileRange, |
@@ -6,6 +10,42 @@ use crate::{ | |||
6 | }; | 10 | }; |
7 | 11 | ||
8 | pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { | 12 | pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { |
9 | let file = db.source_file(frange.file_id); | 13 | let source_file = db.source_file(frange.file_id); |
10 | ra_editor::extend_selection(&file, frange.range).unwrap_or(frange.range) | 14 | if let Some(macro_call) = find_macro_call(source_file.syntax(), frange.range) { |
15 | if let Some(exp) = crate::macros::expand(db, frange.file_id, macro_call) { | ||
16 | if let Some(dst_range) = exp.map_range_forward(frange.range) { | ||
17 | if let Some(dst_range) = ra_editor::extend_selection(exp.source_file(), dst_range) { | ||
18 | if let Some(src_range) = exp.map_range_back(dst_range) { | ||
19 | return src_range; | ||
20 | } | ||
21 | } | ||
22 | } | ||
23 | } | ||
24 | } | ||
25 | ra_editor::extend_selection(&source_file, frange.range).unwrap_or(frange.range) | ||
26 | } | ||
27 | |||
28 | fn find_macro_call(node: SyntaxNodeRef, range: TextRange) -> Option<ast::MacroCall> { | ||
29 | find_covering_node(node, range) | ||
30 | .ancestors() | ||
31 | .find_map(ast::MacroCall::cast) | ||
32 | } | ||
33 | |||
34 | #[cfg(test)] | ||
35 | mod tests { | ||
36 | use crate::mock_analysis::single_file_with_range; | ||
37 | use test_utils::assert_eq_dbg; | ||
38 | |||
39 | #[test] | ||
40 | fn extend_selection_inside_macros() { | ||
41 | let (analysis, frange) = single_file_with_range( | ||
42 | " | ||
43 | fn main() { | ||
44 | ctry!(foo(|x| <|>x<|>)); | ||
45 | } | ||
46 | ", | ||
47 | ); | ||
48 | let r = analysis.extend_selection(frange); | ||
49 | assert_eq_dbg("[51; 56)", &r); | ||
50 | } | ||
11 | } | 51 | } |
diff --git a/crates/ra_analysis/src/macros.rs b/crates/ra_analysis/src/macros.rs index c0dd49dc8..b9feb7fad 100644 --- a/crates/ra_analysis/src/macros.rs +++ b/crates/ra_analysis/src/macros.rs | |||
@@ -61,4 +61,15 @@ impl MacroExpansion { | |||
61 | } | 61 | } |
62 | None | 62 | None |
63 | } | 63 | } |
64 | pub(crate) fn map_range_forward(&self, src_range: TextRange) -> Option<TextRange> { | ||
65 | for (s_range, t_range) in self.ranges_map.iter() { | ||
66 | if src_range.is_subrange(&s_range) { | ||
67 | let src_at_zero_range = src_range - src_range.start(); | ||
68 | let src_range_offset = src_range.start() - s_range.start(); | ||
69 | let src_range = src_at_zero_range + src_range_offset + t_range.start(); | ||
70 | return Some(src_range); | ||
71 | } | ||
72 | } | ||
73 | None | ||
74 | } | ||
64 | } | 75 | } |
diff --git a/crates/ra_analysis/src/mock_analysis.rs b/crates/ra_analysis/src/mock_analysis.rs index 5ce2aa2b4..960529404 100644 --- a/crates/ra_analysis/src/mock_analysis.rs +++ b/crates/ra_analysis/src/mock_analysis.rs | |||
@@ -1,10 +1,10 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use relative_path::RelativePathBuf; | 3 | use relative_path::RelativePathBuf; |
4 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; | 4 | use test_utils::{extract_offset, extract_range, parse_fixture, CURSOR_MARKER}; |
5 | use ra_db::mock::FileMap; | 5 | use ra_db::mock::FileMap; |
6 | 6 | ||
7 | use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FilePosition, SourceRootId}; | 7 | use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FilePosition, FileRange, SourceRootId}; |
8 | 8 | ||
9 | /// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis | 9 | /// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis |
10 | /// from a set of in-memory files. | 10 | /// from a set of in-memory files. |
@@ -66,6 +66,12 @@ impl MockAnalysis { | |||
66 | self.files.push((path.to_string(), text.to_string())); | 66 | self.files.push((path.to_string(), text.to_string())); |
67 | FilePosition { file_id, offset } | 67 | FilePosition { file_id, offset } |
68 | } | 68 | } |
69 | pub fn add_file_with_range(&mut self, path: &str, text: &str) -> FileRange { | ||
70 | let (range, text) = extract_range(text); | ||
71 | let file_id = FileId((self.files.len() + 1) as u32); | ||
72 | self.files.push((path.to_string(), text.to_string())); | ||
73 | FileRange { file_id, range } | ||
74 | } | ||
69 | pub fn id_of(&self, path: &str) -> FileId { | 75 | pub fn id_of(&self, path: &str) -> FileId { |
70 | let (idx, _) = self | 76 | let (idx, _) = self |
71 | .files | 77 | .files |
@@ -115,3 +121,10 @@ pub fn single_file_with_position(code: &str) -> (Analysis, FilePosition) { | |||
115 | let pos = mock.add_file_with_position("/main.rs", code); | 121 | let pos = mock.add_file_with_position("/main.rs", code); |
116 | (mock.analysis(), pos) | 122 | (mock.analysis(), pos) |
117 | } | 123 | } |
124 | |||
125 | /// Creates analysis for a single file, returns range marked with a pair of <|>. | ||
126 | pub fn single_file_with_range(code: &str) -> (Analysis, FileRange) { | ||
127 | let mut mock = MockAnalysis::new(); | ||
128 | let pos = mock.add_file_with_range("/main.rs", code); | ||
129 | (mock.analysis(), pos) | ||
130 | } | ||
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index 65c461148..e839a5a90 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -1,10 +1,10 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{SmolStr, ast::{self, NameOwner, StructFlavor}}; | 3 | use ra_syntax::ast::{self, NameOwner, StructFlavor}; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | DefId, Cancelable, | 6 | DefId, Cancelable, Name, AsName, |
7 | db::{HirDatabase}, | 7 | db::HirDatabase, |
8 | type_ref::TypeRef, | 8 | type_ref::TypeRef, |
9 | }; | 9 | }; |
10 | 10 | ||
@@ -29,26 +29,26 @@ impl Struct { | |||
29 | Ok(db.struct_data(self.def_id)?) | 29 | Ok(db.struct_data(self.def_id)?) |
30 | } | 30 | } |
31 | 31 | ||
32 | pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<SmolStr>> { | 32 | pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { |
33 | Ok(db.struct_data(self.def_id)?.name.clone()) | 33 | Ok(db.struct_data(self.def_id)?.name.clone()) |
34 | } | 34 | } |
35 | } | 35 | } |
36 | 36 | ||
37 | #[derive(Debug, Clone, PartialEq, Eq)] | 37 | #[derive(Debug, Clone, PartialEq, Eq)] |
38 | pub struct StructData { | 38 | pub struct StructData { |
39 | name: Option<SmolStr>, | 39 | name: Option<Name>, |
40 | variant_data: Arc<VariantData>, | 40 | variant_data: Arc<VariantData>, |
41 | } | 41 | } |
42 | 42 | ||
43 | impl StructData { | 43 | impl StructData { |
44 | pub(crate) fn new(struct_def: ast::StructDef) -> StructData { | 44 | pub(crate) fn new(struct_def: ast::StructDef) -> StructData { |
45 | let name = struct_def.name().map(|n| n.text()); | 45 | let name = struct_def.name().map(|n| n.as_name()); |
46 | let variant_data = VariantData::new(struct_def.flavor()); | 46 | let variant_data = VariantData::new(struct_def.flavor()); |
47 | let variant_data = Arc::new(variant_data); | 47 | let variant_data = Arc::new(variant_data); |
48 | StructData { name, variant_data } | 48 | StructData { name, variant_data } |
49 | } | 49 | } |
50 | 50 | ||
51 | pub fn name(&self) -> Option<&SmolStr> { | 51 | pub fn name(&self) -> Option<&Name> { |
52 | self.name.as_ref() | 52 | self.name.as_ref() |
53 | } | 53 | } |
54 | 54 | ||
@@ -70,27 +70,29 @@ impl Enum { | |||
70 | self.def_id | 70 | self.def_id |
71 | } | 71 | } |
72 | 72 | ||
73 | pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<SmolStr>> { | 73 | pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { |
74 | Ok(db.enum_data(self.def_id)?.name.clone()) | 74 | Ok(db.enum_data(self.def_id)?.name.clone()) |
75 | } | 75 | } |
76 | |||
77 | pub fn variants(&self, db: &impl HirDatabase) -> Cancelable<Vec<(Name, Arc<VariantData>)>> { | ||
78 | Ok(db.enum_data(self.def_id)?.variants.clone()) | ||
79 | } | ||
76 | } | 80 | } |
77 | 81 | ||
78 | #[derive(Debug, Clone, PartialEq, Eq)] | 82 | #[derive(Debug, Clone, PartialEq, Eq)] |
79 | pub struct EnumData { | 83 | pub struct EnumData { |
80 | name: Option<SmolStr>, | 84 | name: Option<Name>, |
81 | variants: Vec<(SmolStr, Arc<VariantData>)>, | 85 | variants: Vec<(Name, Arc<VariantData>)>, |
82 | } | 86 | } |
83 | 87 | ||
84 | impl EnumData { | 88 | impl EnumData { |
85 | pub(crate) fn new(enum_def: ast::EnumDef) -> Self { | 89 | pub(crate) fn new(enum_def: ast::EnumDef) -> Self { |
86 | let name = enum_def.name().map(|n| n.text()); | 90 | let name = enum_def.name().map(|n| n.as_name()); |
87 | let variants = if let Some(evl) = enum_def.variant_list() { | 91 | let variants = if let Some(evl) = enum_def.variant_list() { |
88 | evl.variants() | 92 | evl.variants() |
89 | .map(|v| { | 93 | .map(|v| { |
90 | ( | 94 | ( |
91 | v.name() | 95 | v.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), |
92 | .map(|n| n.text()) | ||
93 | .unwrap_or_else(|| SmolStr::new("[error]")), | ||
94 | Arc::new(VariantData::new(v.flavor())), | 96 | Arc::new(VariantData::new(v.flavor())), |
95 | ) | 97 | ) |
96 | }) | 98 | }) |
@@ -105,12 +107,12 @@ impl EnumData { | |||
105 | /// A single field of an enum variant or struct | 107 | /// A single field of an enum variant or struct |
106 | #[derive(Debug, Clone, PartialEq, Eq)] | 108 | #[derive(Debug, Clone, PartialEq, Eq)] |
107 | pub struct StructField { | 109 | pub struct StructField { |
108 | name: SmolStr, | 110 | name: Name, |
109 | type_ref: TypeRef, | 111 | type_ref: TypeRef, |
110 | } | 112 | } |
111 | 113 | ||
112 | impl StructField { | 114 | impl StructField { |
113 | pub fn name(&self) -> SmolStr { | 115 | pub fn name(&self) -> Name { |
114 | self.name.clone() | 116 | self.name.clone() |
115 | } | 117 | } |
116 | pub fn type_ref(&self) -> &TypeRef { | 118 | pub fn type_ref(&self) -> &TypeRef { |
@@ -134,7 +136,7 @@ impl VariantData { | |||
134 | .fields() | 136 | .fields() |
135 | .enumerate() | 137 | .enumerate() |
136 | .map(|(i, fd)| StructField { | 138 | .map(|(i, fd)| StructField { |
137 | name: SmolStr::new(i.to_string()), | 139 | name: Name::tuple_field_name(i), |
138 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), | 140 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), |
139 | }) | 141 | }) |
140 | .collect(); | 142 | .collect(); |
@@ -144,10 +146,7 @@ impl VariantData { | |||
144 | let fields = fl | 146 | let fields = fl |
145 | .fields() | 147 | .fields() |
146 | .map(|fd| StructField { | 148 | .map(|fd| StructField { |
147 | name: fd | 149 | name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), |
148 | .name() | ||
149 | .map(|n| n.text()) | ||
150 | .unwrap_or_else(|| SmolStr::new("[error]")), | ||
151 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), | 150 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), |
152 | }) | 151 | }) |
153 | .collect(); | 152 | .collect(); |
@@ -157,10 +156,10 @@ impl VariantData { | |||
157 | } | 156 | } |
158 | } | 157 | } |
159 | 158 | ||
160 | pub(crate) fn get_field_type_ref(&self, field_name: &str) -> Option<&TypeRef> { | 159 | pub(crate) fn get_field_type_ref(&self, field_name: &Name) -> Option<&TypeRef> { |
161 | self.fields() | 160 | self.fields() |
162 | .iter() | 161 | .iter() |
163 | .find(|f| f.name == field_name) | 162 | .find(|f| f.name == *field_name) |
164 | .map(|f| &f.type_ref) | 163 | .map(|f| &f.type_ref) |
165 | } | 164 | } |
166 | 165 | ||
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index ba43a4502..b41a7429a 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -1,13 +1,10 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::SyntaxNode; |
4 | SmolStr, | ||
5 | SyntaxNode, | ||
6 | }; | ||
7 | use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, FileId, Cancelable}; | 4 | use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, FileId, Cancelable}; |
8 | 5 | ||
9 | use crate::{ | 6 | use crate::{ |
10 | DefLoc, DefId, | 7 | DefLoc, DefId, Name, |
11 | SourceFileItems, SourceItemId, | 8 | SourceFileItems, SourceItemId, |
12 | query_definitions, | 9 | query_definitions, |
13 | FnScopes, | 10 | FnScopes, |
@@ -47,7 +44,7 @@ pub trait HirDatabase: SyntaxDatabase | |||
47 | use fn query_definitions::type_for_def; | 44 | use fn query_definitions::type_for_def; |
48 | } | 45 | } |
49 | 46 | ||
50 | fn type_for_field(def_id: DefId, field: SmolStr) -> Cancelable<Ty> { | 47 | fn type_for_field(def_id: DefId, field: Name) -> Cancelable<Ty> { |
51 | type TypeForFieldQuery; | 48 | type TypeForFieldQuery; |
52 | use fn query_definitions::type_for_field; | 49 | use fn query_definitions::type_for_field; |
53 | } | 50 | } |
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs index 43413acb8..24c346984 100644 --- a/crates/ra_hir/src/module.rs +++ b/crates/ra_hir/src/module.rs | |||
@@ -13,8 +13,8 @@ use ra_db::{SourceRootId, FileId, Cancelable}; | |||
13 | use relative_path::RelativePathBuf; | 13 | use relative_path::RelativePathBuf; |
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | DefKind, DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate, | 16 | Def, DefKind, DefLoc, DefId, |
17 | Name, | 17 | Name, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate, |
18 | arena::{Arena, Id}, | 18 | arena::{Arena, Id}, |
19 | }; | 19 | }; |
20 | 20 | ||
@@ -139,13 +139,8 @@ impl Module { | |||
139 | } else { | 139 | } else { |
140 | return Ok(PerNs::none()); | 140 | return Ok(PerNs::none()); |
141 | }; | 141 | }; |
142 | let module = match curr.loc(db) { | 142 | let module = match curr.resolve(db)? { |
143 | DefLoc { | 143 | Def::Module(it) => it, |
144 | kind: DefKind::Module, | ||
145 | source_root_id, | ||
146 | module_id, | ||
147 | .. | ||
148 | } => Module::new(db, source_root_id, module_id)?, | ||
149 | // TODO here would be the place to handle enum variants... | 144 | // TODO here would be the place to handle enum variants... |
150 | _ => return Ok(PerNs::none()), | 145 | _ => return Ok(PerNs::none()), |
151 | }; | 146 | }; |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs index e4fc141a6..51e8b3da8 100644 --- a/crates/ra_hir/src/name.rs +++ b/crates/ra_hir/src/name.rs | |||
@@ -23,6 +23,18 @@ impl fmt::Debug for Name { | |||
23 | } | 23 | } |
24 | 24 | ||
25 | impl Name { | 25 | impl Name { |
26 | fn new(text: SmolStr) -> Name { | ||
27 | Name { text } | ||
28 | } | ||
29 | |||
30 | pub(crate) fn missing() -> Name { | ||
31 | Name::new("[missing name]".into()) | ||
32 | } | ||
33 | |||
34 | pub(crate) fn tuple_field_name(idx: usize) -> Name { | ||
35 | Name::new(idx.to_string().into()) | ||
36 | } | ||
37 | |||
26 | pub(crate) fn as_known_name(&self) -> Option<KnownName> { | 38 | pub(crate) fn as_known_name(&self) -> Option<KnownName> { |
27 | let name = match self.text.as_str() { | 39 | let name = match self.text.as_str() { |
28 | "isize" => KnownName::Isize, | 40 | "isize" => KnownName::Isize, |
@@ -43,10 +55,6 @@ impl Name { | |||
43 | }; | 55 | }; |
44 | Some(name) | 56 | Some(name) |
45 | } | 57 | } |
46 | |||
47 | fn new(text: SmolStr) -> Name { | ||
48 | Name { text } | ||
49 | } | ||
50 | } | 58 | } |
51 | 59 | ||
52 | pub(crate) trait AsName { | 60 | pub(crate) trait AsName { |
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index 56e3f7e9d..016d86ee6 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -5,7 +5,7 @@ use std::{ | |||
5 | 5 | ||
6 | use rustc_hash::FxHashMap; | 6 | use rustc_hash::FxHashMap; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | AstNode, SyntaxNode, SmolStr, | 8 | AstNode, SyntaxNode, |
9 | ast::{self, NameOwner, ModuleItemOwner} | 9 | ast::{self, NameOwner, ModuleItemOwner} |
10 | }; | 10 | }; |
11 | use ra_db::{SourceRootId, FileId, Cancelable,}; | 11 | use ra_db::{SourceRootId, FileId, Cancelable,}; |
@@ -39,11 +39,7 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<T | |||
39 | ty::type_for_def(db, def_id) | 39 | ty::type_for_def(db, def_id) |
40 | } | 40 | } |
41 | 41 | ||
42 | pub(super) fn type_for_field( | 42 | pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Cancelable<Ty> { |
43 | db: &impl HirDatabase, | ||
44 | def_id: DefId, | ||
45 | field: SmolStr, | ||
46 | ) -> Cancelable<Ty> { | ||
47 | ty::type_for_field(db, def_id, field) | 43 | ty::type_for_field(db, def_id, field) |
48 | } | 44 | } |
49 | 45 | ||
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index ad097d1f1..38720b7b5 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -10,13 +10,12 @@ use rustc_hash::{FxHashMap}; | |||
10 | 10 | ||
11 | use ra_db::{LocalSyntaxPtr, Cancelable}; | 11 | use ra_db::{LocalSyntaxPtr, Cancelable}; |
12 | use ra_syntax::{ | 12 | use ra_syntax::{ |
13 | SmolStr, | ||
14 | ast::{self, AstNode, LoopBodyOwner, ArgListOwner, PrefixOp}, | 13 | ast::{self, AstNode, LoopBodyOwner, ArgListOwner, PrefixOp}, |
15 | SyntaxNodeRef | 14 | SyntaxNodeRef |
16 | }; | 15 | }; |
17 | 16 | ||
18 | use crate::{ | 17 | use crate::{ |
19 | Def, DefId, FnScopes, Module, Function, Struct, Enum, Path, | 18 | Def, DefId, FnScopes, Module, Function, Struct, Enum, Path, Name, AsName, |
20 | db::HirDatabase, | 19 | db::HirDatabase, |
21 | adt::VariantData, | 20 | adt::VariantData, |
22 | type_ref::{TypeRef, Mutability}, | 21 | type_ref::{TypeRef, Mutability}, |
@@ -45,7 +44,7 @@ pub enum Ty { | |||
45 | /// The DefId of the struct/enum. | 44 | /// The DefId of the struct/enum. |
46 | def_id: DefId, | 45 | def_id: DefId, |
47 | /// The name, for displaying. | 46 | /// The name, for displaying. |
48 | name: SmolStr, | 47 | name: Name, |
49 | // later we'll need generic substitutions here | 48 | // later we'll need generic substitutions here |
50 | }, | 49 | }, |
51 | 50 | ||
@@ -276,18 +275,14 @@ pub fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { | |||
276 | pub fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Cancelable<Ty> { | 275 | pub fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Cancelable<Ty> { |
277 | Ok(Ty::Adt { | 276 | Ok(Ty::Adt { |
278 | def_id: s.def_id(), | 277 | def_id: s.def_id(), |
279 | name: s | 278 | name: s.name(db)?.unwrap_or_else(Name::missing), |
280 | .name(db)? | ||
281 | .unwrap_or_else(|| SmolStr::new("[unnamed struct]")), | ||
282 | }) | 279 | }) |
283 | } | 280 | } |
284 | 281 | ||
285 | pub fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Cancelable<Ty> { | 282 | pub fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Cancelable<Ty> { |
286 | Ok(Ty::Adt { | 283 | Ok(Ty::Adt { |
287 | def_id: s.def_id(), | 284 | def_id: s.def_id(), |
288 | name: s | 285 | name: s.name(db)?.unwrap_or_else(Name::missing), |
289 | .name(db)? | ||
290 | .unwrap_or_else(|| SmolStr::new("[unnamed enum]")), | ||
291 | }) | 286 | }) |
292 | } | 287 | } |
293 | 288 | ||
@@ -308,11 +303,7 @@ pub fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { | |||
308 | } | 303 | } |
309 | } | 304 | } |
310 | 305 | ||
311 | pub(super) fn type_for_field( | 306 | pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Cancelable<Ty> { |
312 | db: &impl HirDatabase, | ||
313 | def_id: DefId, | ||
314 | field: SmolStr, | ||
315 | ) -> Cancelable<Ty> { | ||
316 | let def = def_id.resolve(db)?; | 307 | let def = def_id.resolve(db)?; |
317 | let variant_data = match def { | 308 | let variant_data = match def { |
318 | Def::Struct(s) => { | 309 | Def::Struct(s) => { |
@@ -559,14 +550,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
559 | ast::Expr::FieldExpr(e) => { | 550 | ast::Expr::FieldExpr(e) => { |
560 | let receiver_ty = self.infer_expr_opt(e.expr())?; | 551 | let receiver_ty = self.infer_expr_opt(e.expr())?; |
561 | if let Some(nr) = e.name_ref() { | 552 | if let Some(nr) = e.name_ref() { |
562 | let text = nr.text(); | ||
563 | match receiver_ty { | 553 | match receiver_ty { |
564 | Ty::Tuple(fields) => { | 554 | Ty::Tuple(fields) => { |
565 | let i = text.parse::<usize>().ok(); | 555 | let i = nr.text().parse::<usize>().ok(); |
566 | i.and_then(|i| fields.get(i).cloned()) | 556 | i.and_then(|i| fields.get(i).cloned()) |
567 | .unwrap_or(Ty::Unknown) | 557 | .unwrap_or(Ty::Unknown) |
568 | } | 558 | } |
569 | Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, text)?, | 559 | Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, nr.as_name())?, |
570 | _ => Ty::Unknown, | 560 | _ => Ty::Unknown, |
571 | } | 561 | } |
572 | } else { | 562 | } else { |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 3d56ccd97..0d6e62727 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -57,6 +57,7 @@ impl Conv for CompletionItemKind { | |||
57 | CompletionItemKind::Function => Function, | 57 | CompletionItemKind::Function => Function, |
58 | CompletionItemKind::Struct => Struct, | 58 | CompletionItemKind::Struct => Struct, |
59 | CompletionItemKind::Enum => Enum, | 59 | CompletionItemKind::Enum => Enum, |
60 | CompletionItemKind::EnumVariant => EnumMember, | ||
60 | CompletionItemKind::Binding => Variable, | 61 | CompletionItemKind::Binding => Variable, |
61 | CompletionItemKind::Field => Field, | 62 | CompletionItemKind::Field => Field, |
62 | } | 63 | } |