Pass aliases to ImportData

This commit is contained in:
Florian Diebold 2019-02-02 00:18:10 +01:00
parent aa5f6a1ee8
commit 5a7fce4e4c
4 changed files with 47 additions and 8 deletions

View file

@ -21,6 +21,7 @@ impl_arena_id!(ImportId);
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub(super) struct ImportData { pub(super) struct ImportData {
pub(super) path: Path, pub(super) path: Path,
pub(super) alias: Option<Name>,
pub(super) is_glob: bool, pub(super) is_glob: bool,
} }
@ -209,9 +210,10 @@ impl LoweredModule {
} }
fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) { 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 { let import = self.imports.alloc(ImportData {
path, path,
alias,
is_glob: segment.is_none(), is_glob: segment.is_none(),
}); });
if let Some(segment) = segment { if let Some(segment) = segment {

View file

@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use ra_syntax::{ast, AstNode}; use ra_syntax::{ast::{self, NameOwner}, AstNode};
use crate::{Name, AsName, type_ref::TypeRef}; use crate::{Name, AsName, type_ref::TypeRef};
@ -46,7 +46,7 @@ impl Path {
/// Calls `cb` with all paths, represented by this use item. /// Calls `cb` with all paths, represented by this use item.
pub fn expand_use_item<'a>( pub fn expand_use_item<'a>(
item: &'a ast::UseItem, 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() { if let Some(tree) = item.use_tree() {
expand_use_tree(None, tree, &mut cb); expand_use_tree(None, tree, &mut cb);
@ -164,7 +164,7 @@ impl From<Name> for Path {
fn expand_use_tree<'a>( fn expand_use_tree<'a>(
prefix: Option<Path>, prefix: Option<Path>,
tree: &'a ast::UseTree, 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() { if let Some(use_tree_list) = tree.use_tree_list() {
let prefix = match tree.path() { let prefix = match tree.path() {
@ -181,6 +181,7 @@ fn expand_use_tree<'a>(
expand_use_tree(prefix.clone(), child_tree, cb); expand_use_tree(prefix.clone(), child_tree, cb);
} }
} else { } else {
let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name());
if let Some(ast_path) = tree.path() { if let Some(ast_path) = tree.path() {
// Handle self in a path. // Handle self in a path.
// E.g. `use something::{self, <...>}` // E.g. `use something::{self, <...>}`
@ -188,7 +189,7 @@ fn expand_use_tree<'a>(
if let Some(segment) = ast_path.segment() { if let Some(segment) = ast_path.segment() {
if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { if segment.kind() == Some(ast::PathSegmentKind::SelfKw) {
if let Some(prefix) = prefix { if let Some(prefix) = prefix {
cb(prefix, Some(segment)); cb(prefix, Some(segment), alias);
return; return;
} }
} }
@ -196,9 +197,9 @@ fn expand_use_tree<'a>(
} }
if let Some(path) = convert_path(prefix, ast_path) { if let Some(path) = convert_path(prefix, ast_path) {
if tree.has_star() { if tree.has_star() {
cb(path, None) cb(path, None, alias)
} else if let Some(segment) = ast_path.segment() { } else if let Some(segment) = ast_path.segment() {
cb(path, Some(segment)) cb(path, Some(segment), alias)
}; };
} }
// TODO: report errors somewhere // TODO: report errors somewhere

View file

@ -17,6 +17,35 @@ use crate::{
ast::{self, AstNode}, 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 // ArgList
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
#[repr(transparent)] #[repr(transparent)]
@ -4176,6 +4205,10 @@ impl UseTree {
pub fn use_tree_list(&self) -> Option<&UseTreeList> { pub fn use_tree_list(&self) -> Option<&UseTreeList> {
super::child_opt(self) super::child_opt(self)
} }
pub fn alias(&self) -> Option<&Alias> {
super::child_opt(self)
}
} }
// UseTreeList // UseTreeList

View file

@ -593,7 +593,10 @@ Grammar(
options: [ "UseTree" ] options: [ "UseTree" ]
), ),
"UseTree": ( "UseTree": (
options: [ "Path", "UseTreeList" ] options: [ "Path", "UseTreeList", "Alias" ]
),
"Alias": (
traits: ["NameOwner"],
), ),
"UseTreeList": ( "UseTreeList": (
collections: [["use_trees", "UseTree"]] collections: [["use_trees", "UseTree"]]