Skip to content

internal: add library fixture meta #15161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 69 additions & 41 deletions crates/base-db/src/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ pub struct ChangeFixture {
pub change: Change,
}

const SOURCE_ROOT_PREFIX: &str = "/";

impl ChangeFixture {
pub fn parse(ra_fixture: &str) -> ChangeFixture {
Self::parse_with_proc_macros(ra_fixture, Vec::new())
Expand Down Expand Up @@ -131,7 +133,6 @@ impl ChangeFixture {

let mut file_set = FileSet::default();
let mut current_source_root_kind = SourceRootKind::Local;
let source_root_prefix = "/".to_string();
let mut file_id = FileId(0);
let mut roots = Vec::new();

Expand All @@ -151,19 +152,23 @@ impl ChangeFixture {
entry.text.clone()
};

let meta = FileMeta::from(entry);
assert!(meta.path.starts_with(&source_root_prefix));
let meta = FileMeta::from_fixture(entry, current_source_root_kind);
assert!(meta.path.starts_with(SOURCE_ROOT_PREFIX));
if !meta.deps.is_empty() {
assert!(meta.krate.is_some(), "can't specify deps without naming the crate")
}

if let Some(kind) = &meta.introduce_new_source_root {
let root = match current_source_root_kind {
if let Some(kind) = meta.introduce_new_source_root {
assert!(
meta.krate.is_some(),
"new_source_root meta doesn't make sense without crate meta"
);
let prev_kind = mem::replace(&mut current_source_root_kind, kind);
let prev_root = match prev_kind {
SourceRootKind::Local => SourceRoot::new_local(mem::take(&mut file_set)),
SourceRootKind::Library => SourceRoot::new_library(mem::take(&mut file_set)),
};
roots.push(root);
current_source_root_kind = *kind;
roots.push(prev_root);
}

if let Some((krate, origin, version)) = meta.krate {
Expand All @@ -185,7 +190,7 @@ impl ChangeFixture {
Some(toolchain),
);
let prev = crates.insert(crate_name.clone(), crate_id);
assert!(prev.is_none());
assert!(prev.is_none(), "multiple crates with same name: {}", crate_name);
for dep in meta.deps {
let prelude = meta.extern_prelude.contains(&dep);
let dep = CrateName::normalize_dashes(&dep);
Expand Down Expand Up @@ -442,51 +447,74 @@ struct FileMeta {
target_data_layout: Option<String>,
}

fn parse_crate(crate_str: String) -> (String, CrateOrigin, Option<String>) {
if let Some((a, b)) = crate_str.split_once('@') {
let (version, origin) = match b.split_once(':') {
Some(("CratesIo", data)) => match data.split_once(',') {
Some((version, url)) => {
(version, CrateOrigin::Local { repo: Some(url.to_owned()), name: None })
}
_ => panic!("Bad crates.io parameter: {data}"),
},
_ => panic!("Bad string for crate origin: {b}"),
};
(a.to_owned(), origin, Some(version.to_string()))
} else {
let crate_origin = match LangCrateOrigin::from(&*crate_str) {
LangCrateOrigin::Other => CrateOrigin::Local { repo: None, name: None },
origin => CrateOrigin::Lang(origin),
};
(crate_str, crate_origin, None)
}
}

impl From<Fixture> for FileMeta {
fn from(f: Fixture) -> FileMeta {
impl FileMeta {
fn from_fixture(f: Fixture, current_source_root_kind: SourceRootKind) -> Self {
let mut cfg = CfgOptions::default();
f.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into()));
f.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into()));
for (k, v) in f.cfgs {
if let Some(v) = v {
cfg.insert_key_value(k.into(), v.into());
} else {
cfg.insert_atom(k.into());
}
}

let introduce_new_source_root = f.introduce_new_source_root.map(|kind| match &*kind {
"local" => SourceRootKind::Local,
"library" => SourceRootKind::Library,
invalid => panic!("invalid source root kind '{invalid}'"),
});
let current_source_root_kind =
introduce_new_source_root.unwrap_or(current_source_root_kind);

let deps = f.deps;
FileMeta {
Self {
path: f.path,
krate: f.krate.map(parse_crate),
krate: f.krate.map(|it| parse_crate(it, current_source_root_kind, f.library)),
extern_prelude: f.extern_prelude.unwrap_or_else(|| deps.clone()),
deps,
cfg,
edition: f.edition.as_ref().map_or(Edition::CURRENT, |v| Edition::from_str(v).unwrap()),
edition: f.edition.map_or(Edition::CURRENT, |v| Edition::from_str(&v).unwrap()),
env: f.env.into_iter().collect(),
introduce_new_source_root: f.introduce_new_source_root.map(|kind| match &*kind {
"local" => SourceRootKind::Local,
"library" => SourceRootKind::Library,
invalid => panic!("invalid source root kind '{invalid}'"),
}),
introduce_new_source_root,
target_data_layout: f.target_data_layout,
}
}
}

fn parse_crate(
crate_str: String,
current_source_root_kind: SourceRootKind,
explicit_non_workspace_member: bool,
) -> (String, CrateOrigin, Option<String>) {
// syntax:
// "my_awesome_crate"
// "[email protected],http://example.com"
let (name, repo, version) = if let Some((name, remain)) = crate_str.split_once('@') {
let (version, repo) =
remain.split_once(',').expect("crate meta: found '@' without version and url");
(name.to_owned(), Some(repo.to_owned()), Some(version.to_owned()))
} else {
(crate_str, None, None)
};

let non_workspace_member = explicit_non_workspace_member
|| matches!(current_source_root_kind, SourceRootKind::Library);

let origin = match LangCrateOrigin::from(&*name) {
LangCrateOrigin::Other => {
let name = name.clone();
if non_workspace_member {
CrateOrigin::Library { repo, name }
} else {
CrateOrigin::Local { repo, name: Some(name) }
}
}
origin => CrateOrigin::Lang(origin),
};

(name, origin, version)
}

// Identity mapping
#[derive(Debug)]
struct IdentityProcMacroExpander;
Expand Down
6 changes: 3 additions & 3 deletions crates/base-db/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,12 @@ impl ops::Deref for CrateName {
}
}

/// Origin of the crates. It is used in emitting monikers.
/// Origin of the crates.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum CrateOrigin {
/// Crates that are from the rustc workspace
/// Crates that are from the rustc workspace.
Rustc { name: String },
/// Crates that are workspace members,
/// Crates that are workspace members.
Local { repo: Option<String>, name: Option<String> },
/// Crates that are non member libraries.
Library { repo: Option<String>, name: String },
Expand Down
16 changes: 8 additions & 8 deletions crates/ide/src/moniker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ use foo::module::func;
fn main() {
func$0();
}
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub fn func() {}
}
Expand All @@ -336,7 +336,7 @@ use foo::module::func;
fn main() {
func();
}
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub fn func$0() {}
}
Expand All @@ -351,7 +351,7 @@ pub mod module {
fn moniker_for_trait() {
check_moniker(
r#"
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub trait MyTrait {
pub fn func$0() {}
Expand All @@ -368,7 +368,7 @@ pub mod module {
fn moniker_for_trait_constant() {
check_moniker(
r#"
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub trait MyTrait {
const MY_CONST$0: u8;
Expand All @@ -385,7 +385,7 @@ pub mod module {
fn moniker_for_trait_type() {
check_moniker(
r#"
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub trait MyTrait {
type MyType$0;
Expand All @@ -402,7 +402,7 @@ pub mod module {
fn moniker_for_trait_impl_function() {
check_moniker(
r#"
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub trait MyTrait {
pub fn func() {}
Expand Down Expand Up @@ -430,7 +430,7 @@ use foo::St;
fn main() {
let x = St { a$0: 2 };
}
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub struct St {
pub a: i32,
}
Expand All @@ -450,7 +450,7 @@ use foo::module::func;
fn main() {
func();
}
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub fn func() {
let x$0 = 2;
Expand Down
14 changes: 7 additions & 7 deletions crates/rust-analyzer/src/cli/scip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ use foo::example_mod::func;
fn main() {
func$0();
}
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod example_mod {
pub fn func() {}
}
Expand All @@ -337,7 +337,7 @@ pub mod example_mod {
fn symbol_for_trait() {
check_symbol(
r#"
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub trait MyTrait {
pub fn func$0() {}
Expand All @@ -352,7 +352,7 @@ pub mod module {
fn symbol_for_trait_constant() {
check_symbol(
r#"
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub trait MyTrait {
const MY_CONST$0: u8;
Expand All @@ -367,7 +367,7 @@ pub mod module {
fn symbol_for_trait_type() {
check_symbol(
r#"
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub trait MyTrait {
type MyType$0;
Expand All @@ -383,7 +383,7 @@ pub mod module {
fn symbol_for_trait_impl_function() {
check_symbol(
r#"
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub trait MyTrait {
pub fn func() {}
Expand All @@ -410,7 +410,7 @@ pub mod module {
fn main() {
let x = St { a$0: 2 };
}
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub struct St {
pub a: i32,
}
Expand All @@ -428,7 +428,7 @@ pub mod module {
fn main() {
func();
}
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
pub mod module {
pub fn func() {
let x$0 = 2;
Expand Down
Loading