Kotlin creates a synthetic method that exposes a private setter from superclass

Here is a base class from package1:

abstract class BaseClass<T : ViewModel> {
    protected lateinit var model: T
        private set

    protected abstract fun onModelProvided()
}

Subclass is in the another package:

class SubClass(private val lifecycleOwner: LifecycleOwner)
    : BaseClass<CustodyTabViewModel>() {

    override fun onModelProvided() {
        model.updates.observe(lifecycleOwner, NonNullObserver {
            model.subscribe()
        })
    }
}

The setter for model is private in BaseClass and therefore can be accessed from neither point of SubClass. However when these classes are compiled Kotlin compiler inserts synthetic getter and setter for model in SubClass:

public final class SubClass extends BaseClass {
   // $FF: synthetic method
   @NotNull
   public static final CustodyTabViewModel access$getModel$p(SubClass $this) {
      return (CustodyTabViewModel)$this.getModel();
   }

   // $FF: synthetic method
   public static final void access$setModel$p(SubClass $this, @NotNull CustodyTabViewModel var1) {
      $this.setModel(var1);
   }
}

Then when these classes are processed with Proguard:

Warning: package2.SubClass: can't find referenced method 'void setModel(android.arch.lifecycle.ViewModel)' in program class package2.SubClass

Warning: there were 1 unresolved references to program class members.
         Your input classes appear to be inconsistent.
         You may need to recompile the code.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)

Looks like a bug and synthetic setter was created by mistake.

Yes, it’s a bug. https://youtrack.jetbrains.com/issue/KT-22624

1 Like