Overload Resolution Ambiguity - kotlin

After upgrading to Kotlin 1.7.0 i start to receive this error:
Overload resolution ambiguity:
public final fun remove(p0:Property!): Boolean defined in
net.fortuna.ical4j.model.PropertyList
public open fun remove(element: Property!): Boolean defined in
net.fortuna.ical4j.model.PropertyList
In this piece of code
if (it.properties.getProperty<DtEnd>("DTEND") != null) {
it.properties.remove(it.properties.getProperty<DtEnd>("DTEND"))
}
How can i disambiguate this?

Related

Local final class <no name provided> issue for throwable: Class<out Throwable> in Kotlin

I have some problems when trying to migrate my java methods to project with kotlin. I have a method with next signature:
public static RetryTemplate getRetryTemplate(long initialInterval, int maxAttempts, Class<? extends Throwable> throwable) { .... }
or in Kotlin:
fun getRetryTemplate(initialInterval: Long, maxAttempts: Int, throwable: Class<out Throwable>): RetryTemplate? {
When I'm trying to call this method in Kotlin code I get a compiler issue - Local final class no name provided (see screenshot)
RetryUtils.getRetryTemplate(5000, 3, Exception.class)
How to fix it?
It is required to use Exception::class.java
why Intellij not recommended this solution?

"None of the following functions can be called with the arguments supplied" - Why?

The code below fails to compile due to the red underlined check
screenshot added for the lambda parameter types, code:
handledExceptions.forEach { exceptionClass ->
exceptionClassToHandler.compute(exceptionClass.java) { clazz, existingHandler ->
check(null == existingHandler) { "There's already a handler registered for ${clazz.name}" }
{ e: Throwable -> handlerMethod.invoke(bean, exceptionClass.java.cast(e)) }
}
}
For which it claims
None of the following functions can be called with the arguments supplied:
[ERROR] public inline fun check(value: Boolean): Unit defined in kotlin
[ERROR] public inline fun check(value: Boolean, lazyMessage: () -> Any): Unit defined in kotlin
Code compiles fine if I comment out the check.
(or replace it with
if(existingHandler != null){
throw IllegalStateException("There's already a handler registered for ${clazz.name}")
}
)
I feel like I'm missing something obvious. Why doesn't the check compile and how do I get it to?

Unexpected behavior of also/apply, cannot pass references of a instance function into also/apply

To sum up the question in a few words, here is the catch:
The also(strings::add) doesn't work, it says Type inference failed
fun test() = "Test String"
val strings = mutableListOf<String>()
// Type inference failed: inline fun <T> T.also(block: (T) -> Unit): T cannot be applied to receiver: String arguments: (<unknown>)
// None of the following functions can be called with the arguments supplied: public abstract fun add(index: Int, element: String): Unit defined in kotlin.collections.MutableList public abstract fun add(element: String): Boolean defined in kotlin.collections.MutableList
test().also(strings::add).let { /* Use the string later */ }
While doing the same with let does work in the same place:
val strings = mutableListOf<String>()
test().let(strings::add).let { println(it) } // prints true, no compile errors.
Here is the minimal reproducable code.
I want to use the string later so don't want to use let here. What should I do? If i try to use the apply the same compile error occur probably because both also and apply have same callback signature of KFunction1<T, T>. How should one pass these type of references with also/apply?
override fun add(element: E): Boolean as you can see, the function returns Boolean, but apply accepts block: T.() -> Unit, i.e. it accepts only functions that receive a single argument and return no value.

why the translated kotlin code complains about a Array<BaseData>? to be a Array<out BaseData>

Having a java class, using androidStudio to translate to kotlin.
Got a error and not sure how to correctly translate it.
The java code:
public class BaseDataImpl extends BaseData {
private final BaseData[] translators;
public BaseDataImpl(final BaseData... translators) {
this.translators = cloneArray(translators);
}
public static <T> T[] cloneArray(final T[] array) {
if (array == null) {
return null;
}
return array.clone();
}
}
after the code translation, got error: required Array<BaseData>?, found Array<out BaseData>, but the translators in the cloneArray<BaseData>(translators) call is defined as val translators: Array<BaseData>?,
anyone could help to explain?
class BaseDataImpl(vararg translators: BaseData) : BaseData() {
private val translators: Array<BaseData>?
init {
this.translators = cloneArray<BaseData>(translators) //<=== error: required Array<BaseData>?, found Array<out BaseData>
}
companion object {
fun <T> cloneArray(array: Array<T>?): Array<T>? {
return array?.clone()
}
}
}
It is written in the Kotlin function reference regarding varargs:
Inside a function a vararg-parameter of type T is visible as an array of T, i.e. the ts variable in the example above has type Array<out T>.
where the referenced function was:
function <T> asList(vararg ts: T): List<T>
So in your case you actually pass an Array<out BaseData> but you only accept an array of type Array<T>? (in your case Array<BaseData>). Either you adapt all of the types to Array<out T> (which basically is similar as saying List<? extends BaseData> in Java) or you take care that you are only dealing with Ts instead, e.g. with:
inline fun <reified T> cloneArray(array: Array<out T>?): Array<T>? {
return array?.clone()?.map { it }?.toTypedArray()
}
But look up the documentation regarding this: Kotlin generics reference - type projections. You probably can accomplish this even easier.

How do I select which Java overload to override in a Kotlin derived class?

I'm trying to implement in Kotlin an MyIntList extending java.util.AbstractList<Int>. AbstractList<E> defines both a E remove(int index) and a boolean remove(Object o). I use the following code:
class IntList() : AbstractList<Int>() {
....
override fun remove(index: Int): Int {
....
}
}
but this gives an error: return type of 'remove' is not a subtype of the return type of the overridden member 'public open fun remove(element: kotlin.Int!): kotlin.Boolean defined in java.util.AbstractList'
override fun remove(index: Int): Int {
How do I tell Kotlin that I'm trying to override E remove(int index)? (And where does it get that remove(Int):Boolean overload from?)
Turns out that very last sentence was the clue. There is some compiler shenanigans going on in that it thinks I'm implementing MutableList<Int>. And MutableList<E> defines a removeAt(element: E): Boolean which silently compiles into a remove method, changing the name. When I override removeAt everything works.