Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose meta annotation parameters in the LST #3504

Open
kmclarnon opened this issue Aug 26, 2023 · 1 comment
Open

Expose meta annotation parameters in the LST #3504

kmclarnon opened this issue Aug 26, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@kmclarnon
Copy link
Contributor

kmclarnon commented Aug 26, 2023

What problem are you trying to solve?

Given a class structure like this

// from deps on the classpath
@Retention(SOURCE)
@interface A {}

// class i'm inspecting
class MyClass {
  @A
  public void methodA() {}
}

I would like to be able to determine what the RetentionPolicy being used for @A is. For my particular use case this is necessary to determine whether a dependency is directly referenced in bytecode or not (so that we can fix the deps listed in the pom correctly) but I believe there are many situations where this might be useful.

Describe the solution you'd like

I'm not sure I'm qualified to comment on what the ideal situation would be here, but it would be nice if there was a way to go from a JavaType that represented an annotation to a list of J.Annotations on that annotation rather than just a list of JavaType.Class.

Eg something like

class Visitor implements JavaIsoVisitor<ExecutionContext> {

  @Override
  public Annotation visitAnnotation(Annotation annotation, ExecutionContext context) {
    boolean isRetained = annotation.getType()
      .getAnnotations()
      .stream()
      .map(a -> (AnnotationClass)a) // AnnotationClass could be a subtype of JavaType / JavaType.Class that maintains it's args
      .filter(a -> a.getFullyQualifiedName().equals("java.lang.annotation.Retention"))
      .flatMap(a -> a.getArguments().stream())
      .noneMatch(arg -> isSourceRetentionPolicy(arg));
      
    return super.visitAnnotation(annotation, context);
  }
  
  private boolean isSourceRetention(Expression arg) {
    // check if it's value = RetentionPolicy.SOURCE
  }
}

Have you considered any alternatives or workarounds?

The current workaround that I am moving forward with is to pass the classpath urls through from the build to the recipe execution so that a special recipe can use classgraph to find the full class information for the annotations I'm inspecting, but I don't believe this is portable to moderne's saas infrastructure as it requires that all of the dependency jars be available on the local filesystem during recipe execution.

Additional context

Related slack conversation: link

Are you interested in contributing this feature to OpenRewrite?

I would be willing to help with this feature but I do not believe I have enough context to propose the best solution here.

@timtebeek
Copy link
Contributor

@vlsi reported a practical use case for this particular issue in #3880 ; Copying that content here to close that issue.

What problem are you trying to solve?

I don't like how OpenRewrite moved @Nullable from type to a method.

-  @Nullable String getSlotName();
+  @Nullable
+  @Override
+  String getSlotName();

Describe the solution you'd like

@Nullable is a type annotation, so it applies to String type rather than getSlotName() method.

Since OpenRewrite knows the exact definition of the annotation, it should be able to infer that @Nullable is a type annotation while @Override is not.

So I would like the formatting to be

  @Override
  @Nullable String getSlotName();

The emerging jspecify uses only TYPE_USE, see https://github.com/jspecify/jspecify/blob/ee91db649ce2de81d39b55b52345730b3f0f2531/src/main/java/org/jspecify/annotations/Nullable.java#L142, so users should prefer

    @Nullable String newValue;

rather than

    @Nullable
    String newValue;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Backlog
Development

No branches or pull requests

2 participants