From 9e500831dd1c3c302ce3d037e99d728681a89bc7 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 31 Jan 2018 17:29:52 +0100 Subject: [PATCH] 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 --- .../kotlin/codegen/ClassBodyCodegen.java | 18 +- .../kotlin/codegen/PropertyCodegen.java | 37 +++- .../jetbrains/kotlin/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 1 + .../kotlin/resolve/DeclarationsChecker.kt | 17 +- .../resolve/FunctionDescriptorResolver.kt | 5 +- .../ExpectedActualDeclarationChecker.kt | 56 ++++-- .../calls/components/ArgumentsUtils.kt | 1 + .../multiplatform/ExpectedActualResolver.kt | 4 +- .../defaultArguments/annotations.kt | 52 ++++++ .../annotationArgumentEquality.kt | 89 ++++++++++ .../annotationArgumentEquality.txt | 164 ++++++++++++++++++ .../defaultArguments/annotations.kt | 33 ++++ .../defaultArguments/annotations.txt | 100 +++++++++++ .../annotationsViaActualTypeAlias.kt | 65 +++++++ .../annotationsViaActualTypeAlias.txt | 105 +++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 + .../checkers/DiagnosticsTestGenerated.java | 18 ++ .../DiagnosticsUsingJavacTestGenerated.java | 18 ++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 + .../LightAnalysisModeTestGenerated.java | 6 + .../impl/TypeAliasConstructorDescriptor.kt | 4 + .../resolve/constants/CompileTimeConstant.kt | 4 + .../resolve/constants/constantValues.kt | 28 +-- 24 files changed, 790 insertions(+), 48 deletions(-) create mode 100644 compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.txt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.txt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java index 9d62b3a83ad..b1cfc81d0bc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java @@ -5,8 +5,10 @@ package org.jetbrains.kotlin.codegen; +import kotlin.collections.CollectionsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.backend.common.bridges.ImplKt; import org.jetbrains.kotlin.codegen.context.ClassContext; import org.jetbrains.kotlin.codegen.state.GenerationState; @@ -166,16 +168,26 @@ public abstract class ClassBodyCodegen extends MemberCodegen constant = ExpressionCodegen.getCompileTimeConstant( defaultValue, bindingContext, true, state.getShouldInlineConstVals()); @@ -273,6 +279,29 @@ public class PropertyCodegen { mv.visitEnd(); } + private KtExpression loadAnnotationArgumentDefaultValue( + @NotNull KtParameter ktParameter, + @NotNull PropertyDescriptor descriptor, + @Nullable FunctionDescriptor expectedAnnotationConstructor + ) { + KtExpression value = ktParameter.getDefaultValue(); + if (value != null) return value; + + if (expectedAnnotationConstructor != null) { + ValueParameterDescriptor expectedParameter = CollectionsKt.single( + expectedAnnotationConstructor.getValueParameters(), parameter -> parameter.getName().equals(descriptor.getName()) + ); + PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(expectedParameter); + if (!(element instanceof KtParameter)) { + state.getDiagnostics().report(EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND.on(ktParameter)); + return null; + } + return ((KtParameter) element).getDefaultValue(); + } + + return null; + } + private boolean hasBackingField(@NotNull PropertyDescriptor descriptor) { return !isJvmInterface(descriptor.getContainingDeclaration()) && kind != OwnerKind.DEFAULT_IMPLS && diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index e60fb1d0d3a..cff63396431 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -578,6 +578,7 @@ public interface Errors { DiagnosticFactory0 ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0 ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0 ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS = DiagnosticFactory0.create(ERROR); + DiagnosticFactory1 ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND = DiagnosticFactory0.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index a64979730cd..1fe3fc37010 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -253,6 +253,7 @@ public class DefaultErrorMessages { MAP.put(ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE, "Right-hand side of actual type alias cannot contain use-site variance or star projections"); MAP.put(ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION, "Type arguments in the right-hand side of actual type alias should be its type parameters in the same order, e.g. 'actual typealias Foo = Bar'"); MAP.put(ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, "Actual function cannot have default argument values, they should be declared in the expected function"); + MAP.put(ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE, "Parameter ''{0}'' has conflicting values in the expected and actual annotation", NAME); MAP.put(EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND, "Expected function source is not found, therefore it's impossible to generate default argument values declared there. " + diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index edd95b947f7..46378209cf6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue +import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.kotlin.types.* @@ -786,11 +787,17 @@ class DeclarationsChecker( } private fun checkActualFunction(element: KtDeclaration, functionDescriptor: FunctionDescriptor) { - for (valueParameter in functionDescriptor.valueParameters) { - if (valueParameter.declaresDefaultValue()) { - trace.report( - ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS.on(DescriptorToSourceUtils.descriptorToDeclaration(valueParameter) ?: element) - ) + // Actual annotation constructors can have default argument values; their consistency with arguments in the expected annotation + // is checked in ExpectedActualDeclarationChecker.checkAnnotationConstructors + if (!functionDescriptor.isAnnotationConstructor()) { + for (valueParameter in functionDescriptor.valueParameters) { + if (valueParameter.declaresDefaultValue()) { + trace.report( + ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS.on( + DescriptorToSourceUtils.descriptorToDeclaration(valueParameter) ?: element + ) + ) + } } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt index 2512ba3d520..53d2a5e1f70 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt @@ -348,7 +348,10 @@ class FunctionDescriptorResolver( declarationToTrace.toSourceElement() ) constructorDescriptor.isExpect = classDescriptor.isExpect - constructorDescriptor.isActual = modifierList?.hasActualModifier() == true + constructorDescriptor.isActual = + modifierList?.hasActualModifier() == true || + // We don't require 'actual' for constructors of actual annotations + classDescriptor.kind == ClassKind.ANNOTATION_CLASS && classDescriptor.isActual if (declarationToTrace is PsiElement) trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor) val parameterScope = LexicalWritableScope( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt index dee2a26af04..72a6fa60419 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt @@ -17,16 +17,16 @@ package org.jetbrains.kotlin.resolve.checkers import com.intellij.openapi.vfs.VfsUtilCore +import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.AnalysisFlag import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.incremental.components.ExpectActualTracker -import org.jetbrains.kotlin.psi.KtConstructor -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor @@ -57,7 +57,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { fun checkExpectedDeclarationHasActual( reportOn: KtNamedDeclaration, descriptor: MemberDescriptor, - diagnosticHolder: DiagnosticSink, + trace: BindingTrace, platformModule: ModuleDescriptor, expectActualTracker: ExpectActualTracker ) { @@ -77,7 +77,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { assert(compatibility.keys.all { it is Incompatible }) @Suppress("UNCHECKED_CAST") val incompatibility = compatibility as Map> - diagnosticHolder.report(Errors.NO_ACTUAL_FOR_EXPECT.on(reportOn, descriptor, platformModule, incompatibility)) + trace.report(Errors.NO_ACTUAL_FOR_EXPECT.on(reportOn, descriptor, platformModule, incompatibility)) } else { val actualMembers = compatibility.asSequence() .filter { (compatibility, _) -> @@ -108,7 +108,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { this.keys.all { it is Incompatible && it.kind == Compatibility.IncompatibilityKind.STRONG } private fun checkActualDeclarationHasExpected( - reportOn: KtNamedDeclaration, descriptor: MemberDescriptor, diagnosticHolder: DiagnosticSink, checkActual: Boolean + reportOn: KtNamedDeclaration, descriptor: MemberDescriptor, trace: BindingTrace, checkActual: Boolean ) { // Using the platform module instead of the common module is sort of fine here because the former always depends on the latter. // However, it would be clearer to find the common module this platform module implements and look for expected there instead. @@ -123,7 +123,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { // we suppress error, because annotation classes can only have one constructor and it's a 100% boilerplate // to require every annotation constructor with additional parameters with default values be marked with the `actual` modifier if (checkActual && !descriptor.isAnnotationConstructor()) { - diagnosticHolder.report(Errors.ACTUAL_MISSING.on(reportOn)) + trace.report(Errors.ACTUAL_MISSING.on(reportOn)) } return @@ -162,7 +162,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { val classDescriptor = (descriptor as? TypeAliasDescriptor)?.expandedType?.constructor?.declarationDescriptor as? ClassDescriptor ?: (descriptor as ClassDescriptor) - diagnosticHolder.report( + trace.report( Errors.NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS.on( reportOn, classDescriptor, nonTrivialUnfulfilled ) @@ -172,7 +172,18 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { assert(compatibility.keys.all { it is Incompatible }) @Suppress("UNCHECKED_CAST") val incompatibility = compatibility as Map> - diagnosticHolder.report(Errors.ACTUAL_WITHOUT_EXPECT.on(reportOn, descriptor, incompatibility)) + trace.report(Errors.ACTUAL_WITHOUT_EXPECT.on(reportOn, descriptor, incompatibility)) + } else { + val expected = compatibility[Compatible]!!.first() + if (expected is ClassDescriptor && expected.kind == ClassKind.ANNOTATION_CLASS) { + val actualConstructor = + (descriptor as? ClassDescriptor)?.constructors?.singleOrNull() ?: + (descriptor as? TypeAliasDescriptor)?.constructors?.singleOrNull()?.underlyingConstructorDescriptor + val expectedConstructor = expected.constructors.singleOrNull() + if (expectedConstructor != null && actualConstructor != null) { + checkAnnotationConstructors(expectedConstructor, actualConstructor, trace, reportOn) + } + } } } @@ -184,4 +195,29 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { is CallableMemberDescriptor -> kind == CallableMemberDescriptor.Kind.DECLARATION else -> true } + + private fun checkAnnotationConstructors( + expected: ConstructorDescriptor, actual: ConstructorDescriptor, trace: BindingTrace, reportOn: PsiElement + ) { + for (expectedParameterDescriptor in expected.valueParameters) { + // Actual parameter with the same name is guaranteed to exist because this method is only called for compatible annotations + val actualParameterDescriptor = actual.valueParameters.first { it.name == expectedParameterDescriptor.name } + + if (expectedParameterDescriptor.declaresDefaultValue() && actualParameterDescriptor.declaresDefaultValue()) { + val expectedParameter = + DescriptorToSourceUtils.descriptorToDeclaration(expectedParameterDescriptor) as? KtParameter ?: continue + val actualParameter = DescriptorToSourceUtils.descriptorToDeclaration(actualParameterDescriptor) + + val expectedValue = trace.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expectedParameter.defaultValue) + // TODO: support arguments coming from Java via typealias, see PsiAnnotationMethod.getDefaultValue() + val actualValue = (actualParameter as? KtParameter)?.let { parameter -> + trace.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, parameter.defaultValue) + } + if (expectedValue != actualValue) { + val target = (actualParameter as? KtParameter)?.defaultValue ?: (reportOn as? KtTypeAlias)?.nameIdentifier ?: reportOn + trace.report(Errors.ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE.on(target, actualParameterDescriptor)) + } + } + } + } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt index 0c5adaa8c8d..9dc6dd787dd 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt @@ -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 diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt index a4703b7f2cd..d132d92d2e6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt @@ -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" } diff --git a/compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt b/compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt new file mode 100644 index 00000000000..bce27c89f87 --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt @@ -0,0 +1,52 @@ +// !LANGUAGE: +MultiPlatformProjects +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: common.kt + +expect annotation class A1(val x: Int, val y: String = "OK") + +expect annotation class A2(val x: Int = 42, val y: String = "OK") + +expect annotation class A3(val x: Int, val y: String) + +expect annotation class A4(val x: Int = 42, val y: String) + +@A1(0) +@A2 +@A3 +@A4 +fun test() {} + +// FILE: jvm.kt + +import kotlin.test.assertEquals + +actual annotation class A1(actual val x: Int, actual val y: String) + +actual annotation class A2(actual val x: Int, actual val y: String = "OK") + +actual annotation class A3(actual val x: Int = 42, actual val y: String = "OK") + +actual annotation class A4(actual val x: Int, actual val y: String = "OK") + +fun box(): String { + val anno = Class.forName("CommonKt").getDeclaredMethod("test").annotations + + val a1 = anno.single { it.annotationClass == A1::class } as A1 + assertEquals(0, a1.x) + assertEquals("OK", a1.y) + + val a2 = anno.single { it.annotationClass == A2::class } as A2 + assertEquals(42, a2.x) + assertEquals("OK", a2.y) + + val a3 = anno.single { it.annotationClass == A3::class } as A3 + assertEquals(42, a3.x) + assertEquals("OK", a3.y) + + val a4 = anno.single { it.annotationClass == A4::class } as A4 + assertEquals(42, a4.x) + assertEquals("OK", a4.y) + + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt new file mode 100644 index 00000000000..550215ec4b3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt @@ -0,0 +1,89 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt + +import kotlin.reflect.KClass + +expect annotation class Primitives( + val z: Boolean = true, + val c: Char = 'c', + val b: Byte = 42.toByte(), + val s: Short = (-1).toShort(), + val i: Int = -42, + val f: Float = 2.72f, + val j: Long = 123456789123456789L, + val d: Double = 3.14159265358979 +) + +expect annotation class PrimitiveArrays( + val z: BooleanArray = [true], + val c: CharArray = ['c'], + val b: ByteArray = [42.toByte()], + val s: ShortArray = [(-1).toShort()], + val i: IntArray = [-42], + val f: FloatArray = [2.72f], + val j: LongArray = [123456789123456789L], + val d: DoubleArray = [3.14159265358979] +) + +enum class En { A, B } + +annotation class Anno(val value: String = "Anno") + +expect annotation class Classes( + val s: String = "OK", + val e: En = En.B, + // TODO: this does not work at the moment because AnnotationDescriptor subclasses do not implement equals correctly + // val a: Anno = Anno(), + val k: KClass<*> = List::class +) + +expect annotation class ClassArrays( + val s: Array = ["OK"], + val e: Array = [En.B], + // val a: Array = [Anno()], + val k: Array> = [List::class], + vararg val v: Int = [42] +) + +// MODULE: m2-jvm(m1-common) +// FILE: jvm.kt + +import kotlin.reflect.KClass + +actual annotation class Primitives( + actual val z: Boolean = true, + actual val c: Char = 'c', + actual val b: Byte = 42.toByte(), + actual val s: Short = (-1).toShort(), + actual val i: Int = -42, + actual val f: Float = 2.72f, + actual val j: Long = 123456789123456789L, + actual val d: Double = 3.14159265358979 +) + +actual annotation class PrimitiveArrays( + actual val z: BooleanArray = [true], + actual val c: CharArray = ['c'], + actual val b: ByteArray = [42.toByte()], + actual val s: ShortArray = [(-1).toShort()], + actual val i: IntArray = [-42], + actual val f: FloatArray = [2.72f], + actual val j: LongArray = [123456789123456789L], + actual val d: DoubleArray = [3.14159265358979] +) + +actual annotation class Classes( + actual val s: String = "OK", + actual val e: En = En.B, + // actual val a: Anno = Anno(), + actual val k: KClass<*> = List::class +) + +actual annotation class ClassArrays( + actual val s: Array = ["OK"], + actual val e: Array = [En.B], + // actual val a: Array = [Anno()], + actual val k: Array> = [List::class], + actual vararg val v: Int = [42] +) diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.txt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.txt new file mode 100644 index 00000000000..0b451c851ae --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.txt @@ -0,0 +1,164 @@ +// -- Module: -- +package + +public final annotation class Anno : kotlin.Annotation { + public constructor Anno(/*0*/ value: kotlin.String = ...) + public final val value: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class ClassArrays : kotlin.Annotation { + public constructor ClassArrays(/*0*/ s: kotlin.Array = ..., /*1*/ e: kotlin.Array = ..., /*2*/ k: kotlin.Array> = ..., /*3*/ vararg v: kotlin.Int /*kotlin.IntArray*/ = ...) + public expect final val e: kotlin.Array + public expect final val k: kotlin.Array> + public expect final val s: kotlin.Array + public expect final val v: kotlin.IntArray + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class Classes : kotlin.Annotation { + public constructor Classes(/*0*/ s: kotlin.String = ..., /*1*/ e: En = ..., /*2*/ k: kotlin.reflect.KClass<*> = ...) + public expect final val e: En + public expect final val k: kotlin.reflect.KClass<*> + public expect final val s: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final enum class En : kotlin.Enum { + enum entry A + + enum entry B + + private constructor En() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: En): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): En + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final expect annotation class PrimitiveArrays : kotlin.Annotation { + public constructor PrimitiveArrays(/*0*/ z: kotlin.BooleanArray = ..., /*1*/ c: kotlin.CharArray = ..., /*2*/ b: kotlin.ByteArray = ..., /*3*/ s: kotlin.ShortArray = ..., /*4*/ i: kotlin.IntArray = ..., /*5*/ f: kotlin.FloatArray = ..., /*6*/ j: kotlin.LongArray = ..., /*7*/ d: kotlin.DoubleArray = ...) + public expect final val b: kotlin.ByteArray + public expect final val c: kotlin.CharArray + public expect final val d: kotlin.DoubleArray + public expect final val f: kotlin.FloatArray + public expect final val i: kotlin.IntArray + public expect final val j: kotlin.LongArray + public expect final val s: kotlin.ShortArray + public expect final val z: kotlin.BooleanArray + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class Primitives : kotlin.Annotation { + public constructor Primitives(/*0*/ z: kotlin.Boolean = ..., /*1*/ c: kotlin.Char = ..., /*2*/ b: kotlin.Byte = ..., /*3*/ s: kotlin.Short = ..., /*4*/ i: kotlin.Int = ..., /*5*/ f: kotlin.Float = ..., /*6*/ j: kotlin.Long = ..., /*7*/ d: kotlin.Double = ...) + public expect final val b: kotlin.Byte + public expect final val c: kotlin.Char + public expect final val d: kotlin.Double + public expect final val f: kotlin.Float + public expect final val i: kotlin.Int + public expect final val j: kotlin.Long + public expect final val s: kotlin.Short + public expect final val z: kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + + +// -- Module: -- +package + +public final annotation class Anno : kotlin.Annotation { + public constructor Anno(/*0*/ value: kotlin.String = ...) + public final val value: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final actual annotation class ClassArrays : kotlin.Annotation { + public constructor ClassArrays(/*0*/ s: kotlin.Array = ..., /*1*/ e: kotlin.Array = ..., /*2*/ k: kotlin.Array> = ..., /*3*/ vararg v: kotlin.Int /*kotlin.IntArray*/ = ...) + public actual final val e: kotlin.Array + public actual final val k: kotlin.Array> + public actual final val s: kotlin.Array + public actual final val v: kotlin.IntArray + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final actual annotation class Classes : kotlin.Annotation { + public constructor Classes(/*0*/ s: kotlin.String = ..., /*1*/ e: En = ..., /*2*/ k: kotlin.reflect.KClass<*> = ...) + public actual final val e: En + public actual final val k: kotlin.reflect.KClass<*> + public actual final val s: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final enum class En : kotlin.Enum { + enum entry A + + enum entry B + + private constructor En() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: En): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): En + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final actual annotation class PrimitiveArrays : kotlin.Annotation { + public constructor PrimitiveArrays(/*0*/ z: kotlin.BooleanArray = ..., /*1*/ c: kotlin.CharArray = ..., /*2*/ b: kotlin.ByteArray = ..., /*3*/ s: kotlin.ShortArray = ..., /*4*/ i: kotlin.IntArray = ..., /*5*/ f: kotlin.FloatArray = ..., /*6*/ j: kotlin.LongArray = ..., /*7*/ d: kotlin.DoubleArray = ...) + public actual final val b: kotlin.ByteArray + public actual final val c: kotlin.CharArray + public actual final val d: kotlin.DoubleArray + public actual final val f: kotlin.FloatArray + public actual final val i: kotlin.IntArray + public actual final val j: kotlin.LongArray + public actual final val s: kotlin.ShortArray + public actual final val z: kotlin.BooleanArray + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final actual annotation class Primitives : kotlin.Annotation { + public constructor Primitives(/*0*/ z: kotlin.Boolean = ..., /*1*/ c: kotlin.Char = ..., /*2*/ b: kotlin.Byte = ..., /*3*/ s: kotlin.Short = ..., /*4*/ i: kotlin.Int = ..., /*5*/ f: kotlin.Float = ..., /*6*/ j: kotlin.Long = ..., /*7*/ d: kotlin.Double = ...) + public actual final val b: kotlin.Byte + public actual final val c: kotlin.Char + public actual final val d: kotlin.Double + public actual final val f: kotlin.Float + public actual final val i: kotlin.Int + public actual final val j: kotlin.Long + public actual final val s: kotlin.Short + public actual final val z: kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.kt new file mode 100644 index 00000000000..c9f4ca8ec9d --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.kt @@ -0,0 +1,33 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt + +expect annotation class A1(val x: Int, val y: String = "OK") + +expect annotation class A2(val x: Int = 42, val y: String = "OK") + +expect annotation class A3(val x: Int, val y: String) + +expect annotation class A4(val x: Int = 42, val y: String) + +expect annotation class A5(val x: Int = 42, val y: String) + +@A1(0) +@A2 +@A3(0, "") +@A4(0, "") +@A5(0, "") +fun test() {} + +// MODULE: m2-jvm(m1-common) +// FILE: jvm.kt + +actual annotation class A1(actual val x: Int, actual val y: String) + +actual annotation class A2(actual val x: Int, actual val y: String = "OK") + +actual annotation class A3(actual val x: Int = 42, actual val y: String = "OK") + +actual annotation class A4(actual val x: Int, actual val y: String = "OK") + +actual annotation class A5(actual val x: Int = 239, actual val y: String = "OK") diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.txt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.txt new file mode 100644 index 00000000000..ba3815a354f --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.txt @@ -0,0 +1,100 @@ +// -- Module: -- +package + +@A1(x = 0) @A2 @A3(x = 0, y = "") @A4(x = 0, y = "") @A5(x = 0, y = "") public fun test(): kotlin.Unit + +public final expect annotation class A1 : kotlin.Annotation { + public constructor A1(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class A2 : kotlin.Annotation { + public constructor A2(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ...) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class A3 : kotlin.Annotation { + public constructor A3(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class A4 : kotlin.Annotation { + public constructor A4(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class A5 : kotlin.Annotation { + public constructor A5(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + + +// -- Module: -- +package + +@A1(x = 0) @A2 @A3(x = 0, y = "") @A4(x = 0, y = "") @A5(x = 0, y = "") public fun test(): kotlin.Unit + +public final actual annotation class A1 : kotlin.Annotation { + public constructor A1(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String) + public actual final val x: kotlin.Int + public actual final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final actual annotation class A2 : kotlin.Annotation { + public constructor A2(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...) + public actual final val x: kotlin.Int + public actual final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final actual annotation class A3 : kotlin.Annotation { + public constructor A3(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ...) + public actual final val x: kotlin.Int + public actual final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final actual annotation class A4 : kotlin.Annotation { + public constructor A4(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...) + public actual final val x: kotlin.Int + public actual final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final actual annotation class A5 : kotlin.Annotation { + public constructor A5(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ...) + public actual final val x: kotlin.Int + public actual final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.kt new file mode 100644 index 00000000000..d8509bb7995 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.kt @@ -0,0 +1,65 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt + +expect annotation class A1(val x: Int, val y: String = "OK") + +expect annotation class A2(val x: Int = 42, val y: String = "OK") + +expect annotation class A3(val x: Int, val y: String) + +expect annotation class A4(val x: Int = 42, val y: String) + +expect annotation class A5(val x: Int = 42, val y: String) + +@A1(0) +@A2 +@A3(0, "") +@A4(0, "") +@A5(0, "") +fun test() {} + +// MODULE: m2-jvm(m1-common) +// FILE: jvm.kt + +actual typealias A1 = J1 +// TODO: support arguments coming from Java via typealias (KT-22704) +actual typealias A2 = J2 +actual typealias A3 = J3 +actual typealias A4 = J4 +actual typealias A5 = J5 + +// FILE: J1.java + +public @interface J1 { + int x(); + String y(); +} + +// FILE: J2.java + +public @interface J2 { + int x(); + String y() default "OK"; +} + +// FILE: J3.java + +public @interface J3 { + int x() default 42; + String y() default "OK"; +} + +// FILE: J4.java + +public @interface J4 { + int x(); + String y() default "OK"; +} + +// FILE: J5.java + +public @interface J5 { + int x() default 239; + String y() default "OK"; +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.txt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.txt new file mode 100644 index 00000000000..2ed72355c17 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.txt @@ -0,0 +1,105 @@ +// -- Module: -- +package + +@A1(x = 0) @A2 @A3(x = 0, y = "") @A4(x = 0, y = "") @A5(x = 0, y = "") public fun test(): kotlin.Unit + +public final expect annotation class A1 : kotlin.Annotation { + public constructor A1(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class A2 : kotlin.Annotation { + public constructor A2(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ...) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class A3 : kotlin.Annotation { + public constructor A3(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class A4 : kotlin.Annotation { + public constructor A4(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect annotation class A5 : kotlin.Annotation { + public constructor A5(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String) + public expect final val x: kotlin.Int + public expect final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + + +// -- Module: -- +package + +@A1 /* = J1 */(x = 0) @A2 /* = J2 */ @A3 /* = J3 */(x = 0, y = "") @A4 /* = J4 */(x = 0, y = "") @A5 /* = J5 */(x = 0, y = "") public fun test(): kotlin.Unit + +public final annotation class J1 : kotlin.Annotation { + public constructor J1(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String) + public final val x: kotlin.Int + public final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final annotation class J2 : kotlin.Annotation { + public constructor J2(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...) + public final val x: kotlin.Int + public final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final annotation class J3 : kotlin.Annotation { + public constructor J3(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ...) + public final val x: kotlin.Int + public final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final annotation class J4 : kotlin.Annotation { + public constructor J4(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ...) + public final val x: kotlin.Int + public final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final annotation class J5 : kotlin.Annotation { + public constructor J5(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ...) + public final val x: kotlin.Int + public final val y: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} +public actual typealias A1 = J1 +public actual typealias A2 = J2 +public actual typealias A3 = J3 +public actual typealias A4 = J4 +public actual typealias A5 = J5 diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 7f7a7f4f0d7..66ff4568e53 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -12662,6 +12662,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("annotations.kt") + public void testAnnotations() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt"); + doTest(fileName); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 369032d8bb8..a23c4f28e78 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -14236,6 +14236,24 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("annotationArgumentEquality.kt") + public void testAnnotationArgumentEquality() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt"); + doTest(fileName); + } + + @TestMetadata("annotations.kt") + public void testAnnotations() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.kt"); + doTest(fileName); + } + + @TestMetadata("annotationsViaActualTypeAlias.kt") + public void testAnnotationsViaActualTypeAlias() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.kt"); + doTest(fileName); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 5bce717d9d2..e81979d2e8b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -14236,6 +14236,24 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("annotationArgumentEquality.kt") + public void testAnnotationArgumentEquality() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationArgumentEquality.kt"); + doTest(fileName); + } + + @TestMetadata("annotations.kt") + public void testAnnotations() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotations.kt"); + doTest(fileName); + } + + @TestMetadata("annotationsViaActualTypeAlias.kt") + public void testAnnotationsViaActualTypeAlias() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.kt"); + doTest(fileName); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 983254035c8..33971fbbdef 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -12662,6 +12662,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("annotations.kt") + public void testAnnotations() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt"); + doTest(fileName); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 11eea361587..f81517f3169 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -12662,6 +12662,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("annotations.kt") + public void testAnnotations() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/annotations.kt"); + doTest(fileName); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments/constructor.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt index b01bb4a6255..24bfa66220f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt @@ -57,6 +57,10 @@ class TypeAliasConstructorDescriptorImpl private constructor( ) : TypeAliasConstructorDescriptor, FunctionDescriptorImpl(typeAliasDescriptor, original, annotations, Name.special(""), kind, source) { + init { + isActual = typeAliasDescriptor.isActual + } + // When resolution is ran for common calls, type aliases constructors are resolved as extensions // (i.e. after members, and with extension receiver) // But when resolving super-calls (with known set of candidates) constructors of inner classes are expected to have diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/CompileTimeConstant.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/CompileTimeConstant.kt index 3e45bfaa0b6..a377e34028b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/CompileTimeConstant.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/CompileTimeConstant.kt @@ -48,6 +48,10 @@ interface CompileTimeConstant { val usesVariableAsConstant: Boolean, val usesNonConstValAsConstant: Boolean ) + + override fun equals(other: Any?): Boolean + + override fun hashCode(): Int } class TypedCompileTimeConstant( diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt index b41cfc510a5..3d4bf628276 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt @@ -32,17 +32,19 @@ abstract class ConstantValue(open val value: T) { abstract fun accept(visitor: AnnotationArgumentVisitor, data: D): R - override fun toString() = value.toString() + override fun equals(other: Any?): Boolean = this === other || value == (other as? ConstantValue<*>)?.value + + override fun hashCode(): Int = value?.hashCode() ?: 0 + + override fun toString(): String = value.toString() } abstract class IntegerValueConstant protected constructor(value: T) : ConstantValue(value) class AnnotationValue(value: AnnotationDescriptor) : ConstantValue(value) { - override fun getType(module: ModuleDescriptor): KotlinType = value.type override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitAnnotationValue(this, data) - override fun toString() = value.toString() } class ArrayValue( @@ -54,10 +56,6 @@ class ArrayValue( } override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitArrayValue(this, data) - - override fun equals(other: Any?): Boolean = this === other || value == (other as? ArrayValue)?.value - - override fun hashCode() = value.hashCode() } class BooleanValue(value: Boolean) : ConstantValue(value) { @@ -117,14 +115,9 @@ class EnumValue(val enumClassId: ClassId, val enumEntryName: Name) : ConstantVal override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitEnumValue(this, data) override fun toString() = "${enumClassId.shortClassName}.$enumEntryName" - - override fun equals(other: Any?): Boolean = this === other || value == (other as? EnumValue)?.value - - override fun hashCode() = value.hashCode() } abstract class ErrorValue : ConstantValue(Unit) { - @Deprecated("Should not be called, for this is not a real value, but a indication of an error") override val value: Unit get() = throw UnsupportedOperationException() @@ -132,7 +125,6 @@ abstract class ErrorValue : ConstantValue(Unit) { override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitErrorValue(this, data) class ErrorValueWithMessage(val message: String) : ErrorValue() { - override fun getType(module: ModuleDescriptor) = ErrorUtils.createErrorType(message) override fun toString() = message @@ -157,10 +149,6 @@ class IntValue(value: Int) : IntegerValueConstant(value) { override fun getType(module: ModuleDescriptor) = module.builtIns.intType override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitIntValue(this, data) - - override fun equals(other: Any?): Boolean = this === other || value == (other as? IntValue)?.value - - override fun hashCode() = value } class KClassValue(private val type: KotlinType) : ConstantValue(type) { @@ -184,8 +172,6 @@ class NullValue : ConstantValue(null) { override fun getType(module: ModuleDescriptor) = module.builtIns.nullableNothingType override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitNullValue(this, data) - - override fun toString() = "null" } class ShortValue(value: Short) : IntegerValueConstant(value) { @@ -202,8 +188,4 @@ class StringValue(value: String) : ConstantValue(value) { override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitStringValue(this, data) override fun toString() = "\"$value\"" - - override fun equals(other: Any?): Boolean = this === other || value == (other as? StringValue)?.value - - override fun hashCode() = value.hashCode() }