Merge #725
725: Implement `use as` r=matklad a=flodiebold Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
commit
da3802b2ce
6 changed files with 83 additions and 17 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ impl_arena_id!(ImportId);
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub(super) struct ImportData {
|
||||
pub(super) path: Path,
|
||||
pub(super) alias: Option<Name>,
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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<Name>),
|
||||
) {
|
||||
if let Some(tree) = item.use_tree() {
|
||||
expand_use_tree(None, tree, &mut cb);
|
||||
|
|
@ -164,7 +164,7 @@ impl From<Name> for Path {
|
|||
fn expand_use_tree<'a>(
|
||||
prefix: Option<Path>,
|
||||
tree: &'a ast::UseTree,
|
||||
cb: &mut impl FnMut(Path, Option<&'a ast::PathSegment>),
|
||||
cb: &mut impl FnMut(Path, Option<&'a ast::PathSegment>, Option<Name>),
|
||||
) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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<RaTypes>;
|
||||
}
|
||||
|
||||
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<Alias>;
|
||||
fn to_owned(&self) -> TreeArc<Alias> { 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
|
||||
|
|
|
|||
|
|
@ -593,7 +593,10 @@ Grammar(
|
|||
options: [ "UseTree" ]
|
||||
),
|
||||
"UseTree": (
|
||||
options: [ "Path", "UseTreeList" ]
|
||||
options: [ "Path", "UseTreeList", "Alias" ]
|
||||
),
|
||||
"Alias": (
|
||||
traits: ["NameOwner"],
|
||||
),
|
||||
"UseTreeList": (
|
||||
collections: [["use_trees", "UseTree"]]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue