From 06cb5c5fd9436f27ec72a8810c1b5ae90be957e4 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Wed, 5 Mar 2025 18:44:47 -0800 Subject: [PATCH] Fix Component require() IDE integration (#18165) # Objective Component `require()` IDE integration is fully broken, as of #16575. ## Solution This reverts us back to the previous "put the docs on Component trait" impl. This _does_ reduce the accessibility of the required components in rust docs, but the complete erasure of "required component IDE experience" is not worth the price of slightly increased prominence of requires in docs. Additionally, Rust Analyzer has recently started including derive attributes in suggestions, so we aren't losing that benefit of the proc_macro attribute impl. --- .../bevy_core_pipeline/src/motion_blur/mod.rs | 5 +-- crates/bevy_core_pipeline/src/taa/mod.rs | 2 +- crates/bevy_ecs/macros/src/component.rs | 43 ++++++------------- crates/bevy_ecs/macros/src/lib.rs | 10 +---- crates/bevy_ecs/src/component.rs | 2 - crates/bevy_ecs/src/entity/clone_entities.rs | 1 - crates/bevy_ecs/src/lib.rs | 4 +- crates/bevy_ecs/src/system/commands/mod.rs | 2 +- crates/bevy_ecs/src/system/system_registry.rs | 2 +- crates/bevy_gizmos/src/retained.rs | 5 +-- crates/bevy_input/src/gamepad.rs | 1 - crates/bevy_pbr/src/atmosphere/mod.rs | 2 +- crates/bevy_pbr/src/decal/clustered.rs | 2 +- crates/bevy_pbr/src/decal/forward.rs | 4 +- crates/bevy_pbr/src/light_probe/mod.rs | 2 +- crates/bevy_pbr/src/meshlet/mod.rs | 2 +- crates/bevy_pbr/src/ssao/mod.rs | 2 +- crates/bevy_pbr/src/ssr/mod.rs | 2 +- crates/bevy_pbr/src/volumetric_fog/mod.rs | 6 +-- crates/bevy_render/src/camera/camera.rs | 2 +- crates/bevy_render/src/mesh/components.rs | 2 +- crates/bevy_scene/src/components.rs | 5 +-- crates/bevy_sprite/src/sprite.rs | 5 +-- crates/bevy_text/src/text2d.rs | 2 +- .../src/components/transform.rs | 2 +- crates/bevy_ui/src/ui_material.rs | 5 +-- crates/bevy_ui/src/widget/button.rs | 5 +-- crates/bevy_ui/src/widget/text.rs | 2 +- 28 files changed, 40 insertions(+), 89 deletions(-) diff --git a/crates/bevy_core_pipeline/src/motion_blur/mod.rs b/crates/bevy_core_pipeline/src/motion_blur/mod.rs index 7703698f1a..58466d7c82 100644 --- a/crates/bevy_core_pipeline/src/motion_blur/mod.rs +++ b/crates/bevy_core_pipeline/src/motion_blur/mod.rs @@ -9,10 +9,7 @@ use crate::{ use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, weak_handle, Handle}; use bevy_ecs::{ - component::{require, Component}, - query::With, - reflect::ReflectComponent, - schedule::IntoSystemConfigs, + component::Component, query::With, reflect::ReflectComponent, schedule::IntoSystemConfigs, }; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ diff --git a/crates/bevy_core_pipeline/src/taa/mod.rs b/crates/bevy_core_pipeline/src/taa/mod.rs index 55eb25ae02..2f30544be9 100644 --- a/crates/bevy_core_pipeline/src/taa/mod.rs +++ b/crates/bevy_core_pipeline/src/taa/mod.rs @@ -8,7 +8,7 @@ use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, weak_handle, Handle}; use bevy_diagnostic::FrameCount; use bevy_ecs::{ - prelude::{require, Component, Entity, ReflectComponent}, + prelude::{Component, Entity, ReflectComponent}, query::{QueryItem, With}, resource::Resource, schedule::IntoSystemConfigs, diff --git a/crates/bevy_ecs/macros/src/component.rs b/crates/bevy_ecs/macros/src/component.rs index a7bfb5845c..f88ae4349c 100644 --- a/crates/bevy_ecs/macros/src/component.rs +++ b/crates/bevy_ecs/macros/src/component.rs @@ -1,4 +1,4 @@ -use proc_macro::{TokenStream, TokenTree}; +use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::{format_ident, quote, ToTokens}; use std::collections::HashSet; @@ -207,6 +207,18 @@ pub fn derive_component(input: TokenStream) -> TokenStream { let struct_name = &ast.ident; let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl(); + let required_component_docs = attrs.requires.map(|r| { + let paths = r + .iter() + .map(|r| format!("[`{}`]", r.path.to_token_stream())) + .collect::>() + .join(", "); + let doc = format!("**Required Components**: {paths}. \n\n A component's Required Components are inserted whenever it is inserted. Note that this will also insert the required components _of_ the required components, recursively, in depth-first order."); + quote! { + #[doc = #doc] + } + }); + let mutable_type = (attrs.immutable || relationship.is_some()) .then_some(quote! { #bevy_ecs_path::component::Immutable }) .unwrap_or(quote! { #bevy_ecs_path::component::Mutable }); @@ -223,6 +235,7 @@ pub fn derive_component(input: TokenStream) -> TokenStream { // This puts `register_required` before `register_recursive_requires` to ensure that the constructors of _all_ top // level components are initialized first, giving them precedence over recursively defined constructors for the same component type TokenStream::from(quote! { + #required_component_docs impl #impl_generics #bevy_ecs_path::component::Component for #struct_name #type_generics #where_clause { const STORAGE_TYPE: #bevy_ecs_path::component::StorageType = #storage; type Mutability = #mutable_type; @@ -414,34 +427,6 @@ pub(crate) fn ident_or_index(ident: Option<&Ident>, index: usize) -> Member { ) } -pub fn document_required_components(attr: TokenStream, item: TokenStream) -> TokenStream { - let paths = parse_macro_input!(attr with Punctuated::::parse_terminated) - .iter() - .map(|r| format!("[`{}`]", r.path.to_token_stream())) - .collect::>() - .join(", "); - - let bevy_ecs_path = crate::bevy_ecs_path() - .to_token_stream() - .to_string() - .replace(' ', ""); - let required_components_path = bevy_ecs_path + "::component::Component#required-components"; - - // Insert information about required components after any existing doc comments - let mut out = TokenStream::new(); - let mut end_of_attributes_reached = false; - for tt in item { - if !end_of_attributes_reached & matches!(tt, TokenTree::Ident(_)) { - end_of_attributes_reached = true; - let doc: TokenStream = format!("#[doc = \"\n\n# Required Components\n{paths} \n\n A component's [required components]({required_components_path}) are inserted whenever it is inserted. Note that this will also insert the required components _of_ the required components, recursively, in depth-first order.\"]").parse().unwrap(); - out.extend(doc); - } - out.extend(Some(tt)); - } - - out -} - pub const COMPONENT: &str = "component"; pub const STORAGE: &str = "storage"; pub const REQUIRE: &str = "require"; diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index f61889651d..9887f1fabe 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -597,20 +597,12 @@ pub fn derive_resource(input: TokenStream) -> TokenStream { #[proc_macro_derive( Component, - attributes(component, relationship, relationship_target, entities) + attributes(component, require, relationship, relationship_target, entities) )] pub fn derive_component(input: TokenStream) -> TokenStream { component::derive_component(input) } -/// Allows specifying a component's required components. -/// -/// See `Component` docs for usage. -#[proc_macro_attribute] -pub fn require(attr: TokenStream, item: TokenStream) -> TokenStream { - component::document_required_components(attr, item) -} - #[proc_macro_derive(States)] pub fn derive_states(input: TokenStream) -> TokenStream { states::derive_states(input) diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index cf48c7da03..7a67571d89 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -33,8 +33,6 @@ use core::{ use disqualified::ShortName; use thiserror::Error; -pub use bevy_ecs_macros::require; - /// A data type that can be used to store data for an [entity]. /// /// `Component` is a [derivable trait]: this means that a data type can implement it by applying a `#[derive(Component)]` attribute to it. diff --git a/crates/bevy_ecs/src/entity/clone_entities.rs b/crates/bevy_ecs/src/entity/clone_entities.rs index 2220ad29bc..b9564c1352 100644 --- a/crates/bevy_ecs/src/entity/clone_entities.rs +++ b/crates/bevy_ecs/src/entity/clone_entities.rs @@ -846,7 +846,6 @@ mod tests { world::{FromWorld, World}, }; use alloc::vec::Vec; - use bevy_ecs_macros::require; use bevy_ptr::OwningPtr; use bevy_reflect::Reflect; use core::{alloc::Layout, ops::Deref}; diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 8d415d7469..bae3dbfed2 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -72,7 +72,7 @@ pub mod prelude { bundle::Bundle, change_detection::{DetectChanges, DetectChangesMut, Mut, Ref}, children, - component::{require, Component}, + component::Component, entity::{Entity, EntityBorrow, EntityMapper}, event::{Event, EventMutator, EventReader, EventWriter, Events}, hierarchy::{ChildOf, ChildSpawner, ChildSpawnerCommands, Children}, @@ -132,7 +132,7 @@ mod tests { use crate::{ bundle::Bundle, change_detection::Ref, - component::{require, Component, ComponentId, RequiredComponents, RequiredComponentsError}, + component::{Component, ComponentId, RequiredComponents, RequiredComponentsError}, entity::Entity, entity_disabling::DefaultQueryFilters, prelude::Or, diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 442c4185dc..12c5427225 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -2222,7 +2222,7 @@ impl<'a, T: Component> EntityEntryCommands<'a, T> { #[cfg(test)] mod tests { use crate::{ - component::{require, Component}, + component::Component, resource::Resource, system::Commands, world::{CommandQueue, FromWorld, World}, diff --git a/crates/bevy_ecs/src/system/system_registry.rs b/crates/bevy_ecs/src/system/system_registry.rs index cf42d0d875..f1837f99dd 100644 --- a/crates/bevy_ecs/src/system/system_registry.rs +++ b/crates/bevy_ecs/src/system/system_registry.rs @@ -7,7 +7,7 @@ use crate::{ world::World, }; use alloc::boxed::Box; -use bevy_ecs_macros::{require, Component, Resource}; +use bevy_ecs_macros::{Component, Resource}; #[cfg(feature = "bevy_reflect")] use bevy_reflect::Reflect; use core::marker::PhantomData; diff --git a/crates/bevy_gizmos/src/retained.rs b/crates/bevy_gizmos/src/retained.rs index 435f417552..51170144b1 100644 --- a/crates/bevy_gizmos/src/retained.rs +++ b/crates/bevy_gizmos/src/retained.rs @@ -3,10 +3,7 @@ use core::ops::{Deref, DerefMut}; use bevy_asset::Handle; -use bevy_ecs::{ - component::{require, Component}, - reflect::ReflectComponent, -}; +use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_reflect::Reflect; use bevy_transform::components::Transform; diff --git a/crates/bevy_input/src/gamepad.rs b/crates/bevy_input/src/gamepad.rs index 30d503cf79..4487a3caa3 100644 --- a/crates/bevy_input/src/gamepad.rs +++ b/crates/bevy_input/src/gamepad.rs @@ -12,7 +12,6 @@ use bevy_ecs::{ entity::Entity, event::{Event, EventReader, EventWriter}, name::Name, - prelude::require, system::{Commands, Query}, }; use bevy_math::ops; diff --git a/crates/bevy_pbr/src/atmosphere/mod.rs b/crates/bevy_pbr/src/atmosphere/mod.rs index f525c0e2b8..82dc201c5d 100644 --- a/crates/bevy_pbr/src/atmosphere/mod.rs +++ b/crates/bevy_pbr/src/atmosphere/mod.rs @@ -36,7 +36,7 @@ use bevy_app::{App, Plugin}; use bevy_asset::load_internal_asset; use bevy_core_pipeline::core_3d::graph::Node3d; use bevy_ecs::{ - component::{require, Component}, + component::Component, query::{Changed, QueryItem, With}, schedule::IntoSystemConfigs, system::{lifetimeless::Read, Query}, diff --git a/crates/bevy_pbr/src/decal/clustered.rs b/crates/bevy_pbr/src/decal/clustered.rs index 43edcd0bc3..d382d50c8c 100644 --- a/crates/bevy_pbr/src/decal/clustered.rs +++ b/crates/bevy_pbr/src/decal/clustered.rs @@ -20,7 +20,7 @@ use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, weak_handle, AssetId, Handle}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ - component::{require, Component}, + component::Component, entity::{hash_map::EntityHashMap, Entity}, prelude::ReflectComponent, query::With, diff --git a/crates/bevy_pbr/src/decal/forward.rs b/crates/bevy_pbr/src/decal/forward.rs index 7732f1d3a4..8490017fbb 100644 --- a/crates/bevy_pbr/src/decal/forward.rs +++ b/crates/bevy_pbr/src/decal/forward.rs @@ -4,7 +4,7 @@ use crate::{ }; use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, weak_handle, Asset, Assets, Handle}; -use bevy_ecs::component::{require, Component}; +use bevy_ecs::component::Component; use bevy_math::{prelude::Rectangle, Quat, Vec2, Vec3}; use bevy_reflect::{Reflect, TypePath}; use bevy_render::{ @@ -63,7 +63,7 @@ impl Plugin for ForwardDecalPlugin { /// # Usage Notes /// /// * Spawn this component on an entity with a [`crate::MeshMaterial3d`] component holding a [`ForwardDecalMaterial`]. -/// * Any camera rendering a forward decal must have the [`bevy_core_pipeline::DepthPrepass`] component. +/// * Any camera rendering a forward decal must have the [`bevy_core_pipeline::prepass::DepthPrepass`] component. /// * Looking at forward decals at a steep angle can cause distortion. This can be mitigated by padding your decal's /// texture with extra transparent pixels on the edges. #[derive(Component, Reflect)] diff --git a/crates/bevy_pbr/src/light_probe/mod.rs b/crates/bevy_pbr/src/light_probe/mod.rs index c728a1cc6b..65a7ee6740 100644 --- a/crates/bevy_pbr/src/light_probe/mod.rs +++ b/crates/bevy_pbr/src/light_probe/mod.rs @@ -5,7 +5,7 @@ use bevy_asset::{load_internal_asset, weak_handle, AssetId, Handle}; use bevy_core_pipeline::core_3d::Camera3d; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ - component::{require, Component}, + component::Component, entity::Entity, query::With, reflect::ReflectComponent, diff --git a/crates/bevy_pbr/src/meshlet/mod.rs b/crates/bevy_pbr/src/meshlet/mod.rs index 4057f29e39..bf701acb1c 100644 --- a/crates/bevy_pbr/src/meshlet/mod.rs +++ b/crates/bevy_pbr/src/meshlet/mod.rs @@ -65,7 +65,7 @@ use bevy_core_pipeline::{ }; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ - component::{require, Component}, + component::Component, entity::Entity, query::Has, reflect::ReflectComponent, diff --git a/crates/bevy_pbr/src/ssao/mod.rs b/crates/bevy_pbr/src/ssao/mod.rs index 4d97f52cff..3422f511c5 100644 --- a/crates/bevy_pbr/src/ssao/mod.rs +++ b/crates/bevy_pbr/src/ssao/mod.rs @@ -7,7 +7,7 @@ use bevy_core_pipeline::{ prepass::{DepthPrepass, NormalPrepass, ViewPrepassTextures}, }; use bevy_ecs::{ - prelude::{require, Component, Entity}, + prelude::{Component, Entity}, query::{Has, QueryItem, With}, reflect::ReflectComponent, resource::Resource, diff --git a/crates/bevy_pbr/src/ssr/mod.rs b/crates/bevy_pbr/src/ssr/mod.rs index 15b783cef5..fa7424145f 100644 --- a/crates/bevy_pbr/src/ssr/mod.rs +++ b/crates/bevy_pbr/src/ssr/mod.rs @@ -12,7 +12,7 @@ use bevy_core_pipeline::{ }; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ - component::{require, Component}, + component::Component, entity::Entity, query::{Has, QueryItem, With}, reflect::ReflectComponent, diff --git a/crates/bevy_pbr/src/volumetric_fog/mod.rs b/crates/bevy_pbr/src/volumetric_fog/mod.rs index 4b90d63afc..ff0b913f1d 100644 --- a/crates/bevy_pbr/src/volumetric_fog/mod.rs +++ b/crates/bevy_pbr/src/volumetric_fog/mod.rs @@ -36,11 +36,7 @@ use bevy_core_pipeline::core_3d::{ graph::{Core3d, Node3d}, prepare_core_3d_depth_textures, }; -use bevy_ecs::{ - component::{require, Component}, - reflect::ReflectComponent, - schedule::IntoSystemConfigs as _, -}; +use bevy_ecs::{component::Component, reflect::ReflectComponent, schedule::IntoSystemConfigs as _}; use bevy_image::Image; use bevy_math::{ primitives::{Cuboid, Plane3d}, diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 298be27c5f..0c67f0ea04 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -25,7 +25,7 @@ use bevy_ecs::{ component::{Component, HookContext}, entity::{Entity, EntityBorrow}, event::EventReader, - prelude::{require, With}, + prelude::With, query::Has, reflect::ReflectComponent, resource::Resource, diff --git a/crates/bevy_render/src/mesh/components.rs b/crates/bevy_render/src/mesh/components.rs index b5b03ac2b8..f55897ce6d 100644 --- a/crates/bevy_render/src/mesh/components.rs +++ b/crates/bevy_render/src/mesh/components.rs @@ -5,7 +5,7 @@ use crate::{ use bevy_asset::{AsAssetId, AssetEvent, AssetId, Handle}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ - change_detection::DetectChangesMut, component::Component, event::EventReader, prelude::require, + change_detection::DetectChangesMut, component::Component, event::EventReader, reflect::ReflectComponent, system::Query, }; use bevy_platform_support::{collections::HashSet, hash::FixedHasher}; diff --git a/crates/bevy_scene/src/components.rs b/crates/bevy_scene/src/components.rs index 8709c7990f..355628c6c7 100644 --- a/crates/bevy_scene/src/components.rs +++ b/crates/bevy_scene/src/components.rs @@ -1,9 +1,6 @@ use bevy_asset::Handle; use bevy_derive::{Deref, DerefMut}; -use bevy_ecs::{ - component::{require, Component}, - prelude::ReflectComponent, -}; +use bevy_ecs::{component::Component, prelude::ReflectComponent}; use bevy_reflect::{prelude::ReflectDefault, Reflect}; use bevy_transform::components::Transform; use derive_more::derive::From; diff --git a/crates/bevy_sprite/src/sprite.rs b/crates/bevy_sprite/src/sprite.rs index 59c60071a0..82d5f155a8 100644 --- a/crates/bevy_sprite/src/sprite.rs +++ b/crates/bevy_sprite/src/sprite.rs @@ -1,9 +1,6 @@ use bevy_asset::{Assets, Handle}; use bevy_color::Color; -use bevy_ecs::{ - component::{require, Component}, - reflect::ReflectComponent, -}; +use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_image::{Image, TextureAtlas, TextureAtlasLayout}; use bevy_math::{Rect, UVec2, Vec2}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; diff --git a/crates/bevy_text/src/text2d.rs b/crates/bevy_text/src/text2d.rs index 13e9760f29..394b12d03b 100644 --- a/crates/bevy_text/src/text2d.rs +++ b/crates/bevy_text/src/text2d.rs @@ -10,7 +10,7 @@ use bevy_derive::{Deref, DerefMut}; use bevy_ecs::entity::hash_set::EntityHashSet; use bevy_ecs::{ change_detection::{DetectChanges, Ref}, - component::{require, Component}, + component::Component, entity::Entity, prelude::{ReflectComponent, With}, query::{Changed, Without}, diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index 2949015848..8dc4d2453c 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -3,7 +3,7 @@ use bevy_math::{Affine3A, Dir3, Isometry3d, Mat3, Mat4, Quat, Vec3}; use core::ops::Mul; #[cfg(feature = "bevy-support")] -use bevy_ecs::{component::Component, prelude::require}; +use bevy_ecs::component::Component; #[cfg(feature = "bevy_reflect")] use {bevy_ecs::reflect::ReflectComponent, bevy_reflect::prelude::*}; diff --git a/crates/bevy_ui/src/ui_material.rs b/crates/bevy_ui/src/ui_material.rs index a9d712d5be..9f56e834a4 100644 --- a/crates/bevy_ui/src/ui_material.rs +++ b/crates/bevy_ui/src/ui_material.rs @@ -1,10 +1,7 @@ use crate::Node; use bevy_asset::{Asset, AssetId, Handle}; use bevy_derive::{Deref, DerefMut}; -use bevy_ecs::{ - component::{require, Component}, - reflect::ReflectComponent, -}; +use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_reflect::{prelude::ReflectDefault, Reflect}; use bevy_render::{ extract_component::ExtractComponent, diff --git a/crates/bevy_ui/src/widget/button.rs b/crates/bevy_ui/src/widget/button.rs index 8445a4ad62..a4e5afc6fa 100644 --- a/crates/bevy_ui/src/widget/button.rs +++ b/crates/bevy_ui/src/widget/button.rs @@ -1,8 +1,5 @@ use crate::{FocusPolicy, Interaction, Node}; -use bevy_ecs::{ - prelude::{require, Component}, - reflect::ReflectComponent, -}; +use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; /// Marker struct for buttons diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index 42c91fd833..0be96febab 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -7,8 +7,8 @@ use bevy_color::Color; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ change_detection::DetectChanges, + component::Component, entity::Entity, - prelude::{require, Component}, query::With, reflect::ReflectComponent, system::{Query, Res, ResMut},