From 296ee2da4a2460eca49da4565296aeca9d8a2f2c Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 26 Feb 2020 12:45:26 +0300 Subject: [PATCH] [FIR] Support `@LowPriorityInOverloadResolution` annotation --- .../kotlin/fir/resolve/calls/CallKind.kt | 6 +++-- .../kotlin/fir/resolve/calls/Candidate.kt | 1 + .../kotlin/fir/resolve/calls/ResolverParts.kt | 23 +++++++++++++++++++ .../lowPriorityInResolution.kt | 10 ++++++++ .../lowPriorityInResolution.txt | 11 +++++++++ ...FirDiagnosticsWithStdlibTestGenerated.java | 5 ++++ .../resolveWithLowPriorityAnnotation.kt | 1 - .../noInferAndLowPriority.fir.kt | 4 ++-- .../onlyInputTypesAndLowPriority.fir.kt | 4 ++-- 9 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.kt create mode 100644 compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.txt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt index 574ae5e7b7c..8a8f360efc6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt @@ -12,7 +12,8 @@ enum class CallKind(vararg resolutionSequence: ResolutionStage) { CheckExplicitReceiverConsistency, CreateFreshTypeVariableSubstitutorStage, CheckReceivers.Dispatch, - CheckReceivers.Extension + CheckReceivers.Extension, + CheckLowPriorityInOverloadResolution ), SyntheticSelect( MapArguments, @@ -29,7 +30,8 @@ enum class CallKind(vararg resolutionSequence: ResolutionStage) { CheckReceivers.Dispatch, CheckReceivers.Extension, CheckArguments, - EagerResolveOfCallableReferences + EagerResolveOfCallableReferences, + CheckLowPriorityInOverloadResolution ), CallableReference( CheckVisibility, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt index 750f787f2a7..94dabe54af0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt @@ -71,6 +71,7 @@ enum class CandidateApplicability { PARAMETER_MAPPING_ERROR, INAPPLICABLE, SYNTHETIC_RESOLVED, + RESOLVED_LOW_PRIORITY, RESOLVED } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt index dc0221a80f7..ed4313ac7ea 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirExpression @@ -26,6 +27,7 @@ import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind @@ -472,3 +474,24 @@ internal object CheckVisibility : CheckerStage() { } } } + +internal object CheckLowPriorityInOverloadResolution : CheckerStage() { + private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID: ClassId = + ClassId(FqName("kotlin.internal"), Name.identifier("LowPriorityInOverloadResolution")) + + override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) { + val annotations = when (val fir = candidate.symbol.fir) { + is FirSimpleFunction -> fir.annotations + is FirProperty -> fir.annotations + else -> return + } + val hasLowPriorityAnnotation = annotations.any { + val lookupTag = ((it.annotationTypeRef as? FirResolvedTypeRef)?.type as? ConeClassLikeType)?.lookupTag ?: return@any false + lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID + } + + if (hasLowPriorityAnnotation) { + sink.reportApplicability(CandidateApplicability.RESOLVED_LOW_PRIORITY) + } + } +} diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.kt b/compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.kt new file mode 100644 index 00000000000..4dfed7822c1 --- /dev/null +++ b/compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.kt @@ -0,0 +1,10 @@ +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.LowPriorityInOverloadResolution +fun foo(): Int = 1 + +fun foo(): String = "" + +fun test() { + val s = foo() + s.length +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.txt b/compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.txt new file mode 100644 index 00000000000..1bb403859d9 --- /dev/null +++ b/compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.txt @@ -0,0 +1,11 @@ +FILE: lowPriorityInResolution.kt + @R|kotlin/Suppress|(String(INVISIBLE_MEMBER), String(INVISIBLE_REFERENCE)) @R|kotlin/internal/LowPriorityInOverloadResolution|() public final fun foo(): R|kotlin/Int| { + ^foo Int(1) + } + public final fun foo(): R|kotlin/String| { + ^foo String() + } + public final fun test(): R|kotlin/Unit| { + lval s: R|kotlin/String| = R|/foo|() + R|/s|.R|kotlin/String.length| + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index 18a24d58cf7..518bd30fd05 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -163,6 +163,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/resolve/testData/resolveWithStdlib/listPlusAssign.kt"); } + @TestMetadata("lowPriorityInResolution.kt") + public void testLowPriorityInResolution() throws Exception { + runTest("compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.kt"); + } + @TestMetadata("mapList.kt") public void testMapList() throws Exception { runTest("compiler/fir/resolve/testData/resolveWithStdlib/mapList.kt"); diff --git a/compiler/testData/codegen/box/annotations/resolveWithLowPriorityAnnotation.kt b/compiler/testData/codegen/box/annotations/resolveWithLowPriorityAnnotation.kt index 2e61654518f..9b51c9fdb51 100644 --- a/compiler/testData/codegen/box/annotations/resolveWithLowPriorityAnnotation.kt +++ b/compiler/testData/codegen/box/annotations/resolveWithLowPriorityAnnotation.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.fir.kt index 157865a7ac9..9bd466ea712 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/noInferAndLowPriority.fir.kt @@ -11,6 +11,6 @@ public fun Iterable.contains1(element: @kotlin.internal.NoInfer T): Boole fun test() { - val a: Boolean = listOf(1).contains1("") - val b: Boolean = listOf(1).contains1(1) + val a: Boolean = listOf(1).contains1("") + val b: Boolean = listOf(1).contains1(1) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.fir.kt index 9b85571175e..aa469919288 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/onlyInputTypesAndLowPriority.fir.kt @@ -19,8 +19,8 @@ public fun Map.get1(key: Any?): Int = null!! public fun <@kotlin.internal.OnlyInputTypes K, V> Map.get1(key: K): V? = null!! fun test(map: Map) { - val a: Int = listOf(1).contains1("") - val b: Boolean = listOf(1).contains1(1) + val a: Int = listOf(1).contains1("") + val b: Boolean = listOf(1).contains1(1) val c: String? = map.get1("") val d: String? = map.get1(1)