mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 07:04:22 +00:00
use relpaths for module resolve
This commit is contained in:
parent
a422d480a1
commit
cb6205c09d
4 changed files with 35 additions and 18 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -674,6 +674,7 @@ dependencies = [
|
|||
name = "ra_hir"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"id-arena 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use rustc_hash::{FxHashSet, FxHashMap};
|
||||
use relative_path::RelativePathBuf;
|
||||
use ra_syntax::SmolStr;
|
||||
use salsa;
|
||||
|
||||
|
@ -85,10 +86,23 @@ salsa::query_group! {
|
|||
type FileTextQuery;
|
||||
storage input;
|
||||
}
|
||||
/// Path to a file, relative to the root of its source root.
|
||||
fn file_relative_path(file_id: FileId) -> RelativePathBuf {
|
||||
type FileRelativePathQuery;
|
||||
storage input;
|
||||
}
|
||||
fn file_source_root(file_id: FileId) -> SourceRootId {
|
||||
type FileSourceRootQuery;
|
||||
storage input;
|
||||
}
|
||||
fn source_root_files(id: SourceRootId) -> Arc<FxHashSet<FileId>> {
|
||||
type SourceRootFilesQuery;
|
||||
storage input;
|
||||
}
|
||||
fn source_root_file_by_path(id: SourceRootId, path: RelativePathBuf) -> Option<FileId> {
|
||||
type SourceRootFilesByPathQuery;
|
||||
storage input;
|
||||
}
|
||||
fn source_root(id: SourceRootId) -> Arc<SourceRoot> {
|
||||
type SourceRootQuery;
|
||||
storage input;
|
||||
|
|
|
@ -5,6 +5,7 @@ version = "0.1.0"
|
|||
authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
arrayvec = "0.4.9"
|
||||
log = "0.4.5"
|
||||
relative-path = "0.4.0"
|
||||
salsa = "0.8.0"
|
||||
|
|
|
@ -4,9 +4,9 @@ use ra_syntax::{
|
|||
ast::{self, NameOwner},
|
||||
SmolStr,
|
||||
};
|
||||
use relative_path::RelativePathBuf;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use ra_db::{SourceRoot, SourceRootId, FileResolverImp, Cancelable, FileId,};
|
||||
use arrayvec::ArrayVec;
|
||||
use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId};
|
||||
|
||||
use crate::{
|
||||
HirDatabase,
|
||||
|
@ -110,8 +110,7 @@ fn build_subtree(
|
|||
|
||||
let (points_to, problem) = match sub {
|
||||
Submodule::Declaration(name) => {
|
||||
let (points_to, problem) =
|
||||
resolve_submodule(source, &name, &source_root.file_resolver);
|
||||
let (points_to, problem) = resolve_submodule(db, source, &name);
|
||||
let points_to = points_to
|
||||
.into_iter()
|
||||
.map(|file_id| match roots.remove(&file_id) {
|
||||
|
@ -153,30 +152,32 @@ fn build_subtree(
|
|||
}
|
||||
|
||||
fn resolve_submodule(
|
||||
db: &impl HirDatabase,
|
||||
source: ModuleSource,
|
||||
name: &SmolStr,
|
||||
file_resolver: &FileResolverImp,
|
||||
) -> (Vec<FileId>, Option<Problem>) {
|
||||
// TODO: handle submodules of inline modules properly
|
||||
// FIXME: handle submodules of inline modules properly
|
||||
let file_id = source.file_id();
|
||||
let mod_name = file_resolver.file_stem(file_id);
|
||||
let source_root_id = db.file_source_root(file_id);
|
||||
let path = db.file_relative_path(file_id);
|
||||
let dir_path = path.parent().unwrap();
|
||||
let mod_name = path.file_stem().unwrap_or("unknown");
|
||||
let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main";
|
||||
|
||||
let file_mod = RelativePathBuf::from(format!("../{}.rs", name));
|
||||
let dir_mod = RelativePathBuf::from(format!("../{}/mod.rs", name));
|
||||
let file_dir_mod = RelativePathBuf::from(format!("../{}/{}.rs", mod_name, name));
|
||||
let tmp1;
|
||||
let tmp2;
|
||||
let candidates = if is_dir_owner {
|
||||
tmp1 = [&file_mod, &dir_mod];
|
||||
tmp1.iter()
|
||||
let file_mod = dir_path.join(format!("{}.rs", name));
|
||||
let dir_mod = dir_path.join(format!("{}/mod.rs", name));
|
||||
let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name));
|
||||
let mut candidates = ArrayVec::<[_; 2]>::new();
|
||||
if is_dir_owner {
|
||||
candidates.push(file_mod.clone());
|
||||
candidates.push(dir_mod);
|
||||
} else {
|
||||
tmp2 = [&file_dir_mod];
|
||||
tmp2.iter()
|
||||
candidates.push(file_dir_mod.clone());
|
||||
};
|
||||
|
||||
let points_to = candidates
|
||||
.filter_map(|path| file_resolver.resolve(file_id, path))
|
||||
.into_iter()
|
||||
.filter_map(|path| db.source_root_file_by_path(source_root_id, path))
|
||||
.collect::<Vec<_>>();
|
||||
let problem = if points_to.is_empty() {
|
||||
Some(Problem::UnresolvedModule {
|
||||
|
|
Loading…
Reference in a new issue