bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Genenerate doc comments from Required Components

Open killercup opened this issue 1 year ago • 4 comments

What problem does this solve or what need does it fill?

As a user of components with Required Components (#14791), I want to see what other components are going to be inserted easily.

What solution would you like?

Adding the #[required(…)] attribute should also add a doc comment. This will be shown by many IDEs when hovering (or similar) over the type.

Example

/// Makes entity behave like a button by adding sparkle effects on hover.
#[derive(Component)]
#[require(Node, UiImage)]
struct Button;

generates

/// Makes entity behave like a button by adding sparkle effects on hover.
///
/// # Automatically added components
///
/// When inserting this component,
/// [`Node`], and [`UiImage`]
//  are also inserted if not already present.
struct Button;

What alternative(s) have you considered?

  • Telling people to do this manually
  • Hoping that IDEs will do something else to show this

Additional context

#14791 is only proposed as of writing this. This issue may become invalid if it not accepted in its current state.

killercup avatar Aug 17 '24 17:08 killercup

A suggests attribute was also proposed and widely loved. We can probably do them in one PR.

alice-i-cecile avatar Aug 17 '24 18:08 alice-i-cecile

If we want the doc comments on the derived struct itself, we would have to use an attribute proc macro. Derive macros can only generate additional AST, not edit the original. Unless... could we fake it by #[requires()] and #[suggests()] being both a derive macro attribute AND a attribute proc macro? Worth looking into.

ItsDoot avatar Aug 17 '24 18:08 ItsDoot

Derive macros can only generate additional AST, not edit the original.

Hm. Adding the docs to the Component impl would be next to useless as you'd only ever name the type and never the trait, right?

Unless... could we fake it by #[requires()] and #[suggests()] being both a derive macro attribute AND a attribute proc macro? Worth looking into.

That's the mad genius kinda thing that I'm into, but it might also be a bit surprising to users. I'd try it but see how people feel about it before shipping it in a release.

killercup avatar Aug 17 '24 20:08 killercup

I was able to add this in the derive macro by adding a #[doc = ""] attribute to the Component impl. Obviously not ideal because its not directly on the type (and therefore won't show up in most IDE hovers). But it is pretty visible / usable from the generated docs:

image

cart avatar Aug 24 '24 04:08 cart

could we fake it by #[requires()] and #[suggests()] being both a derive macro attribute AND a attribute proc macro? Worth looking into.

I just tested a custom macro crate that just exports

#[proc_macro_attribute]
pub fn require(attr: TokenStream, item: TokenStream) -> TokenStream {
    panic!("test");
}

Main finding:

use bevy::prelude::*;
use require_macro::require;

#[derive(Component)]
#[require(Transform)]
pub struct Foo;

– this does not call the macro!

Only when flipping the attributes like this:

#[require(Transform)]
#[derive(Component)]
pub struct Foo;

does it get interesting, but sadly also not in a way we want:

error[E0659]: `require` is ambiguous
 --> crates/test-required-docs/src/lib.rs:4:3
  |
4 | #[require(Transform)]
  |   ^^^^^^^ ambiguous name
  |
  = note: ambiguous because of a name conflict with a derive helper attribute
note: `require` could refer to the derive helper attribute defined here
 --> crates/test-required-docs/src/lib.rs:5:10
  |
5 | #[derive(Component)]
  |          ^^^^^^^^^
note: `require` could also refer to the attribute macro imported here
 --> crates/test-required-docs/src/lib.rs:2:5
  |
2 | use require_macro::require;
  |     ^^^^^^^^^^^^^^^^^^^^^^
  = help: use `crate::require` to refer to this attribute macro unambiguously

So for now, I don't see a way forward with this.

killercup avatar Aug 29 '24 12:08 killercup

Alright, I'm going to close this as completed: I don't think we're going to do better than the initial implementation in #14971.

alice-i-cecile avatar Aug 29 '24 12:08 alice-i-cecile

Fair enough. Unless the whole Component derive becomes a proc macro (which would be surprising to users I bet), there is no easy way to get this. Next best thing will be editor integration I guess!

killercup avatar Aug 29 '24 12:08 killercup