Skip to content

Commit

Permalink
Allow rust files to be used linkedProjects
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Apr 21, 2024
1 parent 55d9a53 commit af3fc73
Show file tree
Hide file tree
Showing 19 changed files with 198 additions and 149 deletions.
2 changes: 2 additions & 0 deletions crates/base-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub trait FileLoader {
/// Text of the file.
fn file_text(&self, file_id: FileId) -> Arc<str>;
fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId>;
/// Crates whose root's source root is the same as the source root of `file_id`
fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]>;
}

Expand Down Expand Up @@ -104,6 +105,7 @@ pub trait SourceDatabaseExt: SourceDatabase {
#[salsa::input]
fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>;

/// Crates whose root fool is in `id`.
fn source_root_crates(&self, id: SourceRootId) -> Arc<[CrateId]>;
}

Expand Down
5 changes: 4 additions & 1 deletion crates/hir/src/semantics/source_to_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,17 @@ impl SourceToDefCtx<'_, '_> {
let _p = tracing::span!(tracing::Level::INFO, "SourceBinder::file_to_module_def").entered();
let mut mods = SmallVec::new();
for &crate_id in self.db.relevant_crates(file).iter() {
// FIXME: inner items
// Note: `mod` declarations in block modules cannot be supported here
let crate_def_map = self.db.crate_def_map(crate_id);
mods.extend(
crate_def_map
.modules_for_file(file)
.map(|local_id| crate_def_map.module_id(local_id)),
)
}
if mods.is_empty() {
// FIXME: detached file
}
mods
}

Expand Down
2 changes: 1 addition & 1 deletion crates/ide-db/src/prime_caches.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! rust-analyzer is lazy and doesn't compute anything unless asked. This
//! sometimes is counter productive when, for example, the first goto definition
//! request takes longer to compute. This modules implemented prepopulation of
//! request takes longer to compute. This module implements prepopulation of
//! various caches, it's not really advanced at the moment.
mod topologic_sort;

Expand Down
27 changes: 16 additions & 11 deletions crates/project-model/src/build_scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use toolchain::Tool;

use crate::{
cfg::CfgFlag, utf8_stdout, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
InvocationStrategy, Package, Sysroot, TargetKind,
InvocationStrategy, ManifestPath, Package, Sysroot, TargetKind,
};

/// Output of the build script and proc-macro building steps for a workspace.
Expand Down Expand Up @@ -63,7 +63,7 @@ impl WorkspaceBuildScripts {
fn build_command(
config: &CargoConfig,
allowed_features: &FxHashSet<String>,
workspace_root: &AbsPathBuf,
manifest_path: &ManifestPath,
sysroot: Option<&Sysroot>,
) -> io::Result<Command> {
let mut cmd = match config.run_build_script_command.as_deref() {
Expand All @@ -79,7 +79,7 @@ impl WorkspaceBuildScripts {
cmd.args(&config.extra_args);

cmd.arg("--manifest-path");
cmd.arg(workspace_root.join("Cargo.toml"));
cmd.arg(manifest_path.as_ref());

if let Some(target_dir) = &config.target_dir {
cmd.arg("--target-dir").arg(target_dir);
Expand Down Expand Up @@ -116,6 +116,10 @@ impl WorkspaceBuildScripts {
}
}

if manifest_path.extension().map_or(false, |ext| ext == "rs") {
cmd.arg("-Zscript");
}

cmd
}
};
Expand Down Expand Up @@ -154,12 +158,7 @@ impl WorkspaceBuildScripts {
let allowed_features = workspace.workspace_features();

match Self::run_per_ws(
Self::build_command(
config,
&allowed_features,
&workspace.workspace_root().to_path_buf(),
sysroot,
)?,
Self::build_command(config, &allowed_features, workspace.manifest_path(), sysroot)?,
workspace,
current_dir,
progress,
Expand All @@ -172,7 +171,7 @@ impl WorkspaceBuildScripts {
let mut cmd = Self::build_command(
config,
&allowed_features,
&workspace.workspace_root().to_path_buf(),
workspace.manifest_path(),
sysroot,
)?;

Expand Down Expand Up @@ -204,7 +203,13 @@ impl WorkspaceBuildScripts {
))
}
};
let cmd = Self::build_command(config, &Default::default(), workspace_root, None)?;
let cmd = Self::build_command(
config,
&Default::default(),
// This is not gonna be used anyways, so just construct a dummy here
&ManifestPath::try_from(workspace_root.clone()).unwrap(),
None,
)?;
// NB: Cargo.toml could have been modified between `cargo metadata` and
// `cargo check`. We shouldn't assume that package ids we see here are
// exactly those from `config`.
Expand Down
9 changes: 7 additions & 2 deletions crates/project-model/src/cargo_workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub struct CargoWorkspace {
targets: Arena<TargetData>,
workspace_root: AbsPathBuf,
target_directory: AbsPathBuf,
manifest_path: ManifestPath,
}

impl ops::Index<Package> for CargoWorkspace {
Expand Down Expand Up @@ -334,7 +335,7 @@ impl CargoWorkspace {
.with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))
}

pub fn new(mut meta: cargo_metadata::Metadata) -> CargoWorkspace {
pub fn new(mut meta: cargo_metadata::Metadata, manifest_path: ManifestPath) -> CargoWorkspace {
let mut pkg_by_id = FxHashMap::default();
let mut packages = Arena::default();
let mut targets = Arena::default();
Expand Down Expand Up @@ -448,7 +449,7 @@ impl CargoWorkspace {

let target_directory = AbsPathBuf::assert(meta.target_directory);

CargoWorkspace { packages, targets, workspace_root, target_directory }
CargoWorkspace { packages, targets, workspace_root, target_directory, manifest_path }
}

pub fn packages(&self) -> impl ExactSizeIterator<Item = Package> + '_ {
Expand All @@ -466,6 +467,10 @@ impl CargoWorkspace {
&self.workspace_root
}

pub fn manifest_path(&self) -> &ManifestPath {
&self.manifest_path
}

pub fn target_directory(&self) -> &AbsPath {
&self.target_directory
}
Expand Down
24 changes: 18 additions & 6 deletions crates/project-model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ pub use crate::{
sysroot::Sysroot,
workspace::{FileLoader, PackageRoot, ProjectWorkspace},
};
pub use cargo_metadata::Metadata;

#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum ProjectManifest {
ProjectJson(ManifestPath),
CargoToml(ManifestPath),
CargoScript(ManifestPath),
}

impl ProjectManifest {
Expand All @@ -71,7 +73,10 @@ impl ProjectManifest {
if path.file_name().unwrap_or_default() == "Cargo.toml" {
return Ok(ProjectManifest::CargoToml(path));
}
bail!("project root must point to Cargo.toml or rust-project.json: {path}");
if path.extension().unwrap_or_default() == "rs" {
return Ok(ProjectManifest::CargoScript(path));
}
bail!("project root must point to a Cargo.toml, rust-project.json or <script>.rs file: {path}");
}

pub fn discover_single(path: &AbsPath) -> anyhow::Result<ProjectManifest> {
Expand Down Expand Up @@ -146,15 +151,22 @@ impl ProjectManifest {
res.sort();
res
}

pub fn manifest_path(&self) -> &ManifestPath {
match self {
ProjectManifest::ProjectJson(it)
| ProjectManifest::CargoToml(it)
| ProjectManifest::CargoScript(it) => it,
}
}
}

impl fmt::Display for ProjectManifest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ProjectManifest::ProjectJson(it) | ProjectManifest::CargoToml(it) => {
fmt::Display::fmt(&it, f)
}
}
let (ProjectManifest::ProjectJson(it)
| ProjectManifest::CargoToml(it)
| ProjectManifest::CargoScript(it)) = self;
fmt::Display::fmt(&it, f)
}
}

Expand Down
12 changes: 9 additions & 3 deletions crates/project-model/src/manifest_path.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! See [`ManifestPath`].
use std::{fmt, ops, path::Path};
use std::{borrow::Borrow, fmt, ops};

use paths::{AbsPath, AbsPathBuf};

Expand Down Expand Up @@ -54,8 +54,14 @@ impl ops::Deref for ManifestPath {
}
}

impl AsRef<Path> for ManifestPath {
fn as_ref(&self) -> &Path {
impl AsRef<AbsPath> for ManifestPath {
fn as_ref(&self) -> &AbsPath {
self.file.as_ref()
}
}

impl Borrow<AbsPath> for ManifestPath {
fn borrow(&self) -> &AbsPath {
self.file.borrow()
}
}
6 changes: 3 additions & 3 deletions crates/project-model/src/sysroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ impl Sysroot {
.filter(|&package| RELEVANT_SYSROOT_CRATES.contains(&&*package.name))
.map(|package| package.id.clone())
.collect();
let cargo_workspace = CargoWorkspace::new(res);
let cargo_workspace = CargoWorkspace::new(res, sysroot_cargo_toml);
Some(Sysroot {
root: sysroot_dir.clone(),
src_root: Some(Ok(sysroot_src_dir.clone())),
Expand All @@ -368,7 +368,7 @@ impl Sysroot {
.into_iter()
.map(|it| sysroot_src_dir.join(it))
.filter_map(|it| ManifestPath::try_from(it).ok())
.find(|it| fs::metadata(it).is_ok());
.find(|it| fs::metadata(it.as_ref()).is_ok());

if let Some(root) = root {
stitched.crates.alloc(SysrootCrateData {
Expand Down Expand Up @@ -468,7 +468,7 @@ fn get_rustc_src(sysroot_path: &AbsPath) -> Option<ManifestPath> {
let rustc_src = sysroot_path.join("lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml");
let rustc_src = ManifestPath::try_from(rustc_src).ok()?;
tracing::debug!("checking for rustc source code: {rustc_src}");
if fs::metadata(&rustc_src).is_ok() {
if fs::metadata(rustc_src.as_ref()).is_ok() {
Some(rustc_src)
} else {
None
Expand Down
24 changes: 15 additions & 9 deletions crates/project-model/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::ops::Deref;

use base_db::{CrateGraph, FileId, ProcMacroPaths};
use cargo_metadata::Metadata;
use cfg::{CfgAtom, CfgDiff};
use expect_test::{expect_file, ExpectFile};
use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf};
Expand All @@ -9,8 +10,8 @@ use serde::de::DeserializeOwned;
use triomphe::Arc;

use crate::{
CargoWorkspace, CfgOverrides, ProjectJson, ProjectJsonData, ProjectWorkspace, Sysroot,
WorkspaceBuildScripts,
CargoWorkspace, CfgOverrides, ManifestPath, ProjectJson, ProjectJsonData, ProjectWorkspace,
Sysroot, WorkspaceBuildScripts,
};

fn load_cargo(file: &str) -> (CrateGraph, ProcMacroPaths) {
Expand All @@ -21,8 +22,10 @@ fn load_cargo_with_overrides(
file: &str,
cfg_overrides: CfgOverrides,
) -> (CrateGraph, ProcMacroPaths) {
let meta = get_test_json_file(file);
let cargo_workspace = CargoWorkspace::new(meta);
let meta: Metadata = get_test_json_file(file);
let manifest_path =
ManifestPath::try_from(AbsPathBuf::try_from(meta.workspace_root.clone()).unwrap()).unwrap();
let cargo_workspace = CargoWorkspace::new(meta, manifest_path);
let project_workspace = ProjectWorkspace::Cargo {
cargo: cargo_workspace,
build_scripts: WorkspaceBuildScripts::default(),
Expand All @@ -41,8 +44,10 @@ fn load_cargo_with_fake_sysroot(
file_map: &mut FxHashMap<AbsPathBuf, FileId>,
file: &str,
) -> (CrateGraph, ProcMacroPaths) {
let meta = get_test_json_file(file);
let cargo_workspace = CargoWorkspace::new(meta);
let meta: Metadata = get_test_json_file(file);
let manifest_path =
ManifestPath::try_from(AbsPathBuf::try_from(meta.workspace_root.clone()).unwrap()).unwrap();
let cargo_workspace = CargoWorkspace::new(meta, manifest_path);
let project_workspace = ProjectWorkspace::Cargo {
cargo: cargo_workspace,
build_scripts: WorkspaceBuildScripts::default(),
Expand Down Expand Up @@ -268,9 +273,10 @@ fn smoke_test_real_sysroot_cargo() {
return;
}
let file_map = &mut FxHashMap::<AbsPathBuf, FileId>::default();
let meta = get_test_json_file("hello-world-metadata.json");

let cargo_workspace = CargoWorkspace::new(meta);
let meta: Metadata = get_test_json_file("hello-world-metadata.json");
let manifest_path =
ManifestPath::try_from(AbsPathBuf::try_from(meta.workspace_root.clone()).unwrap()).unwrap();
let cargo_workspace = CargoWorkspace::new(meta, manifest_path);
let sysroot = Ok(Sysroot::discover(
AbsPath::assert(Utf8Path::new(env!("CARGO_MANIFEST_DIR"))),
&Default::default(),
Expand Down
Loading

0 comments on commit af3fc73

Please sign in to comment.