[IR] Implement IR checker for expect actual annotations matching
^KT-58551
This commit is contained in:
committed by
Space Team
parent
b6cae1adcc
commit
2980179bd7
+1
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
|||||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||||
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class ExpectedActualDeclarationChecker(
|
class ExpectedActualDeclarationChecker(
|
||||||
|
|||||||
+16
-1
@@ -7,9 +7,10 @@ package org.jetbrains.kotlin.backend.common
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.backend.common.BackendDiagnosticRenderers.INCOMPATIBILITY
|
import org.jetbrains.kotlin.backend.common.BackendDiagnosticRenderers.INCOMPATIBILITY
|
||||||
|
import org.jetbrains.kotlin.backend.common.BackendDiagnosticRenderers.SYMBOL_OWNER_DECLARATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
|
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
|
||||||
import org.jetbrains.kotlin.diagnostics.error0
|
import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME
|
||||||
import org.jetbrains.kotlin.diagnostics.error2
|
import org.jetbrains.kotlin.diagnostics.error2
|
||||||
import org.jetbrains.kotlin.diagnostics.error3
|
import org.jetbrains.kotlin.diagnostics.error3
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
||||||
@@ -17,6 +18,10 @@ import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING
|
|||||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderer
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderer
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.MODULE_WITH_PLATFORM
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.MODULE_WITH_PLATFORM
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||||
|
import org.jetbrains.kotlin.diagnostics.warning2
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||||
|
|
||||||
object CommonBackendErrors {
|
object CommonBackendErrors {
|
||||||
@@ -24,6 +29,7 @@ object CommonBackendErrors {
|
|||||||
val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error2<PsiElement, String, String>()
|
val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error2<PsiElement, String, String>()
|
||||||
val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error2<PsiElement, String, String>()
|
val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error2<PsiElement, String, String>()
|
||||||
val INCOMPATIBLE_MATCHING by error3<PsiElement, String, String, ExpectActualCompatibility.Incompatible<*>>()
|
val INCOMPATIBLE_MATCHING by error3<PsiElement, String, String, ExpectActualCompatibility.Incompatible<*>>()
|
||||||
|
val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning2<PsiElement, IrSymbol, IrSymbol>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
RootDiagnosticRendererFactory.registerFactory(KtDefaultCommonBackendErrorMessages)
|
RootDiagnosticRendererFactory.registerFactory(KtDefaultCommonBackendErrorMessages)
|
||||||
@@ -57,6 +63,12 @@ object KtDefaultCommonBackendErrorMessages : BaseDiagnosticRendererFactory() {
|
|||||||
STRING,
|
STRING,
|
||||||
INCOMPATIBILITY
|
INCOMPATIBILITY
|
||||||
)
|
)
|
||||||
|
map.put(
|
||||||
|
CommonBackendErrors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT,
|
||||||
|
"All annotations from expect declaration `{0}` must be present with the same arguments on actual declaration `{1}` otherwise they have no effect",
|
||||||
|
SYMBOL_OWNER_DECLARATION_FQ_NAME,
|
||||||
|
SYMBOL_OWNER_DECLARATION_FQ_NAME,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,4 +76,7 @@ object BackendDiagnosticRenderers {
|
|||||||
val INCOMPATIBILITY = Renderer<ExpectActualCompatibility.Incompatible<*>> {
|
val INCOMPATIBILITY = Renderer<ExpectActualCompatibility.Incompatible<*>> {
|
||||||
it.reason ?: "<unknown>"
|
it.reason ?: "<unknown>"
|
||||||
}
|
}
|
||||||
|
val SYMBOL_OWNER_DECLARATION_FQ_NAME = Renderer<IrSymbol> {
|
||||||
|
(it.owner as? IrDeclarationWithName)?.fqNameWhenAvailable?.asString() ?: "unknown name"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -33,6 +33,7 @@ object IrActualizer {
|
|||||||
typeSystemContext,
|
typeSystemContext,
|
||||||
ktDiagnosticReporter
|
ktDiagnosticReporter
|
||||||
).collect()
|
).collect()
|
||||||
|
IrExpectActualAnnotationMatchingChecker(expectActualMap, actualDeclarations, typeSystemContext, ktDiagnosticReporter).check()
|
||||||
|
|
||||||
// 2. Remove top-only expect declarations since they are not needed anymore and should not be presented in the final IrFragment
|
// 2. Remove top-only expect declarations since they are not needed anymore and should not be presented in the final IrFragment
|
||||||
// Expect fake-overrides from non-expect classes remain untouched since they will be actualized in the next phase.
|
// Expect fake-overrides from non-expect classes remain untouched since they will be actualized in the next phase.
|
||||||
|
|||||||
+12
@@ -122,6 +122,18 @@ internal fun KtDiagnosticReporterWithImplicitIrBasedContext.reportIncompatibleEx
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun KtDiagnosticReporterWithImplicitIrBasedContext.reportActualAnnotationsNotMatchExpect(
|
||||||
|
expectSymbol: IrSymbol,
|
||||||
|
actualSymbol: IrSymbol,
|
||||||
|
reportOn: IrSymbol,
|
||||||
|
) {
|
||||||
|
at(reportOn.owner as IrDeclaration).report(
|
||||||
|
CommonBackendErrors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT,
|
||||||
|
expectSymbol,
|
||||||
|
actualSymbol,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
internal fun IrElement.containsOptionalExpectation(): Boolean {
|
internal fun IrElement.containsOptionalExpectation(): Boolean {
|
||||||
return this is IrClass &&
|
return this is IrClass &&
|
||||||
this.kind == ClassKind.ANNOTATION_CLASS &&
|
this.kind == ClassKind.ANNOTATION_CLASS &&
|
||||||
|
|||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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.backend.common.actualizer
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
||||||
|
import org.jetbrains.kotlin.ir.util.classIdOrFail
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualAnnotationMatchChecker
|
||||||
|
|
||||||
|
internal class IrExpectActualAnnotationMatchingChecker(
|
||||||
|
private val matchedExpectToActual: Map<IrSymbol, IrSymbol>,
|
||||||
|
private val classActualizationInfo: ClassActualizationInfo,
|
||||||
|
typeSystemContext: IrTypeSystemContext,
|
||||||
|
private val diagnosticsReporter: KtDiagnosticReporterWithImplicitIrBasedContext,
|
||||||
|
) {
|
||||||
|
private val context = object : IrExpectActualMatchingContext(typeSystemContext, classActualizationInfo.actualClasses) {
|
||||||
|
override fun onMatchedClasses(expectClassSymbol: IrClassSymbol, actualClassSymbol: IrClassSymbol) {
|
||||||
|
error("Must not be called")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMatchedCallables(expectSymbol: IrSymbol, actualSymbol: IrSymbol) {
|
||||||
|
error("Must not be called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun check() {
|
||||||
|
for ((expectSymbol, actualSymbol) in matchedExpectToActual.entries) {
|
||||||
|
val incompatibility =
|
||||||
|
AbstractExpectActualAnnotationMatchChecker.areAnnotationsCompatible(expectSymbol, actualSymbol, context) ?: continue
|
||||||
|
|
||||||
|
val reportOn = getTypealiasSymbolIfActualizedViaTypealias(expectSymbol) ?: actualSymbol
|
||||||
|
diagnosticsReporter.reportActualAnnotationsNotMatchExpect(
|
||||||
|
incompatibility.expectSymbol as IrSymbol,
|
||||||
|
incompatibility.actualSymbol as IrSymbol,
|
||||||
|
reportOn,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTypealiasSymbolIfActualizedViaTypealias(expectSymbol: IrSymbol): IrTypeAliasSymbol? {
|
||||||
|
val expectDeclaration = expectSymbol.owner as IrDeclaration
|
||||||
|
val topLevelExpectClass = expectDeclaration.parentsWithSelf.filterIsInstance<IrClass>().lastOrNull() ?: return null
|
||||||
|
val classId = topLevelExpectClass.classIdOrFail
|
||||||
|
return classActualizationInfo.actualTypeAliases[classId]
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
-6
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.name.CallableId
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext
|
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
@@ -446,12 +448,21 @@ internal abstract class IrExpectActualMatchingContext(
|
|||||||
abstract fun onMatchedClasses(expectClassSymbol: IrClassSymbol, actualClassSymbol: IrClassSymbol)
|
abstract fun onMatchedClasses(expectClassSymbol: IrClassSymbol, actualClassSymbol: IrClassSymbol)
|
||||||
abstract fun onMatchedCallables(expectSymbol: IrSymbol, actualSymbol: IrSymbol)
|
abstract fun onMatchedCallables(expectSymbol: IrSymbol, actualSymbol: IrSymbol)
|
||||||
|
|
||||||
override val DeclarationSymbolMarker.annotations: List<ExpectActualMatchingContext.AnnotationCallInfo>
|
override val DeclarationSymbolMarker.annotations: List<AnnotationCallInfo>
|
||||||
// TODO(Roman.Efremov): implement in subsequent commits
|
get() = asIr().annotations.map(::AnnotationCallInfoImpl)
|
||||||
get() = emptyList()
|
|
||||||
|
|
||||||
override fun areAnnotationArgumentsEqual(annotation1: ExpectActualMatchingContext.AnnotationCallInfo, annotation2: ExpectActualMatchingContext.AnnotationCallInfo): Boolean {
|
override fun areAnnotationArgumentsEqual(annotation1: AnnotationCallInfo, annotation2: AnnotationCallInfo): Boolean {
|
||||||
// TODO(Roman.Efremov): implement in subsequent commits
|
fun AnnotationCallInfo.getIrElement(): IrConstructorCall = (this as AnnotationCallInfoImpl).irElement
|
||||||
return true
|
|
||||||
|
return areIrExpressionConstValuesEqual(annotation1.getIrElement(), annotation2.getIrElement())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun getClassIdAfterActualization(classId: ClassId): ClassId {
|
||||||
|
return expectToActualClassMap[classId]?.classId ?: classId
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AnnotationCallInfoImpl(val irElement: IrConstructorCall) : AnnotationCallInfo {
|
||||||
|
override val classId: ClassId?
|
||||||
|
get() = irElement.type.getClass()?.classId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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.backend.common.actualizer
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.types.classOrFail
|
||||||
|
|
||||||
|
internal fun IrExpectActualMatchingContext.areIrExpressionConstValuesEqual(a: IrElement?, b: IrElement?): Boolean {
|
||||||
|
return when {
|
||||||
|
a == null || b == null -> (a == null) == (b == null)
|
||||||
|
|
||||||
|
a::class != b::class -> false
|
||||||
|
|
||||||
|
a is IrConst<*> && b is IrConst<*> -> a.value == b.value
|
||||||
|
|
||||||
|
a is IrClassReference && b is IrClassReference -> equalBy(a, b) {
|
||||||
|
val classId = it.classType.classOrFail.classId
|
||||||
|
getClassIdAfterActualization(classId)
|
||||||
|
}
|
||||||
|
|
||||||
|
a is IrGetEnumValue && b is IrGetEnumValue -> equalBy(a, b) { it.symbol.signature?.toString() }
|
||||||
|
|
||||||
|
a is IrVararg && b is IrVararg -> {
|
||||||
|
equalBy(a, b) { it.elements.size } &&
|
||||||
|
a.elements.zip(b.elements).all { (f, s) -> areIrExpressionConstValuesEqual(f, s) }
|
||||||
|
}
|
||||||
|
|
||||||
|
a is IrConstructorCall && b is IrConstructorCall -> {
|
||||||
|
equalBy(a, b) { it.valueArgumentsCount } &&
|
||||||
|
areCompatibleExpectActualTypes(a.type, b.type) &&
|
||||||
|
(0..<a.valueArgumentsCount).all { i ->
|
||||||
|
areIrExpressionConstValuesEqual(a.getValueArgument(i), b.getValueArgument(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> error("Not handled expression types $a $b")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun <T : Any> equalBy(first: T, second: T, selector: (T) -> Any?): Boolean =
|
||||||
|
selector(first) == selector(second)
|
||||||
+6
-6
@@ -87,8 +87,8 @@ package test
|
|||||||
@ClassArgAnn(ClassForReference::class)
|
@ClassArgAnn(ClassForReference::class)
|
||||||
actual fun getClassExpression() {}
|
actual fun getClassExpression() {}
|
||||||
|
|
||||||
@ClassArgAnn(ClassForReference::class)
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@ClassArgAnn(ClassForReference::class)
|
||||||
actual fun differentClassesWithSameName() {}
|
actual fun differentClassesWithSameName() {}<!>
|
||||||
|
|
||||||
@StringArgAnn("1.9")
|
@StringArgAnn("1.9")
|
||||||
actual fun stringConstant() {}
|
actual fun stringConstant() {}
|
||||||
@@ -114,8 +114,8 @@ actual fun varargInAnnotationWithArraySpread() {}
|
|||||||
@ArrayArgAnn(arrayOf("foo", "bar"))
|
@ArrayArgAnn(arrayOf("foo", "bar"))
|
||||||
actual fun arrayInAnnotation() {}
|
actual fun arrayInAnnotation() {}
|
||||||
|
|
||||||
@ArrayArgAnn(["foo"])
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@ArrayArgAnn(["foo"])
|
||||||
actual fun arrayInAnnotationNotMatch() {}
|
actual fun arrayInAnnotationNotMatch() {}<!>
|
||||||
|
|
||||||
@NestedAnnArg(
|
@NestedAnnArg(
|
||||||
text = "root",
|
text = "root",
|
||||||
@@ -127,7 +127,7 @@ actual fun arrayInAnnotationNotMatch() {}
|
|||||||
)
|
)
|
||||||
actual fun complexNestedAnnotations() {}
|
actual fun complexNestedAnnotations() {}
|
||||||
|
|
||||||
@NestedAnnArg(
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@NestedAnnArg(
|
||||||
text = "root",
|
text = "root",
|
||||||
NestedAnnArg("1"),
|
NestedAnnArg("1"),
|
||||||
NestedAnnArg("2",
|
NestedAnnArg("2",
|
||||||
@@ -135,4 +135,4 @@ actual fun complexNestedAnnotations() {}
|
|||||||
NestedAnnArg("DIFFERENT")
|
NestedAnnArg("DIFFERENT")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
actual fun complexNestedAnnotationsNotMatch() {}
|
actual fun complexNestedAnnotationsNotMatch() {}<!>
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
annotation class Ann(val p: String = "")
|
||||||
|
@Ann("")
|
||||||
|
expect fun explicitDefaultArgument()
|
||||||
|
|
||||||
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
|
// FILE: jvm.kt
|
||||||
|
// No special handling for this case
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann
|
||||||
|
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>explicitDefaultArgument<!>() {}<!>
|
||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
// MODULE: m1-common
|
// MODULE: m1-common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
annotation class Ann(val p: String = "")
|
annotation class Ann(val p: String = "")
|
||||||
|
|||||||
compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTypeParameters.fir.kt
Vendored
+14
-14
@@ -62,26 +62,26 @@ expect fun explicitVsInfered()
|
|||||||
@Ann<A>
|
@Ann<A>
|
||||||
actual fun sameTypeParam() {}
|
actual fun sameTypeParam() {}
|
||||||
|
|
||||||
@Ann<A>
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<A>
|
||||||
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentTypeParam<!>() {}
|
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentTypeParam<!>() {}<!>
|
||||||
|
|
||||||
@Ann<A>
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<A>
|
||||||
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentWithSameName<!>() {}
|
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentWithSameName<!>() {}<!>
|
||||||
|
|
||||||
@Ann<A>
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<A>
|
||||||
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>nonNullvsNull<!>() {}
|
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>nonNullvsNull<!>() {}<!>
|
||||||
|
|
||||||
@Ann<Ann<out A>>
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<Ann<out A>>
|
||||||
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentVariance<!>() {}
|
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentVariance<!>() {}<!>
|
||||||
|
|
||||||
@Ann<Ann<A>>
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<Ann<A>>
|
||||||
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>varianceVsNoVariance<!>() {}
|
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>varianceVsNoVariance<!>() {}<!>
|
||||||
|
|
||||||
@Ann<Ann<in A>>
|
@Ann<Ann<in A>>
|
||||||
actual fun sameVariance() {}
|
actual fun sameVariance() {}
|
||||||
|
|
||||||
@Ann<Ann<Any>>
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<Ann<Any>>
|
||||||
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>startProjection<!>() {}
|
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>startProjection<!>() {}<!>
|
||||||
|
|
||||||
@ComplexNested<A>(
|
@ComplexNested<A>(
|
||||||
ComplexNested<A>(),
|
ComplexNested<A>(),
|
||||||
@@ -89,11 +89,11 @@ actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_E
|
|||||||
)
|
)
|
||||||
actual fun complexSame() {}
|
actual fun complexSame() {}
|
||||||
|
|
||||||
@ComplexNested<A>(
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@ComplexNested<A>(
|
||||||
ComplexNested<A>(),
|
ComplexNested<A>(),
|
||||||
ComplexNested<A>(),
|
ComplexNested<A>(),
|
||||||
)
|
)
|
||||||
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>complexDiffer<!>() {}
|
actual fun complexDiffer() {}<!>
|
||||||
|
|
||||||
@NestedWithSameTypeArgument<A>(
|
@NestedWithSameTypeArgument<A>(
|
||||||
NestedWithSameTypeArgument<A>()
|
NestedWithSameTypeArgument<A>()
|
||||||
|
|||||||
Vendored
+41
@@ -0,0 +1,41 @@
|
|||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
annotation class Ann
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
expect class AnnotationMatching
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
expect class AnnotationOnExpectOnly
|
||||||
|
|
||||||
|
expect class AnnotationOnActualOnly
|
||||||
|
|
||||||
|
expect class AnnotationInside {
|
||||||
|
@Ann
|
||||||
|
fun matches()
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
fun onlyOnExpect()
|
||||||
|
|
||||||
|
fun onlyOnActual()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
|
// FILE: jvm.kt
|
||||||
|
@Ann
|
||||||
|
actual class AnnotationMatching
|
||||||
|
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual class <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>AnnotationOnExpectOnly<!><!>
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
actual class AnnotationOnActualOnly
|
||||||
|
|
||||||
|
actual class AnnotationInside {
|
||||||
|
@Ann
|
||||||
|
actual fun matches() {}
|
||||||
|
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>onlyOnExpect<!>() {}<!>
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
actual fun onlyOnActual() {}
|
||||||
|
}
|
||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
// MODULE: m1-common
|
// MODULE: m1-common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
annotation class Ann
|
annotation class Ann
|
||||||
|
|||||||
+3
-3
@@ -1,17 +1,17 @@
|
|||||||
// -- Module: <m1-common> --
|
// -- Module: <m1-common> --
|
||||||
|
|
||||||
// -- Module: <m1-jvm> --
|
// -- Module: <m1-jvm> --
|
||||||
/jvm.kt:24:14: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
/jvm.kt:23:14: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
||||||
Expected: @Ann public final expect class OnClass defined in root package in file common.kt
|
Expected: @Ann public final expect class OnClass defined in root package in file common.kt
|
||||||
Actual: public final actual class OnClass defined in root package in file jvm.kt
|
Actual: public final actual class OnClass defined in root package in file jvm.kt
|
||||||
actual class OnClass
|
actual class OnClass
|
||||||
^
|
^
|
||||||
/jvm.kt:27:16: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
/jvm.kt:26:16: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
||||||
Expected: @Ann public final expect fun onMember(): Unit defined in OnMember
|
Expected: @Ann public final expect fun onMember(): Unit defined in OnMember
|
||||||
Actual: public final actual fun onMember(): Unit defined in OnMember
|
Actual: public final actual fun onMember(): Unit defined in OnMember
|
||||||
actual fun onMember() {}
|
actual fun onMember() {}
|
||||||
^
|
^
|
||||||
/jvm.kt:34:18: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
/jvm.kt:33:18: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
||||||
Expected: @Ann public final expect class ViaTypealias defined in root package in file common.kt
|
Expected: @Ann public final expect class ViaTypealias defined in root package in file common.kt
|
||||||
Actual: public final class ViaTypealiasImpl defined in root package in file jvm.kt
|
Actual: public final class ViaTypealiasImpl defined in root package in file jvm.kt
|
||||||
actual typealias ViaTypealias = ViaTypealiasImpl
|
actual typealias ViaTypealias = ViaTypealiasImpl
|
||||||
|
|||||||
+3
-3
@@ -1,11 +1,11 @@
|
|||||||
/jvm.kt:(83,90): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
/jvm.kt:(82,89): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
||||||
Expected: @Ann() public final expect class OnClass : Any
|
Expected: @Ann() public final expect class OnClass : Any
|
||||||
Actual: public final actual class OnClass : Any
|
Actual: public final actual class OnClass : Any
|
||||||
|
|
||||||
/jvm.kt:(131,139): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
/jvm.kt:(130,138): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
||||||
Expected: @Ann() public final expect fun onMember(): Unit
|
Expected: @Ann() public final expect fun onMember(): Unit
|
||||||
Actual: public final actual fun onMember(): Unit
|
Actual: public final actual fun onMember(): Unit
|
||||||
|
|
||||||
/jvm.kt:(210,222): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
/jvm.kt:(209,221): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
|
||||||
Expected: @Ann() public final expect class ViaTypealias : Any
|
Expected: @Ann() public final expect class ViaTypealias : Any
|
||||||
Actual: public final class ViaTypealiasImpl : Any
|
Actual: public final class ViaTypealiasImpl : Any
|
||||||
|
|||||||
Vendored
+33
@@ -0,0 +1,33 @@
|
|||||||
|
// RENDER_DIAGNOSTICS_FULL_TEXT
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
annotation class Ann
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
expect class OnClass
|
||||||
|
|
||||||
|
expect class OnMember {
|
||||||
|
@Ann
|
||||||
|
fun onMember()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
expect class ViaTypealias {
|
||||||
|
@Ann
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
|
// FILE: jvm.kt
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual class <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>OnClass<!><!>
|
||||||
|
|
||||||
|
actual class OnMember {
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>onMember<!>() {}<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViaTypealiasImpl {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>ViaTypealias<!> = ViaTypealiasImpl<!>
|
||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
// RENDER_DIAGNOSTICS_FULL_TEXT
|
// RENDER_DIAGNOSTICS_FULL_TEXT
|
||||||
// MODULE: m1-common
|
// MODULE: m1-common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
|
|||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
annotation class Ann
|
||||||
|
|
||||||
|
expect class CompatibleOverrides {
|
||||||
|
fun foo()
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
fun foo(withArg: Any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
|
// FILE: jvm.kt
|
||||||
|
actual class CompatibleOverrides {
|
||||||
|
actual fun foo() {}
|
||||||
|
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>foo<!>(withArg: Any) {}<!>
|
||||||
|
}
|
||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
// MODULE: m1-common
|
// MODULE: m1-common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
annotation class Ann
|
annotation class Ann
|
||||||
|
|||||||
+2
-2
@@ -24,8 +24,8 @@ expect fun differentArgumentsOrder()
|
|||||||
@Ann1
|
@Ann1
|
||||||
actual class AnnotationOrder
|
actual class AnnotationOrder
|
||||||
|
|
||||||
@Ann3(2, 1)
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann3(2, 1)
|
||||||
actual class ValuesOrderInsideAnnotationArgument
|
actual class ValuesOrderInsideAnnotationArgument<!>
|
||||||
|
|
||||||
@Ann4(arg2 = "2", arg1 = "1")
|
@Ann4(arg2 = "2", arg1 = "1")
|
||||||
actual fun differentArgumentsOrder() {}
|
actual fun differentArgumentsOrder() {}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -7,5 +7,5 @@ expect fun floatNumbersComparison()
|
|||||||
|
|
||||||
// MODULE: m1-jvm()()(m1-common)
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
// FILE: jvm.kt
|
// FILE: jvm.kt
|
||||||
@Ann(0.1 + 0.1 + 0.1)
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann(0.1 + 0.1 + 0.1)
|
||||||
actual fun floatNumbersComparison() {}
|
actual fun floatNumbersComparison() {}<!>
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// WITH_STDLIB
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
@Target(AnnotationTarget.TYPEALIAS, AnnotationTarget.CLASS)
|
||||||
|
annotation class Ann
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
expect class KtTypealiasNotMatch
|
||||||
|
|
||||||
|
@Ann
|
||||||
|
expect class AnnotationsNotConsideredOnTypealias
|
||||||
|
|
||||||
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
|
// FILE: jvm.kt
|
||||||
|
class KtTypealiasNotMatchImpl
|
||||||
|
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>KtTypealiasNotMatch<!> = KtTypealiasNotMatchImpl<!>
|
||||||
|
|
||||||
|
class AnnotationsNotConsideredOnTypealiasImpl
|
||||||
|
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann
|
||||||
|
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>AnnotationsNotConsideredOnTypealias<!> = AnnotationsNotConsideredOnTypealiasImpl<!>
|
||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
// MODULE: m1-common
|
// MODULE: m1-common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
|
|||||||
Vendored
+1
-1
@@ -9,6 +9,6 @@ expect annotation class MyDeprecatedMatch
|
|||||||
|
|
||||||
// MODULE: m1-jvm()()(m1-common)
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
// FILE: jvm.kt
|
// FILE: jvm.kt
|
||||||
actual typealias MyDeprecatedNotMatch = java.lang.Deprecated
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias MyDeprecatedNotMatch = java.lang.Deprecated<!>
|
||||||
|
|
||||||
actual typealias MyDeprecatedMatch = java.lang.Deprecated
|
actual typealias MyDeprecatedMatch = java.lang.Deprecated
|
||||||
|
|||||||
Vendored
+11
-1
@@ -1,4 +1,5 @@
|
|||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
// DIAGNOSTICS: -ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION
|
||||||
// MODULE: m1-common
|
// MODULE: m1-common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
@Target(
|
@Target(
|
||||||
@@ -25,8 +26,17 @@ expect annotation class MyDeprecatedNotMatch
|
|||||||
)
|
)
|
||||||
expect annotation class MyDeprecatedMatch
|
expect annotation class MyDeprecatedMatch
|
||||||
|
|
||||||
|
annotation class Ann(val s: String)
|
||||||
|
|
||||||
|
expect abstract class MyAbstractIterator<T> {
|
||||||
|
@Ann("something" + "complex")
|
||||||
|
fun hasNext(): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
// MODULE: m1-jvm()()(m1-common)
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
// FILE: jvm.kt
|
// FILE: jvm.kt
|
||||||
actual typealias MyDeprecatedNotMatch = kotlin.Deprecated
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias MyDeprecatedNotMatch = kotlin.Deprecated<!>
|
||||||
|
|
||||||
actual typealias MyDeprecatedMatch = kotlin.Deprecated
|
actual typealias MyDeprecatedMatch = kotlin.Deprecated
|
||||||
|
|
||||||
|
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias MyAbstractIterator<T> = AbstractIterator<T><!>
|
||||||
|
|||||||
Vendored
+10
@@ -1,4 +1,5 @@
|
|||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
// DIAGNOSTICS: -ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION
|
||||||
// MODULE: m1-common
|
// MODULE: m1-common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
@Target(
|
@Target(
|
||||||
@@ -25,8 +26,17 @@ expect annotation class MyDeprecatedNotMatch
|
|||||||
)
|
)
|
||||||
expect annotation class MyDeprecatedMatch
|
expect annotation class MyDeprecatedMatch
|
||||||
|
|
||||||
|
annotation class Ann(val s: String)
|
||||||
|
|
||||||
|
expect abstract class MyAbstractIterator<T> {
|
||||||
|
@Ann("something" + "complex")
|
||||||
|
fun hasNext(): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
// MODULE: m1-jvm()()(m1-common)
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
// FILE: jvm.kt
|
// FILE: jvm.kt
|
||||||
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MyDeprecatedNotMatch<!> = kotlin.Deprecated
|
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MyDeprecatedNotMatch<!> = kotlin.Deprecated
|
||||||
|
|
||||||
actual typealias MyDeprecatedMatch = kotlin.Deprecated
|
actual typealias MyDeprecatedMatch = kotlin.Deprecated
|
||||||
|
|
||||||
|
actual typealias MyAbstractIterator<T> = AbstractIterator<T>
|
||||||
|
|||||||
Reference in New Issue
Block a user