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.
This commit is contained in:
parent
54701a844e
commit
06cb5c5fd9
@ -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::{
|
||||
|
@ -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,
|
||||
|
@ -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::<Vec<_>>()
|
||||
.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::<Require, Comma>::parse_terminated)
|
||||
.iter()
|
||||
.map(|r| format!("[`{}`]", r.path.to_token_stream()))
|
||||
.collect::<Vec<_>>()
|
||||
.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";
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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};
|
||||
|
@ -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,
|
||||
|
@ -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},
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -12,7 +12,6 @@ use bevy_ecs::{
|
||||
entity::Entity,
|
||||
event::{Event, EventReader, EventWriter},
|
||||
name::Name,
|
||||
prelude::require,
|
||||
system::{Commands, Query},
|
||||
};
|
||||
use bevy_math::ops;
|
||||
|
@ -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},
|
||||
|
@ -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,
|
||||
|
@ -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)]
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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},
|
||||
|
@ -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,
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
@ -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},
|
||||
|
@ -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::*};
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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},
|
||||
|
Loading…
Reference in New Issue
Block a user