aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-02 08:20:50 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-02 08:20:50 +0000
commitda3802b2ce4796461a9fff22f4e9c6fd890879b2 (patch)
treeb3df38ae7b749178d854be9f2e6b16070a373216 /crates
parent4447019f4b5f24728bb7b91b161755ddb373c74c (diff)
parentd8ef8acb47b1be92da97a2d5cd4334bceed5b919 (diff)
Merge #725
725: Implement `use as` r=matklad a=flodiebold Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/nameres.rs21
-rw-r--r--crates/ra_hir/src/nameres/lower.rs4
-rw-r--r--crates/ra_hir/src/nameres/tests.rs24
-rw-r--r--crates/ra_hir/src/path.rs13
-rw-r--r--crates/ra_syntax/src/ast/generated.rs33
-rw-r--r--crates/ra_syntax/src/grammar.ron5
6 files changed, 83 insertions, 17 deletions
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 7ec6512b6..04cc693b3 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -251,10 +251,14 @@ where
251 }; 251 };
252 } 252 }
253 for (import_id, import_data) in input.imports.iter() { 253 for (import_id, import_data) in input.imports.iter() {
254 if let Some(segment) = import_data.path.segments.iter().last() { 254 if let Some(last_segment) = import_data.path.segments.iter().last() {
255 if !import_data.is_glob { 255 if !import_data.is_glob {
256 let name = import_data
257 .alias
258 .clone()
259 .unwrap_or_else(|| last_segment.name.clone());
256 module_items.items.insert( 260 module_items.items.insert(
257 segment.name.clone(), 261 name,
258 Resolution { 262 Resolution {
259 def: PerNs::none(), 263 def: PerNs::none(),
260 import: Some(import_id), 264 import: Some(import_id),
@@ -319,19 +323,18 @@ where
319 323
320 if reached_fixedpoint == ReachedFixedPoint::Yes { 324 if reached_fixedpoint == ReachedFixedPoint::Yes {
321 let last_segment = import.path.segments.last().unwrap(); 325 let last_segment = import.path.segments.last().unwrap();
326 let name = import
327 .alias
328 .clone()
329 .unwrap_or_else(|| last_segment.name.clone());
330 log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def,);
322 self.update(module_id, |items| { 331 self.update(module_id, |items| {
323 let res = Resolution { 332 let res = Resolution {
324 def, 333 def,
325 import: Some(import_id), 334 import: Some(import_id),
326 }; 335 };
327 items.items.insert(last_segment.name.clone(), res); 336 items.items.insert(name, res);
328 }); 337 });
329 log::debug!(
330 "resolved import {:?} ({:?}) cross-source root to {:?}",
331 last_segment.name,
332 import,
333 def,
334 );
335 } 338 }
336 reached_fixedpoint 339 reached_fixedpoint
337 } 340 }
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs
index 9a45fa61c..df87f520f 100644
--- a/crates/ra_hir/src/nameres/lower.rs
+++ b/crates/ra_hir/src/nameres/lower.rs
@@ -21,6 +21,7 @@ impl_arena_id!(ImportId);
21#[derive(Debug, PartialEq, Eq)] 21#[derive(Debug, PartialEq, Eq)]
22pub(super) struct ImportData { 22pub(super) struct ImportData {
23 pub(super) path: Path, 23 pub(super) path: Path,
24 pub(super) alias: Option<Name>,
24 pub(super) is_glob: bool, 25 pub(super) is_glob: bool,
25} 26}
26 27
@@ -209,9 +210,10 @@ impl LoweredModule {
209 } 210 }
210 211
211 fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) { 212 fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) {
212 Path::expand_use_item(item, |path, segment| { 213 Path::expand_use_item(item, |path, segment, alias| {
213 let import = self.imports.alloc(ImportData { 214 let import = self.imports.alloc(ImportData {
214 path, 215 path,
216 alias,
215 is_glob: segment.is_none(), 217 is_glob: segment.is_none(),
216 }); 218 });
217 if let Some(segment) = segment { 219 if let Some(segment) = segment {
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index 0e0683db7..81c8a4f12 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -91,6 +91,30 @@ fn item_map_smoke_test() {
91} 91}
92 92
93#[test] 93#[test]
94fn use_as() {
95 let (item_map, module_id) = item_map(
96 "
97 //- /lib.rs
98 mod foo;
99
100 use crate::foo::Baz as Foo;
101 <|>
102
103 //- /foo/mod.rs
104 pub struct Baz;
105 ",
106 );
107 check_module_item_map(
108 &item_map,
109 module_id,
110 "
111 Foo: t v
112 foo: t
113 ",
114 );
115}
116
117#[test]
94fn use_trees() { 118fn use_trees() {
95 let (item_map, module_id) = item_map( 119 let (item_map, module_id) = item_map(
96 " 120 "
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index e13d84c57..cb0a04500 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -1,6 +1,6 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_syntax::{ast, AstNode}; 3use ra_syntax::{ast::{self, NameOwner}, AstNode};
4 4
5use crate::{Name, AsName, type_ref::TypeRef}; 5use crate::{Name, AsName, type_ref::TypeRef};
6 6
@@ -46,7 +46,7 @@ impl Path {
46 /// Calls `cb` with all paths, represented by this use item. 46 /// Calls `cb` with all paths, represented by this use item.
47 pub fn expand_use_item<'a>( 47 pub fn expand_use_item<'a>(
48 item: &'a ast::UseItem, 48 item: &'a ast::UseItem,
49 mut cb: impl FnMut(Path, Option<&'a ast::PathSegment>), 49 mut cb: impl FnMut(Path, Option<&'a ast::PathSegment>, Option<Name>),
50 ) { 50 ) {
51 if let Some(tree) = item.use_tree() { 51 if let Some(tree) = item.use_tree() {
52 expand_use_tree(None, tree, &mut cb); 52 expand_use_tree(None, tree, &mut cb);
@@ -164,7 +164,7 @@ impl From<Name> for Path {
164fn expand_use_tree<'a>( 164fn expand_use_tree<'a>(
165 prefix: Option<Path>, 165 prefix: Option<Path>,
166 tree: &'a ast::UseTree, 166 tree: &'a ast::UseTree,
167 cb: &mut impl FnMut(Path, Option<&'a ast::PathSegment>), 167 cb: &mut impl FnMut(Path, Option<&'a ast::PathSegment>, Option<Name>),
168) { 168) {
169 if let Some(use_tree_list) = tree.use_tree_list() { 169 if let Some(use_tree_list) = tree.use_tree_list() {
170 let prefix = match tree.path() { 170 let prefix = match tree.path() {
@@ -181,6 +181,7 @@ fn expand_use_tree<'a>(
181 expand_use_tree(prefix.clone(), child_tree, cb); 181 expand_use_tree(prefix.clone(), child_tree, cb);
182 } 182 }
183 } else { 183 } else {
184 let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name());
184 if let Some(ast_path) = tree.path() { 185 if let Some(ast_path) = tree.path() {
185 // Handle self in a path. 186 // Handle self in a path.
186 // E.g. `use something::{self, <...>}` 187 // E.g. `use something::{self, <...>}`
@@ -188,7 +189,7 @@ fn expand_use_tree<'a>(
188 if let Some(segment) = ast_path.segment() { 189 if let Some(segment) = ast_path.segment() {
189 if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { 190 if segment.kind() == Some(ast::PathSegmentKind::SelfKw) {
190 if let Some(prefix) = prefix { 191 if let Some(prefix) = prefix {
191 cb(prefix, Some(segment)); 192 cb(prefix, Some(segment), alias);
192 return; 193 return;
193 } 194 }
194 } 195 }
@@ -196,9 +197,9 @@ fn expand_use_tree<'a>(
196 } 197 }
197 if let Some(path) = convert_path(prefix, ast_path) { 198 if let Some(path) = convert_path(prefix, ast_path) {
198 if tree.has_star() { 199 if tree.has_star() {
199 cb(path, None) 200 cb(path, None, alias)
200 } else if let Some(segment) = ast_path.segment() { 201 } else if let Some(segment) = ast_path.segment() {
201 cb(path, Some(segment)) 202 cb(path, Some(segment), alias)
202 }; 203 };
203 } 204 }
204 // TODO: report errors somewhere 205 // TODO: report errors somewhere
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index d0561c495..60480c699 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -17,6 +17,35 @@ use crate::{
17 ast::{self, AstNode}, 17 ast::{self, AstNode},
18}; 18};
19 19
20// Alias
21#[derive(Debug, PartialEq, Eq, Hash)]
22#[repr(transparent)]
23pub struct Alias {
24 pub(crate) syntax: SyntaxNode,
25}
26unsafe impl TransparentNewType for Alias {
27 type Repr = rowan::SyntaxNode<RaTypes>;
28}
29
30impl AstNode for Alias {
31 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
32 match syntax.kind() {
33 ALIAS => Some(Alias::from_repr(syntax.into_repr())),
34 _ => None,
35 }
36 }
37 fn syntax(&self) -> &SyntaxNode { &self.syntax }
38}
39
40impl ToOwned for Alias {
41 type Owned = TreeArc<Alias>;
42 fn to_owned(&self) -> TreeArc<Alias> { TreeArc::cast(self.syntax.to_owned()) }
43}
44
45
46impl ast::NameOwner for Alias {}
47impl Alias {}
48
20// ArgList 49// ArgList
21#[derive(Debug, PartialEq, Eq, Hash)] 50#[derive(Debug, PartialEq, Eq, Hash)]
22#[repr(transparent)] 51#[repr(transparent)]
@@ -4176,6 +4205,10 @@ impl UseTree {
4176 pub fn use_tree_list(&self) -> Option<&UseTreeList> { 4205 pub fn use_tree_list(&self) -> Option<&UseTreeList> {
4177 super::child_opt(self) 4206 super::child_opt(self)
4178 } 4207 }
4208
4209 pub fn alias(&self) -> Option<&Alias> {
4210 super::child_opt(self)
4211 }
4179} 4212}
4180 4213
4181// UseTreeList 4214// UseTreeList
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 47334bdf0..a2ccd7cb9 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -593,7 +593,10 @@ Grammar(
593 options: [ "UseTree" ] 593 options: [ "UseTree" ]
594 ), 594 ),
595 "UseTree": ( 595 "UseTree": (
596 options: [ "Path", "UseTreeList" ] 596 options: [ "Path", "UseTreeList", "Alias" ]
597 ),
598 "Alias": (
599 traits: ["NameOwner"],
597 ), 600 ),
598 "UseTreeList": ( 601 "UseTreeList": (
599 collections: [["use_trees", "UseTree"]] 602 collections: [["use_trees", "UseTree"]]