Choose Java field during overload resolution with a pure Kotlin property

^KT-31244 Fixed
This commit is contained in:
Denis Zharkov
2019-12-17 17:58:49 +03:00
parent aa8578b675
commit e8131d6e30
20 changed files with 326 additions and 3 deletions
@@ -12775,6 +12775,21 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/properties"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@TestMetadata("fieldPropertyOverloads.kt")
public void testFieldPropertyOverloads() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/fieldPropertyOverloads.kt");
}
@TestMetadata("fieldPropertyOverloadsDisabled.kt")
public void testFieldPropertyOverloadsDisabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/fieldPropertyOverloadsDisabled.kt");
}
@TestMetadata("fieldPropertyOverloadsNI.kt")
public void testFieldPropertyOverloadsNI() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/fieldPropertyOverloadsNI.kt");
}
@TestMetadata("interface.kt")
public void testInterface() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/interface.kt");
@@ -12785,6 +12800,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/j+k/properties/isName.kt");
}
@TestMetadata("staticFieldPropertyOverloads.kt")
public void testStaticFieldPropertyOverloads() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/staticFieldPropertyOverloads.kt");
}
@TestMetadata("val.kt")
public void testVal() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/val.kt");
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2019 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.resolve.jvm
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
import org.jetbrains.kotlin.resolve.DescriptorEquivalenceForOverrides
import org.jetbrains.kotlin.resolve.calls.results.PlatformOverloadsSpecificityComparator
class JvmPlatformOverloadsSpecificityComparator(
val languageVersionSettings: LanguageVersionSettings
) : PlatformOverloadsSpecificityComparator {
override fun isMoreSpecificShape(specific: CallableDescriptor, general: CallableDescriptor): Boolean {
if (specific !is PropertyDescriptor || general !is PropertyDescriptor) return false
if (specific.dispatchReceiverParameter == null || general.dispatchReceiverParameter == null) return false
if (specific.containingDeclaration !is ClassDescriptor) return false
if (!DescriptorEquivalenceForOverrides
.areEquivalent(specific.containingDeclaration, general.containingDeclaration, allowCopiesFromTheSameDeclaration = true)
) return false
if (!languageVersionSettings.supportsFeature(LanguageFeature.PreferJavaFieldOverload)) return false
return specific.isJavaField && !general.isJavaField
}
}
@@ -102,6 +102,7 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
container.useImpl<JvmModuleAccessibilityChecker>()
container.useImpl<JvmModuleAccessibilityChecker.ClassifierUsage>()
container.useImpl<JvmTypeSpecificityComparator>()
container.useImpl<JvmPlatformOverloadsSpecificityComparator>()
container.useImpl<JvmDefaultSuperCallChecker>()
container.useImpl<JvmSamConversionTransformer>()
container.useInstance(FunctionWithBigAritySupport.LanguageVersionDependent)
@@ -54,11 +54,13 @@ fun <RC : ResolvedCall<*>> RC.createFlatSignature(): FlatSignature<RC> {
fun createOverloadingConflictResolver(
builtIns: KotlinBuiltIns,
module: ModuleDescriptor,
specificityComparator: TypeSpecificityComparator
specificityComparator: TypeSpecificityComparator,
platformOverloadsSpecificityComparator: PlatformOverloadsSpecificityComparator
) = OverloadingConflictResolver(
builtIns,
module,
specificityComparator,
platformOverloadsSpecificityComparator,
MutableResolvedCall<*>::getResultingDescriptor,
ConstraintSystemBuilderImpl.Companion::forSpecificity,
MutableResolvedCall<*>::createFlatSignature,
@@ -41,10 +41,11 @@ public class ResolutionResultsHandler {
public ResolutionResultsHandler(
@NotNull KotlinBuiltIns builtIns,
@NotNull ModuleDescriptor module,
@NotNull TypeSpecificityComparator specificityComparator
@NotNull TypeSpecificityComparator specificityComparator,
@NotNull PlatformOverloadsSpecificityComparator platformOverloadsSpecificityComparator
) {
overloadingConflictResolver = FlatSignatureForResolvedCallKt.createOverloadingConflictResolver(
builtIns, module, specificityComparator
builtIns, module, specificityComparator, platformOverloadsSpecificityComparator
);
}
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstituto
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.results.FlatSignature
import org.jetbrains.kotlin.resolve.calls.results.OverloadingConflictResolver
import org.jetbrains.kotlin.resolve.calls.results.PlatformOverloadsSpecificityComparator
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.resolve.calls.tower.TowerResolver
@@ -36,12 +37,14 @@ class CallableReferenceOverloadConflictResolver(
builtIns: KotlinBuiltIns,
module: ModuleDescriptor,
specificityComparator: TypeSpecificityComparator,
platformOverloadsSpecificityComparator: PlatformOverloadsSpecificityComparator,
statelessCallbacks: KotlinResolutionStatelessCallbacks,
constraintInjector: ConstraintInjector
) : OverloadingConflictResolver<CallableReferenceCandidate>(
builtIns,
module,
specificityComparator,
platformOverloadsSpecificityComparator,
{ it.candidate },
{ statelessCallbacks.createConstraintSystemForOverloadResolution(constraintInjector, builtIns) },
Companion::createFlatSignature,
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallArgument
import org.jetbrains.kotlin.resolve.calls.results.FlatSignature
import org.jetbrains.kotlin.resolve.calls.results.OverloadingConflictResolver
import org.jetbrains.kotlin.resolve.calls.results.PlatformOverloadsSpecificityComparator
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
@@ -32,12 +33,14 @@ class NewOverloadingConflictResolver(
builtIns: KotlinBuiltIns,
module: ModuleDescriptor,
specificityComparator: TypeSpecificityComparator,
platformOverloadsSpecificityComparator: PlatformOverloadsSpecificityComparator,
statelessCallbacks: KotlinResolutionStatelessCallbacks,
constraintInjector: ConstraintInjector
) : OverloadingConflictResolver<KotlinResolutionCandidate>(
builtIns,
module,
specificityComparator,
platformOverloadsSpecificityComparator,
{
// todo investigate
it.resolvedCall.candidateDescriptor
@@ -37,6 +37,7 @@ open class OverloadingConflictResolver<C : Any>(
private val builtIns: KotlinBuiltIns,
private val module: ModuleDescriptor,
private val specificityComparator: TypeSpecificityComparator,
private val platformOverloadsSpecificityComparator: PlatformOverloadsSpecificityComparator,
private val getResultingDescriptor: (C) -> CallableDescriptor,
private val createEmptyConstraintSystem: () -> SimpleConstraintSystem,
private val createFlatSignature: (C) -> FlatSignature<C>,
@@ -364,6 +365,10 @@ open class OverloadingConflictResolver<C : Any>(
return false
}
if (platformOverloadsSpecificityComparator.isMoreSpecificShape(call2.candidateDescriptor(), call1.candidateDescriptor())) {
return false
}
return true
}
@@ -411,6 +416,10 @@ open class OverloadingConflictResolver<C : Any>(
if (f.isExpect && !g.isExpect) return false
}
if (platformOverloadsSpecificityComparator.isMoreSpecificShape(g, f)) {
return false
}
return true
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2019 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.resolve.calls.results
import org.jetbrains.kotlin.container.DefaultImplementation
import org.jetbrains.kotlin.descriptors.CallableDescriptor
@DefaultImplementation(impl = PlatformOverloadsSpecificityComparator.None::class)
interface PlatformOverloadsSpecificityComparator {
fun isMoreSpecificShape(specific: CallableDescriptor, general: CallableDescriptor): Boolean
object None : PlatformOverloadsSpecificityComparator {
override fun isMoreSpecificShape(specific: CallableDescriptor, general: CallableDescriptor) = false
}
}
@@ -0,0 +1,27 @@
// 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.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() }
c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
CompressionType.ZIP::name checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() }
c::size checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() }
}
@@ -0,0 +1,27 @@
// 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.name checkType { _<Double>() }
c.size checkType { _<String>() }
CompressionType.ZIP::name checkType { _<kotlin.reflect.KProperty0<Double>>() }
c::size checkType { _<kotlin.reflect.KProperty0<String>>() }
}
@@ -0,0 +1,26 @@
// SKIP_TXT
// !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.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() }
c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
CompressionType.ZIP::name checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() }
c::size checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() }
}
@@ -0,0 +1,26 @@
// SKIP_TXT
// !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<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() }
c.<!OVERLOAD_RESOLUTION_AMBIGUITY!>size<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
CompressionType.ZIP::<!OVERLOAD_RESOLUTION_AMBIGUITY!>name<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() }
c::<!OVERLOAD_RESOLUTION_AMBIGUITY!>size<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() }
}
@@ -0,0 +1,27 @@
// 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.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() }
c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
CompressionType.ZIP::name checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() }
c::size checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() }
}
@@ -0,0 +1,27 @@
// 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.name checkType { _<Double>() }
c.size checkType { _<String>() }
CompressionType.ZIP::name checkType { _<kotlin.reflect.KProperty0<Double>>() }
c::size checkType { _<kotlin.reflect.KProperty0<String>>() }
}
@@ -0,0 +1,16 @@
// SKIP_TXT
// !LANGUAGE: +PreferJavaFieldOverload
// FILE: a/JClass.java
package a;
public class JClass {
public static int foo = 42;
}
// FILE: a.kt
package b
val foo = 42
// FILE: b.kt
import a.JClass.foo
import b.foo
fun test() { <!AMBIGUITY!>foo<!> }
@@ -0,0 +1,16 @@
// SKIP_TXT
// !LANGUAGE: +PreferJavaFieldOverload
// FILE: a/JClass.java
package a;
public class JClass {
public static int foo = 42;
}
// FILE: a.kt
package b
val foo = 42
// FILE: b.kt
import a.JClass.foo
import b.foo
fun test() { <!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!> }
@@ -12782,6 +12782,21 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/properties"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@TestMetadata("fieldPropertyOverloads.kt")
public void testFieldPropertyOverloads() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/fieldPropertyOverloads.kt");
}
@TestMetadata("fieldPropertyOverloadsDisabled.kt")
public void testFieldPropertyOverloadsDisabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/fieldPropertyOverloadsDisabled.kt");
}
@TestMetadata("fieldPropertyOverloadsNI.kt")
public void testFieldPropertyOverloadsNI() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/fieldPropertyOverloadsNI.kt");
}
@TestMetadata("interface.kt")
public void testInterface() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/interface.kt");
@@ -12792,6 +12807,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/j+k/properties/isName.kt");
}
@TestMetadata("staticFieldPropertyOverloads.kt")
public void testStaticFieldPropertyOverloads() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/staticFieldPropertyOverloads.kt");
}
@TestMetadata("val.kt")
public void testVal() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/val.kt");
@@ -12777,6 +12777,21 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/properties"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@TestMetadata("fieldPropertyOverloads.kt")
public void testFieldPropertyOverloads() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/fieldPropertyOverloads.kt");
}
@TestMetadata("fieldPropertyOverloadsDisabled.kt")
public void testFieldPropertyOverloadsDisabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/fieldPropertyOverloadsDisabled.kt");
}
@TestMetadata("fieldPropertyOverloadsNI.kt")
public void testFieldPropertyOverloadsNI() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/fieldPropertyOverloadsNI.kt");
}
@TestMetadata("interface.kt")
public void testInterface() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/interface.kt");
@@ -12787,6 +12802,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/j+k/properties/isName.kt");
}
@TestMetadata("staticFieldPropertyOverloads.kt")
public void testStaticFieldPropertyOverloads() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/staticFieldPropertyOverloads.kt");
}
@TestMetadata("val.kt")
public void testVal() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/properties/val.kt");
@@ -120,6 +120,7 @@ enum class LanguageFeature(
AllowAssigningArrayElementsToVarargsInNamedFormForFunctions(KOTLIN_1_4),
AllowNullOperatorsForResult(KOTLIN_1_4),
AllowResultInReturnType(KOTLIN_1_4),
PreferJavaFieldOverload(KOTLIN_1_4),
ProperVisibilityForCompanionObjectInstanceField(sinceVersion = null, kind = BUG_FIX),
// Temporarily disabled, see KT-27084/KT-22379