Issue with ReplaceWith and this

So I have an issue with deprecating extension function. I think it is easiest to explain it on example so let’s say we have these two extension functions (it’s a stupid example but it serves just to show where the issue is).

@Deprecated("message", ReplaceWith("save(MyClass(this), foo, bar)"))
ClassFromLib.saveOld(foo: String, bar: String)

ClassFromLib.save(myClass: MyClass, foo: String, bar: String)

Where my class is something like this:

class MyClass(param: BaseClass)

So the usage for those extension methods would be:

class CallerClass(val libClass: ClassFormLib): BaseClass {
    fun someFun() {
        libClass.saveOld("foo", "bar")
        
        libClass.save(MyClass(this), "foo", "bar")
    }
}

And when in Android Studio I try to replace call of saveOld function I actually get something like this:

libClass.save(MyClass(libClass), "foo", "bar")

And that is a type mismatch because required is BaseClass but it got ClassFormLib, what I really wanted was that I literally get this not instance on which that extension function is called. I understand that this is expected behaviour and it works as it should - this is detected and it presumes that it reffers to instance of class on which it is called, but I just want literally this to be there. Is that possible in any way?

I have a stupid workaround for that, I wrote deprecation like this:

@Deprecated("message", ReplaceWith("save(MyClass(thi), foo, bar)"))
ClassFromLib.saveOld(foo: String, bar: String)

But that just stupid because than somebody who uses that need to manually add s.

No idea if this is possible. Just out of interest what happens if you don’t have a BaseClass as a reciever, eg.

fun someGenericFunction(libClass: ClassFromLib) {
    libClass.saveOld("foo", "bar")
}

Based on what I see you would want to replace that with

fun someGenericFunction(libClass: ClassFromLib) {
    libClass.save(MyClass(this), "foo", "bar")
}

but there is no this so it would result in a compiler error.
Or did I understand your problem wrong?

1 Like

Sorry I realised that I had one error in original post. But I edited it and fixed that issue. It might be that it confused you. I don’t understand what exactly you mean by “what happens”. In my case those methods are always called inside some class which inherits BaseClass. And in your case, yes I want it to be like you wrote it but actually what I will get is this:

fun someGenericFunction(libClass: ClassFromLib) {
    libClass.save(MyClass(libClass), "foo", "bar")
}

Because deprecation rule will recognize keyword this and it will replace this with the object on which that method is called so in this case libClass. But I wanted it to just put MyClass(this) as first param.