8000 GitHub - agentgt/avaje-prisms: java annotation processing, fork of hickory (updated to Java 11 with module-info)
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

agentgt/avaje-prisms

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build JDK EA License Maven Central : avaje-prisms

Avaje Prisms

Fork of the legendary hickory annotation processor. Hickory has served pretty well since it was created in 2010, but it's unmaintained and doesn't have module support.

Differences from Hickory

  • Upgrades from JDK 6 to 11
  • Adds modular support via module-info
  • @GeneratedPrism is now repeatable
  • Generates a getAllInstances method to retrieve a list of prisms from an element
  • Generates an isPresent method to easily check if an element has the target annotation
  • Generates Optional factory methods
  • Generates a getAllInstances method to retrieve a list of prisms from an element
  • Generates a getAllOnMetaAnnotations method to retrieve a list of prisms from an element's annotations
  • Exposes the fully qualified type of the target annotation as a string.
  • getInstance returns null instead of throwing exceptions when the provided mirror doesn't match the prism target
  • null annotation array values are returned as empty lists

What's a Prism?

When writing annotation processors the two conventional mechanisms to access the annotations are both awkward. Element.getAnnotation() can throw Exceptions if the annotation or its members are not semantically correct, and it can also fail to work on some modular projects. (This is one the reasons why <annotationProcessorPaths> is required for modular projects but it is seriously limited and technically not correct either: MCOMPILER-391 and MCOMPILER-412) Moreover, when calling a member with a Class return type, you need to catch an exception to extract the TypeMirror.

On the other hand, AnnotationMirror and AnnotationValue do a good job of modelling both correct and incorrect annotations, but provide no simple mechanism to determine whether it is correct or incorrect, and provide no convenient functionality to access the member values in a simple type specific way. While AnnotationMirror and AnnotationValue provide an ideal mechanism for dealing with unknown annotations, they are inconvenient for reading member values from known annotations.

A Prism provides a solution to this problem by combining the advantages of the pure reflective model of AnnotationMirror and the runtime (real) model provided by Element.getAnnotation(), hence the term Prism to capture this idea of partial reflection.

A prism has the same member methods as the annotation except that the return types are translated from runtime types to compile time types as follows...

  • Primitive members return their equivalent wrapper class in the prism.
  • Class members return a TypeMirror from the mirror API.
  • Enum members return a String being the name of the enum constant (because the constant value in the mirror API might not match those available in the runtime it cannot consistently return the appropriate enum).
  • String members return Strings.
  • Annotation members return a Prism of the annotation. If a prism for that annotation is generated from the same @GeneratePrisms annotation as the prism that uses it, then an instance of that prism will be returned. Otherwise a Prism for that annotation is supplied as an inner class of the dependant Prism. the name of which is the simple name of the referenced annotation type.
  • Array members return a List where X is the appropriate prism mapping of the array component as above.

How to use

1. Add avaje-prisms as a dependency in your annotation processor.

    <dependency>
      <groupId>io.avaje</groupId>
      <artifactId>avaje-prisms</artifactId>
      <version>1.6</version>
      <optional>true</optional>
      <scope>provided</scope>
    </dependency>

2. Replace <compilerArgument>-proc:none</compilerArgument> with this annotation processor

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration> 
    <annotationProcessorPaths>
      <path>
          <groupId>io.avaje</groupId>
          <artifactId>avaje-prisms</artifactId>
          <version>1.6</version>
      </path>
    </annotationProcessorPaths>
  </configuration>
</plugin>

3. Add @GeneratePrism targeting an annotation to a package-info.java/class.

// package-info.java
@GeneratePrism(MyExampleAnnotation.class)
package org.example

4. Use the Generated Prism Class

 void someFunction(Element element) {
    
MyExampleAnnotationPrism exampleAnnotation = MyExampleAnnotationPrism.getInstanceOn(element);
//can get the original annotation type as a string
String annotationQualifiedType = MyExampleAnnotationPrism.PRISM_TYPE

//can easily retrive the annotation values as if the annotation was present on the classpath.
exampleAnnotation.getValue()
  ...
    }

Related Works

About

java annotation processing, fork of hickory (updated to Java 11 with module-info)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 100.0%
0