Skip to content

Commit

Permalink
Use one BevyManifest instance in proc macros (#16766)
Browse files Browse the repository at this point in the history
# Objective

- Minor consistency improvement in proc macro code.
- Remove `get_path_direct` since it was only used once anyways and
doesn't add much.

## Solution
- Possibly a minor performance improvement since the `Cargo.toml` wont
be parsed as often.

## Testing

- I don't think it breaks anything.
- This is my first time working on bevy itself. Is there a script to do
a quick verify of my pr?

## Other PR

Similar to #7536 but has no extra dependencies.

Co-authored-by: François Mockers <[email protected]>
  • Loading branch information
raldone01 and mockersf authored Dec 15, 2024
1 parent 73a66d6 commit 760d0a3
Show file tree
Hide file tree
Showing 12 changed files with 22 additions and 36 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_asset/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use quote::{format_ident, quote};
use syn::{parse_macro_input, Data, DeriveInput, Path};

pub(crate) fn bevy_asset_path() -> Path {
BevyManifest::default().get_path("bevy_asset")
BevyManifest::shared().get_path("bevy_asset")
}

const DEPENDENCY_ATTRIBUTE: &str = "dependency";
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ pub fn derive_enum_variant_meta(input: TokenStream) -> TokenStream {
#[proc_macro_derive(AppLabel)]
pub fn derive_app_label(input: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(input as syn::DeriveInput);
let mut trait_path = BevyManifest::default().get_path("bevy_app");
let mut trait_path = BevyManifest::shared().get_path("bevy_app");
let mut dyn_eq_path = trait_path.clone();
trait_path.segments.push(format_ident!("AppLabel").into());
dyn_eq_path.segments.push(format_ident!("DynEq").into());
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ pub fn derive_system_set(input: TokenStream) -> TokenStream {
}

pub(crate) fn bevy_ecs_path() -> syn::Path {
BevyManifest::default().get_path("bevy_ecs")
BevyManifest::shared().get_path("bevy_ecs")
}

#[proc_macro_derive(Event)]
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_encase_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use encase_derive_impl::{implement, syn};
const ENCASE: &str = "encase";

fn bevy_encase_path() -> syn::Path {
let bevy_manifest = BevyManifest::default();
let bevy_manifest = BevyManifest::shared();
bevy_manifest
.get_subcrate("render")
.map(|bevy_render_path| {
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_gizmos/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use syn::{parse_macro_input, parse_quote, DeriveInput, Path};
#[proc_macro_derive(GizmoConfigGroup)]
pub fn derive_gizmo_config_group(input: TokenStream) -> TokenStream {
let mut ast = parse_macro_input!(input as DeriveInput);
let bevy_gizmos_path: Path = BevyManifest::default().get_path("bevy_gizmos");
let bevy_reflect_path: Path = BevyManifest::default().get_path("bevy_reflect");
let bevy_gizmos_path: Path = BevyManifest::shared().get_path("bevy_gizmos");
let bevy_reflect_path: Path = BevyManifest::shared().get_path("bevy_reflect");

ast.generics.make_where_clause().predicates.push(
parse_quote! { Self: #bevy_reflect_path::Reflect + #bevy_reflect_path::TypePath + Default},
Expand Down
34 changes: 10 additions & 24 deletions crates/bevy_macro_utils/src/bevy_manifest.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
extern crate proc_macro;

use proc_macro::TokenStream;
use std::{env, path::PathBuf};
use std::{env, path::PathBuf, sync::LazyLock};
use toml_edit::{DocumentMut, Item};

/// The path to the `Cargo.toml` file for the Bevy project.
pub struct BevyManifest {
manifest: DocumentMut,
}

impl Default for BevyManifest {
fn default() -> Self {
Self {
const BEVY: &str = "bevy";
const BEVY_INTERNAL: &str = "bevy_internal";

impl BevyManifest {
/// Returns a global shared instance of the [`BevyManifest`] struct.
pub fn shared() -> &'static LazyLock<Self> {
static LAZY_SELF: LazyLock<BevyManifest> = LazyLock::new(|| BevyManifest {
manifest: env::var_os("CARGO_MANIFEST_DIR")
.map(PathBuf::from)
.map(|mut path| {
Expand All @@ -30,13 +34,10 @@ impl Default for BevyManifest {
})
})
.expect("CARGO_MANIFEST_DIR is not defined."),
}
});
&LAZY_SELF
}
}
const BEVY: &str = "bevy";
const BEVY_INTERNAL: &str = "bevy_internal";

impl BevyManifest {
/// Attempt to retrieve the [path](syn::Path) of a particular package in
/// the [manifest](BevyManifest) by [name](str).
pub fn maybe_get_path(&self, name: &str) -> Option<syn::Path> {
Expand Down Expand Up @@ -73,21 +74,6 @@ impl BevyManifest {
.or_else(|| deps_dev.and_then(find_in_deps))
}

/// Returns the path for the crate with the given name.
///
/// This is a convenience method for constructing a [manifest] and
/// calling the [`get_path`] method.
///
/// This method should only be used where you just need the path and can't
/// cache the [manifest]. If caching is possible, it's recommended to create
/// the [manifest] yourself and use the [`get_path`] method.
///
/// [`get_path`]: Self::get_path
/// [manifest]: Self
pub fn get_path_direct(name: &str) -> syn::Path {
Self::default().get_path(name)
}

/// Returns the path for the crate with the given name.
pub fn get_path(&self, name: &str) -> syn::Path {
self.maybe_get_path(name)
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_reflect/derive/src/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ use syn::Path;

/// Returns the correct path for `bevy_reflect`.
pub(crate) fn get_bevy_reflect_path() -> Path {
BevyManifest::get_path_direct("bevy_reflect")
BevyManifest::shared().get_path("bevy_reflect")
}
2 changes: 1 addition & 1 deletion crates/bevy_reflect/derive/src/trait_reflection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub(crate) fn reflect_trait(_args: &TokenStream, input: TokenStream) -> TokenStr
let trait_ident = &item_trait.ident;
let trait_vis = &item_trait.vis;
let reflect_trait_ident = crate::ident::get_reflect_ident(&item_trait.ident.to_string());
let bevy_reflect_path = BevyManifest::default().get_path("bevy_reflect");
let bevy_reflect_path = BevyManifest::shared().get_path("bevy_reflect");

let struct_doc = format!(
" A type generated by the #[reflect_trait] macro for the `{trait_ident}` trait.\n\n This allows casting from `dyn Reflect` to `dyn {trait_ident}`.",
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/macros/src/as_bind_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ enum BindingState<'a> {
}

pub fn derive_as_bind_group(ast: syn::DeriveInput) -> Result<TokenStream> {
let manifest = BevyManifest::default();
let manifest = BevyManifest::shared();
let render_path = manifest.get_path("bevy_render");
let image_path = manifest.get_path("bevy_image");
let asset_path = manifest.get_path("bevy_asset");
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/macros/src/extract_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use syn::{parse_macro_input, parse_quote, DeriveInput, Path};
pub fn derive_extract_component(input: TokenStream) -> TokenStream {
let mut ast = parse_macro_input!(input as DeriveInput);
let bevy_render_path: Path = crate::bevy_render_path();
let bevy_ecs_path: Path = bevy_macro_utils::BevyManifest::default()
let bevy_ecs_path: Path = bevy_macro_utils::BevyManifest::shared()
.maybe_get_path("bevy_ecs")
.expect("bevy_ecs should be found in manifest");

Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use quote::format_ident;
use syn::{parse_macro_input, DeriveInput};

pub(crate) fn bevy_render_path() -> syn::Path {
BevyManifest::default()
BevyManifest::shared()
.maybe_get_path("bevy_render")
// NOTE: If the derivation is within bevy_render, then we need to return 'crate'
.unwrap_or_else(|| BevyManifest::parse_str("crate"))
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_state/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ pub fn derive_substates(input: TokenStream) -> TokenStream {
}

pub(crate) fn bevy_state_path() -> syn::Path {
BevyManifest::default().get_path("bevy_state")
BevyManifest::shared().get_path("bevy_state")
}

0 comments on commit 760d0a3

Please sign in to comment.