Skip to content

Commit 19f6cdc

Browse files
bors[bot]matklad
andcommitted
Merge #268
268: WIP: resolve imports across crates r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 34956b7 + 7784c7a commit 19f6cdc

File tree

12 files changed

+373
-169
lines changed

12 files changed

+373
-169
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[workspace]
22
members = [ "crates/*" ]
3-
exclude = [ "crates/rowan"]
43

54
[profile.release]
65
debug = true

crates/ra_db/src/input.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::sync::Arc;
22

3-
use rustc_hash::FxHashMap;
4-
use rustc_hash::FxHashSet;
3+
use rustc_hash::{FxHashSet, FxHashMap};
4+
use ra_syntax::SmolStr;
55
use salsa;
66

77
use crate::file_resolver::FileResolverImp;
@@ -20,25 +20,32 @@ pub struct CrateGraph {
2020
#[derive(Debug, Clone, PartialEq, Eq)]
2121
struct CrateData {
2222
file_id: FileId,
23-
deps: Vec<Dependency>,
23+
dependencies: Vec<Dependency>,
2424
}
2525

2626
impl CrateData {
2727
fn new(file_id: FileId) -> CrateData {
2828
CrateData {
2929
file_id,
30-
deps: Vec::new(),
30+
dependencies: Vec::new(),
3131
}
3232
}
3333

34-
fn add_dep(&mut self, dep: CrateId) {
35-
self.deps.push(Dependency { crate_: dep })
34+
fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) {
35+
self.dependencies.push(Dependency { name, crate_id })
3636
}
3737
}
3838

3939
#[derive(Debug, Clone, PartialEq, Eq)]
4040
pub struct Dependency {
41-
crate_: CrateId,
41+
pub crate_id: CrateId,
42+
pub name: SmolStr,
43+
}
44+
45+
impl Dependency {
46+
pub fn crate_id(&self) -> CrateId {
47+
self.crate_id
48+
}
4249
}
4350

4451
impl CrateGraph {
@@ -48,8 +55,11 @@ impl CrateGraph {
4855
assert!(prev.is_none());
4956
crate_id
5057
}
51-
pub fn add_dep(&mut self, from: CrateId, to: CrateId) {
52-
self.arena.get_mut(&from).unwrap().add_dep(to)
58+
//FIXME: check that we don't have cycles here.
59+
// Just a simple depth first search from `to` should work,
60+
// the graph is small.
61+
pub fn add_dep(&mut self, from: CrateId, name: SmolStr, to: CrateId) {
62+
self.arena.get_mut(&from).unwrap().add_dep(name, to)
5363
}
5464
pub fn crate_root(&self, crate_id: CrateId) -> FileId {
5565
self.arena[&crate_id].file_id
@@ -61,6 +71,12 @@ impl CrateGraph {
6171
.find(|(_crate_id, data)| data.file_id == file_id)?;
6272
Some(crate_id)
6373
}
74+
pub fn dependencies<'a>(
75+
&'a self,
76+
crate_id: CrateId,
77+
) -> impl Iterator<Item = &'a Dependency> + 'a {
78+
self.arena[&crate_id].dependencies.iter()
79+
}
6480
}
6581

6682
salsa::query_group! {

crates/ra_db/src/mock.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use relative_path::{RelativePath, RelativePathBuf};
55

66
use crate::{FileId, FileResolver, SourceRoot, FileResolverImp};
77

8-
#[derive(Default, Debug)]
8+
#[derive(Default, Debug, Clone)]
99
pub struct FileMap(Vec<(FileId, RelativePathBuf)>);
1010

1111
impl FileMap {
@@ -28,6 +28,11 @@ impl FileMap {
2828
self.iter().map(|(id, _)| id).collect()
2929
}
3030

31+
pub fn file_id(&self, path: &str) -> FileId {
32+
assert!(path.starts_with('/'));
33+
self.iter().find(|(_, p)| p == &path[1..]).unwrap().0
34+
}
35+
3136
fn iter<'a>(&'a self) -> impl Iterator<Item = (FileId, &'a RelativePath)> + 'a {
3237
self.0
3338
.iter()

crates/ra_hir/src/krate.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use ra_syntax::SmolStr;
2+
pub use ra_db::CrateId;
3+
4+
use crate::{HirDatabase, Module, Cancelable};
5+
6+
/// hir::Crate describes a single crate. It's the main inteface with which
7+
/// crate's dependencies interact. Mostly, it should be just a proxy for the
8+
/// root module.
9+
#[derive(Debug)]
10+
pub struct Crate {
11+
crate_id: CrateId,
12+
}
13+
14+
#[derive(Debug)]
15+
pub struct CrateDependency {
16+
pub krate: Crate,
17+
pub name: SmolStr,
18+
}
19+
20+
impl Crate {
21+
pub(crate) fn new(crate_id: CrateId) -> Crate {
22+
Crate { crate_id }
23+
}
24+
pub fn dependencies(&self, db: &impl HirDatabase) -> Vec<CrateDependency> {
25+
let crate_graph = db.crate_graph();
26+
crate_graph
27+
.dependencies(self.crate_id)
28+
.map(|dep| {
29+
let krate = Crate::new(dep.crate_id());
30+
let name = dep.name.clone();
31+
CrateDependency { krate, name }
32+
})
33+
.collect()
34+
}
35+
pub fn root_module(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> {
36+
let crate_graph = db.crate_graph();
37+
let file_id = crate_graph.crate_root(self.crate_id);
38+
let source_root_id = db.file_source_root(file_id);
39+
let module_tree = db.module_tree(source_root_id)?;
40+
// FIXME: teach module tree about crate roots instead of guessing
41+
let (module_id, _) = ctry!(module_tree
42+
.modules_with_sources()
43+
.find(|(_, src)| src.file_id() == file_id));
44+
45+
let module = Module::new(db, source_root_id, module_id)?;
46+
Ok(Some(module))
47+
}
48+
}

crates/ra_hir/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ pub mod db;
1818
#[cfg(test)]
1919
mod mock;
2020
mod query_definitions;
21-
mod function;
22-
mod module;
2321
mod path;
2422
mod arena;
2523
pub mod source_binder;
2624

25+
mod krate;
26+
mod module;
27+
mod function;
28+
2729
use std::ops::Index;
2830

2931
use ra_syntax::{SyntaxNodeRef, SyntaxNode};
@@ -36,6 +38,7 @@ use crate::{
3638

3739
pub use self::{
3840
path::{Path, PathKind},
41+
krate::Crate,
3942
module::{Module, ModuleId, Problem, nameres::ItemMap},
4043
function::{Function, FnScopes},
4144
};

crates/ra_hir/src/mock.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::sync::Arc;
22

33
use parking_lot::Mutex;
44
use salsa::{self, Database};
5-
use ra_db::{LocationIntener, BaseDatabase, FilePosition, mock::FileMap, FileId, WORKSPACE};
5+
use ra_db::{LocationIntener, BaseDatabase, FilePosition, mock::FileMap, FileId, WORKSPACE, CrateGraph};
66
use relative_path::RelativePathBuf;
77
use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset};
88

@@ -16,7 +16,24 @@ pub(crate) struct MockDatabase {
1616
}
1717

1818
impl MockDatabase {
19+
pub(crate) fn with_files(fixture: &str) -> (MockDatabase, FileMap) {
20+
let (db, file_map, position) = MockDatabase::from_fixture(fixture);
21+
assert!(position.is_none());
22+
(db, file_map)
23+
}
24+
1925
pub(crate) fn with_position(fixture: &str) -> (MockDatabase, FilePosition) {
26+
let (db, _, position) = MockDatabase::from_fixture(fixture);
27+
let position = position.expect("expected a marker ( <|> )");
28+
(db, position)
29+
}
30+
31+
pub(crate) fn set_crate_graph(&mut self, crate_graph: CrateGraph) {
32+
self.query_mut(ra_db::CrateGraphQuery)
33+
.set((), Arc::new(crate_graph));
34+
}
35+
36+
fn from_fixture(fixture: &str) -> (MockDatabase, FileMap, Option<FilePosition>) {
2037
let mut db = MockDatabase::default();
2138

2239
let mut position = None;
@@ -32,11 +49,10 @@ impl MockDatabase {
3249
db.add_file(&mut file_map, &entry.meta, &entry.text);
3350
}
3451
}
35-
let position = position.expect("expected a marker (<|>)");
36-
let source_root = file_map.into_source_root();
52+
let source_root = file_map.clone().into_source_root();
3753
db.query_mut(ra_db::SourceRootQuery)
3854
.set(WORKSPACE, Arc::new(source_root));
39-
(db, position)
55+
(db, file_map, position)
4056
}
4157

4258
fn add_file(&mut self, file_map: &mut FileMap, path: &str, text: &str) -> FileId {

crates/ra_hir/src/module.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use ra_db::{SourceRootId, FileId, Cancelable};
1212
use relative_path::RelativePathBuf;
1313

1414
use crate::{
15-
DefKind, DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId,
15+
DefKind, DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate,
1616
arena::{Arena, Id},
1717
};
1818

@@ -64,6 +64,15 @@ impl Module {
6464
})
6565
}
6666

67+
/// Returns the crate this module is part of.
68+
pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> {
69+
let root_id = self.module_id.crate_root(&self.tree);
70+
let file_id = root_id.source(&self.tree).file_id();
71+
let crate_graph = db.crate_graph();
72+
let crate_id = crate_graph.crate_id_for_crate_root(file_id)?;
73+
Some(Crate::new(crate_id))
74+
}
75+
6776
/// The root of the tree this module is part of
6877
pub fn crate_root(&self) -> Module {
6978
let root_id = self.module_id.crate_root(&self.tree);

0 commit comments

Comments
 (0)