Skip to content

Fix type arguments for annotations#2848

Open
jonamireh wants to merge 3 commits intogoogle:mainfrom
jonamireh:bug/2622
Open

Fix type arguments for annotations#2848
jonamireh wants to merge 3 commits intogoogle:mainfrom
jonamireh:bug/2622

Conversation

@jonamireh
Copy link
Copy Markdown
Contributor

Summary

This PR fixes #2622 to allow type arguments to be read from parameterized annotations. Additionally, this PR also allows them to be read when the parameterized annotation is an argument to another annotation

Test Plan

Compiler tests were added for all of these cases

🤖 Co-authored with Codex

@google-cla
Copy link
Copy Markdown

google-cla bot commented Mar 25, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@jonamireh
Copy link
Copy Markdown
Contributor Author

@ting-yuan @jaschdoc I rebased with the correct email for CLA, let me know if there's anything I need!

Copy link
Copy Markdown
Collaborator

@jaschdoc jaschdoc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jonamireh, thank you for the PR! Looks good overall. I left some feedback to improve readability and tests.

Comment on lines +52 to +56
(annotationApplication.psi as? KtAnnotationEntry)?.typeReference?.let {
KSTypeReferenceImpl.getCached(it, this@KSAnnotationResolvedImpl)
} ?: annotationApplication.psi?.resolveCall()?.signature?.returnType?.let {
KSTypeReferenceResolvedImpl.getCached(it, parent = this@KSAnnotationResolvedImpl)
} ?: KSTypeReferenceResolvedImpl.getCached(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you either name things a bit more or explain in comments what happens here?

)
}

override fun toResult(): List<String> = results
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be sorted to ensure results are stable across changes to the resolver. You might also need to update the expected output in annotationTypeArguments.kt.

Comment on lines +43 to +54
private fun renderAnnotation(label: String, annotation: KSAnnotation) {
val typeArguments = annotation.annotationType.element!!.typeArguments
results.add("$label.annotationType: ${annotation.annotationType}")
results.add("$label.typeArgCount: ${typeArguments.size}")
results.add(
"$label.typeArgs: ${
typeArguments.joinToString { argument ->
argument.type!!.resolve().declaration.qualifiedName!!.asString()
}
}"
)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Could you split rendering and adding to list into separate functions or just add the list of strings to the result at the call site? Example:

renderAnnotation(propertyName, annotation).forEach { results.add(it) }

Comment on lines +28 to +33
override fun process(resolver: Resolver): List<KSAnnotated> {
listOf("target", "nestedTarget").forEach { propertyName ->
val property = resolver.getPropertyDeclarationByName(resolver.getKSNameFromString(propertyName), true)!!
val annotation = property.annotations.single { it.shortName.asString() == "MapConvert" }
renderAnnotation(propertyName, annotation)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, you should obtain these properties by calling resolver.getSymbolsWithAnnotation, so if the test is ever updated, the processor will catch the change.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also change the targets to classes instead of val-bound unit values.

Comment on lines +35 to +39
val containerProperty =
resolver.getPropertyDeclarationByName(resolver.getKSNameFromString("containerTarget"), true)!!
val containerAnnotation = containerProperty.annotations.single { it.shortName.asString() == "Container" }
val nestedAnnotation = containerAnnotation.arguments.single().value as KSAnnotation
renderAnnotation("containerTarget.nested", nestedAnnotation)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same thing applies here. You should obtain containerTarget by calling resolver.getSymbolsWithAnnotation("Container")

@jonamireh
Copy link
Copy Markdown
Contributor Author

jonamireh commented Apr 14, 2026

Thanks for the feedback! Addressed them all 🙂

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

Successfully merging this pull request may close these issues.

typeArguments returns an empty list

2 participants