From ded62686a0a7a1ad471f9d9fd9d63f8b110e30bc Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 16 Oct 2015 17:51:27 +0300 Subject: [PATCH] Added 'LowPriorityInOverloadResolution' annotation --- .../kotlin/resolve/calls/tasks/TaskPrioritizer.kt | 10 ++++++++-- .../annotations/resolveWithLowPriorityAnnotation.kt | 7 +++++++ .../BlackBoxWithStdlibCodegenTestGenerated.java | 6 ++++++ .../jetbrains/kotlin/resolve/annotationsForResolve.kt | 5 +++++ libraries/stdlib/src/kotlin/internal/Annotations.kt | 7 +++++++ 5 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/annotations/resolveWithLowPriorityAnnotation.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt index 9a2bad986b1..dba47b8d488 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt @@ -25,9 +25,9 @@ import org.jetbrains.kotlin.psi.Call import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.doNotAnalyze import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getUnaryPlusOrMinusOperatorFunctionName import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized -import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getUnaryPlusOrMinusOperatorFunctionName import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCol import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCollectors import org.jetbrains.kotlin.resolve.calls.tasks.collectors.filtered import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject +import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue @@ -480,7 +481,7 @@ public class TaskPrioritizer( override fun getPriority(candidate: ResolutionCandidate) = if (hasImplicitDynamicReceiver(candidate)) 0 - else (if (isVisible(candidate)) 2 else 0) + (if (isSynthesized(candidate)) 0 else 1) + else (if (!isVisible(candidate) || hasLowPriority(candidate)) 0 else 2) + (if (isSynthesized(candidate)) 0 else 1) override fun getMaxPriority() = 3 @@ -492,6 +493,11 @@ public class TaskPrioritizer( return Visibilities.isVisible(receiverValue, candidateDescriptor, context.scope.ownerDescriptor) } + private fun hasLowPriority(candidate: ResolutionCandidate?): Boolean { + if (candidate == null) return false + return candidate.descriptor.hasLowPriorityInOverloadResolution() + } + private fun isSynthesized(candidate: ResolutionCandidate): Boolean { val descriptor = candidate.getDescriptor() return descriptor is CallableMemberDescriptor && isOrOverridesSynthesized(descriptor) diff --git a/compiler/testData/codegen/boxWithStdlib/annotations/resolveWithLowPriorityAnnotation.kt b/compiler/testData/codegen/boxWithStdlib/annotations/resolveWithLowPriorityAnnotation.kt new file mode 100644 index 00000000000..48fe83401f9 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/annotations/resolveWithLowPriorityAnnotation.kt @@ -0,0 +1,7 @@ +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.LowPriorityInOverloadResolution +fun foo(i: Int) = 1 + +fun foo(a: Any) = 2 + +fun box() = if (foo(1) == 2) "OK" else "fail" \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 8e7c9c02243..a083cd94868 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -130,6 +130,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("resolveWithLowPriorityAnnotation.kt") + public void testResolveWithLowPriorityAnnotation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/annotations/resolveWithLowPriorityAnnotation.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("varargInAnnotationParameter.kt") public void testVarargInAnnotationParameter() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt index 61e4dafccd5..592ae4d0de3 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.resolve.descriptorUtil +import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.name.FqName @@ -28,6 +29,10 @@ private val EXACT_ANNOTATION_FQ_NAME = FqName("kotlin.internal.Exact") public fun Annotated.hasExactAnnotation(): Boolean = annotations.hasAnnotation(EXACT_ANNOTATION_FQ_NAME) +private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME = FqName("kotlin.internal.LowPriorityInOverloadResolution") + +public fun CallableDescriptor.hasLowPriorityInOverloadResolution(): Boolean = annotations.hasAnnotation(LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME) + private val ONLY_INPUT_TYPES_FQ_NAME = FqName("kotlin.internal.OnlyInputTypes") public fun TypeParameterDescriptor.hasOnlyInputTypesAnnotation(): Boolean = annotations.hasAnnotation(ONLY_INPUT_TYPES_FQ_NAME) \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/internal/Annotations.kt b/libraries/stdlib/src/kotlin/internal/Annotations.kt index 5df144a9d53..af662d21c93 100644 --- a/libraries/stdlib/src/kotlin/internal/Annotations.kt +++ b/libraries/stdlib/src/kotlin/internal/Annotations.kt @@ -30,6 +30,13 @@ internal annotation class NoInfer @Retention(AnnotationRetention.SOURCE) internal annotation class Exact +/** + * Specifies that a corresponding member has the lowest priority in overload resolution. + */ +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY) +@Retention(AnnotationRetention.SOURCE) +internal annotation class LowPriorityInOverloadResolution + /** * The value of this type parameter should be mentioned in input types (argument types, receiver type or expected type). */