镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Add annotation processor (java + ksp) that can execute at compile-time #685

Open

Description

@solonovamax

Add an implementation of the annotation processors that can be run at compile time to parse the commands into a file format that can then be loaded at runtime. the format could, perhaps, be json.

Annotation processors implementing javax.annotation.processing.Processor and com.google.devtools.ksp.processing.SymbolProcessor would be quite beneficial, as it would anyone using the cloud annotations api to avoid having to scan the classpath to register their commands using something like reflections, and is much more convenient than having to manually list all the classes with commands.

I'm going to look into doing this myself, but for some reason gh mobile doesn't let me assign myself while creating the issue.

ways it could be done:

  • simply serialize a json array of class names to run reflection on at runtime
  • run the reflection & annotation processing (eg. interpreting the value of the @Command(String) annotation, parsing the default value (if possible), etc.) at compile time instead of runtime then serialize this as a json datastructure. the format could be smth like this (not comprehensive):
    commands:
      - class: [class name]
        root: [root command name]
        permission: [permission]
        meta: [meta stuff]
        - commands: [list of nested commands]
          method: [method name]
          name: [command name]
          permission: permission
          meta: [meta stuff]
          arguments:
            - name: [argument name]
              aliases: [aliases]
              parameterName: [name of parameter]
              parameterIndex: [index of parameter] # the index can be used when the class is compiled without parameter names
              default:
                value: [default value] # if specified
                method: [name of method] # if specified
              type: [fully qualified type]
          commands: [nested subcommands]

Activity

  1. zml2008 commented on Feb 5, 2024

    @zml2008
    Collaborator

    I think this'd be super cool -- I'd had some similar thoughts, but they'd involved doing codegen to write out the builder logic to register commands rather than depending on some intermediate format.

    The struggle I ran into was how to handle extracting parameters from custom argument types -- there might be some manual work needed? or a service registry that's AP-specific.

  2. solonovamax commented on Feb 6, 2024

    @solonovamax
    ContributorAuthor

    I think this'd be super cool -- I'd had some similar thoughts, but they'd involved doing codegen to write out the builder logic to register commands rather than depending on some intermediate format.

    what similar thoughts? also, I wanted to explicitly avoid codegen bc codegen feels kinda icky to me when it could just be a file with the information that gets parsed, instead

    The struggle I ran into was how to handle extracting parameters from custom argument types -- there might be some manual work needed? or a service registry that's AP-specific.

    personally, for this I was thinking "if the argument cannot be extracted, just serialize it as a string and then it'll get extracted at runtime lol"

  3. Citymonstret commented on Feb 7, 2024

    @Citymonstret
    Member

    and is much more convenient than having to manually list all the classes with commands.

    This can already be avoided by using the command containers. Other than being a fun experiment, I am not sure what this unlocks that isn't already possible.

    simply serialize a json array of class names to run reflection on at runtime

    "simply serialize a json array" is not a thing in Java. Neither cloud-core nor cloud-annotations has a dependency on a JSON serializer


    but they'd involved doing codegen to write out the builder logic to register commands rather than depending on some intermediate format.

    This is something I've been thinking about as well. EngineHub has had success with this way of creating commands, and I'm not at all opposed to the idea of generating command builders.

    The struggle I ran into was how to handle extracting parameters from custom argument types -- there might be some manual work needed? or a service registry that's AP-specific.

    cloud-core already allows you to create command components from the parsed type rather than a specific parser, as long as the command builder is "attached" to the command manager. The part that is tricky is the customization of command components using annotations, which should be a less significant problem to deal with. cloud-annotations uses annotation mappers to map the annotations to parser parameters, which are then passed to the parser registry. The issue that we'd need to solve here is how we'd do these mappings during AP.

  4. solonovamax commented on Feb 7, 2024

    @solonovamax
    ContributorAuthor

    and is much more convenient than having to manually list all the classes with commands.

    This can already be avoided by using the command containers. Other than being a fun experiment, I am not sure what this unlocks that isn't already possible.

    yeah I didn't realize the command containers already existed. though, from what I am aware, the command containers still need to do runtime reflection to get methods, method parameter types, etc.
    it would be cool if this could be moved to compile-time

    also, one part of this would be supporting the command containers in kotlin's KSP.

    simply serialize a json array of class names to run reflection on at runtime

    "simply serialize a json array" is not a thing in Java. Neither cloud-core nor cloud-annotations has a dependency on a JSON serializer

    yeah, it'd be a separate module. I said json bc it's a common format, but it could always just be smth custom

    but they'd involved doing codegen to write out the builder logic to register commands rather than depending on some intermediate format.

    This is something I've been thinking about as well. EngineHub has had success with this way of creating commands, and I'm not at all opposed to the idea of generating command builders.

    doing codegen could always be viable as well. I just would prefer to avoid codegen if possible though lol

    The struggle I ran into was how to handle extracting parameters from custom argument types -- there might be some manual work needed? or a service registry that's AP-specific.

    cloud-core already allows you to create command components from the parsed type rather than a specific parser, as long as the command builder is "attached" to the command manager. The part that is tricky is the customization of command components using annotations, which should be a less significant problem to deal with. cloud-annotations uses annotation mappers to map the annotations to parser parameters, which are then passed to the parser registry. The issue that we'd need to solve here is how we'd do these mappings during AP.

    maybe there'd be some way to run the compiled annotation mappers at compile time? idk.

  5. zml2008 commented on Feb 7, 2024

    @zml2008
    Collaborator

    Honestly JavaPoet makes codegen super fun and easy, and it's kinda the standard for Java APs these days

  6. solonovamax commented on Feb 7, 2024

    @solonovamax
    ContributorAuthor

    Honestly JavaPoet makes codegen super fun and easy, and it's kinda the standard for Java APs these days

    yeah, I just feel that a custom serialized format would be "easier"

    because, there's not really any need to codegen what can be put in a file to be read at runtime, as no client code will ever be interacting directly with this. it'd just be something like invoking AnnotationProcessorCommandLoader.load() or smth, idk
    then, it'd either load the fileformat and parse it then loop over it, or load a fileformat with a list of class names and then run a function on those classes.
    effectively the same thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions