Allow expect/actual annotation constructors to have default values

When a parameter has a default argument value both in the expected
annotation and in the actual annotation, they must be equal. This check
has been only implemented for the case when actual annotation is Kotlin
source code, and NOT a Java class coming from an actual typealias. The
latter case would require a bit more work in passing a platform-specific
annotation-value-reading component to ExpectedActualDeclarationChecker,
and is therefore postponed.

For now, Java annotations that are visible through actual type aliases
cannot have default argument values for parameters which already have
default values in the expected annotation declaration

 #KT-22703 Fixed
 #KT-22704 Open
This commit is contained in:
Alexander Udalov
2018-01-31 17:29:52 +01:00
parent 71fe8c02a3
commit 9e500831dd
24 changed files with 790 additions and 48 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.model.CollectionLiteralKotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor
import org.jetbrains.kotlin.resolve.descriptorUtil.isParameterOfAnnotation
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
@@ -70,7 +70,7 @@ object ExpectedActualResolver {
is CallableMemberDescriptor -> {
val container = actual.containingDeclaration
val candidates = when (container) {
is ClassDescriptor -> {
is ClassifierDescriptorWithTypeParameters -> {
// TODO: replace with 'singleOrNull' as soon as multi-module diagnostic tests are refactored
val expectedClass =
findExpectedForActual(container, commonModule)?.values?.firstOrNull()?.firstOrNull() as? ClassDescriptor
@@ -223,7 +223,7 @@ object ExpectedActualResolver {
parentSubstitutor: Substitutor? = null
): Compatibility {
assert(a.name == b.name) { "This function should be invoked only for declarations with the same name: $a, $b" }
assert(a.containingDeclaration is ClassDescriptor == b.containingDeclaration is ClassDescriptor) {
assert(a.containingDeclaration is ClassifierDescriptorWithTypeParameters == b.containingDeclaration is ClassifierDescriptorWithTypeParameters) {
"This function should be invoked only for declarations in the same kind of container (both members or both top level): $a, $b"
}