diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt index b2cd8ea956c..b336d070533 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt @@ -65,7 +65,7 @@ private fun StorageComponentContainer.configureJavaTopDownAnalysis( useInstance(VirtualFileFinderFactory.getInstance(project).create(moduleContentScope)) - useImpl() + useInstance(JavaPropertyInitializerEvaluatorImpl) useImpl() useImpl() useImpl() diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluatorImpl.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluatorImpl.kt index a2eca0c9a2c..d866c663a4b 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluatorImpl.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/JavaPropertyInitializerEvaluatorImpl.kt @@ -20,20 +20,21 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.load.java.structure.JavaField import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory +import org.jetbrains.kotlin.types.KotlinType -class JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator { - override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>? { - val evaluated = field.initializerValue ?: return null +object JavaPropertyInitializerEvaluatorImpl : JavaPropertyInitializerEvaluator { + override fun getInitializerConstant(field: JavaField, descriptor: PropertyDescriptor): ConstantValue<*>? = + field.initializerValue?.let { value -> convertLiteralValue(value, descriptor.type) } - return when (evaluated) { - //Note: evaluated expression may be of class that does not match field type in some cases - // tested for Int, left other checks just in case + internal fun convertLiteralValue(value: Any, expectedType: KotlinType): ConstantValue<*>? = + when (value) { + // Note: `value` expression may be of class that does not match field type in some cases + // tested for Int, left other checks just in case is Byte, is Short, is Int, is Long -> { - ConstantValueFactory.createIntegerConstantValue((evaluated as Number).toLong(), descriptor.type, false) + ConstantValueFactory.createIntegerConstantValue((value as Number).toLong(), expectedType, false) } else -> { - ConstantValueFactory.createConstantValue(evaluated) + ConstantValueFactory.createConstantValue(value) } } - } } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/multiplatform/JavaActualAnnotationArgumentExtractor.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/multiplatform/JavaActualAnnotationArgumentExtractor.kt new file mode 100644 index 00000000000..a2ccdd73064 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/multiplatform/JavaActualAnnotationArgumentExtractor.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.jvm.multiplatform + +import com.intellij.psi.PsiAnnotationMethod +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluatorImpl +import org.jetbrains.kotlin.load.java.structure.* +import org.jetbrains.kotlin.load.java.structure.impl.JavaAnnotationArgumentImpl +import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker +import org.jetbrains.kotlin.resolve.constants.ConstantValue +import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory +import org.jetbrains.kotlin.resolve.constants.EnumValue +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.typeUtil.builtIns + +class JavaActualAnnotationArgumentExtractor : ExpectedActualDeclarationChecker.ActualAnnotationArgumentExtractor { + override fun extractActualValue(argument: PsiElement, expectedType: KotlinType): ConstantValue<*>? = + (argument as? PsiAnnotationMethod) + ?.defaultValue + ?.let { JavaAnnotationArgumentImpl.create(it, null) } + ?.convert(expectedType) + + // This code is similar to LazyJavaAnnotationDescriptor.resolveAnnotationArgument, but cannot be reused until + // KClassValue/AnnotationValue are untied from descriptors/types, because here we do not have an instance of LazyJavaResolverContext. + private fun JavaAnnotationArgument.convert(expectedType: KotlinType): ConstantValue<*>? { + return when (this) { + is JavaLiteralAnnotationArgument -> value?.let { + JavaPropertyInitializerEvaluatorImpl.convertLiteralValue(it, expectedType) + } + is JavaEnumValueAnnotationArgument -> { + enumClassId?.let { enumClassId -> + entryName?.let { entryName -> + EnumValue(enumClassId, entryName) + } + } + } + is JavaArrayAnnotationArgument -> { + val elementType = expectedType.builtIns.getArrayElementType(expectedType) + ConstantValueFactory.createArrayValue(getElements().mapNotNull { it.convert(elementType) }, expectedType) + } + is JavaAnnotationAsAnnotationArgument -> { + // TODO: support annotations as annotation arguments (KT-28077) + null + } + is JavaClassObjectAnnotationArgument -> { + // TODO: support class literals as annotation arguments + null + } + else -> null + } + } +} 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 84f1a78ffa7..a753a002a2d 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 @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.resolve.checkers.BigFunctionTypeAvailabilityChecker import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.jvm.* import org.jetbrains.kotlin.resolve.jvm.checkers.* +import org.jetbrains.kotlin.resolve.jvm.multiplatform.JavaActualAnnotationArgumentExtractor import org.jetbrains.kotlin.synthetic.JavaSyntheticScopes import org.jetbrains.kotlin.types.DynamicTypesSettings import org.jetbrains.kotlin.types.expressions.FunctionWithBigAritySupport @@ -34,7 +35,7 @@ object JvmPlatformConfigurator : PlatformConfigurator( TypeParameterBoundIsNotArrayChecker(), JvmSyntheticApplicabilityChecker(), StrictfpApplicabilityChecker(), - ExpectedActualDeclarationChecker, + ExpectedActualDeclarationChecker(listOf(JavaActualAnnotationArgumentExtractor())), JvmAnnotationsTargetNonExistentAccessorChecker(), BadInheritedJavaSignaturesChecker ), 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 054ccabbd75..6d35b13e883 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt @@ -17,10 +17,7 @@ package org.jetbrains.kotlin.resolve.checkers import com.intellij.openapi.vfs.VfsUtilCore -import com.intellij.psi.PsiAnnotationMethod -import com.intellij.psi.PsiCall import com.intellij.psi.PsiElement -import com.intellij.psi.PsiLiteral import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* @@ -30,7 +27,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.resolve.* -import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant +import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor import org.jetbrains.kotlin.resolve.descriptorUtil.isPrimaryConstructorOfInlineClass import org.jetbrains.kotlin.resolve.descriptorUtil.module @@ -39,12 +36,15 @@ import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver.Compati import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver.Compatibility.Compatible import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver.Compatibility.Incompatible import org.jetbrains.kotlin.resolve.source.PsiSourceFile +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.ifEmpty import java.io.File -object ExpectedActualDeclarationChecker : DeclarationChecker { - val OPTIONAL_EXPECTATION_FQ_NAME = FqName("kotlin.OptionalExpectation") +class ExpectedActualDeclarationChecker(val argumentExtractors: List = emptyList()) : DeclarationChecker { + interface ActualAnnotationArgumentExtractor { + fun extractActualValue(argument: PsiElement, expectedType: KotlinType): ConstantValue<*>? + } override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { if (!context.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return @@ -96,27 +96,6 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { } } - @JvmStatic - fun isOptionalAnnotationClass(descriptor: DeclarationDescriptor): Boolean = - descriptor is ClassDescriptor && - descriptor.kind == ClassKind.ANNOTATION_CLASS && - descriptor.isExpect && - descriptor.annotations.hasAnnotation(OPTIONAL_EXPECTATION_FQ_NAME) - - // TODO: move to some other place which is accessible both from backend-common and js.serializer - @JvmStatic - fun shouldGenerateExpectClass(descriptor: ClassDescriptor): Boolean { - assert(descriptor.isExpect) { "Not an expected class: $descriptor" } - - if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(descriptor)) { - with(ExpectedActualResolver) { - return descriptor.findCompatibleActualForExpected(descriptor.module).isEmpty() - } - } - - return false - } - private fun ExpectActualTracker.reportExpectActual(expected: MemberDescriptor, actualMembers: Sequence) { if (this is ExpectActualTracker.DoNothing) return @@ -133,9 +112,6 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { .safeAs() ?.run { VfsUtilCore.virtualToIoFile(psiFile.virtualFile) } - fun Map>.allStrongIncompatibilities(): Boolean = - this.keys.all { it is Incompatible && it.kind == Compatibility.IncompatibilityKind.STRONG } - private fun checkActualDeclarationHasExpected( reportOn: KtNamedDeclaration, descriptor: MemberDescriptor, trace: BindingTrace, checkActual: Boolean ) { @@ -257,12 +233,9 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { val actualParameter = DescriptorToSourceUtils.descriptorToDeclaration(actualParameterDescriptor) val expectedValue = trace.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expectedParameter.defaultValue) + ?.toConstantValue(expectedParameterDescriptor.type) - if (javaDefaultValueEqualsExpectedValue(actualParameter, trace, expectedParameter, expectedValue)) continue - - val actualValue = (actualParameter as? KtParameter)?.let { parameter -> - trace.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, parameter.defaultValue) - } + val actualValue = getActualAnnotationParameterValue(actualParameter, trace.bindingContext, expectedParameterDescriptor.type) 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)) @@ -271,19 +244,47 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { } } - private fun javaDefaultValueEqualsExpectedValue( - actualParameter: PsiElement?, trace: BindingTrace, expectedParameter: KtParameter, expectedValue: CompileTimeConstant<*>? - ): Boolean { - val actualPsi = (actualParameter as? PsiAnnotationMethod)?.defaultValue ?: return false - val expectedType = trace.bindingContext.get(BindingContext.EXPECTED_EXPRESSION_TYPE, expectedParameter.defaultValue) ?: return false - val actualValue = when (actualPsi) { - is PsiLiteral -> actualPsi.value - is PsiCall -> { - //TODO: arrays and annotations - return false - } - else -> return false + private fun getActualAnnotationParameterValue( + actualParameter: PsiElement?, bindingContext: BindingContext, expectedType: KotlinType + ): ConstantValue<*>? { + if (actualParameter is KtParameter) { + return bindingContext.get(BindingContext.COMPILE_TIME_VALUE, actualParameter.defaultValue)?.toConstantValue(expectedType) } - return (actualValue == expectedValue?.getValue(expectedType)) + + if (actualParameter != null) { + for (extractor in argumentExtractors) { + extractor.extractActualValue(actualParameter, expectedType)?.let { return it } + } + } + + return null + } + + companion object { + val OPTIONAL_EXPECTATION_FQ_NAME = FqName("kotlin.OptionalExpectation") + + @JvmStatic + fun isOptionalAnnotationClass(descriptor: DeclarationDescriptor): Boolean = + descriptor is ClassDescriptor && + descriptor.kind == ClassKind.ANNOTATION_CLASS && + descriptor.isExpect && + descriptor.annotations.hasAnnotation(OPTIONAL_EXPECTATION_FQ_NAME) + + // TODO: move to some other place which is accessible both from backend-common and js.serializer + @JvmStatic + fun shouldGenerateExpectClass(descriptor: ClassDescriptor): Boolean { + assert(descriptor.isExpect) { "Not an expected class: $descriptor" } + + if (isOptionalAnnotationClass(descriptor)) { + with(ExpectedActualResolver) { + return descriptor.findCompatibleActualForExpected(descriptor.module).isEmpty() + } + } + + return false + } + + fun Map>.allStrongIncompatibilities(): Boolean = + this.keys.all { it is Incompatible && it.kind == Compatibility.IncompatibilityKind.STRONG } } } diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.kt new file mode 100644 index 00000000000..4c49a8c0173 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.kt @@ -0,0 +1,77 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt + +import kotlin.reflect.KClass + +expect annotation class Anno( + val b: Byte = 1.toByte(), + val c: Char = 'x', + val d: Double = 3.14, + val f: Float = -2.72f, + val i: Int = 42424242, + val i2: Int = 53535353, + val j: Long = 239239239239239L, + val j2: Long = 239239L, + val s: Short = 42.toShort(), + val z: Boolean = true, + val ba: ByteArray = [(-1).toByte()], + val ca: CharArray = ['y'], + val da: DoubleArray = [-3.14159], + val fa: FloatArray = [2.7218f], + val ia: IntArray = [424242], + val ja: LongArray = [239239239239L, 239239L], + val sa: ShortArray = [(-43).toShort()], + val za: BooleanArray = [false, true], + val str: String = "fizz", + // TODO: val k: KClass<*> = Number::class, + val e: E = E.E1, + // TODO: val a: A = A("1"), + val stra: Array = ["bu", "zz"], + // TODO: val ka: Array> = [Double::class, String::class, LongArray::class, Array>>::class], + val ea: Array = [E.E2, E.E3] + // TODO: val aa: Array = [A("2"), A("3")] +) + +enum class E { E1, E2, E3 } + +annotation class A(val value: String) + +@Anno +fun test() {} + +// MODULE: m2-jvm(m1-common) +// FILE: jvm.kt + +actual typealias Anno = Jnno + +// FILE: Jnno.java + +public @interface Jnno { + byte b() default 1; + char c() default 'x'; + double d() default 3.14; + float f() default -2.72f; + int i() default 42424242; + int i2() default 21212121 + 32323232; + long j() default 239239239239239L; + long j2() default 239239; + short s() default 42; + boolean z() default true; + byte[] ba() default {-1}; + char[] ca() default {'y'}; + double[] da() default {-3.14159}; + float[] fa() default {2.7218f}; + int[] ia() default {424242}; + long[] ja() default {239239239239L, 239239}; + short[] sa() default {-43}; + boolean[] za() default {false, true}; + String str() default "fi" + "zz"; + // TODO: Class k() default Number.class; + E e() default E.E1; + // TODO: A a() default @A("1"); + String[] stra() default {"bu", "zz"}; + // TODO: Class[] ka() default {double.class, String.class, long[].class, Integer[][][].class}; + E[] ea() default {E.E2, E.E3}; + // TODO: A[] aa() default {@A("2"), @A("3")}; +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.txt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.txt new file mode 100644 index 00000000000..8b5e19a7b74 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.txt @@ -0,0 +1,129 @@ +// -- Module: -- +package + +@Anno public fun test(): kotlin.Unit + +public final annotation class A : kotlin.Annotation { + public constructor A(/*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 Anno : kotlin.Annotation { + public constructor Anno(/*0*/ b: kotlin.Byte = ..., /*1*/ c: kotlin.Char = ..., /*2*/ d: kotlin.Double = ..., /*3*/ f: kotlin.Float = ..., /*4*/ i: kotlin.Int = ..., /*5*/ i2: kotlin.Int = ..., /*6*/ j: kotlin.Long = ..., /*7*/ j2: kotlin.Long = ..., /*8*/ s: kotlin.Short = ..., /*9*/ z: kotlin.Boolean = ..., /*10*/ ba: kotlin.ByteArray = ..., /*11*/ ca: kotlin.CharArray = ..., /*12*/ da: kotlin.DoubleArray = ..., /*13*/ fa: kotlin.FloatArray = ..., /*14*/ ia: kotlin.IntArray = ..., /*15*/ ja: kotlin.LongArray = ..., /*16*/ sa: kotlin.ShortArray = ..., /*17*/ za: kotlin.BooleanArray = ..., /*18*/ str: kotlin.String = ..., /*19*/ e: E = ..., /*20*/ stra: kotlin.Array = ..., /*21*/ ea: kotlin.Array = ...) + public expect final val b: kotlin.Byte + public expect final val ba: kotlin.ByteArray + public expect final val c: kotlin.Char + public expect final val ca: kotlin.CharArray + public expect final val d: kotlin.Double + public expect final val da: kotlin.DoubleArray + public expect final val e: E + public expect final val ea: kotlin.Array + public expect final val f: kotlin.Float + public expect final val fa: kotlin.FloatArray + public expect final val i: kotlin.Int + public expect final val i2: kotlin.Int + public expect final val ia: kotlin.IntArray + public expect final val j: kotlin.Long + public expect final val j2: kotlin.Long + public expect final val ja: kotlin.LongArray + public expect final val s: kotlin.Short + public expect final val sa: kotlin.ShortArray + public expect final val str: kotlin.String + public expect final val stra: kotlin.Array + public expect final val z: kotlin.Boolean + public expect final val za: 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 enum class E : kotlin.Enum { + enum entry E1 + + enum entry E2 + + enum entry E3 + + private constructor E() + 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: E): 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): E + public final /*synthesized*/ fun values(): kotlin.Array +} + + +// -- Module: -- +package + +@Anno /* = Jnno */ public fun test(): kotlin.Unit + +public final annotation class A : kotlin.Annotation { + public constructor A(/*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 enum class E : kotlin.Enum { + enum entry E1 + + enum entry E2 + + enum entry E3 + + private constructor E() + 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: E): 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): E + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final annotation class Jnno : kotlin.Annotation { + public constructor Jnno(/*0*/ b: kotlin.Byte = ..., /*1*/ c: kotlin.Char = ..., /*2*/ d: kotlin.Double = ..., /*3*/ f: kotlin.Float = ..., /*4*/ i: kotlin.Int = ..., /*5*/ i2: kotlin.Int = ..., /*6*/ j: kotlin.Long = ..., /*7*/ j2: kotlin.Long = ..., /*8*/ s: kotlin.Short = ..., /*9*/ z: kotlin.Boolean = ..., /*10*/ ba: kotlin.ByteArray = ..., /*11*/ ca: kotlin.CharArray = ..., /*12*/ da: kotlin.DoubleArray = ..., /*13*/ fa: kotlin.FloatArray = ..., /*14*/ ia: kotlin.IntArray = ..., /*15*/ ja: kotlin.LongArray = ..., /*16*/ sa: kotlin.ShortArray = ..., /*17*/ za: kotlin.BooleanArray = ..., /*18*/ str: kotlin.String = ..., /*19*/ e: E = ..., /*20*/ stra: kotlin.Array = ..., /*21*/ ea: kotlin.Array = ...) + public final val b: kotlin.Byte + public final val ba: kotlin.ByteArray + public final val c: kotlin.Char + public final val ca: kotlin.CharArray + public final val d: kotlin.Double + public final val da: kotlin.DoubleArray + public final val e: E + public final val ea: kotlin.Array + public final val f: kotlin.Float + public final val fa: kotlin.FloatArray + public final val i: kotlin.Int + public final val i2: kotlin.Int + public final val ia: kotlin.IntArray + public final val j: kotlin.Long + public final val j2: kotlin.Long + public final val ja: kotlin.LongArray + public final val s: kotlin.Short + public final val sa: kotlin.ShortArray + public final val str: kotlin.String + public final val stra: kotlin.Array + public final val z: kotlin.Boolean + public final val za: 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 actual typealias Anno = Jnno diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index f5eb5dc039f..007ba2de518 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -13059,6 +13059,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.kt"); } + @TestMetadata("annotationsViaActualTypeAlias2.kt") + public void testAnnotationsViaActualTypeAlias2() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.kt"); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { runTest("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 e55aa7d6b67..58420a36f16 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -13059,6 +13059,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias.kt"); } + @TestMetadata("annotationsViaActualTypeAlias2.kt") + public void testAnnotationsViaActualTypeAlias2() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.kt"); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt index f5a7155dda6..19544f60e6d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.BindingTraceContext import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics +import org.jetbrains.kotlin.resolve.jvm.multiplatform.JavaActualAnnotationArgumentExtractor class PlatformExpectedAnnotator : Annotator { override fun annotate(element: PsiElement, holder: AnnotationHolder) { @@ -49,12 +50,12 @@ class PlatformExpectedAnnotator : Annotator { val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return if (!descriptor.isExpect) return + // TODO: obtain the list of annotation argument extractors from platform somehow + val checker = ExpectedActualDeclarationChecker(listOf(JavaActualAnnotationArgumentExtractor())) + val trace = BindingTraceContext() for (module in implementingModules) { - ExpectedActualDeclarationChecker.checkExpectedDeclarationHasActual( - declaration, descriptor, trace, module, - ExpectActualTracker.DoNothing - ) + checker.checkExpectedDeclarationHasActual(declaration, descriptor, trace, module, ExpectActualTracker.DoNothing) } val suppressionCache = KotlinCacheService.getInstance(declaration.project).getSuppressionCache() diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/OptionalExpectationInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/OptionalExpectationInspection.kt index e6a6d9ccf71..cdd86759707 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/OptionalExpectationInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/OptionalExpectationInspection.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.psi.classOrObjectVisitor import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.resolve.MultiTargetPlatform import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker -import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker.allStrongIncompatibilities +import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker.Companion.allStrongIncompatibilities import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.getMultiTargetPlatform import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt index bb44713110a..cb6ede53b78 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt @@ -43,7 +43,7 @@ object JsPlatformConfigurator : PlatformConfigurator( JsExternalChecker, JsInheritanceChecker, JsMultipleInheritanceChecker, JsRuntimeAnnotationChecker, JsDynamicDeclarationChecker, - ExpectedActualDeclarationChecker + ExpectedActualDeclarationChecker() ), additionalCallCheckers = listOf( ReifiedTypeParameterSubstitutionChecker(), diff --git a/konan/library-reader/src/org/jetbrains/kotlin/resolve/konan/platform/KonanPlatformConfigurator.kt b/konan/library-reader/src/org/jetbrains/kotlin/resolve/konan/platform/KonanPlatformConfigurator.kt index 8f8125e52f1..26aad52348a 100644 --- a/konan/library-reader/src/org/jetbrains/kotlin/resolve/konan/platform/KonanPlatformConfigurator.kt +++ b/konan/library-reader/src/org/jetbrains/kotlin/resolve/konan/platform/KonanPlatformConfigurator.kt @@ -19,7 +19,7 @@ import org.jetbrains.kotlin.types.DynamicTypesSettings object KonanPlatformConfigurator : PlatformConfigurator( DynamicTypesSettings(), - additionalDeclarationCheckers = listOf(ExpectedActualDeclarationChecker), + additionalDeclarationCheckers = listOf(ExpectedActualDeclarationChecker()), additionalCallCheckers = listOf( org.jetbrains.kotlin.resolve.jvm.checkers.SuperCallWithDefaultArgumentsChecker(), ReifiedTypeParameterSubstitutionChecker()