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

[ksp2] Annotation Target "PARAM" on constructor property is not respected #2225

Open
acejingbo opened this issue Nov 20, 2024 · 0 comments
Open

Comments

@acejingbo
Copy link

acejingbo commented Nov 20, 2024

In short #1302 still exist in KSP2, but i think only if the annotation is declared in java

Long explanation:
Base on https://kotlinlang.org/docs/annotations.html#annotation-use-site-targets

If you don't specify a use-site target, the target is chosen according to the @target annotation of the annotation being used. If there are multiple applicable targets, the first applicable target from the following list is used:
param
property
field

Therefore, when an annotation with @target including "PARAMETER" is applied to a constructor property, it should be applied on the parameter KSNode not the property KSNode

However, in ksp2, it seems applied on both the parameter and the property

I notice this only happens when the annotation is declared in java

Repro

3097d3b : I created an java JavaAnnoWithParamAndFieldTarget and an kotlin annotation AnnoWithParamAndFieldTarget, both have @target include both field and parameter. And then i applied both on a constructor property fullName

Expected

  • Property fullName should have neither JavaAnnoWithParamAndFieldTarget nor AnnoWithParamAndFieldTarget.
  • Param fullName should be both JavaAnnoWithParamAndFieldTarget and AnnoWithParamAndFieldTarget

Actual

  • Property fullName have JavaAnnoWithParamAndFieldTarget
  • Param fullName have both JavaAnnoWithParamAndFieldTarget and AnnoWithParamAndFieldTarget
org.opentest4j.AssertionFailedError: 

expected: <Annotation on property: Anno
true
Annotation on constructor param: Anno
Annotation on constructor param: AnnoWithParamAndFieldTarget
Annotation on constructor param: JavaAnnoWithParamAndFieldTarget
true> 

but was: <Annotation on property: Anno
Annotation on property: JavaAnnoWithParamAndFieldTarget
true
Annotation on constructor param: Anno
Annotation on constructor param: AnnoWithParamAndFieldTarget
Annotation on constructor param: JavaAnnoWithParamAndFieldTarget
true>

Suggested fix

After debug, i think it's because

).filterNot { valueParameterAnnotation ->
valueParameterAnnotation.annotationType.resolve().declaration.annotations.any { metaAnnotation ->
metaAnnotation.annotationType.resolve().declaration.qualifiedName
?.asString() == "kotlin.annotation.Target" &&
(metaAnnotation.arguments.singleOrNull()?.value as? ArrayList<*>)?.any {
(it as? KSClassDeclaration)?.qualifiedName
?.asString() == "kotlin.annotation.AnnotationTarget.VALUE_PARAMETER"
} ?: false
}
only checked Kotlin annotation target "kotlin.annotation.Target", but not java annotation target

(Unrelated question for that line of code is: shouldn't this filterNot only happens if ktPropertySymbol.isFromPrimaryConstructor, cause only constructor property have both property and param node? This didn't cause any bug for me just curious. Thanks feel free to ignore.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant