diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantReturnUnitTypeChecker.fir.txt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantReturnUnitTypeChecker.fir.txt index b1bd68e22fe..598098cb0e4 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantReturnUnitTypeChecker.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantReturnUnitTypeChecker.fir.txt @@ -22,7 +22,7 @@ FILE: RedundantReturnUnitTypeChecker.kt super() } - public final fun too(): @R|kotlin/Annotation|() R|kotlin/Unit| { + public final fun too(): @R|kotlin/Annotation|() R|@R|kotlin/Annotation|() kotlin/Unit| { } public final fun foo(): R|kotlin/Unit| { diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateTypeMismatch.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateTypeMismatch.fir.txt index 72599548ac1..9d78be1a73a 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateTypeMismatch.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateTypeMismatch.fir.txt @@ -19,7 +19,7 @@ FILE: delegateTypeMismatch.kt public get(): R|kotlin/Boolean| private final fun property(initialValue: R|T|): R|kotlin/properties/ReadWriteProperty| { - ^property Q|kotlin/properties/Delegates|.R|kotlin/properties/Delegates.vetoable|(R|/initialValue|, = vetoable@fun (_: R|kotlin/reflect/KProperty<*>|, _: R|T|, _: R|T|): R|kotlin/Boolean| { + ^property Q|kotlin/properties/Delegates|.R|kotlin/properties/Delegates.vetoable|(R|/initialValue|, = vetoable@fun (_: R|@R|kotlin/ParameterName|(name = String(property)) kotlin/reflect/KProperty<*>|, _: R|T|, _: R|T|): R|kotlin/Boolean| { ^ when () { this@R|/A|.R|/A.isLocked| -> { throw R|java/lang/IllegalStateException.IllegalStateException|(String(Cannot modify readonly DescriptorRendererOptions)) diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt index 562e8cceb0b..bc5d111157c 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.name.Name object StandardClassIds { - private val BASE_KOTLIN_PACKAGE = FqName("kotlin") + val BASE_KOTLIN_PACKAGE = FqName("kotlin") val BASE_REFLECT_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("reflect")) private fun String.baseId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier(this)) private fun ClassId.unsignedId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier("U" + shortClassName.identifier)) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt index dd8028efa84..688e77225cd 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir.backend import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.classId import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.StandardClassIds @@ -100,6 +101,10 @@ class Fir2IrTypeConverter( typeAnnotations += it } } + for (attributeAnnotation in attributes.customAnnotations) { + if (annotations.any { it.classId == attributeAnnotation.classId }) continue + typeAnnotations += callGenerator.convertToIrConstructorCall(attributeAnnotation) as? IrConstructorCall ?: continue + } IrSimpleTypeImpl( irSymbol, !typeContext.definitelyNotNull && this.isMarkedNullable, fullyExpandedType(session).typeArguments.map { it.toIrTypeArgument(typeContext) }, diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/CustomAnnotationTypeAttribute.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/CustomAnnotationTypeAttribute.kt new file mode 100644 index 00000000000..25b6dd2b5d5 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/CustomAnnotationTypeAttribute.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2021 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.fir.types + +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.render +import kotlin.reflect.KClass + +class CustomAnnotationTypeAttribute(val annotations: List) : ConeAttribute() { + override fun union(other: CustomAnnotationTypeAttribute?): CustomAnnotationTypeAttribute? = null + + override fun intersect(other: CustomAnnotationTypeAttribute?): CustomAnnotationTypeAttribute? = null + + override fun isSubtypeOf(other: CustomAnnotationTypeAttribute?): Boolean = true + + override fun toString(): String = annotations.joinToString(separator = " ") { it.render() } + + override val key: KClass + get() = CustomAnnotationTypeAttribute::class +} + +private val ConeAttributes.custom: CustomAnnotationTypeAttribute? by ConeAttributes.attributeAccessor() + +val ConeAttributes.customAnnotations: List get() = custom?.annotations.orEmpty() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt index 778e0845323..96dc289ab49 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt @@ -95,6 +95,7 @@ fun List.computeTypeAttributes( ): ConeAttributes { if (this.isEmpty()) return ConeAttributes.Empty val attributes = mutableListOf>() + val customAnnotations = mutableListOf() for (annotation in this) { val type = annotation.annotationTypeRef.coneTypeSafe() ?: continue when (val classId = type.lookupTag.classId) { @@ -102,9 +103,18 @@ fun List.computeTypeAttributes( CompilerConeAttributes.NoInfer.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.NoInfer CompilerConeAttributes.ExtensionFunctionType.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.ExtensionFunctionType CompilerConeAttributes.UnsafeVariance.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.UnsafeVariance - else -> additionalProcessor.invoke(attributes, classId) + else -> { + if (classId.startsWith(StandardClassIds.BASE_KOTLIN_PACKAGE.shortName())) { + // The check ^ is intended to leave only annotations which may be important for BE + customAnnotations += annotation + } + additionalProcessor.invoke(attributes, classId) + } } } + if (customAnnotations.isNotEmpty()) { + attributes += CustomAnnotationTypeAttribute(customAnnotations) + } return ConeAttributes.create(attributes) } diff --git a/compiler/testData/codegen/box/javaInterop/generics/covariantOverrideWithDeclarationSiteProjection.kt b/compiler/testData/codegen/box/javaInterop/generics/covariantOverrideWithDeclarationSiteProjection.kt index 3539ed036d0..8851929302f 100644 --- a/compiler/testData/codegen/box/javaInterop/generics/covariantOverrideWithDeclarationSiteProjection.kt +++ b/compiler/testData/codegen/box/javaInterop/generics/covariantOverrideWithDeclarationSiteProjection.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/loadJava/compiledJava/mutability/LoadIterableWithNullability.fir.txt b/compiler/testData/loadJava/compiledJava/mutability/LoadIterableWithNullability.fir.txt index afffa9d149a..7bf69dc0146 100644 --- a/compiler/testData/loadJava/compiledJava/mutability/LoadIterableWithNullability.fir.txt +++ b/compiler/testData/loadJava/compiledJava/mutability/LoadIterableWithNullability.fir.txt @@ -1,10 +1,10 @@ public abstract interface LoadIterableWithNullability!|> : R|kotlin/Any| { - @R|org/jetbrains/annotations/NotNull|() @R|kotlin/annotations/jvm/Mutable|() public abstract fun getIterable(): R|@EnhancedNullability kotlin/collections/MutableIterable!>| + @R|org/jetbrains/annotations/NotNull|() @R|kotlin/annotations/jvm/Mutable|() public abstract fun getIterable(): R|@EnhancedNullability @R|kotlin/annotations/jvm/Mutable|() kotlin/collections/MutableIterable!>| - public abstract fun setIterable(@R|kotlin/annotations/jvm/Mutable|() @R|org/jetbrains/annotations/NotNull|() Iterable: R|@EnhancedNullability kotlin/collections/MutableIterable!>|): R|kotlin/Unit| + public abstract fun setIterable(@R|kotlin/annotations/jvm/Mutable|() @R|org/jetbrains/annotations/NotNull|() Iterable: R|@EnhancedNullability @R|kotlin/annotations/jvm/Mutable|() kotlin/collections/MutableIterable!>|): R|kotlin/Unit| - @R|org/jetbrains/annotations/NotNull|() @R|kotlin/annotations/jvm/ReadOnly|() public abstract fun getReadOnlyIterable(): R|@EnhancedNullability kotlin/collections/Iterable!>| + @R|org/jetbrains/annotations/NotNull|() @R|kotlin/annotations/jvm/ReadOnly|() public abstract fun getReadOnlyIterable(): R|@EnhancedNullability @R|kotlin/annotations/jvm/ReadOnly|() kotlin/collections/Iterable!>| - public abstract fun setReadOnlyIterable(@R|kotlin/annotations/jvm/ReadOnly|() @R|org/jetbrains/annotations/NotNull|() Iterable: R|@EnhancedNullability kotlin/collections/Iterable!>|): R|kotlin/Unit| + public abstract fun setReadOnlyIterable(@R|kotlin/annotations/jvm/ReadOnly|() @R|org/jetbrains/annotations/NotNull|() Iterable: R|@EnhancedNullability @R|kotlin/annotations/jvm/ReadOnly|() kotlin/collections/Iterable!>|): R|kotlin/Unit| }