-
Notifications
You must be signed in to change notification settings - Fork 253
Allow project model to download crates #1020
Changes from 4 commits
54e5273
bf66a15
1efd7c0
caf2427
746ffb5
2ae5662
1352bdf
a98c9a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /// This module represents the RLS view of the Cargo project model: | ||
| /// a graph of interdependent packages. | ||
| //! This module represents the RLS view of the Cargo project model: | ||
| //! a graph of interdependent packages. | ||
| use std::{ | ||
| collections::HashMap, | ||
| sync::Arc, | ||
|
|
@@ -20,15 +20,16 @@ use racer; | |
|
|
||
| #[derive(Debug)] | ||
| pub struct ProjectModel { | ||
| manifest_to_id: HashMap<PathBuf, Package>, | ||
| packages: Vec<PackageData>, | ||
| current_lib: Option<(String, PathBuf)>, | ||
|
||
| } | ||
|
|
||
| #[derive(Debug, Clone, Copy)] | ||
| pub struct Package(usize); | ||
|
|
||
| #[derive(Debug)] | ||
| struct PackageData { | ||
| manifest: PathBuf, | ||
| lib: Option<PathBuf>, | ||
| deps: Vec<Dep>, | ||
| } | ||
|
|
@@ -40,12 +41,12 @@ pub struct Dep { | |
| } | ||
|
|
||
| impl ProjectModel { | ||
| pub fn load(manifest: &Path, vfs: &Vfs) -> Result<ProjectModel, failure::Error> { | ||
| assert!(manifest.ends_with("Cargo.toml")); | ||
| pub fn load(current_manifest: &Path, vfs: &Vfs) -> Result<ProjectModel, failure::Error> { | ||
| assert!(current_manifest.ends_with("Cargo.toml")); | ||
| let mut config = Config::default()?; | ||
| // frozen=true, locked=true | ||
| config.configure(0, Some(true), &None, true, true, &None, &[])?; | ||
| let ws = Workspace::new(&manifest, &config)?; | ||
| // frozen = false, locked = false | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: It's definitely not making things any more worse/more complicated, since we currently https://github.com/rust-lang-nursery/rls/blob/master/src/build/cargo.rs#L572 a Cargo config with defaults (frozen, locked = false) as well.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| config.configure(0, Some(true), &None, false, false, &None, &[])?; | ||
| let ws = Workspace::new(¤t_manifest, &config)?; | ||
| // get resolve from lock file | ||
| let prev = { | ||
| let lock_path = ws.root().to_owned().join("Cargo.lock"); | ||
|
|
@@ -55,30 +56,39 @@ impl ProjectModel { | |
| let v: EncodableResolve = resolve.try_into()?; | ||
| Some(v.into_resolve(&ws)?) | ||
| } | ||
| _ => None | ||
| _ => None, | ||
| } | ||
| }; | ||
| // then resolve precisely and add overrides | ||
| let mut registry = PackageRegistry::new(ws.config())?; | ||
| let resolve = resolve_with_prev(&mut registry, &ws, prev.as_ref())?; | ||
| let cargo_packages = { | ||
| let ids: Vec<PackageId> = resolve.iter().cloned().collect(); | ||
| registry.get(&ids) | ||
| }; | ||
|
|
||
| let mut pkg_id_to_pkg = HashMap::new(); | ||
| let mut manifest_to_id = HashMap::new(); | ||
| let mut packages = Vec::new(); | ||
| let mut current_lib = None; | ||
| for (idx, pkg_id) in resolve.iter().enumerate() { | ||
| let pkg = Package(idx); | ||
| pkg_id_to_pkg.insert(pkg_id.clone(), pkg); | ||
| let cargo_pkg = cargo_packages.get(pkg_id)?; | ||
| let manifest = cargo_pkg.manifest_path().to_owned(); | ||
| packages.push(PackageData { | ||
| manifest: cargo_pkg.manifest_path().to_owned(), | ||
| lib: cargo_pkg.targets().iter() | ||
| lib: cargo_pkg | ||
| .targets() | ||
| .iter() | ||
| .find(|t| t.is_lib()) | ||
| .map(|t| t.src_path().to_owned()), | ||
| .map(|t| { | ||
| let src_path = t.src_path().to_owned(); | ||
| if manifest == current_manifest { | ||
| current_lib = Some((t.name().replace('-', "_"), src_path.clone())); | ||
| } | ||
| src_path | ||
| }), | ||
| deps: Vec::new(), | ||
| }) | ||
| }); | ||
| manifest_to_id.insert(manifest, pkg); | ||
| } | ||
| for pkg_id in resolve.iter() { | ||
| for (dep_id, _) in resolve.deps(&pkg_id) { | ||
|
|
@@ -99,20 +109,20 @@ impl ProjectModel { | |
| } | ||
| } | ||
| } | ||
| Ok(ProjectModel { packages }) | ||
| Ok(ProjectModel { | ||
| manifest_to_id, | ||
| packages, | ||
| current_lib, | ||
| }) | ||
| } | ||
|
|
||
| pub fn package_for_manifest(&self, manifest_path: &Path) -> Option<Package> { | ||
| self.packages.iter() | ||
| .enumerate() | ||
| .find(|(_idx, p)| p.manifest == manifest_path) | ||
| .map(|(idx, _p)| Package(idx)) | ||
| self.manifest_to_id.get(manifest_path).map(|&x| x) | ||
| } | ||
|
|
||
| fn get(&self, pkg: Package) -> &PackageData { | ||
| &self.packages[pkg.0] | ||
| } | ||
|
|
||
| } | ||
|
|
||
| impl Package { | ||
|
|
@@ -140,6 +150,12 @@ impl racer::ProjectModelProvider for RacerProjectModel { | |
| } | ||
| } | ||
| fn resolve_dependency(&self, manifest: &Path, libname: &str) -> Option<PathBuf> { | ||
| // for completion in tests/examples dir | ||
| if let Some(ref current_lib) = self.0.current_lib { | ||
| if current_lib.0 == libname { | ||
| return Some(current_lib.1.clone()); | ||
| } | ||
| } | ||
| let pkg = self.0.package_for_manifest(manifest)?; | ||
| let dep = pkg.deps(&self.0) | ||
| .iter() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍