FIR: introduce JvmPlatformOverloadsConflictResolver

The added here JvmPlatformOverloadsConflictResolver prefers Java field
to property in case of conflicts.
This commit is contained in:
Mikhail Glukhikh
2021-04-02 12:29:59 +03:00
parent 9b3c154bef
commit caeb0b43be
9 changed files with 53 additions and 77 deletions
@@ -22,7 +22,8 @@ object JvmCallConflictResolverFactory : ConeCallConflictResolverFactory() {
val specificityComparator = JvmTypeSpecificityComparator(components.ctx)
return ConeCompositeConflictResolver(
ConeOverloadConflictResolver(specificityComparator, components),
ConeEquivalentCallConflictResolver(specificityComparator, components)
ConeEquivalentCallConflictResolver(specificityComparator, components),
JvmPlatformOverloadsConflictResolver(specificityComparator, components)
)
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.resolve.calls.jvm
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.FirField
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.calls.AbstractConeCallConflictResolver
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
class JvmPlatformOverloadsConflictResolver(
specificityComparator: TypeSpecificityComparator,
inferenceComponents: InferenceComponents
) : AbstractConeCallConflictResolver(specificityComparator, inferenceComponents) {
override fun chooseMaximallySpecificCandidates(
candidates: Set<Candidate>,
discriminateGenerics: Boolean,
discriminateAbstracts: Boolean
): Set<Candidate> {
if (!inferenceComponents.session.languageVersionSettings.supportsFeature(LanguageFeature.PreferJavaFieldOverload)) {
return candidates
}
val result = mutableSetOf<Candidate>()
outerLoop@ for (myCandidate in candidates) {
val me = myCandidate.symbol.fir
if (me is FirProperty && me.symbol.containingClass() != null) {
for (otherCandidate in candidates) {
val other = otherCandidate.symbol.fir
if (other is FirField && other.symbol.containingClass() != null) {
// NB: FE 1.0 does class equivalence check here
// However, in FIR container classes aren't the same for our samples (see fieldPropertyOverloads.kt)
// E.g. we can have SomeConcreteJavaEnum for field and kotlin.Enum for static property 'name'
continue@outerLoop
}
}
}
result += myCandidate
}
return result
}
}
@@ -1,5 +1,4 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// FILE: test.kt
@@ -1,21 +0,0 @@
// !LANGUAGE: +PreferJavaFieldOverload
// FILE: B.java
public abstract class B implements A {
public int size = 1;
}
// FILE: main.kt
interface A {
val size: Int
}
class C : B() {
override val size: Int get() = 1
}
fun foo() {
C().<!OVERLOAD_RESOLUTION_AMBIGUITY!>size<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +PreferJavaFieldOverload
// FILE: B.java
@@ -1,27 +0,0 @@
// SKIP_TXT
// !LANGUAGE: +PreferJavaFieldOverload
// !CHECK_TYPE
// FILE: CompressionType.java
public enum CompressionType {
ZIP(1.0);
public final double name;
CompressionType(double name) {
this.name = name;
}
}
// FILE: CollectionWithSize.java
public abstract class CollectionWithSize implements java.util.Collection<String> {
public final String size = "";
}
// FILE: main.kt
fun main(c: CollectionWithSize) {
CompressionType.ZIP.<!OVERLOAD_RESOLUTION_AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Double>() }
c.<!OVERLOAD_RESOLUTION_AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
CompressionType.ZIP::<!UNRESOLVED_REFERENCE!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<Double>>() }
c::<!UNRESOLVED_REFERENCE!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<String>>() }
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// SKIP_TXT
// !LANGUAGE: +PreferJavaFieldOverload
// !CHECK_TYPE
@@ -1,27 +0,0 @@
// SKIP_TXT
// !LANGUAGE: +PreferJavaFieldOverload +NewInference
// !CHECK_TYPE
// FILE: CompressionType.java
public enum CompressionType {
ZIP(1.0);
public final double name;
CompressionType(double name) {
this.name = name;
}
}
// FILE: CollectionWithSize.java
public abstract class CollectionWithSize implements java.util.Collection<String> {
public final String size = "";
}
// FILE: main.kt
fun main(c: CollectionWithSize) {
CompressionType.ZIP.<!OVERLOAD_RESOLUTION_AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Double>() }
c.<!OVERLOAD_RESOLUTION_AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
CompressionType.ZIP::<!UNRESOLVED_REFERENCE!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<Double>>() }
c::<!UNRESOLVED_REFERENCE!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<String>>() }
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// SKIP_TXT
// !LANGUAGE: +PreferJavaFieldOverload +NewInference
// !CHECK_TYPE