From aa5f6a1ee8b56343e9f3dc9b1578d56f29dd2bc8 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 2 Feb 2019 00:17:48 +0100 Subject: Add test for `use as` --- crates/ra_hir/src/nameres/tests.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'crates') 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 @@ -90,6 +90,30 @@ fn item_map_smoke_test() { ); } +#[test] +fn use_as() { + let (item_map, module_id) = item_map( + " + //- /lib.rs + mod foo; + + use crate::foo::Baz as Foo; + <|> + + //- /foo/mod.rs + pub struct Baz; + ", + ); + check_module_item_map( + &item_map, + module_id, + " + Foo: t v + foo: t + ", + ); +} + #[test] fn use_trees() { let (item_map, module_id) = item_map( -- cgit v1.2.3 From 5a7fce4e4cd8846a49ce007910f72340007d9c8c Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 2 Feb 2019 00:18:10 +0100 Subject: Pass aliases to ImportData --- crates/ra_hir/src/nameres/lower.rs | 4 +++- crates/ra_hir/src/path.rs | 13 +++++++------ crates/ra_syntax/src/ast/generated.rs | 33 +++++++++++++++++++++++++++++++++ crates/ra_syntax/src/grammar.ron | 5 ++++- 4 files changed, 47 insertions(+), 8 deletions(-) (limited to 'crates') 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); #[derive(Debug, PartialEq, Eq)] pub(super) struct ImportData { pub(super) path: Path, + pub(super) alias: Option, pub(super) is_glob: bool, } @@ -209,9 +210,10 @@ impl LoweredModule { } fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) { - Path::expand_use_item(item, |path, segment| { + Path::expand_use_item(item, |path, segment, alias| { let import = self.imports.alloc(ImportData { path, + alias, is_glob: segment.is_none(), }); if let Some(segment) = segment { 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 @@ use std::sync::Arc; -use ra_syntax::{ast, AstNode}; +use ra_syntax::{ast::{self, NameOwner}, AstNode}; use crate::{Name, AsName, type_ref::TypeRef}; @@ -46,7 +46,7 @@ impl Path { /// Calls `cb` with all paths, represented by this use item. pub fn expand_use_item<'a>( item: &'a ast::UseItem, - mut cb: impl FnMut(Path, Option<&'a ast::PathSegment>), + mut cb: impl FnMut(Path, Option<&'a ast::PathSegment>, Option), ) { if let Some(tree) = item.use_tree() { expand_use_tree(None, tree, &mut cb); @@ -164,7 +164,7 @@ impl From for Path { fn expand_use_tree<'a>( prefix: Option, tree: &'a ast::UseTree, - cb: &mut impl FnMut(Path, Option<&'a ast::PathSegment>), + cb: &mut impl FnMut(Path, Option<&'a ast::PathSegment>, Option), ) { if let Some(use_tree_list) = tree.use_tree_list() { let prefix = match tree.path() { @@ -181,6 +181,7 @@ fn expand_use_tree<'a>( expand_use_tree(prefix.clone(), child_tree, cb); } } else { + let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); if let Some(ast_path) = tree.path() { // Handle self in a path. // E.g. `use something::{self, <...>}` @@ -188,7 +189,7 @@ fn expand_use_tree<'a>( if let Some(segment) = ast_path.segment() { if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { if let Some(prefix) = prefix { - cb(prefix, Some(segment)); + cb(prefix, Some(segment), alias); return; } } @@ -196,9 +197,9 @@ fn expand_use_tree<'a>( } if let Some(path) = convert_path(prefix, ast_path) { if tree.has_star() { - cb(path, None) + cb(path, None, alias) } else if let Some(segment) = ast_path.segment() { - cb(path, Some(segment)) + cb(path, Some(segment), alias) }; } // 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::{ ast::{self, AstNode}, }; +// Alias +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct Alias { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for Alias { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for Alias { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + ALIAS => Some(Alias::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl ToOwned for Alias { + type Owned = TreeArc; + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } +} + + +impl ast::NameOwner for Alias {} +impl Alias {} + // ArgList #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] @@ -4176,6 +4205,10 @@ impl UseTree { pub fn use_tree_list(&self) -> Option<&UseTreeList> { super::child_opt(self) } + + pub fn alias(&self) -> Option<&Alias> { + super::child_opt(self) + } } // 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( options: [ "UseTree" ] ), "UseTree": ( - options: [ "Path", "UseTreeList" ] + options: [ "Path", "UseTreeList", "Alias" ] + ), + "Alias": ( + traits: ["NameOwner"], ), "UseTreeList": ( collections: [["use_trees", "UseTree"]] -- cgit v1.2.3 From d8ef8acb47b1be92da97a2d5cd4334bceed5b919 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 2 Feb 2019 00:23:59 +0100 Subject: Use aliases in import resolution --- crates/ra_hir/src/nameres.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'crates') 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 }; } for (import_id, import_data) in input.imports.iter() { - if let Some(segment) = import_data.path.segments.iter().last() { + if let Some(last_segment) = import_data.path.segments.iter().last() { if !import_data.is_glob { + let name = import_data + .alias + .clone() + .unwrap_or_else(|| last_segment.name.clone()); module_items.items.insert( - segment.name.clone(), + name, Resolution { def: PerNs::none(), import: Some(import_id), @@ -319,19 +323,18 @@ where if reached_fixedpoint == ReachedFixedPoint::Yes { let last_segment = import.path.segments.last().unwrap(); + let name = import + .alias + .clone() + .unwrap_or_else(|| last_segment.name.clone()); + log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def,); self.update(module_id, |items| { let res = Resolution { def, import: Some(import_id), }; - items.items.insert(last_segment.name.clone(), res); + items.items.insert(name, res); }); - log::debug!( - "resolved import {:?} ({:?}) cross-source root to {:?}", - last_segment.name, - import, - def, - ); } reached_fixedpoint } -- cgit v1.2.3