openrewrite / openrewrite/rewrite
Kotlin and Groovy type attribution gaps behind AttributeValue's degraded classification
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 3.7k
- Forks
- 570
- Avg merge
- 13h 12m
- Merged PRs (30d)
- 261
Description
What's the issue?
- #8166 introduced the
AttributeValuetrait (#8160), which classifies annotation attribute values syntax-first and discriminates enum constants viaFlag.Enum(JVMSACC_ENUM) on the referencedJavaType.Variable— the contract javac-attributed Java fulfills. On Kotlin and Groovy sources the same code degrades (enum constants classify asCONSTANT_REFERENCE, constant references don't fold), not because of the trait but because of parser/type-mapping gaps. The divergences are captured as@ExpectedToFailtests inrewrite-groovy/.../AttributeValueTraitTestandrewrite-kotlin/.../AttributeValueTraitTest, asserting the Java-aligned semantics — each flips red the moment its gap is fixed. - https://github.com/openrewrite/rewrite/pull/8178 fixed the Kotlin part of this issue.
The gaps
1. Kotlin: Flag.Enum is never set on enum entries (one-line fix)
KotlinTypeMapping.kt:1171 — variableType(FirVariable, …) computes flags via mapToFlagsBitmap(visibility, modality, isStatic) with no enum-entry branch, even though enum entries flow through this very method (:519-520) and the enum class does get the bit (:446-447, flags or (1L shl 14)). Fix: add the bit when variable is FirEnumEntry. Unblocks AttributeValue#isEnumConstant(..) on Kotlin.
2. Groovy: property-access references carry no fieldType at all
GroovyParserVisitor#visitPropertyExpression converts the property name to a J.Identifier with fieldType hard-coded null — the resolved FieldNode is never looked up, although GroovyTypeMapping.variableType(FieldNode) exists and declared enum constants get proper attribution (GroovyParserVisitor:850). Groovy's enum-constant FieldNodes carry ACC_ENUM at Phases.CANONICALIZATION (set by EnumHelper), so attaching typeMapping.variableType(classNode.getField(name)) when the receiver's static type resolves would fix enum discrimination and give getReferencedField() to all Groovy constant references, including idiomatic bare class refs (@Foo(type = String)). Needs scoping to statically unambiguous receivers (dynamic dispatch).
3. Both: no JavaType.Annotation element values → no constant fold
Neither type mapping constructs ElementValues (zero references in either module), so AttributeValue#getConstantValue() cannot resolve Constants.NAME on these sources, while javac paths fold even binary-dependency constants (ReloadableJava17TypeMapping.listAnnotations:644, Attribute.Constant fold at :704). Larger effort — possibly split per language.
4. Both: list/collection literals are opaque to array normalization
G.ListLiteral/K.ListLiteral are not J.NewArray and cannot be referenced from rewrite-java, so AttributeValue#getElements() returns them as one opaque value. This one is likely not a parser fix (mapping them to J.NewArray would break print fidelity) — it wants a trait extension seam or a shared interface in rewrite-java. Listed here for completeness; could be split out.
Expected behavior
The @ExpectedToFail test markers: ENUM_CONSTANT:isEnum=true, folded CONSTANT_REFERENCE:n, ARRAY:elements=2, and CLASS_LITERAL for Groovy bare class references.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the @ExpectedToFail tests in rewrite-groovy/.../AttributeValueTraitTest and rewrite-kotlin/.../AttributeValueTraitTest, noting that the Kotlin gap was addressed by PR #8178. For the remaining work, read GroovyParserVisitor#visitPropertyExpression and GroovyTypeMapping.variableType(FieldNode), then verify the expected enum, constant-reference, array, and class-literal behavior without expanding the dynamic-dispatch scope.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- groovy, java, kotlin
- Domain
- compilers, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100