Skip to content

Added @JsonWriter on enum instance method and property getter - #705

Open
dsudomoin wants to merge 1 commit into
kora-projects:1.0from
dsudomoin:feature/json-enum-jsonwriter-instance-getter
Open

Added @JsonWriter on enum instance method and property getter#705
dsudomoin wants to merge 1 commit into
kora-projects:1.0from
dsudomoin:feature/json-enum-jsonwriter-instance-getter

Conversation

@dsudomoin

Copy link
Copy Markdown
Contributor

Motivation

Enum @JsonWriter (from #701) required the value extractor to be a static method — a Kotlin companion object function (or Java public static) taking the enum and returning the JSON value. Putting @JsonWriter on a plain instance method produced a hard must be static error, and there was no property-level form. This PR broadens the accepted shapes so the common cases read naturally.

What changed

@JsonWriter on an enum now additionally accepts:

  • instance method@JsonWriter fun jsonValue(): V (0 params), including @JsonWriter override fun toString(): V;
  • Kotlin property getter@get:JsonWriter val value: V (KSP only; Java has no property concept).

The static (companion) form is unchanged and validated exactly as before. The forms are disambiguated by parameter count:

form shape
static (companion / public static) exactly 1 param of the enum type
instance method 0 params
Kotlin property getter @get: on the property

Value-source priority is unchanged: @JsonWriter (any form) → @Json getter → toString.

Examples

enum class AssetType(val value: String) {
    CURRENCY("currency"), OTHER("other");

    // any one of these now works:
    @JsonWriter fun toValue(): String = value               // instance method
    // @JsonWriter override fun toString(): String = value   // toString override
    // companion { @JsonWriter fun toValue(t: AssetType) = t.value }  // static (as before)
}

// property getter form:
enum class AssetType2(@get:JsonWriter val value: String) { A("a"), B("b") }

Note: a bare @JsonWriter val value (no use-site target) is still rejected by the Kotlin compiler, because @JsonWriter is @Target({TYPE, METHOD}) — use @get:JsonWriter.

Implementation

No runtime change — the generated writer still delegates to EnumJsonWriter<T,V>; only the extractor code block and the value type change.

  • KSP EnumJsonWriterGenerator.detectWriterMethod: accepts body methods and getter-annotated properties in addition to companion methods. An instance member is emitted as Enum::member (a (Enum) -> V), the static one as { e -> Enum.m(e) }.
  • KSP JsonSymbolProcessor: triggers writer generation for a @get:JsonWriter property, handling both KSPropertyDeclaration and KSPropertyGetter (the symbol reported by getSymbolsWithAnnotation for a @get: target varies by KSP version).
  • APT EnumWriterGenerator.detectWriterMethod: accepts instance methods; the existing Enum::method codegen already resolves to Function<Enum,V> for both static and instance forms, so generateEnumWriter is untouched. (Property getters are Kotlin-only, so APT stays method-only.)

Tests

Added to EnumTest (KSP + APT), covering: instance method, toString override, property getter (with and without @Json, to exercise the generation trigger), the from-extension path, and negative cases (instance method with params → no parameters; non-public → must be public). Full :json:json-symbol-processor:test and :json:json-annotation-processor:test are green.

…tter

Previously an enum's @JsonWriter value extractor had to be a static method (Kotlin companion object / Java public static) taking the enum and returning the JSON value. This extends the supported forms: an instance method `@JsonWriter fun jsonValue(): V` (0 params, including `@JsonWriter override fun toString()`), and a Kotlin property getter `@get:JsonWriter val value: V` (KSP only - Java has no property concept).

The static (companion) form is unchanged and still validated; the two method forms are disambiguated by parameter count (static: 1 param of the enum type; instance: 0 params). Generated code references an instance member as Enum::member (a (Enum) -> V function), the static one via a { e -> Enum.m(e) } lambda - no runtime EnumJsonWriter change.

KSP: EnumJsonWriterGenerator.detectWriterMethod now accepts body methods and getter-annotated properties; JsonSymbolProcessor triggers writer generation for a @get:JsonWriter property (handling both KSPropertyDeclaration and KSPropertyGetter, since the reported symbol varies by KSP version). APT: EnumWriterGenerator.detectWriterMethod accepts instance methods; the Enum::method codegen already resolves to Function<Enum,V> for both static and instance forms.
@GoodforGod GoodforGod added new feature New feature request module: json Related to JSON module labels Jul 11, 2026
@GoodforGod GoodforGod modified the milestone: v2.0.0 Jul 11, 2026
@GoodforGod GoodforGod changed the title feat(json): allow @JsonWriter on enum instance method and property getter Added @JsonWriter on enum instance method and property getter Jul 14, 2026
@GoodforGod GoodforGod added this to the v1.2.19 milestone Jul 18, 2026
@GoodforGod GoodforGod removed this from the v1.2.19 milestone Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

module: json Related to JSON module new feature New feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants