From 6372c01e49c5ebfca02d3443c17a54c6e0793045 Mon Sep 17 00:00:00 2001 From: Alexander Podkhalyuzin Date: Tue, 28 Apr 2020 17:17:31 +0300 Subject: [PATCH] Added missing specificity comparator to FIR This is required to correctly resolve overloading in cases when we need to find most specific alternative in Java between int and Integer. --- .../j+k/FlexiblePrimitiveOverloading.kt | 6 + .../j+k/FlexiblePrimitiveOverloading.txt | 4 + ...FirDiagnosticsWithStdlibTestGenerated.java | 5 + compiler/fir/jvm/build.gradle.kts | 1 + .../jvm/JvmCallConflictResolverFactory.kt | 12 +- .../kotlin/fir/types/ConeTypeContext.kt | 5 +- .../jvm/JvmTypeSpecificityComparator.kt | 8 +- .../jvm/platform/JvmPlatformConfigurator.kt | 2 +- .../j+k/primitiveOverrides/kt11140.fir.kt | 24 ---- .../tests/j+k/primitiveOverrides/kt11140.kt | 1 + .../primitiveOverrides/specializedMap.fir.kt | 113 ------------------ .../j+k/primitiveOverrides/specializedMap.kt | 1 + .../intVsIntegerAmbiguity.fir.kt | 37 ------ .../platformTypes/intVsIntegerAmbiguity.kt | 1 + 14 files changed, 39 insertions(+), 181 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.kt create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.txt delete mode 100644 compiler/testData/diagnostics/tests/j+k/primitiveOverrides/kt11140.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/j+k/primitiveOverrides/specializedMap.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/platformTypes/intVsIntegerAmbiguity.fir.kt diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.kt new file mode 100644 index 00000000000..6e2900790fd --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.kt @@ -0,0 +1,6 @@ +// FULL_JDK +import java.lang.Integer.getInteger + +fun foo() { + getInteger("text", 239) +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.txt new file mode 100644 index 00000000000..c7939573405 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.txt @@ -0,0 +1,4 @@ +FILE: FlexiblePrimitiveOverloading.kt + public final fun foo(): R|kotlin/Unit| { + R|java/lang/Integer.getInteger|(String(text), Int(239)) + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index 126ad49f60c..33b4f17a1ac 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -725,6 +725,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FieldSubstitution.kt"); } + @TestMetadata("FlexiblePrimitiveOverloading.kt") + public void testFlexiblePrimitiveOverloading() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.kt"); + } + @TestMetadata("flexibleTypeAliases.kt") public void testFlexibleTypeAliases() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/flexibleTypeAliases.kt"); diff --git a/compiler/fir/jvm/build.gradle.kts b/compiler/fir/jvm/build.gradle.kts index b097fe409a2..b44f2f63121 100644 --- a/compiler/fir/jvm/build.gradle.kts +++ b/compiler/fir/jvm/build.gradle.kts @@ -8,6 +8,7 @@ dependencies { implementation(project(":compiler:fir:cones")) implementation(project(":compiler:fir:tree")) implementation(project(":compiler:fir:resolve")) + implementation(project(":compiler:frontend.java")) } diff --git a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/calls/jvm/JvmCallConflictResolverFactory.kt b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/calls/jvm/JvmCallConflictResolverFactory.kt index 4590995f92e..bc249bde07c 100644 --- a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/calls/jvm/JvmCallConflictResolverFactory.kt +++ b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/calls/jvm/JvmCallConflictResolverFactory.kt @@ -10,14 +10,18 @@ import org.jetbrains.kotlin.fir.resolve.calls.ConeCompositeConflictResolver import org.jetbrains.kotlin.fir.resolve.calls.ConeOverloadConflictResolver import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator +import org.jetbrains.kotlin.resolve.jvm.JvmTypeSpecificityComparator object JvmCallConflictResolverFactory : ConeCallConflictResolverFactory() { override fun create( typeSpecificityComparator: TypeSpecificityComparator, components: InferenceComponents - ) = ConeCompositeConflictResolver( - ConeOverloadConflictResolver(TypeSpecificityComparator.NONE, components), - ConeEquivalentCallConflictResolver(TypeSpecificityComparator.NONE, components) - ) + ): ConeCompositeConflictResolver { + val specificityComparator = JvmTypeSpecificityComparator(components.ctx) + return ConeCompositeConflictResolver( + ConeOverloadConflictResolver(specificityComparator, components), + ConeEquivalentCallConflictResolver(specificityComparator, components) + ) + } } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index ec764b0a972..59b3cdcafd9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -379,7 +379,10 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } override fun SimpleTypeMarker.isPrimitiveType(): Boolean { - return false //TODO + if (this is ConeClassLikeType) { + return StandardClassIds.primitiveTypes.contains(this.lookupTag.classId) + } + return false } override fun SimpleTypeMarker.isStubType(): Boolean { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmTypeSpecificityComparator.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmTypeSpecificityComparator.kt index 3c5e357df2b..2c79bae5161 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmTypeSpecificityComparator.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmTypeSpecificityComparator.kt @@ -18,9 +18,15 @@ package org.jetbrains.kotlin.resolve.jvm import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.types.model.KotlinTypeMarker +import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContextDelegate -class JvmTypeSpecificityComparator(val context: TypeSystemInferenceExtensionContextDelegate) : TypeSpecificityComparator { +/** + * We should use delegate context for DI in old frontend. For the FIR we don't have context delegate, so we should use parent class. + */ +class JvmTypeSpecificityComparatorDelegate(override val context: TypeSystemInferenceExtensionContextDelegate) : JvmTypeSpecificityComparator(context) + +open class JvmTypeSpecificityComparator(open val context: TypeSystemInferenceExtensionContext) : TypeSpecificityComparator { override fun isDefinitelyLessSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean = with(context) { val simpleGeneral = general.asSimpleType() diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt index 78e8fcf4475..025c8792cda 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt @@ -102,7 +102,7 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase( container.useImpl() container.useImpl() container.useImpl() - container.useImpl() + container.useImpl() container.useImpl() container.useImpl() container.useImpl() diff --git a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/kt11140.fir.kt b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/kt11140.fir.kt deleted file mode 100644 index 8adec367303..00000000000 --- a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/kt11140.fir.kt +++ /dev/null @@ -1,24 +0,0 @@ -// JAVAC_EXPECTED_FILE -// FILE: B.java -public interface B { - double put(int x, double y); - T2 put(T1 x, T2 y); -} -// FILE: A.java -import java.util.HashMap; - -public class A extends HashMap implements B { - public double put(int x, double y) { - return 1.0; - } - - @Override - public Double put(Integer key, Double value) { - return super.put(key, value); - } -} -// FILE: main.kt -fun test(){ - val o = A() - o.put(1, 2.0) -} diff --git a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/kt11140.kt b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/kt11140.kt index 748414ef3b5..19c038e7bea 100644 --- a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/kt11140.kt +++ b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/kt11140.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // JAVAC_EXPECTED_FILE // FILE: B.java public interface B { diff --git a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/specializedMap.fir.kt b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/specializedMap.fir.kt deleted file mode 100644 index bf6ee149928..00000000000 --- a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/specializedMap.fir.kt +++ /dev/null @@ -1,113 +0,0 @@ -// FILE: AbstractSpecializedMap.java -public abstract class AbstractSpecializedMap implements java.util.Map { - public abstract double put(int x, double y); - public abstract double remove(int k); - public abstract double get(int k); - - public abstract boolean containsKey(int k); - public boolean containsKey(Object x) { - return false; - } - - public abstract boolean containsValue(double v); - public boolean containsValue(Object x) { - return false; - } -} - -// FILE: SpecializedMap.java -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -public class SpecializedMap extends AbstractSpecializedMap { - public double put(int x, double y) { - return 123.0; - } - - @Override - public Double get(Object key) { - return null; - } - - @Override - public Double put(Integer key, Double value) { - return null; - } - - public double remove(int k) { - return 456.0; - } - - - public Double remove(Object ok) { - return null; - } - - - public double get(int k) { - return 789.0; - } - - public boolean containsKey(int k) { - return true; - } - - public boolean containsValue(double v) { - return true; - } - - @Override - public void putAll(Map m) { - } - - @Override - public void clear() { - - } - - @NotNull - @Override - public Set keySet() { - return null; - } - - @NotNull - @Override - public Collection values() { - return null; - } - - @NotNull - @Override - public Set> entrySet() { - return null; - } - - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return false; - } -} - -// FILE: main.kt -fun foo(x: SpecializedMap) { - x.containsKey(1) - x.containsKey(null) - - x.get(2) - x.get(null) - - x.remove(3) - x.remove(null) - - x.put(4, 5.0) - x.put(4, null) -} diff --git a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/specializedMap.kt b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/specializedMap.kt index 1aaaa82660d..f26f5d83449 100644 --- a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/specializedMap.kt +++ b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/specializedMap.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: AbstractSpecializedMap.java public abstract class AbstractSpecializedMap implements java.util.Map { public abstract double put(int x, double y); diff --git a/compiler/testData/diagnostics/tests/platformTypes/intVsIntegerAmbiguity.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/intVsIntegerAmbiguity.fir.kt deleted file mode 100644 index 3eb86c36c4b..00000000000 --- a/compiler/testData/diagnostics/tests/platformTypes/intVsIntegerAmbiguity.fir.kt +++ /dev/null @@ -1,37 +0,0 @@ -// !CHECK_TYPE -// !DIAGNOSTICS: -UNUSED_PARAMETER -// FILE: p/J.java - -package p; - -public class J { - public interface A {} - public static A foo(int s); - - public interface B {} - public static B foo(Integer s); - - public static Integer getInteger(); -} - -// FILE: k.kt - -import p.* -import p.J.* - -class C - -fun foo(i: Int?) : C = null!! - -fun test(i: Int, ni: Int?) { - checkSubtype(foo(2)) - checkSubtype(J.foo(2)) - checkSubtype(J.foo(i)) - checkSubtype(J.foo(ni)) - checkSubtype(foo(ni)) - checkSubtype(J.foo(ni)) - - foo(J.getInteger()) - J.foo(J.getInteger()) -} - diff --git a/compiler/testData/diagnostics/tests/platformTypes/intVsIntegerAmbiguity.kt b/compiler/testData/diagnostics/tests/platformTypes/intVsIntegerAmbiguity.kt index 0cd1e4e50b4..a18ead33ba3 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/intVsIntegerAmbiguity.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/intVsIntegerAmbiguity.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !CHECK_TYPE // !DIAGNOSTICS: -UNUSED_PARAMETER // FILE: p/J.java