From 1541b996dabb994d815d7b8c5ba3f215f60363aa Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Sat, 10 Apr 2021 23:55:31 +0200 Subject: [PATCH 01/10] Use bevy_reflect as path in case of no direct references Fixes #1844 --- .../bevy_reflect_derive/Cargo.toml | 2 +- .../bevy_reflect_derive/src/lib.rs | 11 +--- .../bevy_reflect_derive/src/modules.rs | 60 ++++++++++++------- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml b/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml index debf6625049ca..77866acc16a26 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml +++ b/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml @@ -19,5 +19,5 @@ proc-macro = true syn = "1.0" proc-macro2 = "1.0" quote = "1.0" -find-crate = "0.6" +cargo-manifest = "0.2.3" uuid = { version = "0.8", features = ["v4", "serde"] } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index 7d1b5fdc86f0d..526745b604fe9 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -4,7 +4,6 @@ mod modules; mod reflect_trait; mod type_uuid; -use find_crate::Manifest; use modules::{get_modules, get_path}; use proc_macro::TokenStream; use proc_macro2::Span; @@ -558,15 +557,7 @@ impl Parse for ReflectDef { pub fn impl_reflect_value(input: TokenStream) -> TokenStream { let reflect_value_def = parse_macro_input!(input as ReflectDef); - let manifest = Manifest::new().unwrap(); - let crate_path = if let Some(package) = manifest.find(|name| name == "bevy") { - format!("{}::reflect", package.name) - } else if let Some(package) = manifest.find(|name| name == "bevy_reflect") { - package.name - } else { - "crate".to_string() - }; - let bevy_reflect_path = get_path(&crate_path); + let bevy_reflect_path = get_path(&get_modules().bevy_reflect); let ty = &reflect_value_def.type_name; let reflect_attrs = reflect_value_def .attrs diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs b/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs index 73335874c0532..863309c96c232 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs @@ -1,5 +1,6 @@ -use find_crate::{Dependencies, Manifest}; +use cargo_manifest::{DepsSet, Manifest}; use proc_macro::TokenStream; +use std::{env, path::PathBuf}; use syn::Path; #[derive(Debug)] @@ -28,31 +29,44 @@ impl Modules { } pub fn get_modules() -> Modules { - let mut manifest = Manifest::new().unwrap(); - // Only look for regular dependencies in the first pass. - manifest.dependencies = Dependencies::Release; - - if let Some(package) = manifest.find(|name| name == "bevy") { - Modules::meta(&package.name) - } else if let Some(package) = manifest.find(|name| name == "bevy_internal") { - Modules::meta(&package.name) - } else if let Some(_package) = manifest.find(|name| name == "bevy_reflect") { - Modules::external() - } else { - // If reflect is not found as a regular dependency, - // try dev-dependencies. - manifest.dependencies = Dependencies::Dev; - - if let Some(package) = manifest.find(|name| name == "bevy") { - Modules::meta(&package.name) - } else if let Some(package) = manifest.find(|name| name == "bevy_internal") { - Modules::meta(&package.name) - } else if let Some(_package) = manifest.find(|name| name == "bevy_reflect") { - Modules::external() + const BEVY: &str = "bevy"; + const BEVY_EXTERNAL: &str = "bevy_reflect"; + const BEVY_INTERNAL: &str = "bevy_internal"; + + fn find_in_deps(deps: DepsSet) -> Option { + if let Some(dep) = deps.get(BEVY) { + Some(Modules::meta(dep.package().unwrap_or(BEVY))) + } else if let Some(dep) = deps.get(BEVY_INTERNAL) { + Some(Modules::meta(dep.package().unwrap_or(BEVY_INTERNAL))) + } else if let Some(_) = deps.get(BEVY_EXTERNAL) { + Some(Modules::external()) } else { - Modules::internal() + None } } + + let manifest = env::var_os("CARGO_MANIFEST_DIR") + .map(PathBuf::from) + .map(|mut path| { + path.push("Cargo.toml"); + Manifest::from_path(path).unwrap() + }) + .unwrap(); + let deps = manifest.dependencies; + let deps_dev = manifest.dev_dependencies; + + manifest + .package + .and_then(|p| { + if p.name == BEVY_EXTERNAL { + Some(Modules::internal()) + } else { + None + } + }) + .or_else(|| deps.and_then(find_in_deps)) + .or_else(|| deps_dev.and_then(find_in_deps)) + .unwrap_or_else(|| Modules::external()) } pub fn get_path(path_str: &str) -> Path { From 507c8f9385a4834460b204a83b6b6d42b7159194 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Sun, 11 Apr 2021 01:23:47 +0200 Subject: [PATCH 02/10] Formatting --- crates/bevy_reflect/bevy_reflect_derive/src/modules.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs b/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs index 863309c96c232..672159dcd651a 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs @@ -54,7 +54,7 @@ pub fn get_modules() -> Modules { .unwrap(); let deps = manifest.dependencies; let deps_dev = manifest.dev_dependencies; - + manifest .package .and_then(|p| { From 29f266c893a08885a79b8b5db7a98e95f1e1d9a5 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Sun, 11 Apr 2021 15:10:51 +0200 Subject: [PATCH 03/10] Clippy --- crates/bevy_reflect/bevy_reflect_derive/src/modules.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs b/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs index 672159dcd651a..eeeac292325a7 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs @@ -38,7 +38,7 @@ pub fn get_modules() -> Modules { Some(Modules::meta(dep.package().unwrap_or(BEVY))) } else if let Some(dep) = deps.get(BEVY_INTERNAL) { Some(Modules::meta(dep.package().unwrap_or(BEVY_INTERNAL))) - } else if let Some(_) = deps.get(BEVY_EXTERNAL) { + } else if deps.get(BEVY_EXTERNAL).is_some() { Some(Modules::external()) } else { None @@ -66,7 +66,7 @@ pub fn get_modules() -> Modules { }) .or_else(|| deps.and_then(find_in_deps)) .or_else(|| deps_dev.and_then(find_in_deps)) - .unwrap_or_else(|| Modules::external()) + .unwrap_or_else(Modules::external) } pub fn get_path(path_str: &str) -> Path { From 690fb2d7aed287784897727eb4c4caa4ee51754c Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Fri, 23 Apr 2021 00:32:16 +0200 Subject: [PATCH 04/10] Shared module path detection for macroses --- crates/bevy_derive/Cargo.toml | 3 +- crates/bevy_derive/src/bytes.rs | 5 +- crates/bevy_derive/src/enum_variant_meta.rs | 5 +- crates/bevy_derive/src/modules.rs | 65 ++++------------ crates/bevy_derive/src/render_resource.rs | 8 +- crates/bevy_derive/src/render_resources.rs | 5 +- crates/bevy_derive/src/resource.rs | 5 +- crates/bevy_derive/src/shader_defs.rs | 5 +- crates/bevy_ecs/macros/Cargo.toml | 3 +- crates/bevy_ecs/macros/src/lib.rs | 23 +----- crates/bevy_ecs/src/event.rs | 1 - crates/bevy_ecs/src/lib.rs | 1 - crates/bevy_macro_utils/Cargo.toml | 18 +++++ crates/bevy_macro_utils/src/lib.rs | 58 +++++++++++++++ .../bevy_reflect_derive/Cargo.toml | 3 +- .../bevy_reflect_derive/src/lib.rs | 8 +- .../bevy_reflect_derive/src/modules.rs | 74 ------------------- .../bevy_reflect_derive/src/reflect_trait.rs | 6 +- .../bevy_reflect_derive/src/type_uuid.rs | 6 +- 19 files changed, 121 insertions(+), 181 deletions(-) create mode 100644 crates/bevy_macro_utils/Cargo.toml create mode 100644 crates/bevy_macro_utils/src/lib.rs delete mode 100644 crates/bevy_reflect/bevy_reflect_derive/src/modules.rs diff --git a/crates/bevy_derive/Cargo.toml b/crates/bevy_derive/Cargo.toml index 9cff52e78c665..b1e1036cbc2a1 100644 --- a/crates/bevy_derive/Cargo.toml +++ b/crates/bevy_derive/Cargo.toml @@ -16,8 +16,9 @@ keywords = ["bevy"] proc-macro = true [dependencies] +bevy_macro_utils = { path = "../bevy_macro_utils", version = "0.5.0" } + Inflector = { version = "0.11.4", default-features = false } -find-crate = "0.6" proc-macro2 = "1.0" quote = "1.0" syn = "1.0" diff --git a/crates/bevy_derive/src/bytes.rs b/crates/bevy_derive/src/bytes.rs index a3469b8c764e7..25c061d3487e4 100644 --- a/crates/bevy_derive/src/bytes.rs +++ b/crates/bevy_derive/src/bytes.rs @@ -1,4 +1,4 @@ -use crate::modules::{get_modules, get_path}; +use crate::modules::get_modules; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields}; @@ -13,8 +13,7 @@ pub fn derive_bytes(input: TokenStream) -> TokenStream { _ => panic!("Expected a struct with named fields."), }; - let modules = get_modules(&ast.attrs); - let bevy_core_path = get_path(&modules.bevy_core); + let bevy_core_path = get_modules(&ast.attrs).bevy_core; let fields = fields .iter() diff --git a/crates/bevy_derive/src/enum_variant_meta.rs b/crates/bevy_derive/src/enum_variant_meta.rs index ceb689b90bc0f..bdba41e6380ce 100644 --- a/crates/bevy_derive/src/enum_variant_meta.rs +++ b/crates/bevy_derive/src/enum_variant_meta.rs @@ -1,4 +1,4 @@ -use crate::modules::{get_modules, get_path}; +use crate::modules::get_modules; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Data, DeriveInput}; @@ -10,8 +10,7 @@ pub fn derive_enum_variant_meta(input: TokenStream) -> TokenStream { _ => panic!("Expected an enum."), }; - let modules = get_modules(&ast.attrs); - let bevy_util_path = get_path(&modules.bevy_utils); + let bevy_util_path = get_modules(&ast.attrs).bevy_utils; let generics = ast.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); diff --git a/crates/bevy_derive/src/modules.rs b/crates/bevy_derive/src/modules.rs index 25793efffc550..a198dd3197d65 100644 --- a/crates/bevy_derive/src/modules.rs +++ b/crates/bevy_derive/src/modules.rs @@ -1,47 +1,12 @@ -use find_crate::Manifest; -use proc_macro::TokenStream; -use syn::{Attribute, Path}; +use bevy_macro_utils::{get_module_path, get_path}; +use syn::Attribute; -#[derive(Debug)] pub struct Modules { - pub bevy_render: String, - pub bevy_asset: String, - pub bevy_core: String, - pub bevy_utils: String, - pub bevy_app: String, -} - -impl Modules { - pub fn meta(name: &str) -> Modules { - Modules { - bevy_asset: format!("{}::asset", name), - bevy_render: format!("{}::render", name), - bevy_core: format!("{}::core", name), - bevy_utils: format!("{}::utils", name), - bevy_app: format!("{}::app", name), - } - } - - pub fn external() -> Modules { - Modules { - bevy_asset: "bevy_asset".to_string(), - bevy_render: "bevy_render".to_string(), - bevy_core: "bevy_core".to_string(), - bevy_utils: "bevy_utils".to_string(), - bevy_app: "bevy_app".to_string(), - } - } -} - -fn get_meta() -> Option { - let manifest = Manifest::new().unwrap(); - if let Some(package) = manifest.find(|name| name == "bevy") { - Some(Modules::meta(&package.name)) - } else if let Some(package) = manifest.find(|name| name == "bevy_internal") { - Some(Modules::meta(&package.name)) - } else { - None - } + pub bevy_app: syn::Path, + pub bevy_asset: syn::Path, + pub bevy_core: syn::Path, + pub bevy_render: syn::Path, + pub bevy_utils: syn::Path, } const AS_CRATE_ATTRIBUTE_NAME: &str = "as_crate"; @@ -51,21 +16,23 @@ fn validate_as_crate_attribute(tokens: &str) -> bool { } pub fn get_modules(attributes: &[Attribute]) -> Modules { - let mut modules = get_meta().unwrap_or_else(Modules::external); + let mut modules = Modules { + bevy_app: get_module_path("bevy_app"), + bevy_asset: get_module_path("bevy_asset"), + bevy_core: get_module_path("bevy_core"), + bevy_render: get_module_path("bevy_render"), + bevy_utils: get_module_path("bevy_utils"), + }; for attribute in attributes.iter() { if *attribute.path.get_ident().as_ref().unwrap() == AS_CRATE_ATTRIBUTE_NAME { let value = attribute.tokens.to_string(); if !validate_as_crate_attribute(&value) { panic!("The attribute `#[as_crate{}]` is invalid. It must follow the format `#[as_crate()]`", value); - } else if value[1..value.len() - 1] == modules.bevy_render { - modules.bevy_render = "crate".to_string(); + } else if get_path(&value[1..value.len() - 1]) == modules.bevy_render { + modules.bevy_render = get_path("crate"); } } } modules } - -pub fn get_path(path_str: &str) -> Path { - syn::parse(path_str.parse::().unwrap()).unwrap() -} diff --git a/crates/bevy_derive/src/render_resource.rs b/crates/bevy_derive/src/render_resource.rs index e8c758cc072aa..f1fed4afab888 100644 --- a/crates/bevy_derive/src/render_resource.rs +++ b/crates/bevy_derive/src/render_resource.rs @@ -1,4 +1,4 @@ -use crate::modules::{get_modules, get_path}; +use crate::modules::get_modules; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput, Path}; @@ -7,9 +7,9 @@ pub fn derive_render_resource(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); let modules = get_modules(&ast.attrs); - let bevy_render_path: Path = get_path(&modules.bevy_render); - let bevy_asset_path: Path = get_path(&modules.bevy_asset); - let bevy_core_path: Path = get_path(&modules.bevy_core); + let bevy_render_path: Path = modules.bevy_render; + let bevy_asset_path: Path = modules.bevy_asset; + let bevy_core_path: Path = modules.bevy_core; let struct_name = &ast.ident; let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl(); diff --git a/crates/bevy_derive/src/render_resources.rs b/crates/bevy_derive/src/render_resources.rs index ed9d9e06a9340..82a60888b2fe2 100644 --- a/crates/bevy_derive/src/render_resources.rs +++ b/crates/bevy_derive/src/render_resources.rs @@ -1,4 +1,4 @@ -use crate::modules::{get_modules, get_path}; +use crate::modules::get_modules; use proc_macro::TokenStream; use quote::{format_ident, quote}; use syn::{ @@ -21,9 +21,8 @@ static RENDER_RESOURCE_ATTRIBUTE_NAME: &str = "render_resources"; pub fn derive_render_resources(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let modules = get_modules(&ast.attrs); - let bevy_render_path: Path = get_path(&modules.bevy_render); + let bevy_render_path: Path = get_modules(&ast.attrs).bevy_render; let attributes = ast .attrs .iter() diff --git a/crates/bevy_derive/src/resource.rs b/crates/bevy_derive/src/resource.rs index 22c2543e7d3f7..a32855193f67a 100644 --- a/crates/bevy_derive/src/resource.rs +++ b/crates/bevy_derive/src/resource.rs @@ -1,4 +1,4 @@ -use crate::modules::{get_modules, get_path}; +use crate::modules::get_modules; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields}; @@ -13,8 +13,7 @@ pub fn derive_from_resources(input: TokenStream) -> TokenStream { _ => panic!("Expected a struct with named fields."), }; - let modules = get_modules(&ast.attrs); - let bevy_app_path = get_path(&modules.bevy_app); + let bevy_app_path = get_modules(&ast.attrs).bevy_app; let field_types = fields.iter().map(|field| &field.ty); diff --git a/crates/bevy_derive/src/shader_defs.rs b/crates/bevy_derive/src/shader_defs.rs index 0e5820e7c3420..56a70521fba1a 100644 --- a/crates/bevy_derive/src/shader_defs.rs +++ b/crates/bevy_derive/src/shader_defs.rs @@ -1,4 +1,4 @@ -use crate::modules::{get_modules, get_path}; +use crate::modules::get_modules; use inflector::Inflector; use proc_macro::TokenStream; use proc_macro2::Ident; @@ -9,8 +9,7 @@ static SHADER_DEF_ATTRIBUTE_NAME: &str = "shader_def"; pub fn derive_shader_defs(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let modules = get_modules(&ast.attrs); - let bevy_render_path: Path = get_path(&modules.bevy_render); + let bevy_render_path: Path = get_modules(&ast.attrs).bevy_render; let fields = match &ast.data { Data::Struct(DataStruct { diff --git a/crates/bevy_ecs/macros/Cargo.toml b/crates/bevy_ecs/macros/Cargo.toml index fa451f9b4f1d4..c443f27fa235f 100644 --- a/crates/bevy_ecs/macros/Cargo.toml +++ b/crates/bevy_ecs/macros/Cargo.toml @@ -13,7 +13,8 @@ license = "MIT" proc-macro = true [dependencies] +bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.5.0" } + syn = "1.0" quote = "1.0" proc-macro2 = "1.0" -find-crate = "0.6" diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index b8ed1d882bbfb..22f2353d5df7b 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -1,6 +1,6 @@ extern crate proc_macro; -use find_crate::{Dependencies, Manifest}; +use bevy_macro_utils::get_module_path; use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::{format_ident, quote}; @@ -471,24 +471,5 @@ fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 { } fn bevy_ecs_path() -> syn::Path { - fn find_in_manifest(manifest: &mut Manifest, dependencies: Dependencies) -> Option { - manifest.dependencies = dependencies; - if let Some(package) = manifest.find(|name| name == "bevy") { - Some(format!("{}::ecs", package.name)) - } else if let Some(package) = manifest.find(|name| name == "bevy_internal") { - Some(format!("{}::ecs", package.name)) - } else if let Some(package) = manifest.find(|name| name == "bevy_ecs") { - Some(package.name) - } else { - None - } - } - - let mut manifest = Manifest::new().unwrap(); - let path_str = find_in_manifest(&mut manifest, Dependencies::Release) - .or_else(|| find_in_manifest(&mut manifest, Dependencies::Dev)) - .unwrap_or_else(|| "bevy_ecs".to_string()); - - let path: Path = syn::parse(path_str.parse::().unwrap()).unwrap(); - path + get_module_path("bevy_ecs") } diff --git a/crates/bevy_ecs/src/event.rs b/crates/bevy_ecs/src/event.rs index 889d9d22e8b4c..8e3d1d4c92dd8 100644 --- a/crates/bevy_ecs/src/event.rs +++ b/crates/bevy_ecs/src/event.rs @@ -1,4 +1,3 @@ -use crate as bevy_ecs; use crate::{ component::Component, system::{Local, Res, ResMut, SystemParam}, diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index f45c6790a5780..e0e2e9a04e526 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -78,7 +78,6 @@ mod tests { #[test] fn bundle_derive() { - use crate as bevy_ecs; #[derive(Bundle, PartialEq, Debug)] struct Foo { x: &'static str, diff --git a/crates/bevy_macro_utils/Cargo.toml b/crates/bevy_macro_utils/Cargo.toml new file mode 100644 index 0000000000000..a53335643fcf5 --- /dev/null +++ b/crates/bevy_macro_utils/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "bevy_macro_utils" +version = "0.5.0" +edition = "2018" +authors = [ + "Bevy Contributors ", + "Carter Anderson ", +] +description = "A collection of utils for Bevy Engine" +homepage = "https://bevyengine.org" +repository = "https://github.com/bevyengine/bevy" +license = "MIT" +keywords = ["bevy"] + +[dependencies] +cargo-manifest = "0.2.3" +proc-macro2 = "1.0" +syn = "1.0" diff --git a/crates/bevy_macro_utils/src/lib.rs b/crates/bevy_macro_utils/src/lib.rs new file mode 100644 index 0000000000000..cfe8cb230b914 --- /dev/null +++ b/crates/bevy_macro_utils/src/lib.rs @@ -0,0 +1,58 @@ +extern crate proc_macro; + +use cargo_manifest::{DepsSet, Manifest}; +use proc_macro::TokenStream; +use std::{env, path::PathBuf}; + +pub fn get_module_path(name: &str) -> syn::Path { + const BEVY: &str = "bevy"; + const BEVY_INTERNAL: &str = "bevy_internal"; + + let find_in_deps = |deps: DepsSet| -> Option { + let package = if let Some(dep) = deps.get(BEVY) { + Some(dep.package().unwrap_or(BEVY)) + } else if let Some(dep) = deps.get(BEVY_INTERNAL) { + Some(dep.package().unwrap_or(BEVY_INTERNAL)) + } else { + None + }; + + package.map(get_path).map(|mut p| { + if let Some(module) = name.strip_prefix("bevy_") { + p.segments.push(parse_path(module)); + } + p + }) + }; + + let manifest = env::var_os("CARGO_MANIFEST_DIR") + .map(PathBuf::from) + .map(|mut path| { + path.push("Cargo.toml"); + Manifest::from_path(path).unwrap() + }) + .unwrap(); + let deps = manifest.dependencies; + let deps_dev = manifest.dev_dependencies; + + manifest + .package + .and_then(|p| { + if p.name == name && env::var("CARGO_PRIMARY_PACKAGE").is_ok() { + Some(get_path("crate")) + } else { + None + } + }) + .or_else(|| deps.and_then(find_in_deps)) + .or_else(|| deps_dev.and_then(find_in_deps)) + .unwrap_or_else(|| get_path(name)) +} + +pub fn get_path(path: &str) -> syn::Path { + parse_path(path) +} + +fn parse_path(path: &str) -> T { + syn::parse(path.parse::().unwrap()).unwrap() +} diff --git a/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml b/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml index 77866acc16a26..8d884ca706e0a 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml +++ b/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml @@ -16,8 +16,9 @@ keywords = ["bevy"] proc-macro = true [dependencies] +bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.5.0" } + syn = "1.0" proc-macro2 = "1.0" quote = "1.0" -cargo-manifest = "0.2.3" uuid = { version = "0.8", features = ["v4", "serde"] } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index 526745b604fe9..a3a7598020b19 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -1,10 +1,9 @@ extern crate proc_macro; -mod modules; mod reflect_trait; mod type_uuid; -use modules::{get_modules, get_path}; +use bevy_macro_utils::get_module_path; use proc_macro::TokenStream; use proc_macro2::Span; use quote::quote; @@ -105,8 +104,7 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream { .map(|(f, _attr, i)| (*f, *i)) .collect::>(); - let modules = get_modules(); - let bevy_reflect_path = get_path(&modules.bevy_reflect); + let bevy_reflect_path = get_module_path("bevy_reflect"); let type_name = &ast.ident; let mut reflect_attrs = ReflectAttrs::default(); @@ -557,7 +555,7 @@ impl Parse for ReflectDef { pub fn impl_reflect_value(input: TokenStream) -> TokenStream { let reflect_value_def = parse_macro_input!(input as ReflectDef); - let bevy_reflect_path = get_path(&get_modules().bevy_reflect); + let bevy_reflect_path = get_module_path("bevy_reflect"); let ty = &reflect_value_def.type_name; let reflect_attrs = reflect_value_def .attrs diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs b/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs deleted file mode 100644 index eeeac292325a7..0000000000000 --- a/crates/bevy_reflect/bevy_reflect_derive/src/modules.rs +++ /dev/null @@ -1,74 +0,0 @@ -use cargo_manifest::{DepsSet, Manifest}; -use proc_macro::TokenStream; -use std::{env, path::PathBuf}; -use syn::Path; - -#[derive(Debug)] -pub struct Modules { - pub bevy_reflect: String, -} - -impl Modules { - pub fn meta(name: &str) -> Modules { - Modules { - bevy_reflect: format!("{}::reflect", name), - } - } - - pub fn external() -> Modules { - Modules { - bevy_reflect: "bevy_reflect".to_string(), - } - } - - pub fn internal() -> Modules { - Modules { - bevy_reflect: "crate".to_string(), - } - } -} - -pub fn get_modules() -> Modules { - const BEVY: &str = "bevy"; - const BEVY_EXTERNAL: &str = "bevy_reflect"; - const BEVY_INTERNAL: &str = "bevy_internal"; - - fn find_in_deps(deps: DepsSet) -> Option { - if let Some(dep) = deps.get(BEVY) { - Some(Modules::meta(dep.package().unwrap_or(BEVY))) - } else if let Some(dep) = deps.get(BEVY_INTERNAL) { - Some(Modules::meta(dep.package().unwrap_or(BEVY_INTERNAL))) - } else if deps.get(BEVY_EXTERNAL).is_some() { - Some(Modules::external()) - } else { - None - } - } - - let manifest = env::var_os("CARGO_MANIFEST_DIR") - .map(PathBuf::from) - .map(|mut path| { - path.push("Cargo.toml"); - Manifest::from_path(path).unwrap() - }) - .unwrap(); - let deps = manifest.dependencies; - let deps_dev = manifest.dev_dependencies; - - manifest - .package - .and_then(|p| { - if p.name == BEVY_EXTERNAL { - Some(Modules::internal()) - } else { - None - } - }) - .or_else(|| deps.and_then(find_in_deps)) - .or_else(|| deps_dev.and_then(find_in_deps)) - .unwrap_or_else(Modules::external) -} - -pub fn get_path(path_str: &str) -> Path { - syn::parse(path_str.parse::().unwrap()).unwrap() -} diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/reflect_trait.rs b/crates/bevy_reflect/bevy_reflect_derive/src/reflect_trait.rs index d4378d664d874..14e2bf490889d 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/reflect_trait.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/reflect_trait.rs @@ -1,10 +1,9 @@ +use bevy_macro_utils::get_module_path; use proc_macro::TokenStream; use proc_macro2::Span; use quote::quote; use syn::{parse::Parse, parse_macro_input, Attribute, Ident, ItemTrait, Token}; -use crate::modules::{get_modules, get_path}; - pub struct TraitInfo { item_trait: ItemTrait, } @@ -29,8 +28,7 @@ pub fn reflect_trait(_args: TokenStream, input: TokenStream) -> TokenStream { let trait_ident = &item_trait.ident; let reflect_trait_ident = Ident::new(&format!("Reflect{}", item_trait.ident), Span::call_site()); - let modules = get_modules(); - let bevy_reflect_path = get_path(&modules.bevy_reflect); + let bevy_reflect_path = get_module_path("bevy_reflect"); TokenStream::from(quote! { #item_trait diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs index 257bafac7006c..64abd9027c064 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs @@ -1,17 +1,15 @@ extern crate proc_macro; +use bevy_macro_utils::get_module_path; use quote::quote; use syn::{parse::*, *}; use uuid::Uuid; -use crate::modules::{get_modules, get_path}; - pub fn type_uuid_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { // Construct a representation of Rust code as a syntax tree // that we can manipulate let ast: DeriveInput = syn::parse(input).unwrap(); - let modules = get_modules(); - let bevy_reflect_path: Path = get_path(&modules.bevy_reflect); + let bevy_reflect_path: Path = get_module_path("bevy_reflect"); // Build the trait implementation let name = &ast.ident; From b7f3c8fbe035d04791ab6484db0595ad8c8a80d1 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Tue, 27 Apr 2021 19:22:30 +0200 Subject: [PATCH 05/10] Removed env variable usage --- crates/bevy_ecs/src/event.rs | 1 + crates/bevy_ecs/src/lib.rs | 1 + crates/bevy_macro_utils/src/lib.rs | 11 +---------- crates/bevy_reflect/src/impls/glam.rs | 1 + crates/bevy_reflect/src/impls/std.rs | 1 + crates/bevy_reflect/src/lib.rs | 2 +- crates/bevy_reflect/src/path.rs | 1 + 7 files changed, 7 insertions(+), 11 deletions(-) diff --git a/crates/bevy_ecs/src/event.rs b/crates/bevy_ecs/src/event.rs index 8e3d1d4c92dd8..889d9d22e8b4c 100644 --- a/crates/bevy_ecs/src/event.rs +++ b/crates/bevy_ecs/src/event.rs @@ -1,3 +1,4 @@ +use crate as bevy_ecs; use crate::{ component::Component, system::{Local, Res, ResMut, SystemParam}, diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index e0e2e9a04e526..cdb3432494d67 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -36,6 +36,7 @@ pub mod prelude { #[cfg(test)] mod tests { + use crate as bevy_ecs; use crate::{ bundle::Bundle, component::{Component, ComponentDescriptor, ComponentId, StorageType, TypeInfo}, diff --git a/crates/bevy_macro_utils/src/lib.rs b/crates/bevy_macro_utils/src/lib.rs index cfe8cb230b914..6acf1b2c4c5ef 100644 --- a/crates/bevy_macro_utils/src/lib.rs +++ b/crates/bevy_macro_utils/src/lib.rs @@ -35,16 +35,7 @@ pub fn get_module_path(name: &str) -> syn::Path { let deps = manifest.dependencies; let deps_dev = manifest.dev_dependencies; - manifest - .package - .and_then(|p| { - if p.name == name && env::var("CARGO_PRIMARY_PACKAGE").is_ok() { - Some(get_path("crate")) - } else { - None - } - }) - .or_else(|| deps.and_then(find_in_deps)) + deps.and_then(find_in_deps) .or_else(|| deps_dev.and_then(find_in_deps)) .unwrap_or_else(|| get_path(name)) } diff --git a/crates/bevy_reflect/src/impls/glam.rs b/crates/bevy_reflect/src/impls/glam.rs index 24f5f6a8213f0..93c749159e11e 100644 --- a/crates/bevy_reflect/src/impls/glam.rs +++ b/crates/bevy_reflect/src/impls/glam.rs @@ -1,3 +1,4 @@ +use crate as bevy_reflect; use crate::ReflectDeserialize; use bevy_reflect_derive::impl_reflect_value; use glam::{IVec2, IVec3, IVec4, Mat3, Mat4, Quat, UVec2, UVec3, UVec4, Vec2, Vec3, Vec4}; diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index b893fd12579f6..bb8067fee5066 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -1,3 +1,4 @@ +use crate as bevy_reflect; use crate::{ map_partial_eq, serde::Serializable, DynamicMap, FromType, GetTypeRegistration, List, ListIter, Map, MapIter, Reflect, ReflectDeserialize, ReflectMut, ReflectRef, TypeRegistration, diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index f8319dc78ef7c..f6a45b18aa8f4 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -55,7 +55,7 @@ mod tests { }; use crate::serde::{ReflectDeserializer, ReflectSerializer}; - + use crate as bevy_reflect; use super::*; #[test] diff --git a/crates/bevy_reflect/src/path.rs b/crates/bevy_reflect/src/path.rs index c19a7cc55c27f..12f36e5dd7426 100644 --- a/crates/bevy_reflect/src/path.rs +++ b/crates/bevy_reflect/src/path.rs @@ -308,6 +308,7 @@ fn next_token<'a>(path: &'a str, index: &mut usize) -> Option> { #[allow(clippy::float_cmp, clippy::approx_constant)] mod tests { use super::GetPath; + use crate as bevy_reflect; use crate::*; #[test] fn reflect_path() { From 88344cbb0b15fa6033e5ef5209369af9486b4c6d Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Tue, 27 Apr 2021 19:25:01 +0200 Subject: [PATCH 06/10] Added macro utils to publish.sh --- tools/publish.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/publish.sh b/tools/publish.sh index 6d827feaf6214..85008c6247912 100644 --- a/tools/publish.sh +++ b/tools/publish.sh @@ -1,6 +1,7 @@ # if crate A depends on crate B, B must come before A in this list crates=( bevy_utils + bevy_macro_utils bevy_derive bevy_math bevy_tasks From 0282eed04fc214e7a5d8db7ebd383c352593dd31 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Tue, 27 Apr 2021 19:27:59 +0200 Subject: [PATCH 07/10] Formatting --- crates/bevy_reflect/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index f6a45b18aa8f4..7726ce7ee4e76 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -54,9 +54,9 @@ mod tests { Deserializer, }; - use crate::serde::{ReflectDeserializer, ReflectSerializer}; - use crate as bevy_reflect; use super::*; + use crate as bevy_reflect; + use crate::serde::{ReflectDeserializer, ReflectSerializer}; #[test] fn reflect_struct() { From 2fedad561e54f73ceaa3abdd200f268e8ca938c4 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Sat, 1 May 2021 22:59:38 +0200 Subject: [PATCH 08/10] One time manifest parsing --- crates/bevy_derive/src/modules.rs | 13 ++++++----- crates/bevy_macro_utils/src/lib.rs | 35 ++++++++++++++++++------------ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/crates/bevy_derive/src/modules.rs b/crates/bevy_derive/src/modules.rs index a198dd3197d65..113a7fe48eea3 100644 --- a/crates/bevy_derive/src/modules.rs +++ b/crates/bevy_derive/src/modules.rs @@ -1,4 +1,4 @@ -use bevy_macro_utils::{get_module_path, get_path}; +use bevy_macro_utils::{get_manifest, get_module_path_by_manifest, get_path}; use syn::Attribute; pub struct Modules { @@ -16,12 +16,13 @@ fn validate_as_crate_attribute(tokens: &str) -> bool { } pub fn get_modules(attributes: &[Attribute]) -> Modules { + let manifest = get_manifest(); let mut modules = Modules { - bevy_app: get_module_path("bevy_app"), - bevy_asset: get_module_path("bevy_asset"), - bevy_core: get_module_path("bevy_core"), - bevy_render: get_module_path("bevy_render"), - bevy_utils: get_module_path("bevy_utils"), + bevy_app: get_module_path_by_manifest("bevy_app", &manifest), + bevy_asset: get_module_path_by_manifest("bevy_asset", &manifest), + bevy_core: get_module_path_by_manifest("bevy_core", &manifest), + bevy_render: get_module_path_by_manifest("bevy_render", &manifest), + bevy_utils: get_module_path_by_manifest("bevy_utils", &manifest), }; for attribute in attributes.iter() { if *attribute.path.get_ident().as_ref().unwrap() == AS_CRATE_ATTRIBUTE_NAME { diff --git a/crates/bevy_macro_utils/src/lib.rs b/crates/bevy_macro_utils/src/lib.rs index 6acf1b2c4c5ef..374deccc4fadd 100644 --- a/crates/bevy_macro_utils/src/lib.rs +++ b/crates/bevy_macro_utils/src/lib.rs @@ -4,11 +4,19 @@ use cargo_manifest::{DepsSet, Manifest}; use proc_macro::TokenStream; use std::{env, path::PathBuf}; +pub fn get_path(path: &str) -> syn::Path { + parse_str(path) +} + pub fn get_module_path(name: &str) -> syn::Path { + get_module_path_by_manifest(name, &get_manifest()) +} + +pub fn get_module_path_by_manifest(name: &str, manifest: &Manifest) -> syn::Path { const BEVY: &str = "bevy"; const BEVY_INTERNAL: &str = "bevy_internal"; - let find_in_deps = |deps: DepsSet| -> Option { + let find_in_deps = |deps: &DepsSet| -> Option { let package = if let Some(dep) = deps.get(BEVY) { Some(dep.package().unwrap_or(BEVY)) } else if let Some(dep) = deps.get(BEVY_INTERNAL) { @@ -19,31 +27,30 @@ pub fn get_module_path(name: &str) -> syn::Path { package.map(get_path).map(|mut p| { if let Some(module) = name.strip_prefix("bevy_") { - p.segments.push(parse_path(module)); + p.segments.push(parse_str(module)); } p }) }; - let manifest = env::var_os("CARGO_MANIFEST_DIR") - .map(PathBuf::from) - .map(|mut path| { - path.push("Cargo.toml"); - Manifest::from_path(path).unwrap() - }) - .unwrap(); - let deps = manifest.dependencies; - let deps_dev = manifest.dev_dependencies; + let deps = manifest.dependencies.as_ref(); + let deps_dev = manifest.dev_dependencies.as_ref(); deps.and_then(find_in_deps) .or_else(|| deps_dev.and_then(find_in_deps)) .unwrap_or_else(|| get_path(name)) } -pub fn get_path(path: &str) -> syn::Path { - parse_path(path) +pub fn get_manifest() -> Manifest { + env::var_os("CARGO_MANIFEST_DIR") + .map(PathBuf::from) + .map(|mut path| { + path.push("Cargo.toml"); + Manifest::from_path(path).unwrap() + }) + .unwrap() } -fn parse_path(path: &str) -> T { +fn parse_str(path: &str) -> T { syn::parse(path.parse::().unwrap()).unwrap() } From 3daefb2f9f669259ef3f9611cf147f618b50f8c3 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Fri, 7 May 2021 23:55:07 +0200 Subject: [PATCH 09/10] Clippy suggestion --- crates/bevy_macro_utils/src/lib.rs | 27 +++++++++++++-------------- crates/bevy_reflect/src/type_uuid.rs | 1 + 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/bevy_macro_utils/src/lib.rs b/crates/bevy_macro_utils/src/lib.rs index 374deccc4fadd..3a4c51f95cd57 100644 --- a/crates/bevy_macro_utils/src/lib.rs +++ b/crates/bevy_macro_utils/src/lib.rs @@ -17,20 +17,19 @@ pub fn get_module_path_by_manifest(name: &str, manifest: &Manifest) -> syn::Path const BEVY_INTERNAL: &str = "bevy_internal"; let find_in_deps = |deps: &DepsSet| -> Option { - let package = if let Some(dep) = deps.get(BEVY) { - Some(dep.package().unwrap_or(BEVY)) - } else if let Some(dep) = deps.get(BEVY_INTERNAL) { - Some(dep.package().unwrap_or(BEVY_INTERNAL)) - } else { - None - }; - - package.map(get_path).map(|mut p| { - if let Some(module) = name.strip_prefix("bevy_") { - p.segments.push(parse_str(module)); - } - p - }) + deps.get(BEVY) + .map(|dep| dep.package().unwrap_or(BEVY)) + .or_else(|| { + deps.get(BEVY_INTERNAL) + .map(|dep| dep.package().unwrap_or(BEVY_INTERNAL)) + }) + .map(get_path) + .map(|mut p| { + if let Some(module) = name.strip_prefix("bevy_") { + p.segments.push(parse_str(module)); + } + p + }) }; let deps = manifest.dependencies.as_ref(); diff --git a/crates/bevy_reflect/src/type_uuid.rs b/crates/bevy_reflect/src/type_uuid.rs index fe59e9173779e..29689131aacdf 100644 --- a/crates/bevy_reflect/src/type_uuid.rs +++ b/crates/bevy_reflect/src/type_uuid.rs @@ -26,6 +26,7 @@ where #[cfg(test)] mod test { use super::*; + use crate as bevy_reflect; #[derive(TypeUuid)] #[uuid = "af6466c2-a9f4-11eb-bcbc-0242ac130002"] From f020195e93891348d53b2729a34b6f038eabe8a1 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Tue, 18 May 2021 16:05:43 -0700 Subject: [PATCH 10/10] BevyManifest, remove as_crate, remove Modules --- crates/bevy_derive/src/bytes.rs | 4 +- crates/bevy_derive/src/enum_variant_meta.rs | 4 +- crates/bevy_derive/src/lib.rs | 12 +-- crates/bevy_derive/src/modules.rs | 44 ++-------- crates/bevy_derive/src/render_resource.rs | 10 +-- crates/bevy_derive/src/render_resources.rs | 4 +- crates/bevy_derive/src/resource.rs | 8 +- crates/bevy_derive/src/shader_defs.rs | 4 +- crates/bevy_ecs/macros/src/lib.rs | 4 +- crates/bevy_macro_utils/src/lib.rs | 82 ++++++++++--------- .../bevy_reflect_derive/src/lib.rs | 6 +- .../bevy_reflect_derive/src/reflect_trait.rs | 4 +- .../bevy_reflect_derive/src/type_uuid.rs | 4 +- .../render_resource/render_resource.rs | 4 +- 14 files changed, 80 insertions(+), 114 deletions(-) diff --git a/crates/bevy_derive/src/bytes.rs b/crates/bevy_derive/src/bytes.rs index 25c061d3487e4..453ade9ed3ec1 100644 --- a/crates/bevy_derive/src/bytes.rs +++ b/crates/bevy_derive/src/bytes.rs @@ -1,4 +1,4 @@ -use crate::modules::get_modules; +use bevy_macro_utils::BevyManifest; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields}; @@ -13,7 +13,7 @@ pub fn derive_bytes(input: TokenStream) -> TokenStream { _ => panic!("Expected a struct with named fields."), }; - let bevy_core_path = get_modules(&ast.attrs).bevy_core; + let bevy_core_path = BevyManifest::default().get_path(crate::modules::BEVY_CORE); let fields = fields .iter() diff --git a/crates/bevy_derive/src/enum_variant_meta.rs b/crates/bevy_derive/src/enum_variant_meta.rs index bdba41e6380ce..66ed1f0ff7d2a 100644 --- a/crates/bevy_derive/src/enum_variant_meta.rs +++ b/crates/bevy_derive/src/enum_variant_meta.rs @@ -1,4 +1,4 @@ -use crate::modules::get_modules; +use bevy_macro_utils::BevyManifest; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Data, DeriveInput}; @@ -10,7 +10,7 @@ pub fn derive_enum_variant_meta(input: TokenStream) -> TokenStream { _ => panic!("Expected an enum."), }; - let bevy_util_path = get_modules(&ast.attrs).bevy_utils; + let bevy_util_path = BevyManifest::default().get_path(crate::modules::BEVY_UTILS); let generics = ast.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); diff --git a/crates/bevy_derive/src/lib.rs b/crates/bevy_derive/src/lib.rs index 4b34c3ba2fdc3..a73093ed2aa7e 100644 --- a/crates/bevy_derive/src/lib.rs +++ b/crates/bevy_derive/src/lib.rs @@ -14,33 +14,33 @@ use proc_macro::TokenStream; /// Derives the FromResources trait. Each field must also implement the FromResources trait or this /// will fail. FromResources is automatically implemented for types that implement Default. -#[proc_macro_derive(FromResources, attributes(as_crate))] +#[proc_macro_derive(FromResources)] pub fn derive_from_resources(input: TokenStream) -> TokenStream { resource::derive_from_resources(input) } /// Derives the Bytes trait. Each field must also implements Bytes or this will fail. -#[proc_macro_derive(Bytes, attributes(as_crate))] +#[proc_macro_derive(Bytes)] pub fn derive_bytes(input: TokenStream) -> TokenStream { bytes::derive_bytes(input) } /// Derives the RenderResources trait. Each field must implement RenderResource or this will fail. /// You can ignore fields using `#[render_resources(ignore)]`. -#[proc_macro_derive(RenderResources, attributes(render_resources, as_crate))] +#[proc_macro_derive(RenderResources, attributes(render_resources))] pub fn derive_render_resources(input: TokenStream) -> TokenStream { render_resources::derive_render_resources(input) } /// Derives the RenderResource trait. The type must also implement `Bytes` or this will fail. -#[proc_macro_derive(RenderResource, attributes(as_crate))] +#[proc_macro_derive(RenderResource)] pub fn derive_render_resource(input: TokenStream) -> TokenStream { render_resource::derive_render_resource(input) } /// Derives the ShaderDefs trait. Each field must implement ShaderDef or this will fail. /// You can ignore fields using `#[shader_defs(ignore)]`. -#[proc_macro_derive(ShaderDefs, attributes(shader_def, as_crate))] +#[proc_macro_derive(ShaderDefs, attributes(shader_def))] pub fn derive_shader_defs(input: TokenStream) -> TokenStream { shader_defs::derive_shader_defs(input) } @@ -56,7 +56,7 @@ pub fn bevy_main(attr: TokenStream, item: TokenStream) -> TokenStream { bevy_main::bevy_main(attr, item) } -#[proc_macro_derive(EnumVariantMeta, attributes(as_crate))] +#[proc_macro_derive(EnumVariantMeta)] pub fn derive_enum_variant_meta(input: TokenStream) -> TokenStream { enum_variant_meta::derive_enum_variant_meta(input) } diff --git a/crates/bevy_derive/src/modules.rs b/crates/bevy_derive/src/modules.rs index 113a7fe48eea3..7e7dcbc98e7e2 100644 --- a/crates/bevy_derive/src/modules.rs +++ b/crates/bevy_derive/src/modules.rs @@ -1,39 +1,5 @@ -use bevy_macro_utils::{get_manifest, get_module_path_by_manifest, get_path}; -use syn::Attribute; - -pub struct Modules { - pub bevy_app: syn::Path, - pub bevy_asset: syn::Path, - pub bevy_core: syn::Path, - pub bevy_render: syn::Path, - pub bevy_utils: syn::Path, -} - -const AS_CRATE_ATTRIBUTE_NAME: &str = "as_crate"; - -fn validate_as_crate_attribute(tokens: &str) -> bool { - tokens.len() > 2 && tokens.starts_with('(') && tokens.ends_with(')') -} - -pub fn get_modules(attributes: &[Attribute]) -> Modules { - let manifest = get_manifest(); - let mut modules = Modules { - bevy_app: get_module_path_by_manifest("bevy_app", &manifest), - bevy_asset: get_module_path_by_manifest("bevy_asset", &manifest), - bevy_core: get_module_path_by_manifest("bevy_core", &manifest), - bevy_render: get_module_path_by_manifest("bevy_render", &manifest), - bevy_utils: get_module_path_by_manifest("bevy_utils", &manifest), - }; - for attribute in attributes.iter() { - if *attribute.path.get_ident().as_ref().unwrap() == AS_CRATE_ATTRIBUTE_NAME { - let value = attribute.tokens.to_string(); - if !validate_as_crate_attribute(&value) { - panic!("The attribute `#[as_crate{}]` is invalid. It must follow the format `#[as_crate()]`", value); - } else if get_path(&value[1..value.len() - 1]) == modules.bevy_render { - modules.bevy_render = get_path("crate"); - } - } - } - - modules -} +pub const BEVY_APP: &str = "bevy_app"; +pub const BEVY_ASSET: &str = "bevy_asset"; +pub const BEVY_CORE: &str = "bevy_core"; +pub const BEVY_RENDER: &str = "bevy_render"; +pub const BEVY_UTILS: &str = "bevy_utils"; diff --git a/crates/bevy_derive/src/render_resource.rs b/crates/bevy_derive/src/render_resource.rs index f1fed4afab888..e39ef3db37e27 100644 --- a/crates/bevy_derive/src/render_resource.rs +++ b/crates/bevy_derive/src/render_resource.rs @@ -1,15 +1,15 @@ -use crate::modules::get_modules; +use bevy_macro_utils::BevyManifest; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput, Path}; pub fn derive_render_resource(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let modules = get_modules(&ast.attrs); + let manifest = BevyManifest::default(); - let bevy_render_path: Path = modules.bevy_render; - let bevy_asset_path: Path = modules.bevy_asset; - let bevy_core_path: Path = modules.bevy_core; + let bevy_render_path: Path = manifest.get_path(crate::modules::BEVY_RENDER); + let bevy_asset_path: Path = manifest.get_path(crate::modules::BEVY_ASSET); + let bevy_core_path: Path = manifest.get_path(crate::modules::BEVY_CORE); let struct_name = &ast.ident; let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl(); diff --git a/crates/bevy_derive/src/render_resources.rs b/crates/bevy_derive/src/render_resources.rs index 82a60888b2fe2..7977e2ae1cf34 100644 --- a/crates/bevy_derive/src/render_resources.rs +++ b/crates/bevy_derive/src/render_resources.rs @@ -1,4 +1,4 @@ -use crate::modules::get_modules; +use bevy_macro_utils::BevyManifest; use proc_macro::TokenStream; use quote::{format_ident, quote}; use syn::{ @@ -22,7 +22,7 @@ static RENDER_RESOURCE_ATTRIBUTE_NAME: &str = "render_resources"; pub fn derive_render_resources(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let bevy_render_path: Path = get_modules(&ast.attrs).bevy_render; + let bevy_render_path: Path = BevyManifest::default().get_path(crate::modules::BEVY_RENDER); let attributes = ast .attrs .iter() diff --git a/crates/bevy_derive/src/resource.rs b/crates/bevy_derive/src/resource.rs index a32855193f67a..110b5605ca6d4 100644 --- a/crates/bevy_derive/src/resource.rs +++ b/crates/bevy_derive/src/resource.rs @@ -1,4 +1,4 @@ -use crate::modules::get_modules; +use bevy_macro_utils::BevyManifest; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields}; @@ -13,15 +13,11 @@ pub fn derive_from_resources(input: TokenStream) -> TokenStream { _ => panic!("Expected a struct with named fields."), }; - let bevy_app_path = get_modules(&ast.attrs).bevy_app; - + let bevy_app_path = BevyManifest::default().get_path(crate::modules::BEVY_APP); let field_types = fields.iter().map(|field| &field.ty); - let fields = fields.iter().map(|field| field.ident.as_ref().unwrap()); - let generics = ast.generics; let (impl_generics, ty_generics, _where_clause) = generics.split_for_impl(); - let struct_name = &ast.ident; TokenStream::from(quote! { diff --git a/crates/bevy_derive/src/shader_defs.rs b/crates/bevy_derive/src/shader_defs.rs index 56a70521fba1a..627b9b39ef32c 100644 --- a/crates/bevy_derive/src/shader_defs.rs +++ b/crates/bevy_derive/src/shader_defs.rs @@ -1,4 +1,4 @@ -use crate::modules::get_modules; +use bevy_macro_utils::BevyManifest; use inflector::Inflector; use proc_macro::TokenStream; use proc_macro2::Ident; @@ -9,7 +9,7 @@ static SHADER_DEF_ATTRIBUTE_NAME: &str = "shader_def"; pub fn derive_shader_defs(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let bevy_render_path: Path = get_modules(&ast.attrs).bevy_render; + let bevy_render_path: Path = BevyManifest::default().get_path(crate::modules::BEVY_RENDER); let fields = match &ast.data { Data::Struct(DataStruct { diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 22f2353d5df7b..1d4cb94c2a7c0 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -1,6 +1,6 @@ extern crate proc_macro; -use bevy_macro_utils::get_module_path; +use bevy_macro_utils::BevyManifest; use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::{format_ident, quote}; @@ -471,5 +471,5 @@ fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 { } fn bevy_ecs_path() -> syn::Path { - get_module_path("bevy_ecs") + BevyManifest::default().get_path("bevy_ecs") } diff --git a/crates/bevy_macro_utils/src/lib.rs b/crates/bevy_macro_utils/src/lib.rs index 3a4c51f95cd57..2933d9d8000d9 100644 --- a/crates/bevy_macro_utils/src/lib.rs +++ b/crates/bevy_macro_utils/src/lib.rs @@ -4,50 +4,56 @@ use cargo_manifest::{DepsSet, Manifest}; use proc_macro::TokenStream; use std::{env, path::PathBuf}; -pub fn get_path(path: &str) -> syn::Path { - parse_str(path) +pub struct BevyManifest { + manifest: Manifest, } -pub fn get_module_path(name: &str) -> syn::Path { - get_module_path_by_manifest(name, &get_manifest()) +impl Default for BevyManifest { + fn default() -> Self { + Self { + manifest: env::var_os("CARGO_MANIFEST_DIR") + .map(PathBuf::from) + .map(|mut path| { + path.push("Cargo.toml"); + Manifest::from_path(path).unwrap() + }) + .unwrap(), + } + } } -pub fn get_module_path_by_manifest(name: &str, manifest: &Manifest) -> syn::Path { - const BEVY: &str = "bevy"; - const BEVY_INTERNAL: &str = "bevy_internal"; - - let find_in_deps = |deps: &DepsSet| -> Option { - deps.get(BEVY) - .map(|dep| dep.package().unwrap_or(BEVY)) - .or_else(|| { - deps.get(BEVY_INTERNAL) - .map(|dep| dep.package().unwrap_or(BEVY_INTERNAL)) - }) - .map(get_path) - .map(|mut p| { - if let Some(module) = name.strip_prefix("bevy_") { - p.segments.push(parse_str(module)); - } - p - }) - }; - - let deps = manifest.dependencies.as_ref(); - let deps_dev = manifest.dev_dependencies.as_ref(); - - deps.and_then(find_in_deps) - .or_else(|| deps_dev.and_then(find_in_deps)) - .unwrap_or_else(|| get_path(name)) +impl BevyManifest { + pub fn get_path(&self, name: &str) -> syn::Path { + const BEVY: &str = "bevy"; + const BEVY_INTERNAL: &str = "bevy_internal"; + + let find_in_deps = |deps: &DepsSet| -> Option { + let package = if let Some(dep) = deps.get(BEVY) { + dep.package().unwrap_or(BEVY) + } else if let Some(dep) = deps.get(BEVY_INTERNAL) { + dep.package().unwrap_or(BEVY_INTERNAL) + } else { + return None; + }; + + let mut path = get_path(package); + if let Some(module) = name.strip_prefix("bevy_") { + path.segments.push(parse_str(module)); + } + Some(path) + }; + + let deps = self.manifest.dependencies.as_ref(); + let deps_dev = self.manifest.dev_dependencies.as_ref(); + + deps.and_then(find_in_deps) + .or_else(|| deps_dev.and_then(find_in_deps)) + .unwrap_or_else(|| get_path(name)) + } } -pub fn get_manifest() -> Manifest { - env::var_os("CARGO_MANIFEST_DIR") - .map(PathBuf::from) - .map(|mut path| { - path.push("Cargo.toml"); - Manifest::from_path(path).unwrap() - }) - .unwrap() +fn get_path(path: &str) -> syn::Path { + parse_str(path) } fn parse_str(path: &str) -> T { diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index a3a7598020b19..b393622fb8806 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -3,7 +3,7 @@ extern crate proc_macro; mod reflect_trait; mod type_uuid; -use bevy_macro_utils::get_module_path; +use bevy_macro_utils::BevyManifest; use proc_macro::TokenStream; use proc_macro2::Span; use quote::quote; @@ -104,7 +104,7 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream { .map(|(f, _attr, i)| (*f, *i)) .collect::>(); - let bevy_reflect_path = get_module_path("bevy_reflect"); + let bevy_reflect_path = BevyManifest::default().get_path("bevy_reflect"); let type_name = &ast.ident; let mut reflect_attrs = ReflectAttrs::default(); @@ -555,7 +555,7 @@ impl Parse for ReflectDef { pub fn impl_reflect_value(input: TokenStream) -> TokenStream { let reflect_value_def = parse_macro_input!(input as ReflectDef); - let bevy_reflect_path = get_module_path("bevy_reflect"); + let bevy_reflect_path = BevyManifest::default().get_path("bevy_reflect"); let ty = &reflect_value_def.type_name; let reflect_attrs = reflect_value_def .attrs diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/reflect_trait.rs b/crates/bevy_reflect/bevy_reflect_derive/src/reflect_trait.rs index 14e2bf490889d..64b0aea378368 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/reflect_trait.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/reflect_trait.rs @@ -1,4 +1,4 @@ -use bevy_macro_utils::get_module_path; +use bevy_macro_utils::BevyManifest; use proc_macro::TokenStream; use proc_macro2::Span; use quote::quote; @@ -28,7 +28,7 @@ pub fn reflect_trait(_args: TokenStream, input: TokenStream) -> TokenStream { let trait_ident = &item_trait.ident; let reflect_trait_ident = Ident::new(&format!("Reflect{}", item_trait.ident), Span::call_site()); - let bevy_reflect_path = get_module_path("bevy_reflect"); + let bevy_reflect_path = BevyManifest::default().get_path("bevy_reflect"); TokenStream::from(quote! { #item_trait diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs index 18d5b6e3aef32..16d13bb207b05 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/type_uuid.rs @@ -1,6 +1,6 @@ extern crate proc_macro; -use bevy_macro_utils::get_module_path; +use bevy_macro_utils::BevyManifest; use quote::{quote, ToTokens}; use syn::{parse::*, *}; use uuid::Uuid; @@ -9,7 +9,7 @@ pub fn type_uuid_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStre // Construct a representation of Rust code as a syntax tree // that we can manipulate let ast: DeriveInput = syn::parse(input).unwrap(); - let bevy_reflect_path: Path = get_module_path("bevy_reflect"); + let bevy_reflect_path: Path = BevyManifest::default().get_path("bevy_reflect"); // Build the trait implementation let name = &ast.ident; diff --git a/crates/bevy_render/src/renderer/render_resource/render_resource.rs b/crates/bevy_render/src/renderer/render_resource/render_resource.rs index 33a104d6c029b..40f4d7113bf17 100644 --- a/crates/bevy_render/src/renderer/render_resource/render_resource.rs +++ b/crates/bevy_render/src/renderer/render_resource/render_resource.rs @@ -277,9 +277,9 @@ impl RenderResources for bevy_transform::prelude::GlobalTransform { #[cfg(test)] mod test { use super::*; + use crate as bevy_render; #[derive(RenderResource, Bytes)] - #[as_crate(bevy_render)] struct GenericRenderResource where T: Bytes + Send + Sync + 'static, @@ -288,7 +288,6 @@ mod test { } #[derive(RenderResources)] - #[as_crate(bevy_render)] struct GenericRenderResources where T: RenderResource + Send + Sync + 'static, @@ -298,7 +297,6 @@ mod test { #[derive(Bytes, RenderResource, RenderResources)] #[render_resources(from_self)] - #[as_crate(bevy_render)] struct FromSelfGenericRenderResources where T: Bytes + Send + Sync + 'static,