Skip to content

Extension properties setters does not work as expected #5588

Closed
@ibaklan

Description

@ibaklan

After recently merged extension methods pull request extension properties definition (getters and setters) become available.
Actually it is possible to define extension setter (together with extension getter), but on use-site only extension getter works as expected, attempt to use extension setter leads to compilation error.

Demonstrating examples (extension activation via implicits or via import - same result)
Example 1 (using import)

object TestMain {
  def main(args: Array[String]): Unit = {
    testExtensionProperty()
  }

  case class Foo(var foo: String)

  object fooExt {
    // define `Foo`-extension property with getter and setter delegating to `Foo.foo`
    def (thisFoo: Foo) fooExt: String = thisFoo.foo
    def (thisFoo: Foo) fooExt_= (value: String): Unit = { thisFoo.foo = value }
  }

  def testExtensionProperty(): Unit = {
    import fooExt._
    val foo = Foo("initVal")
    assert(foo.fooExt == "initVal")
    foo.fooExt = "updatedVal"
    assert(foo.foo == "updatedVal")
    assert(foo.fooExt == "updatedVal")
  }
}

Example 2 (using implicits)

object TestMain2 {
  def main(args: Array[String]): Unit = {
    testExtensionProperty()
  }

  case class Foo(var foo: String)

  implicit object fooExt {
    // define `Foo`-extension property with getter and setter delegating to `Foo.foo`
    def (thisFoo: Foo) fooExt: String = thisFoo.foo
    def (thisFoo: Foo) fooExt_= (value: String): Unit = { thisFoo.foo = value }
  }

  def testExtensionProperty(): Unit = {
    //import fooExt._
    val foo = Foo("initVal")
    assert(foo.fooExt == "initVal")
    foo.fooExt = "updatedVal"
    assert(foo.foo == "updatedVal")
    assert(foo.fooExt == "updatedVal")
  }
}

Expected behaviour - code snippets should be compilable, asserts should be passed successfully

Actual behavior - code compilation fails with error

    foo.fooExt = "updatedVal"
    ^^^^^^^^^^^^^^^^^^^^^^^^^
    reassignment to val `fooExt`

FYI
Kotlin extension properties works as expected (with both getters and setters):
Same (working) example in Kotlin may look like this:

object TestMain {

    @JvmStatic
    fun main(arg: Array<String>) {
        testExtensionProperty()
    }

    data class Foo(var foo: String)

    var Foo.fooExt : String
        get() = foo
        set(value: String) { foo = value }

    fun testExtensionProperty() {
        val foo = Foo("initVal")
        assert(foo.fooExt == "initVal")
        foo.fooExt = "updatedVal"
        assert(foo.foo == "updatedVal")
        assert(foo.fooExt == "updatedVal")
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions