mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Reformat all
This commit is contained in:
parent
857c1650ef
commit
6be50f7d5d
35 changed files with 423 additions and 367 deletions
|
@ -1,22 +1,22 @@
|
|||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use ra_editor::{find_node_at_offset};
|
||||
use ra_editor::find_node_at_offset;
|
||||
use ra_syntax::{
|
||||
AtomEdit, File, TextUnit, AstNode, SyntaxNodeRef,
|
||||
algo::visit::{visitor, visitor_ctx, Visitor, VisitorCtx},
|
||||
ast::{self, AstChildren, LoopBodyOwner, ModuleItemOwner},
|
||||
AstNode, AtomEdit, File,
|
||||
SyntaxKind::*,
|
||||
SyntaxNodeRef, TextUnit,
|
||||
};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use crate::{
|
||||
FileId, Cancelable,
|
||||
input::FilesDatabase,
|
||||
db::{self, SyntaxDatabase},
|
||||
descriptors::DescriptorDatabase,
|
||||
descriptors::function::FnScopes,
|
||||
descriptors::module::{ModuleTree, ModuleId, ModuleScope},
|
||||
descriptors::module::{ModuleId, ModuleScope, ModuleTree},
|
||||
descriptors::DescriptorDatabase,
|
||||
input::FilesDatabase,
|
||||
Cancelable, FileId,
|
||||
};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CompletionItem {
|
||||
/// What user sees in pop-up
|
||||
|
@ -27,7 +27,11 @@ pub struct CompletionItem {
|
|||
pub snippet: Option<String>,
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_based_completion(db: &db::RootDatabase, file_id: FileId, offset: TextUnit) -> Cancelable<Option<Vec<CompletionItem>>> {
|
||||
pub(crate) fn resolve_based_completion(
|
||||
db: &db::RootDatabase,
|
||||
file_id: FileId,
|
||||
offset: TextUnit,
|
||||
) -> Cancelable<Option<Vec<CompletionItem>>> {
|
||||
let source_root_id = db.file_source_root(file_id);
|
||||
let file = db.file_syntax(file_id);
|
||||
let module_tree = db.module_tree(source_root_id)?;
|
||||
|
@ -56,9 +60,12 @@ pub(crate) fn resolve_based_completion(db: &db::RootDatabase, file_id: FileId, o
|
|||
Ok(Some(res))
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub(crate) fn find_target_module(module_tree: &ModuleTree, module_id: ModuleId, file: &File, offset: TextUnit) -> Option<ModuleId> {
|
||||
pub(crate) fn find_target_module(
|
||||
module_tree: &ModuleTree,
|
||||
module_id: ModuleId,
|
||||
file: &File,
|
||||
offset: TextUnit,
|
||||
) -> Option<ModuleId> {
|
||||
let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), offset)?;
|
||||
let mut crate_path = crate_path(name_ref)?;
|
||||
|
||||
|
@ -71,8 +78,10 @@ pub(crate) fn find_target_module(module_tree: &ModuleTree, module_id: ModuleId,
|
|||
}
|
||||
|
||||
fn crate_path(name_ref: ast::NameRef) -> Option<Vec<ast::NameRef>> {
|
||||
let mut path = name_ref.syntax()
|
||||
.parent().and_then(ast::PathSegment::cast)?
|
||||
let mut path = name_ref
|
||||
.syntax()
|
||||
.parent()
|
||||
.and_then(ast::PathSegment::cast)?
|
||||
.parent_path();
|
||||
let mut res = Vec::new();
|
||||
loop {
|
||||
|
@ -80,8 +89,7 @@ fn crate_path(name_ref: ast::NameRef) -> Option<Vec<ast::NameRef>> {
|
|||
match segment.kind()? {
|
||||
ast::PathSegmentKind::Name(name) => res.push(name),
|
||||
ast::PathSegmentKind::CrateKw => break,
|
||||
ast::PathSegmentKind::SelfKw | ast::PathSegmentKind::SuperKw =>
|
||||
return None,
|
||||
ast::PathSegmentKind::SelfKw | ast::PathSegmentKind::SuperKw => return None,
|
||||
}
|
||||
path = path.qualifier()?;
|
||||
}
|
||||
|
@ -89,7 +97,6 @@ fn crate_path(name_ref: ast::NameRef) -> Option<Vec<ast::NameRef>> {
|
|||
Some(res)
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn scope_completion(
|
||||
db: &db::RootDatabase,
|
||||
file_id: FileId,
|
||||
|
@ -158,11 +165,7 @@ fn complete_module_items(
|
|||
);
|
||||
}
|
||||
|
||||
fn complete_name_ref(
|
||||
file: &File,
|
||||
name_ref: ast::NameRef,
|
||||
acc: &mut Vec<CompletionItem>,
|
||||
) {
|
||||
fn complete_name_ref(file: &File, name_ref: ast::NameRef, acc: &mut Vec<CompletionItem>) {
|
||||
if !is_node::<ast::Path>(name_ref.syntax()) {
|
||||
return;
|
||||
}
|
||||
|
@ -273,7 +276,11 @@ fn is_in_loop_body(name_ref: ast::NameRef) -> bool {
|
|||
.visit::<ast::LoopExpr, _>(LoopBodyOwner::loop_body)
|
||||
.accept(node);
|
||||
if let Some(Some(body)) = loop_body {
|
||||
if name_ref.syntax().range().is_subrange(&body.syntax().range()) {
|
||||
if name_ref
|
||||
.syntax()
|
||||
.range()
|
||||
.is_subrange(&body.syntax().range())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -368,9 +375,9 @@ fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec<Completi
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use test_utils::{assert_eq_dbg};
|
||||
use test_utils::assert_eq_dbg;
|
||||
|
||||
use crate::mock_analysis::{single_file_with_position};
|
||||
use crate::mock_analysis::single_file_with_position;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ra_editor::LineIndex;
|
||||
use ra_syntax::File;
|
||||
|
@ -8,14 +6,13 @@ use salsa;
|
|||
|
||||
use crate::{
|
||||
db,
|
||||
Cancelable, Canceled,
|
||||
descriptors::{
|
||||
DescriptorDatabase, SubmodulesQuery, ModuleTreeQuery, ModuleScopeQuery,
|
||||
FnSyntaxQuery, FnScopesQuery
|
||||
DescriptorDatabase, FnScopesQuery, FnSyntaxQuery, ModuleScopeQuery, ModuleTreeQuery,
|
||||
SubmodulesQuery,
|
||||
},
|
||||
symbol_index::SymbolIndex,
|
||||
syntax_ptr::{SyntaxPtrDatabase, ResolveSyntaxPtrQuery},
|
||||
FileId,
|
||||
syntax_ptr::{ResolveSyntaxPtrQuery, SyntaxPtrDatabase},
|
||||
Cancelable, Canceled, FileId,
|
||||
};
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use ra_syntax::{
|
||||
ast::{AstNode, FnDef, FnDefNode},
|
||||
};
|
||||
use ra_syntax::ast::{AstNode, FnDef, FnDefNode};
|
||||
|
||||
use crate::{
|
||||
descriptors::{
|
||||
DescriptorDatabase,
|
||||
function::{FnId, FnScopes},
|
||||
},
|
||||
use crate::descriptors::{
|
||||
function::{FnId, FnScopes},
|
||||
DescriptorDatabase,
|
||||
};
|
||||
|
||||
/// Resolve `FnId` to the corresponding `SyntaxNode`
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
pub(super) mod imp;
|
||||
mod scope;
|
||||
|
||||
use std::cmp::{min, max};
|
||||
use std::cmp::{max, min};
|
||||
|
||||
use ra_syntax::{
|
||||
ast::{self, AstNode, DocCommentsOwner, NameOwner},
|
||||
TextRange, TextUnit
|
||||
TextRange, TextUnit,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
FileId,
|
||||
syntax_ptr::SyntaxPtr
|
||||
};
|
||||
|
||||
pub(crate) use self::scope::{FnScopes, resolve_local_name};
|
||||
use crate::{syntax_ptr::SyntaxPtr, FileId};
|
||||
|
||||
pub(crate) use self::scope::{resolve_local_name, FnScopes};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct FnId(SyntaxPtr);
|
||||
|
@ -26,14 +22,13 @@ impl FnId {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FnDescriptor {
|
||||
pub name: String,
|
||||
pub label: String,
|
||||
pub ret_type: Option<String>,
|
||||
pub params: Vec<String>,
|
||||
pub doc: Option<String>
|
||||
pub doc: Option<String>,
|
||||
}
|
||||
|
||||
impl FnDescriptor {
|
||||
|
@ -57,7 +52,9 @@ impl FnDescriptor {
|
|||
};
|
||||
|
||||
if let Some((comment_range, docs)) = FnDescriptor::extract_doc_comments(node) {
|
||||
let comment_range = comment_range.checked_sub(node.syntax().range().start()).unwrap();
|
||||
let comment_range = comment_range
|
||||
.checked_sub(node.syntax().range().start())
|
||||
.unwrap();
|
||||
let start = comment_range.start().to_usize();
|
||||
let end = comment_range.end().to_usize();
|
||||
|
||||
|
@ -94,7 +91,7 @@ impl FnDescriptor {
|
|||
ret_type,
|
||||
params,
|
||||
label: label.trim().to_owned(),
|
||||
doc
|
||||
doc,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -105,10 +102,13 @@ impl FnDescriptor {
|
|||
|
||||
let comment_text = node.doc_comment_text();
|
||||
|
||||
let (begin, end) = node.doc_comments()
|
||||
let (begin, end) = node
|
||||
.doc_comments()
|
||||
.map(|comment| comment.syntax().range())
|
||||
.map(|range| (range.start().to_usize(), range.end().to_usize()))
|
||||
.fold((std::usize::MAX, std::usize::MIN), |acc, range| (min(acc.0, range.0), max(acc.1, range.1)));
|
||||
.fold((std::usize::MAX, std::usize::MIN), |acc, range| {
|
||||
(min(acc.0, range.0), max(acc.1, range.1))
|
||||
});
|
||||
|
||||
let range = TextRange::from_to(TextUnit::from_usize(begin), TextUnit::from_usize(end));
|
||||
|
||||
|
@ -134,4 +134,3 @@ impl FnDescriptor {
|
|||
res
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,9 +51,7 @@ impl FnScopes {
|
|||
&self.get(scope).entries
|
||||
}
|
||||
pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator<Item = ScopeId> + 'a {
|
||||
generate(self.scope_for(node), move |&scope| {
|
||||
self.get(scope).parent
|
||||
})
|
||||
generate(self.scope_for(node), move |&scope| self.get(scope).parent)
|
||||
}
|
||||
fn root_scope(&mut self) -> ScopeId {
|
||||
let res = ScopeId(self.scopes.len() as u32);
|
||||
|
@ -273,13 +271,12 @@ pub fn resolve_local_name<'a>(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ra_editor::find_node_at_offset;
|
||||
use ra_syntax::File;
|
||||
use test_utils::extract_offset;
|
||||
use ra_editor::{find_node_at_offset};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
fn do_check(code: &str, expected: &[&str]) {
|
||||
let (off, code) = extract_offset(code);
|
||||
let code = {
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
pub(crate) mod module;
|
||||
pub(crate) mod function;
|
||||
pub(crate) mod module;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use ra_syntax::{
|
||||
SmolStr,
|
||||
ast::{self, AstNode, FnDefNode},
|
||||
TextRange
|
||||
SmolStr, TextRange,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
FileId, Cancelable,
|
||||
db::SyntaxDatabase,
|
||||
descriptors::module::{ModuleTree, ModuleId, ModuleScope},
|
||||
descriptors::function::{FnId, FnScopes, resolve_local_name},
|
||||
descriptors::function::{resolve_local_name, FnId, FnScopes},
|
||||
descriptors::module::{ModuleId, ModuleScope, ModuleTree},
|
||||
input::SourceRootId,
|
||||
syntax_ptr::{SyntaxPtrDatabase, LocalSyntaxPtr},
|
||||
syntax_ptr::{LocalSyntaxPtr, SyntaxPtrDatabase},
|
||||
Cancelable, FileId,
|
||||
};
|
||||
|
||||
|
||||
salsa::query_group! {
|
||||
pub(crate) trait DescriptorDatabase: SyntaxDatabase + SyntaxPtrDatabase {
|
||||
fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> {
|
||||
|
@ -49,23 +47,20 @@ salsa::query_group! {
|
|||
#[derive(Debug)]
|
||||
pub struct ReferenceDescriptor {
|
||||
pub range: TextRange,
|
||||
pub name: String
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeclarationDescriptor<'a> {
|
||||
pat: ast::BindPat<'a>,
|
||||
pub range: TextRange
|
||||
pub range: TextRange,
|
||||
}
|
||||
|
||||
impl<'a> DeclarationDescriptor<'a> {
|
||||
pub fn new(pat: ast::BindPat) -> DeclarationDescriptor {
|
||||
let range = pat.syntax().range();
|
||||
|
||||
DeclarationDescriptor {
|
||||
pat,
|
||||
range
|
||||
}
|
||||
DeclarationDescriptor { pat, range }
|
||||
}
|
||||
|
||||
pub fn find_all_refs(&self) -> Vec<ReferenceDescriptor> {
|
||||
|
@ -73,22 +68,22 @@ impl<'a> DeclarationDescriptor<'a> {
|
|||
|
||||
let fn_def = match self.pat.syntax().ancestors().find_map(ast::FnDef::cast) {
|
||||
Some(def) => def,
|
||||
None => return Default::default()
|
||||
None => return Default::default(),
|
||||
};
|
||||
|
||||
let fn_scopes = FnScopes::new(fn_def);
|
||||
|
||||
let refs : Vec<_> = fn_def.syntax().descendants()
|
||||
let refs: Vec<_> = fn_def
|
||||
.syntax()
|
||||
.descendants()
|
||||
.filter_map(ast::NameRef::cast)
|
||||
.filter(|name_ref| {
|
||||
match resolve_local_name(*name_ref, &fn_scopes) {
|
||||
None => false,
|
||||
Some(entry) => entry.ptr() == name_ptr,
|
||||
}
|
||||
.filter(|name_ref| match resolve_local_name(*name_ref, &fn_scopes) {
|
||||
None => false,
|
||||
Some(entry) => entry.ptr() == name_ptr,
|
||||
})
|
||||
.map(|name_ref| ReferenceDescriptor {
|
||||
name: name_ref.syntax().text().to_string(),
|
||||
range : name_ref.syntax().range(),
|
||||
range: name_ref.syntax().range(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use ra_syntax::{
|
||||
ast::{self, NameOwner},
|
||||
SmolStr,
|
||||
};
|
||||
use relative_path::RelativePathBuf;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use ra_syntax::{
|
||||
SmolStr,
|
||||
ast::{self, NameOwner},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
FileId, Cancelable, FileResolverImp, db,
|
||||
input::{SourceRoot, SourceRootId},
|
||||
db,
|
||||
descriptors::DescriptorDatabase,
|
||||
input::{SourceRoot, SourceRootId},
|
||||
Cancelable, FileId, FileResolverImp,
|
||||
};
|
||||
|
||||
use super::{
|
||||
ModuleData, ModuleTree, ModuleId, LinkId, LinkData, Problem, ModuleScope
|
||||
};
|
||||
use super::{LinkData, LinkId, ModuleData, ModuleId, ModuleScope, ModuleTree, Problem};
|
||||
|
||||
|
||||
pub(crate) fn submodules(db: &impl DescriptorDatabase, file_id: FileId) -> Cancelable<Arc<Vec<SmolStr>>> {
|
||||
pub(crate) fn submodules(
|
||||
db: &impl DescriptorDatabase,
|
||||
file_id: FileId,
|
||||
) -> Cancelable<Arc<Vec<SmolStr>>> {
|
||||
db::check_canceled(db)?;
|
||||
let file = db.file_syntax(file_id);
|
||||
let root = file.ast();
|
||||
|
@ -57,13 +58,11 @@ pub(crate) fn module_tree(
|
|||
Ok(Arc::new(res))
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
|
||||
pub struct Submodule {
|
||||
pub name: SmolStr,
|
||||
}
|
||||
|
||||
|
||||
fn create_module_tree<'a>(
|
||||
db: &impl DescriptorDatabase,
|
||||
source_root: SourceRootId,
|
||||
|
@ -82,7 +81,15 @@ fn create_module_tree<'a>(
|
|||
continue; // TODO: use explicit crate_roots here
|
||||
}
|
||||
assert!(!roots.contains_key(&file_id));
|
||||
let module_id = build_subtree(db, &source_root, &mut tree, &mut visited, &mut roots, None, file_id)?;
|
||||
let module_id = build_subtree(
|
||||
db,
|
||||
&source_root,
|
||||
&mut tree,
|
||||
&mut visited,
|
||||
&mut roots,
|
||||
None,
|
||||
file_id,
|
||||
)?;
|
||||
roots.insert(file_id, module_id);
|
||||
}
|
||||
Ok(tree)
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
pub(super) mod imp;
|
||||
pub(crate) mod scope;
|
||||
|
||||
use ra_syntax::{
|
||||
ast::{self, AstNode, NameOwner},
|
||||
SmolStr, SyntaxNode,
|
||||
};
|
||||
use relative_path::RelativePathBuf;
|
||||
use ra_syntax::{ast::{self, NameOwner, AstNode}, SmolStr, SyntaxNode};
|
||||
|
||||
use crate::FileId;
|
||||
|
||||
|
@ -16,9 +19,11 @@ pub(crate) struct ModuleTree {
|
|||
|
||||
impl ModuleTree {
|
||||
pub(crate) fn modules_for_file(&self, file_id: FileId) -> Vec<ModuleId> {
|
||||
self.mods.iter()
|
||||
self.mods
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_idx, it)| it.file_id == file_id).map(|(idx, _)| ModuleId(idx as u32))
|
||||
.filter(|(_idx, it)| it.file_id == file_id)
|
||||
.map(|(idx, _)| ModuleId(idx as u32))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -50,7 +55,7 @@ impl ModuleId {
|
|||
}
|
||||
pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
|
||||
tree.module(self).parent
|
||||
}
|
||||
}
|
||||
pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> {
|
||||
let link = self.parent_link(tree)?;
|
||||
Some(tree.link(link).owner)
|
||||
|
@ -69,18 +74,15 @@ impl ModuleId {
|
|||
curr
|
||||
}
|
||||
pub(crate) fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> {
|
||||
let link = tree.module(self)
|
||||
let link = tree
|
||||
.module(self)
|
||||
.children
|
||||
.iter()
|
||||
.map(|&it| tree.link(it))
|
||||
.find(|it| it.name == name)?;
|
||||
Some(*link.points_to.first()?)
|
||||
}
|
||||
pub(crate) fn problems(
|
||||
self,
|
||||
tree: &ModuleTree,
|
||||
root: ast::Root,
|
||||
) -> Vec<(SyntaxNode, Problem)> {
|
||||
pub(crate) fn problems(self, tree: &ModuleTree, root: ast::Root) -> Vec<(SyntaxNode, Problem)> {
|
||||
tree.module(self)
|
||||
.children
|
||||
.iter()
|
||||
|
@ -98,11 +100,7 @@ impl LinkId {
|
|||
pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId {
|
||||
tree.link(self).owner
|
||||
}
|
||||
pub(crate) fn bind_source<'a>(
|
||||
self,
|
||||
tree: &ModuleTree,
|
||||
root: ast::Root<'a>,
|
||||
) -> ast::Module<'a> {
|
||||
pub(crate) fn bind_source<'a>(self, tree: &ModuleTree, root: ast::Root<'a>) -> ast::Module<'a> {
|
||||
imp::modules(root)
|
||||
.find(|(name, _)| name == &tree.link(self).name)
|
||||
.unwrap()
|
||||
|
@ -125,7 +123,6 @@ struct LinkData {
|
|||
problem: Option<Problem>,
|
||||
}
|
||||
|
||||
|
||||
impl ModuleTree {
|
||||
fn module(&self, id: ModuleId) -> &ModuleData {
|
||||
&self.mods[id.0 as usize]
|
||||
|
@ -152,4 +149,3 @@ impl ModuleTree {
|
|||
id
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
//! Backend for module-level scope resolution & completion
|
||||
|
||||
|
||||
use ra_syntax::{
|
||||
ast::{self, ModuleItemOwner},
|
||||
File, AstNode, SmolStr,
|
||||
AstNode, File, SmolStr,
|
||||
};
|
||||
|
||||
use crate::syntax_ptr::LocalSyntaxPtr;
|
||||
|
@ -103,7 +102,7 @@ fn collect_imports(tree: ast::UseTree, acc: &mut Vec<Entry>) {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ra_syntax::{File};
|
||||
use ra_syntax::File;
|
||||
|
||||
fn do_check(code: &str, expected: &[&str]) {
|
||||
let file = File::parse(&code);
|
||||
|
|
|
@ -13,24 +13,21 @@ use ra_syntax::{
|
|||
use rayon::prelude::*;
|
||||
use relative_path::RelativePath;
|
||||
use rustc_hash::FxHashSet;
|
||||
use salsa::{ParallelDatabase, Database};
|
||||
use salsa::{Database, ParallelDatabase};
|
||||
|
||||
use crate::{
|
||||
AnalysisChange,
|
||||
db::{
|
||||
self, SyntaxDatabase, FileSyntaxQuery,
|
||||
},
|
||||
input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE},
|
||||
completion::{resolve_based_completion, scope_completion, CompletionItem},
|
||||
db::{self, FileSyntaxQuery, SyntaxDatabase},
|
||||
descriptors::{
|
||||
DescriptorDatabase, DeclarationDescriptor,
|
||||
module::{ModuleTree, Problem},
|
||||
function::{FnDescriptor, FnId},
|
||||
module::{ModuleTree, Problem},
|
||||
DeclarationDescriptor, DescriptorDatabase,
|
||||
},
|
||||
completion::{scope_completion, resolve_based_completion, CompletionItem},
|
||||
input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE},
|
||||
symbol_index::SymbolIndex,
|
||||
syntax_ptr::SyntaxPtrDatabase,
|
||||
CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position,
|
||||
Query, SourceChange, SourceFileEdit, Cancelable,
|
||||
AnalysisChange, Cancelable, CrateGraph, CrateId, Diagnostic, FileId, FileResolver,
|
||||
FileSystemEdit, Position, Query, SourceChange, SourceFileEdit,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -94,7 +91,6 @@ pub(crate) struct AnalysisHostImpl {
|
|||
db: db::RootDatabase,
|
||||
}
|
||||
|
||||
|
||||
impl AnalysisHostImpl {
|
||||
pub fn new() -> AnalysisHostImpl {
|
||||
let db = db::RootDatabase::default();
|
||||
|
@ -108,7 +104,7 @@ impl AnalysisHostImpl {
|
|||
}
|
||||
pub fn analysis(&self) -> AnalysisImpl {
|
||||
AnalysisImpl {
|
||||
db: self.db.fork() // freeze revision here
|
||||
db: self.db.fork(), // freeze revision here
|
||||
}
|
||||
}
|
||||
pub fn apply_change(&mut self, change: AnalysisChange) {
|
||||
|
@ -120,7 +116,8 @@ impl AnalysisHostImpl {
|
|||
.set(file_id, Arc::new(text))
|
||||
}
|
||||
if !(change.files_added.is_empty() && change.files_removed.is_empty()) {
|
||||
let file_resolver = change.file_resolver
|
||||
let file_resolver = change
|
||||
.file_resolver
|
||||
.expect("change resolver when changing set of files");
|
||||
let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE));
|
||||
for (file_id, text) in change.files_added {
|
||||
|
@ -174,7 +171,8 @@ impl AnalysisHostImpl {
|
|||
.set((), Arc::new(libraries));
|
||||
}
|
||||
if let Some(crate_graph) = change.crate_graph {
|
||||
self.db.query(crate::input::CrateGraphQuery)
|
||||
self.db
|
||||
.query(crate::input::CrateGraphQuery)
|
||||
.set((), Arc::new(crate_graph))
|
||||
}
|
||||
}
|
||||
|
@ -194,18 +192,22 @@ impl AnalysisImpl {
|
|||
}
|
||||
pub fn world_symbols(&self, query: Query) -> Cancelable<Vec<(FileId, FileSymbol)>> {
|
||||
let buf: Vec<Arc<SymbolIndex>> = if query.libs {
|
||||
self.db.libraries().iter()
|
||||
self.db
|
||||
.libraries()
|
||||
.iter()
|
||||
.map(|&lib_id| self.db.library_symbols(lib_id))
|
||||
.collect()
|
||||
} else {
|
||||
let files = &self.db.source_root(WORKSPACE).files;
|
||||
let db = self.db.clone();
|
||||
files.par_iter()
|
||||
files
|
||||
.par_iter()
|
||||
.map_with(db, |db, &file_id| db.file_symbols(file_id))
|
||||
.filter_map(|it| it.ok())
|
||||
.collect()
|
||||
};
|
||||
self.db.query(FileSyntaxQuery)
|
||||
self.db
|
||||
.query(FileSyntaxQuery)
|
||||
.sweep(salsa::SweepStrategy::default().discard_values());
|
||||
Ok(query.search(&buf))
|
||||
}
|
||||
|
@ -216,7 +218,8 @@ impl AnalysisImpl {
|
|||
pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> {
|
||||
let module_tree = self.module_tree(file_id)?;
|
||||
|
||||
let res = module_tree.modules_for_file(file_id)
|
||||
let res = module_tree
|
||||
.modules_for_file(file_id)
|
||||
.into_iter()
|
||||
.filter_map(|module_id| {
|
||||
let link = module_id.parent_link(&module_tree)?;
|
||||
|
@ -237,7 +240,8 @@ impl AnalysisImpl {
|
|||
pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
|
||||
let module_tree = self.module_tree(file_id)?;
|
||||
let crate_graph = self.db.crate_graph();
|
||||
let res = module_tree.modules_for_file(file_id)
|
||||
let res = module_tree
|
||||
.modules_for_file(file_id)
|
||||
.into_iter()
|
||||
.map(|it| it.root(&module_tree))
|
||||
.map(|it| it.file_id(&module_tree))
|
||||
|
@ -249,7 +253,11 @@ impl AnalysisImpl {
|
|||
pub fn crate_root(&self, crate_id: CrateId) -> FileId {
|
||||
self.db.crate_graph().crate_roots[&crate_id]
|
||||
}
|
||||
pub fn completions(&self, file_id: FileId, offset: TextUnit) -> Cancelable<Option<Vec<CompletionItem>>> {
|
||||
pub fn completions(
|
||||
&self,
|
||||
file_id: FileId,
|
||||
offset: TextUnit,
|
||||
) -> Cancelable<Option<Vec<CompletionItem>>> {
|
||||
let mut res = Vec::new();
|
||||
let mut has_completions = false;
|
||||
if let Some(scope_based) = scope_completion(&self.db, file_id, offset) {
|
||||
|
@ -260,11 +268,7 @@ impl AnalysisImpl {
|
|||
res.extend(scope_based);
|
||||
has_completions = true;
|
||||
}
|
||||
let res = if has_completions {
|
||||
Some(res)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let res = if has_completions { Some(res) } else { None };
|
||||
Ok(res)
|
||||
}
|
||||
pub fn approximately_resolve_symbol(
|
||||
|
@ -326,12 +330,11 @@ impl AnalysisImpl {
|
|||
let syntax = file.syntax();
|
||||
|
||||
// Find the binding associated with the offset
|
||||
let maybe_binding = find_node_at_offset::<ast::BindPat>(syntax, offset)
|
||||
.or_else(|| {
|
||||
let name_ref = find_node_at_offset::<ast::NameRef>(syntax, offset)?;
|
||||
let resolved = resolve_local_name(&self.db, file_id, name_ref)?;
|
||||
find_node_at_offset::<ast::BindPat>(syntax, resolved.1.end())
|
||||
});
|
||||
let maybe_binding = find_node_at_offset::<ast::BindPat>(syntax, offset).or_else(|| {
|
||||
let name_ref = find_node_at_offset::<ast::NameRef>(syntax, offset)?;
|
||||
let resolved = resolve_local_name(&self.db, file_id, name_ref)?;
|
||||
find_node_at_offset::<ast::BindPat>(syntax, resolved.1.end())
|
||||
});
|
||||
|
||||
let binding = match maybe_binding {
|
||||
None => return Vec::new(),
|
||||
|
@ -341,8 +344,11 @@ impl AnalysisImpl {
|
|||
let decl = DeclarationDescriptor::new(binding);
|
||||
|
||||
let mut ret = vec![(file_id, decl.range)];
|
||||
ret.extend(decl.find_all_refs().into_iter()
|
||||
.map(|ref_desc| (file_id, ref_desc.range )));
|
||||
ret.extend(
|
||||
decl.find_all_refs()
|
||||
.into_iter()
|
||||
.map(|ref_desc| (file_id, ref_desc.range)),
|
||||
);
|
||||
|
||||
ret
|
||||
}
|
||||
|
@ -526,7 +532,8 @@ impl AnalysisImpl {
|
|||
Some(id) => id,
|
||||
None => return Vec::new(),
|
||||
};
|
||||
module_id.child(module_tree, name.as_str())
|
||||
module_id
|
||||
.child(module_tree, name.as_str())
|
||||
.map(|it| it.file_id(module_tree))
|
||||
.into_iter()
|
||||
.collect()
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
use std::{
|
||||
sync::Arc,
|
||||
fmt,
|
||||
};
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
use salsa;
|
||||
use rustc_hash::FxHashSet;
|
||||
use relative_path::RelativePath;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustc_hash::FxHashSet;
|
||||
use salsa;
|
||||
|
||||
use crate::{symbol_index::SymbolIndex, FileResolverImp};
|
||||
|
||||
|
|
|
@ -6,23 +6,20 @@ extern crate relative_path;
|
|||
extern crate rustc_hash;
|
||||
extern crate salsa;
|
||||
|
||||
mod input;
|
||||
mod completion;
|
||||
mod db;
|
||||
mod descriptors;
|
||||
mod imp;
|
||||
mod symbol_index;
|
||||
mod completion;
|
||||
mod syntax_ptr;
|
||||
mod input;
|
||||
pub mod mock_analysis;
|
||||
mod symbol_index;
|
||||
mod syntax_ptr;
|
||||
|
||||
use std::{
|
||||
fmt,
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
use ra_syntax::{AtomEdit, File, TextRange, TextUnit};
|
||||
use relative_path::RelativePathBuf;
|
||||
use rayon::prelude::*;
|
||||
use relative_path::RelativePathBuf;
|
||||
|
||||
use crate::{
|
||||
imp::{AnalysisHostImpl, AnalysisImpl, FileResolverImp},
|
||||
|
@ -30,13 +27,12 @@ use crate::{
|
|||
};
|
||||
|
||||
pub use crate::{
|
||||
descriptors::function::FnDescriptor,
|
||||
completion::CompletionItem,
|
||||
input::{FileId, FileResolver, CrateGraph, CrateId},
|
||||
descriptors::function::FnDescriptor,
|
||||
input::{CrateGraph, CrateId, FileId, FileResolver},
|
||||
};
|
||||
pub use ra_editor::{
|
||||
FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable,
|
||||
RunnableKind, StructureNode,
|
||||
FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, RunnableKind, StructureNode,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
|
@ -50,8 +46,7 @@ impl std::fmt::Display for Canceled {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Canceled {
|
||||
}
|
||||
impl std::error::Error for Canceled {}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AnalysisChange {
|
||||
|
@ -76,7 +71,6 @@ impl fmt::Debug for AnalysisChange {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl AnalysisChange {
|
||||
pub fn new() -> AnalysisChange {
|
||||
AnalysisChange::default()
|
||||
|
@ -251,12 +245,15 @@ impl Analysis {
|
|||
pub fn approximately_resolve_symbol(
|
||||
&self,
|
||||
file_id: FileId,
|
||||
offset: TextUnit
|
||||
offset: TextUnit,
|
||||
) -> Cancelable<Vec<(FileId, FileSymbol)>> {
|
||||
self.imp
|
||||
.approximately_resolve_symbol(file_id, offset)
|
||||
self.imp.approximately_resolve_symbol(file_id, offset)
|
||||
}
|
||||
pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit, ) -> Cancelable<Vec<(FileId, TextRange)>> {
|
||||
pub fn find_all_refs(
|
||||
&self,
|
||||
file_id: FileId,
|
||||
offset: TextUnit,
|
||||
) -> Cancelable<Vec<(FileId, TextRange)>> {
|
||||
Ok(self.imp.find_all_refs(file_id, offset))
|
||||
}
|
||||
pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> {
|
||||
|
@ -276,7 +273,11 @@ impl Analysis {
|
|||
let file = self.imp.file_syntax(file_id);
|
||||
Ok(ra_editor::highlight(&file))
|
||||
}
|
||||
pub fn completions(&self, file_id: FileId, offset: TextUnit) -> Cancelable<Option<Vec<CompletionItem>>> {
|
||||
pub fn completions(
|
||||
&self,
|
||||
file_id: FileId,
|
||||
offset: TextUnit,
|
||||
) -> Cancelable<Option<Vec<CompletionItem>>> {
|
||||
self.imp.completions(file_id, offset)
|
||||
}
|
||||
pub fn assists(&self, file_id: FileId, range: TextRange) -> Cancelable<Vec<SourceChange>> {
|
||||
|
@ -307,7 +308,11 @@ impl LibraryData {
|
|||
let file = File::parse(text);
|
||||
(*file_id, file)
|
||||
}));
|
||||
LibraryData { files, file_resolver: FileResolverImp::new(file_resolver), symbol_index }
|
||||
LibraryData {
|
||||
files,
|
||||
file_resolver: FileResolverImp::new(file_resolver),
|
||||
symbol_index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use relative_path::{RelativePath, RelativePathBuf};
|
||||
use ra_syntax::TextUnit;
|
||||
use relative_path::{RelativePath, RelativePathBuf};
|
||||
use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER};
|
||||
|
||||
use crate::{
|
||||
AnalysisChange, Analysis, AnalysisHost, FileId, FileResolver,
|
||||
};
|
||||
use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FileResolver};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FilePosition {
|
||||
|
@ -51,7 +48,10 @@ impl MockAnalysis {
|
|||
let mut res = MockAnalysis::new();
|
||||
for entry in parse_fixture(fixture) {
|
||||
if entry.text.contains(CURSOR_MARKER) {
|
||||
assert!(position.is_none(), "only one marker (<|>) per fixture is allowed");
|
||||
assert!(
|
||||
position.is_none(),
|
||||
"only one marker (<|>) per fixture is allowed"
|
||||
);
|
||||
position = Some(res.add_file_with_position(&entry.meta, &entry.text));
|
||||
} else {
|
||||
res.add_file(&entry.meta, &entry.text);
|
||||
|
@ -73,7 +73,10 @@ impl MockAnalysis {
|
|||
FilePosition { file_id, offset }
|
||||
}
|
||||
pub fn id_of(&self, path: &str) -> FileId {
|
||||
let (idx, _) = self.files.iter().enumerate()
|
||||
let (idx, _) = self
|
||||
.files
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, (p, _text))| path == p)
|
||||
.expect("no file in this mock");
|
||||
FileId(idx as u32 + 1)
|
||||
|
|
|
@ -57,10 +57,7 @@ impl SymbolIndex {
|
|||
}
|
||||
|
||||
impl Query {
|
||||
pub(crate) fn search(
|
||||
self,
|
||||
indices: &[Arc<SymbolIndex>],
|
||||
) -> Vec<(FileId, FileSymbol)> {
|
||||
pub(crate) fn search(self, indices: &[Arc<SymbolIndex>]) -> Vec<(FileId, FileSymbol)> {
|
||||
let mut op = fst::map::OpBuilder::new();
|
||||
for file_symbols in indices.iter() {
|
||||
let automaton = fst::automaton::Subsequence::new(&self.lowercased);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use ra_syntax::{
|
||||
File, TextRange, SyntaxKind, SyntaxNode, SyntaxNodeRef,
|
||||
ast::{self, AstNode},
|
||||
File, SyntaxKind, SyntaxNode, SyntaxNodeRef, TextRange,
|
||||
};
|
||||
|
||||
use crate::FileId;
|
||||
use crate::db::SyntaxDatabase;
|
||||
use crate::FileId;
|
||||
|
||||
salsa::query_group! {
|
||||
pub(crate) trait SyntaxPtrDatabase: SyntaxDatabase {
|
||||
|
@ -52,12 +52,10 @@ trait ToAst {
|
|||
impl<'a> ToAst for &'a OwnedAst<ast::FnDef<'static>> {
|
||||
type Ast = ast::FnDef<'a>;
|
||||
fn to_ast(self) -> ast::FnDef<'a> {
|
||||
ast::FnDef::cast(self.syntax.borrowed())
|
||||
.unwrap()
|
||||
ast::FnDef::cast(self.syntax.borrowed()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A pionter to a syntax node inside a file.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct LocalSyntaxPtr {
|
||||
|
@ -79,22 +77,29 @@ impl LocalSyntaxPtr {
|
|||
if curr.range() == self.range && curr.kind() == self.kind {
|
||||
return curr.owned();
|
||||
}
|
||||
curr = curr.children()
|
||||
curr = curr
|
||||
.children()
|
||||
.find(|it| self.range.is_subrange(&it.range()))
|
||||
.unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn into_global(self, file_id: FileId) -> SyntaxPtr {
|
||||
SyntaxPtr { file_id, local: self}
|
||||
SyntaxPtr {
|
||||
file_id,
|
||||
local: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_local_syntax_ptr() {
|
||||
let file = File::parse("struct Foo { f: u32, }");
|
||||
let field = file.syntax().descendants().find_map(ast::NamedFieldDef::cast).unwrap();
|
||||
let field = file
|
||||
.syntax()
|
||||
.descendants()
|
||||
.find_map(ast::NamedFieldDef::cast)
|
||||
.unwrap();
|
||||
let ptr = LocalSyntaxPtr::new(field.syntax());
|
||||
let field_syntax = ptr.resolve(&file);
|
||||
assert_eq!(field.syntax(), field_syntax);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue