Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit e926d49

Browse files
authoredAug 28, 2018
Merge pull request #1020 from kngwyu/racer-pm-fix
Allow project model to download crates
2 parents 6bda4d5 + a98c9a0 commit e926d49

File tree

2 files changed

+101
-23
lines changed

2 files changed

+101
-23
lines changed
 

‎src/project_model.rs

+35-22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/// This module represents the RLS view of the Cargo project model:
2-
/// a graph of interdependent packages.
1+
//! This module represents the RLS view of the Cargo project model:
2+
//! a graph of interdependent packages.
33
use std::{
44
collections::HashMap,
55
sync::Arc,
@@ -20,6 +20,7 @@ use racer;
2020

2121
#[derive(Debug)]
2222
pub struct ProjectModel {
23+
manifest_to_id: HashMap<PathBuf, Package>,
2324
packages: Vec<PackageData>,
2425
}
2526

@@ -28,8 +29,7 @@ pub struct Package(usize);
2829

2930
#[derive(Debug)]
3031
struct PackageData {
31-
manifest: PathBuf,
32-
lib: Option<PathBuf>,
32+
lib: Option<(PathBuf, String)>,
3333
deps: Vec<Dep>,
3434
}
3535

@@ -40,12 +40,12 @@ pub struct Dep {
4040
}
4141

4242
impl ProjectModel {
43-
pub fn load(manifest: &Path, vfs: &Vfs) -> Result<ProjectModel, failure::Error> {
44-
assert!(manifest.ends_with("Cargo.toml"));
43+
pub fn load(ws_manifest: &Path, vfs: &Vfs) -> Result<ProjectModel, failure::Error> {
44+
assert!(ws_manifest.ends_with("Cargo.toml"));
4545
let mut config = Config::default()?;
46-
// frozen=true, locked=true
47-
config.configure(0, Some(true), &None, true, true, &None, &[])?;
48-
let ws = Workspace::new(&manifest, &config)?;
46+
// frozen = false, locked = false
47+
config.configure(0, Some(true), &None, false, false, &None, &[])?;
48+
let ws = Workspace::new(&ws_manifest, &config)?;
4949
// get resolve from lock file
5050
let prev = {
5151
let lock_path = ws.root().to_owned().join("Cargo.lock");
@@ -55,30 +55,33 @@ impl ProjectModel {
5555
let v: EncodableResolve = resolve.try_into()?;
5656
Some(v.into_resolve(&ws)?)
5757
}
58-
_ => None
58+
_ => None,
5959
}
6060
};
61-
// then resolve precisely and add overrides
6261
let mut registry = PackageRegistry::new(ws.config())?;
6362
let resolve = resolve_with_prev(&mut registry, &ws, prev.as_ref())?;
6463
let cargo_packages = {
6564
let ids: Vec<PackageId> = resolve.iter().cloned().collect();
6665
registry.get(&ids)
6766
};
68-
6967
let mut pkg_id_to_pkg = HashMap::new();
68+
let mut manifest_to_id = HashMap::new();
7069
let mut packages = Vec::new();
7170
for (idx, pkg_id) in resolve.iter().enumerate() {
7271
let pkg = Package(idx);
7372
pkg_id_to_pkg.insert(pkg_id.clone(), pkg);
7473
let cargo_pkg = cargo_packages.get(pkg_id)?;
74+
let manifest = cargo_pkg.manifest_path().to_owned();
7575
packages.push(PackageData {
76-
manifest: cargo_pkg.manifest_path().to_owned(),
77-
lib: cargo_pkg.targets().iter()
76+
lib: cargo_pkg
77+
.targets()
78+
.iter()
7879
.find(|t| t.is_lib())
79-
.map(|t| t.src_path().to_owned()),
80+
// racer expect name 'underscored'(crate) name
81+
.map(|t| (t.src_path().to_owned(), t.name().replace('-', "_"))),
8082
deps: Vec::new(),
81-
})
83+
});
84+
manifest_to_id.insert(manifest, pkg);
8285
}
8386
for pkg_id in resolve.iter() {
8487
for (dep_id, _) in resolve.deps(&pkg_id) {
@@ -99,28 +102,31 @@ impl ProjectModel {
99102
}
100103
}
101104
}
102-
Ok(ProjectModel { packages })
105+
Ok(ProjectModel {
106+
manifest_to_id,
107+
packages,
108+
})
103109
}
104110

105111
pub fn package_for_manifest(&self, manifest_path: &Path) -> Option<Package> {
106-
self.packages.iter()
107-
.enumerate()
108-
.find(|(_idx, p)| p.manifest == manifest_path)
109-
.map(|(idx, _p)| Package(idx))
112+
self.manifest_to_id.get(manifest_path).map(|&x| x)
110113
}
111114

112115
fn get(&self, pkg: Package) -> &PackageData {
113116
&self.packages[pkg.0]
114117
}
115118

119+
fn get_lib(&self, pkg: Package) -> Option<&(PathBuf, String)> {
120+
self.packages[pkg.0].lib.as_ref()
121+
}
116122
}
117123

118124
impl Package {
119125
pub fn deps(self, project: &ProjectModel) -> &[Dep] {
120126
&project.get(self).deps
121127
}
122128
pub fn lib_root(self, project: &ProjectModel) -> Option<&Path> {
123-
project.get(self).lib.as_ref().map(|p| p.as_path())
129+
project.get(self).lib.as_ref().map(|p| p.0.as_path())
124130
}
125131
}
126132

@@ -141,6 +147,13 @@ impl racer::ProjectModelProvider for RacerProjectModel {
141147
}
142148
fn resolve_dependency(&self, manifest: &Path, libname: &str) -> Option<PathBuf> {
143149
let pkg = self.0.package_for_manifest(manifest)?;
150+
// if current package has a library target, we have to provide its own name
151+
// in examples/tests/benches directory
152+
if let Some(lib) = self.0.get_lib(pkg) {
153+
if lib.1 == libname {
154+
return Some(lib.0.clone());
155+
}
156+
}
144157
let dep = pkg.deps(&self.0)
145158
.iter()
146159
.find(|dep| dep.crate_name == libname)?

‎tests/tests.rs

+66-1
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,69 @@ fn changing_workspace_lib_retains_bin_diagnostics() {
311311

312312
rls.shutdown_exit();
313313
});
314-
}
314+
}
315+
316+
#[test]
317+
fn cmd_test_complete_self_crate_name() {
318+
timeout(Duration::from_secs(TIME_LIMIT_SECS), ||{
319+
let p = project("ws_with_test_dir")
320+
.file("Cargo.toml", r#"
321+
[workspace]
322+
members = ["library"]
323+
"#)
324+
.file("library/Cargo.toml", r#"
325+
[package]
326+
name = "library"
327+
version = "0.1.0"
328+
authors = ["Example <rls@example.com>"]
329+
"#)
330+
.file("library/src/lib.rs", r#"
331+
pub fn function() -> usize { 5 }
332+
"#)
333+
.file("library/tests/test.rs", r#"
334+
extern crate library;
335+
use library::~
336+
"#)
337+
.build();
338+
339+
let root_path = p.root();
340+
let rls_child = p.rls().spawn().unwrap();
341+
let mut rls = RlsHandle::new(rls_child);
342+
343+
rls.request(0, "initialize", Some(json!({
344+
"rootPath": root_path,
345+
"capabilities": {}
346+
}))).unwrap();
347+
348+
rls.expect_messages(&[
349+
ExpectedMessage::new(Some(0)).expect_contains("capabilities"),
350+
ExpectedMessage::new(None).expect_contains("progress").expect_contains(r#"title":"Building""#),
351+
ExpectedMessage::new(None).expect_contains("progress").expect_contains("library"),
352+
ExpectedMessage::new(None).expect_contains("progress").expect_contains("library"),
353+
ExpectedMessage::new(None).expect_contains("progress").expect_contains(r#"title":"Building""#),
354+
ExpectedMessage::new(None).expect_contains("progress").expect_contains(r#""done":true"#),
355+
ExpectedMessage::new(None).expect_contains("progress").expect_contains(r#"title":"Indexing""#),
356+
ExpectedMessage::new(None).expect_contains("expected identifier, found"),
357+
ExpectedMessage::new(None).expect_contains("progress").expect_contains(r#""done":true"#),
358+
]);
359+
rls.request(0, "textDocument/completion", Some(json!({
360+
"context": {
361+
"triggerCharacter": ":",
362+
"triggerKind": 2
363+
},
364+
"position": {
365+
"character": 32,
366+
"line": 2
367+
},
368+
"textDocument": {
369+
"uri": format!("file://{}/library/tests/test.rs", root_path.as_path().display()),
370+
"version": 1
371+
}
372+
}))).unwrap();
373+
rls.expect_messages(&[
374+
ExpectedMessage::new(Some(0)).expect_contains("result").expect_contains("pub fn function() -> usize"),
375+
]);
376+
377+
rls.shutdown_exit();
378+
});
379+
}

0 commit comments

Comments
 (0)
This repository has been archived.