From 5a87a24f8288d905428db755c7ea806640b6ac1d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 21 Nov 2018 17:18:26 +0300 Subject: move Path --- crates/ra_analysis/src/descriptors/mod.rs | 21 +--- .../ra_analysis/src/descriptors/module/nameres.rs | 82 ++-------------- crates/ra_analysis/src/descriptors/path.rs | 106 +++++++++++++++++++++ 3 files changed, 117 insertions(+), 92 deletions(-) create mode 100644 crates/ra_analysis/src/descriptors/path.rs (limited to 'crates/ra_analysis/src') diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index 82658211f..e6225479d 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs @@ -1,11 +1,12 @@ pub(crate) mod function; pub(crate) mod module; +mod path; use std::sync::Arc; use ra_syntax::{ - ast::{self, AstNode, FnDefNode}, - TextRange, SmolStr, + ast::{self, FnDefNode}, + TextRange, }; use crate::{ @@ -18,6 +19,8 @@ use crate::{ Cancelable, }; +pub(crate) use self::path::{Path, PathKind}; + salsa::query_group! { pub(crate) trait DescriptorDatabase: SyntaxDatabase + IdDatabase { fn fn_scopes(fn_id: FnId) -> Arc { @@ -50,20 +53,6 @@ salsa::query_group! { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct Path { - kind: PathKind, - segments: Vec, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum PathKind { - Abs, - Self_, - Super, - Crate, -} - #[derive(Debug)] pub struct ReferenceDescriptor { pub range: TextRange, diff --git a/crates/ra_analysis/src/descriptors/module/nameres.rs b/crates/ra_analysis/src/descriptors/module/nameres.rs index 526e42af3..bf671470c 100644 --- a/crates/ra_analysis/src/descriptors/module/nameres.rs +++ b/crates/ra_analysis/src/descriptors/module/nameres.rs @@ -195,86 +195,16 @@ impl InputModuleItems { } fn add_use_item(&mut self, item: ast::UseItem) { - if let Some(tree) = item.use_tree() { - self.add_use_tree(None, tree); - } - } - - fn add_use_tree(&mut self, prefix: Option, tree: ast::UseTree) { - if let Some(use_tree_list) = tree.use_tree_list() { - let prefix = match tree.path() { - None => prefix, - Some(path) => match convert_path(prefix, path) { - Some(it) => Some(it), - None => return, // TODO: report errors somewhere - }, + Path::expand_use_item(item, |path, ptr| { + let kind = match ptr { + None => ImportKind::Glob, + Some(ptr) => ImportKind::Named(ptr), }; - for tree in use_tree_list.use_trees() { - self.add_use_tree(prefix.clone(), tree); - } - } else { - if let Some(ast_path) = tree.path() { - if let Some(path) = convert_path(prefix, ast_path) { - let kind = if tree.has_star() { - ImportKind::Glob - } else { - let ptr = LocalSyntaxPtr::new(ast_path.segment().unwrap().syntax()); - ImportKind::Named(ptr) - }; - self.imports.push(Import { kind, path }) - } - } - } + self.imports.push(Import { kind, path }) + }) } } -fn convert_path(prefix: Option, path: ast::Path) -> Option { - let prefix = if let Some(qual) = path.qualifier() { - Some(convert_path(prefix, qual)?) - } else { - None - }; - let segment = path.segment()?; - let res = match segment.kind()? { - ast::PathSegmentKind::Name(name) => { - let mut res = prefix.unwrap_or_else(|| Path { - kind: PathKind::Abs, - segments: Vec::with_capacity(1), - }); - res.segments.push(name.text()); - res - } - ast::PathSegmentKind::CrateKw => { - if prefix.is_some() { - return None; - } - Path { - kind: PathKind::Crate, - segments: Vec::new(), - } - } - ast::PathSegmentKind::SelfKw => { - if prefix.is_some() { - return None; - } - Path { - kind: PathKind::Self_, - segments: Vec::new(), - } - } - ast::PathSegmentKind::SuperKw => { - if prefix.is_some() { - return None; - } - Path { - kind: PathKind::Super, - segments: Vec::new(), - } - } - }; - Some(res) -} - impl ModuleItem { fn new<'a>(item: impl ast::NameOwner<'a>) -> Option { let name = item.name()?.text(); diff --git a/crates/ra_analysis/src/descriptors/path.rs b/crates/ra_analysis/src/descriptors/path.rs new file mode 100644 index 000000000..4ed561b51 --- /dev/null +++ b/crates/ra_analysis/src/descriptors/path.rs @@ -0,0 +1,106 @@ +use ra_syntax::{SmolStr, ast, AstNode}; + +use crate::syntax_ptr::LocalSyntaxPtr; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct Path { + pub(crate) kind: PathKind, + pub(crate) segments: Vec, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum PathKind { + Abs, + Self_, + Super, + Crate, +} + +impl Path { + pub(crate) fn expand_use_item( + item: ast::UseItem, + mut cb: impl FnMut(Path, Option), + ) { + if let Some(tree) = item.use_tree() { + expand_use_tree(None, tree, &mut cb); + } + } +} + +fn expand_use_tree( + prefix: Option, + tree: ast::UseTree, + cb: &mut impl FnMut(Path, Option), +) { + if let Some(use_tree_list) = tree.use_tree_list() { + let prefix = match tree.path() { + None => prefix, + Some(path) => match convert_path(prefix, path) { + Some(it) => Some(it), + None => return, // TODO: report errors somewhere + }, + }; + for tree in use_tree_list.use_trees() { + expand_use_tree(prefix.clone(), tree, cb); + } + } else { + if let Some(ast_path) = tree.path() { + if let Some(path) = convert_path(prefix, ast_path) { + let ptr = if tree.has_star() { + None + } else { + let ptr = LocalSyntaxPtr::new(ast_path.segment().unwrap().syntax()); + Some(ptr) + }; + cb(path, ptr) + } + } + } +} + +fn convert_path(prefix: Option, path: ast::Path) -> Option { + let prefix = if let Some(qual) = path.qualifier() { + Some(convert_path(prefix, qual)?) + } else { + None + }; + let segment = path.segment()?; + let res = match segment.kind()? { + ast::PathSegmentKind::Name(name) => { + let mut res = prefix.unwrap_or_else(|| Path { + kind: PathKind::Abs, + segments: Vec::with_capacity(1), + }); + res.segments.push(name.text()); + res + } + ast::PathSegmentKind::CrateKw => { + if prefix.is_some() { + return None; + } + Path { + kind: PathKind::Crate, + segments: Vec::new(), + } + } + ast::PathSegmentKind::SelfKw => { + if prefix.is_some() { + return None; + } + Path { + kind: PathKind::Self_, + segments: Vec::new(), + } + } + ast::PathSegmentKind::SuperKw => { + if prefix.is_some() { + return None; + } + Path { + kind: PathKind::Super, + segments: Vec::new(), + } + } + }; + Some(res) +} -- cgit v1.2.3