Kotlin-OverloadableSetters
1.0.0indexedEnables multiple setters for properties, resolved by argument type and invoked via standard property assignment; ideal for builders/DSLs, with inheritance-aware resolution and IDE diagnostics.
Enables multiple setters for properties, resolved by argument type and invoked via standard property assignment; ideal for builders/DSLs, with inheritance-aware resolution and IDE diagnostics.
Give properties multiple setters! Define multiple ways to set a field, and invoke them with standard property syntax!
Overloaded setters will be resolved like standard property setters:
// MyClass.kt
class MyClass {
// On an annotated property:
@HasCustomSetters
var foo: () -> String = { "" }
// Both in-class methods...
fun `set-foo`(value: String) {
foo = { value }
}
}
// ...and extension methods...
fun MyClass.`set-foo`(value: Int) {
foo = value.toString() // delegates to the above `set-foo`
}
// ...can be invoked with standard property syntax:
fun main() {
val inst = MyClass()
// vanilla property set
inst.foo = { "a deferred string" }
assert(inst.foo() == "a deferred string")
// invokes in-class method `MyClass#set-foo(String)`
inst.foo = "a string literal"
assert(inst.foo() == "a string literal")
// invokes extension method `MyClass.set-foo(Int)`
inst.foo = 0
assert(inst.foo() == "0")
}
This is primarily useful for builders and DSLs:
myBuilder {
defaultValue = "a literal string"
defaultValue = 0
defaultValue = { someExpensiveComputation() }
}
Setters for an inherited property may also be resolved on subclasses, as long as the property is annotated either on the type or above it on the inheritance hierarchy.
This isn't unique to setters, and is a consideration when creating any method.
Add the following to your plugins block:
plugins {
id("io.github.cbrandt77.kt.overloadablesetters")
}
To get hints directly in IntelliJ IDEA, including linking to custom setters, validating signatures, and more:
idea.is.internal=truekotlin.k2.only.bundled.compiler.plugins.enabled entry to .Note that diagnostics do not work on IDEA 2025.2 due to a compiler bug fixed in 2025.3.
interface Parent {
var parentProperty: String
}
class Child1 : Parent {
fun `set-parentProperty`(value: Int) {
parentProperty = value.toString()
}
}
class Child2 : Parent {
fun `set-parentProperty`(value: Int) {
throw IllegalArgumentException("No Ints Allowed")
}
}
Child1().parentProperty = 2 // Calls `Child1#set-parentProperty`
Child2().parentProperty = 2 // Calls `Child2#set-parentProperty`
interface UnannotedParent {
var unannotatedProperty: String
}
class Child : UnannotatedParent {
override var unannotatedProperty: String = ""
}
fun Child.`set-unannotatedProperty`(value: Int) {
this.unannotatedProperty = value.toString()
}
Child().unannotatedProperty = 2 // Works
(Child() as Parent).unannotatedProperty = 2 // ERROR: Not annotated
falseSurfaced from shared tags and platforms — no rankings paid for.