Package org.openrewrite.java.trait
Class AttributeValue
java.lang.Object
org.openrewrite.java.trait.AttributeValue
- All Implemented Interfaces:
org.openrewrite.trait.Trait<Expression>
@Incubating(since="8.87.0")
public class AttributeValue
extends Object
implements org.openrewrite.trait.Trait<Expression>
The value of an annotation attribute (a JLS §9.7.1 "element value"), in any of the
syntactic shapes annotations permit — not only the plain literals covered by
Literal:
AttributeValue.Kind.LITERAL—@Foo(name = "s"),@Foo(count = -1)AttributeValue.Kind.CLASS_LITERAL—@Foo(clazz = A.class),int.class,String[].class; KotlinA::classandA::class.javaAttributeValue.Kind.ENUM_CONSTANT—@Retention(RetentionPolicy.RUNTIME), in qualified, fully qualified, or statically imported spellingAttributeValue.Kind.CONSTANT_REFERENCE—@Foo(name = Constants.NAME)or a statically importedNAMEAttributeValue.Kind.NESTED_ANNOTATION—@Foo(bar = @Bar("x"))AttributeValue.Kind.ARRAY—@Foo(exclude = {A.class, B.class})AttributeValue.Kind.EXPRESSION— everything else, e.g.@Foo(name = "a" + "b")
Flag.Enum on the referenced JavaType.Variable). Unattributed references
degrade to AttributeValue.Kind.CONSTANT_REFERENCE with a null
getReferencedField(). The same degradation applies on Groovy and Kotlin
sources, whose type mappings do not set Flag.Enum: there enum constants always
classify as AttributeValue.Kind.CONSTANT_REFERENCE. Groovy and Kotlin list literals are not
J.NewArray and classify as AttributeValue.Kind.EXPRESSION without element
normalization.
The trait is cursor-bearing: Trait.getTree() / Trait.getCursor() give recipes the
exact expression to edit, and for arrays getElements() yields one cursor-bearing
value per element. Parentheses are transparent for classification and value access;
Trait.getTree() still returns the original expression.
Optional.empty() from Annotated.getAttributeValue(String) means only that
the attribute is not explicitly present in the source. A present value whose typed
accessors return null means "present but not resolvable that way" — the two
conditions the Optional<Literal> accessors used to conflate.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumThe syntactic shape of an annotation attribute value.static classMatches expressions in annotation attribute value position: a positional argument of aJ.Annotation, or the right-hand side of a named argument'sJ.Assignment. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription@Nullable JavaType@Nullable ObjectThe compile-time constant represented by this value, if one can be determined.The values of this attribute normalized to a list: an array initializer yields oneAttributeValueper element, each with its own cursor, so that both reads and surgical edits can address individual elements; every scalar shape yieldssingletonList(this).getKind()getName()@Nullable JavaType.Variable<T> @Nullable TgetValue(com.fasterxml.jackson.core.type.TypeReference<T> type) <T> @Nullable TgetConstantValue()coerced with Jackson, using the same mapper and scalar-to-collection normalization asLiteral.getValue(Class).booleanisArray()booleanbooleanisClassLiteral(String fullyQualifiedName) booleanbooleanisEnumConstant(String fullyQualifiedEnumName, String constantName) booleanbooleanMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.openrewrite.trait.Trait
getCursor, getTree
-
Constructor Details
-
AttributeValue
public AttributeValue()
-
-
Method Details
-
getKind
-
isLiteral
public boolean isLiteral() -
isClassLiteral
public boolean isClassLiteral() -
isClassLiteral
- Parameters:
fullyQualifiedName- The fully qualified name of a reference type.- Returns:
trueif this value is a class literal referencing the given type. Requires type attribution; inner class$and.spellings are considered equal. Primitive and array class literals never match.
-
isEnumConstant
- Parameters:
fullyQualifiedEnumName- The fully qualified name of the enum type.constantName- The name of the enum constant.- Returns:
trueif this value is the given enum constant, e.g.isEnumConstant("java.lang.annotation.RetentionPolicy", "RUNTIME"). Covers the qualified, fully qualified, and statically imported spellings uniformly.
-
isConstantReference
public boolean isConstantReference() -
isNestedAnnotation
public boolean isNestedAnnotation() -
isArray
public boolean isArray()- Returns:
trueif this value is written as an explicit array initializer (J.NewArray). The brace-less single-element form@Foo(exclude = A.class)of an array-typed attribute is NOT syntactically an array; usegetElements()for uniformly normalized element access.
-
getName
- Returns:
- the name of the annotation attribute this value is assigned to, or
"value"for a positional (implicit) value. Array elements report the name of their containing attribute.
-
getElements
The values of this attribute normalized to a list: an array initializer yields oneAttributeValueper element, each with its own cursor, so that both reads and surgical edits can address individual elements; every scalar shape yieldssingletonList(this). This mirrors the normalization the JLS applies to array-typed attributes, where the brace-less single-element form@Foo(exclude = A.class)means{A.class}— both forms iterate identically here. An empty initializer{}yields an empty list.- Returns:
- the individual values of this attribute.
-
asLiteral
- Returns:
- this value as the
Literaltrait when it is aJ.Literalor an array composed entirely of literals — exactly the shapesLiteral.Matchermatches. Unlike theOptional<Literal>accessors onAnnotated, this sees through parentheses. Note this answers "is itLiteral-compatible", which differs fromisLiteral()for all-literal arrays.
-
asAnnotated
- Returns:
- this value as the
Annotatedtrait when it is a nested annotation, enabling recursive attribute access.
-
getClassValue
- Returns:
- for a class literal, the referenced type: a
JavaType.FullyQualifiedforA.class, aJavaType.Primitiveforint.class, aJavaType.ArrayforString[].class.nullwhen this value is not a class literal or type attribution is missing.
-
getReferencedField
- Returns:
- the static field referenced by this value when it is an enum constant or a
constant reference: the variable's
owneris the declaring type and itsnamethe constant's name — identical across the qualified, fully qualified, and statically imported spellings. Distinguish enums viaisEnumConstant(String, String).nullwhen this value is not a reference or attribution is missing; class literals returnnullhere (their syntheticVariable{name="class"}is deliberately hidden — usegetClassValue()).
-
getConstantValue
The compile-time constant represented by this value, if one can be determined.- Returns:
- the constant value, or
nullwhen this value does not represent a determinable constant.
-
getValue
getConstantValue()coerced with Jackson, using the same mapper and scalar-to-collection normalization asLiteral.getValue(Class).- Returns:
- the coerced constant value, or
nullwhen unresolvable or not coercible.
-
getValue
public <T> @Nullable T getValue(com.fasterxml.jackson.core.type.TypeReference<T> type) - See Also:
-