Refactor and improve code obtaining actual Java annotation parameter values

Extract Java-specific code into module 'frontend.java' and use already
existing JavaAnnotationArgument facilities to determine the default
parameter value in an actual Java annotation class.

Annotation arguments are not yet supported because to create an instance
of AnnotationValue, we need a descriptor, which is not available at this
point.

 #KT-22704 In Progress
 #KT-28077 Open
This commit is contained in:
Alexander Udalov
2018-10-18 13:13:25 +02:00
parent c08540175b
commit 49d6a7a7cb
13 changed files with 342 additions and 66 deletions
@@ -65,7 +65,7 @@ private fun StorageComponentContainer.configureJavaTopDownAnalysis(
useInstance(VirtualFileFinderFactory.getInstance(project).create(moduleContentScope))
useImpl<JavaPropertyInitializerEvaluatorImpl>()
useInstance(JavaPropertyInitializerEvaluatorImpl)
useImpl<AnnotationResolverImpl>()
useImpl<SignaturePropagatorImpl>()
useImpl<TraceBasedErrorReporter>()
@@ -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)
}
}
}
}
@@ -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
}
}
}
@@ -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
),
@@ -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<ActualAnnotationArgumentExtractor> = 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<MemberDescriptor>) {
if (this is ExpectActualTracker.DoNothing) return
@@ -133,9 +112,6 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
.safeAs<PsiSourceFile>()
?.run { VfsUtilCore.virtualToIoFile(psiFile.virtualFile) }
fun Map<out Compatibility, Collection<MemberDescriptor>>.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<out Compatibility, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean =
this.keys.all { it is Incompatible && it.kind == Compatibility.IncompatibilityKind.STRONG }
}
}
@@ -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<String> = ["bu", "zz"],
// TODO: val ka: Array<KClass<*>> = [Double::class, String::class, LongArray::class, Array<Array<Array<Int>>>::class],
val ea: Array<E> = [E.E2, E.E3]
// TODO: val aa: Array<A> = [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")};
}
@@ -0,0 +1,129 @@
// -- Module: <m1-common> --
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<kotlin.String> = ..., /*21*/ ea: kotlin.Array<E> = ...)
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<E>
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<kotlin.String>
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<E> {
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<E>
}
// -- Module: <m2-jvm> --
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<E> {
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<E!>!
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<E>
}
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<kotlin.String> = ..., /*21*/ ea: kotlin.Array<E> = ...)
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<E>
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<kotlin.String>
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
@@ -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");
@@ -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");
@@ -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()
@@ -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
@@ -43,7 +43,7 @@ object JsPlatformConfigurator : PlatformConfigurator(
JsExternalChecker, JsInheritanceChecker, JsMultipleInheritanceChecker,
JsRuntimeAnnotationChecker,
JsDynamicDeclarationChecker,
ExpectedActualDeclarationChecker
ExpectedActualDeclarationChecker()
),
additionalCallCheckers = listOf(
ReifiedTypeParameterSubstitutionChecker(),
@@ -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()