diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java index a59e5292452..3c44f53f6cc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java @@ -136,16 +136,14 @@ public class JvmSerializerExtension extends SerializerExtension { @Override public void serializeType(@NotNull KotlinType type, @NotNull ProtoBuf.Type.Builder proto) { // TODO: don't store type annotations in our binary metadata on Java 8, use *TypeAnnotations attributes instead - for (AnnotationDescriptor annotation : type.getAnnotations()) { + for (AnnotationDescriptor annotation : DescriptorUtilsKt.getNonSourceAnnotations(type)) { proto.addExtension(JvmProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation)); } } @Override - public void serializeTypeParameter( - @NotNull TypeParameterDescriptor typeParameter, @NotNull ProtoBuf.TypeParameter.Builder proto - ) { - for (AnnotationDescriptor annotation : typeParameter.getAnnotations()) { + public void serializeTypeParameter(@NotNull TypeParameterDescriptor typeParameter, @NotNull ProtoBuf.TypeParameter.Builder proto) { + for (AnnotationDescriptor annotation : DescriptorUtilsKt.getNonSourceAnnotations(typeParameter)) { proto.addExtension(JvmProtoBuf.typeParameterAnnotation, annotationSerializer.serializeAnnotation(annotation)); } } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt index 9d2b0eaa8e3..d85e9b0f0e7 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt @@ -33,6 +33,8 @@ import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.constants.IntValue import org.jetbrains.kotlin.resolve.constants.NullValue import org.jetbrains.kotlin.resolve.constants.StringValue +import org.jetbrains.kotlin.resolve.descriptorUtil.isSourceAnnotation +import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.contains @@ -396,7 +398,9 @@ class DescriptorSerializer private constructor( builder.versionRequirement = requirement } - builder.addAllAnnotation(descriptor.annotations.map { extension.annotationSerializer.serializeAnnotation(it) }) + for (annotation in descriptor.nonSourceAnnotations) { + builder.addAnnotation(extension.annotationSerializer.serializeAnnotation(annotation)) + } return builder } @@ -775,7 +779,11 @@ class DescriptorSerializer private constructor( Variance.OUT_VARIANCE -> ProtoBuf.Type.Argument.Projection.OUT } - private fun hasAnnotations(descriptor: Annotated): Boolean = !descriptor.annotations.isEmpty() + private fun hasAnnotations(descriptor: Annotated): Boolean { + // Sadly, we can't just return `descriptor.nonSourceAnnotations.isNotEmpty()` because that would not + // consider use-site-targeted annotations + return descriptor.annotations.getAllAnnotations().filterNot { it.annotation.isSourceAnnotation }.isNotEmpty() + } fun sort(descriptors: Collection): List = ArrayList(descriptors).apply { diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtensionBase.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtensionBase.kt index 9d86d44249a..ac85508fe3d 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtensionBase.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtensionBase.kt @@ -20,13 +20,14 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.constants.NullValue +import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations import org.jetbrains.kotlin.types.KotlinType open class KotlinSerializerExtensionBase(private val protocol: SerializerExtensionProtocol) : SerializerExtension() { override val stringTable = StringTableImpl() override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) { - for (annotation in descriptor.annotations) { + for (annotation in descriptor.nonSourceAnnotations) { proto.addExtension(protocol.classAnnotation, annotationSerializer.serializeAnnotation(annotation)) } } @@ -36,19 +37,19 @@ open class KotlinSerializerExtensionBase(private val protocol: SerializerExtensi } override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder) { - for (annotation in descriptor.annotations) { + for (annotation in descriptor.nonSourceAnnotations) { proto.addExtension(protocol.constructorAnnotation, annotationSerializer.serializeAnnotation(annotation)) } } override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) { - for (annotation in descriptor.annotations) { + for (annotation in descriptor.nonSourceAnnotations) { proto.addExtension(protocol.functionAnnotation, annotationSerializer.serializeAnnotation(annotation)) } } override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) { - for (annotation in descriptor.annotations) { + for (annotation in descriptor.nonSourceAnnotations) { proto.addExtension(protocol.propertyAnnotation, annotationSerializer.serializeAnnotation(annotation)) } val constantInitializer = descriptor.compileTimeInitializer ?: return @@ -58,25 +59,25 @@ open class KotlinSerializerExtensionBase(private val protocol: SerializerExtensi } override fun serializeEnumEntry(descriptor: ClassDescriptor, proto: ProtoBuf.EnumEntry.Builder) { - for (annotation in descriptor.annotations) { + for (annotation in descriptor.nonSourceAnnotations) { proto.addExtension(protocol.enumEntryAnnotation, annotationSerializer.serializeAnnotation(annotation)) } } override fun serializeValueParameter(descriptor: ValueParameterDescriptor, proto: ProtoBuf.ValueParameter.Builder) { - for (annotation in descriptor.annotations) { + for (annotation in descriptor.nonSourceAnnotations) { proto.addExtension(protocol.parameterAnnotation, annotationSerializer.serializeAnnotation(annotation)) } } override fun serializeType(type: KotlinType, proto: ProtoBuf.Type.Builder) { - for (annotation in type.annotations) { + for (annotation in type.nonSourceAnnotations) { proto.addExtension(protocol.typeAnnotation, annotationSerializer.serializeAnnotation(annotation)) } } override fun serializeTypeParameter(typeParameter: TypeParameterDescriptor, proto: ProtoBuf.TypeParameter.Builder) { - for (annotation in typeParameter.annotations) { + for (annotation in typeParameter.nonSourceAnnotations) { proto.addExtension(protocol.typeParameterAnnotation, annotationSerializer.serializeAnnotation(annotation)) } } diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.kt b/compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.kt new file mode 100644 index 00000000000..995b43c418f --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.kt @@ -0,0 +1,17 @@ +// ALLOW_AST_ACCESS +// NO_CHECK_SOURCE_VS_BINARY + +package test + +@Target(AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPEALIAS, AnnotationTarget.TYPE) +@Retention(AnnotationRetention.SOURCE) +annotation class A + +class TypeParameterAnnotation { + fun <@A T> foo(x: T) {} +} + +@A +typealias TypeAliasAnnotation = List + +fun typeAnnotation(): @A Unit {} diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.txt b/compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.txt new file mode 100644 index 00000000000..2dcff05a5cd --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.txt @@ -0,0 +1,13 @@ +package test + +public fun typeAnnotation(): kotlin.Unit + +@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPEALIAS, AnnotationTarget.TYPE}) @kotlin.annotation.Retention(value = AnnotationRetention.SOURCE) public final annotation class A : kotlin.Annotation { + /*primary*/ public constructor A() +} + +public final class TypeParameterAnnotation { + /*primary*/ public constructor TypeParameterAnnotation() + public final fun foo(/*0*/ x: T): kotlin.Unit +} +public typealias TypeAliasAnnotation = kotlin.collections.List diff --git a/compiler/testData/serialization/builtinsSerializer/binaryRetainedAnnotation.kt b/compiler/testData/serialization/builtinsSerializer/binaryRetainedAnnotation.kt new file mode 100644 index 00000000000..99796764d56 --- /dev/null +++ b/compiler/testData/serialization/builtinsSerializer/binaryRetainedAnnotation.kt @@ -0,0 +1,21 @@ +package test + +import kotlin.annotation.AnnotationTarget.* + +@Retention(AnnotationRetention.BINARY) +@Target(CLASS, CONSTRUCTOR, FUNCTION, PROPERTY, VALUE_PARAMETER, TYPE, TYPE_PARAMETER) +annotation class A + +@A +class Klass @A constructor() + +@A +fun <@A T> function(@A param: Unit): @A Unit {} + +@A +val property = Unit + +enum class Enum { + @A + ENTRY +} diff --git a/compiler/testData/serialization/builtinsSerializer/binaryRetainedAnnotation.txt b/compiler/testData/serialization/builtinsSerializer/binaryRetainedAnnotation.txt new file mode 100644 index 00000000000..eba3372b80b --- /dev/null +++ b/compiler/testData/serialization/builtinsSerializer/binaryRetainedAnnotation.txt @@ -0,0 +1,26 @@ +package test + +@test.A public val property: kotlin.Unit +@test.A public fun function(/*0*/ @test.A param: kotlin.Unit): @test.A kotlin.Unit + +@kotlin.annotation.Retention(value = AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER}) public final annotation class A : kotlin.Annotation { + public constructor A() +} + +public final enum class Enum : kotlin.Enum { + @test.A enum entry ENTRY + + private constructor Enum() + 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: test.Enum): kotlin.Int + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Enum + public final /*synthesized*/ fun values(): kotlin.Array +} + +@test.A public final class Klass { + @test.A public constructor Klass() +} diff --git a/compiler/testData/serialization/builtinsSerializer/sourceRetainedAnnotation.kt b/compiler/testData/serialization/builtinsSerializer/sourceRetainedAnnotation.kt new file mode 100644 index 00000000000..24564a1c2ca --- /dev/null +++ b/compiler/testData/serialization/builtinsSerializer/sourceRetainedAnnotation.kt @@ -0,0 +1,21 @@ +package test + +import kotlin.annotation.AnnotationTarget.* + +@Retention(AnnotationRetention.SOURCE) +@Target(CLASS, CONSTRUCTOR, FUNCTION, PROPERTY, VALUE_PARAMETER, TYPE, TYPE_PARAMETER) +annotation class A + +@A +class Klass @A constructor() + +@A +fun <@A T> function(@A param: Unit): @A Unit {} + +@A +val property = Unit + +enum class Enum { + @A + ENTRY +} diff --git a/compiler/testData/serialization/builtinsSerializer/sourceRetainedAnnotation.txt b/compiler/testData/serialization/builtinsSerializer/sourceRetainedAnnotation.txt new file mode 100644 index 00000000000..078881e0ffa --- /dev/null +++ b/compiler/testData/serialization/builtinsSerializer/sourceRetainedAnnotation.txt @@ -0,0 +1,26 @@ +package test + +public val property: kotlin.Unit +public fun function(/*0*/ param: kotlin.Unit): kotlin.Unit + +@kotlin.annotation.Retention(value = AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER}) public final annotation class A : kotlin.Annotation { + public constructor A() +} + +public final enum class Enum : kotlin.Enum { + enum entry ENTRY + + private constructor Enum() + 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: test.Enum): kotlin.Int + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Enum + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final class Klass { + public constructor Klass() +} diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractLoadJavaTest.java b/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractLoadJavaTest.java index 5cf6787adc2..6148815ff4c 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractLoadJavaTest.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractLoadJavaTest.java @@ -119,7 +119,8 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { if (useTypeTableInSerializer) { configuration.put(JVMConfigurationKeys.USE_TYPE_TABLE, true); } - updateConfigurationWithDirectives(ktFile, configuration); + String fileContent = FileUtil.loadFile(ktFile, true); + updateConfigurationWithDirectives(fileContent, configuration); KotlinCoreEnvironment environment = KotlinCoreEnvironment.createForTests(getTestRootDisposable(), configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES); @@ -143,11 +144,17 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { DescriptorValidator.validate(errorTypesForbidden(), packageFromSource); DescriptorValidator.validate(new DeserializedScopeValidationVisitor(), packageFromBinary); Configuration comparatorConfiguration = COMPARATOR_CONFIGURATION.checkPrimaryConstructors(true).checkPropertyAccessors(true).checkFunctionContracts(true); - compareDescriptors(packageFromSource, packageFromBinary, comparatorConfiguration, txtFile); + + if (InTextDirectivesUtils.isDirectiveDefined(fileContent, "NO_CHECK_SOURCE_VS_BINARY")) { + // If NO_CHECK_SOURCE_VS_BINARY is enabled, only check that binary descriptors correspond to the .txt file content + validateAndCompareDescriptorWithFile(packageFromBinary, comparatorConfiguration, txtFile); + } + else { + compareDescriptors(packageFromSource, packageFromBinary, comparatorConfiguration, txtFile); + } } - private static void updateConfigurationWithDirectives(File file, CompilerConfiguration configuration) throws IOException { - String content = FileUtil.loadFile(file, true); + private static void updateConfigurationWithDirectives(String content, CompilerConfiguration configuration) { String version = InTextDirectivesUtils.findStringWithPrefixes(content, "// LANGUAGE_VERSION:"); if (version != null) { LanguageVersion explicitVersion = LanguageVersion.fromVersionString(version); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java index a72228be87e..96aa38dc0f9 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java @@ -2089,6 +2089,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt"); } + @TestMetadata("SourceRetention.kt") + public void testSourceRetention() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.kt"); + } + @TestMetadata("SupertypesAndBounds.kt") public void testSupertypesAndBounds() throws Exception { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SupertypesAndBounds.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadKotlinWithTypeTableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadKotlinWithTypeTableTestGenerated.java index d36b0b73c05..01e5ac7e886 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadKotlinWithTypeTableTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadKotlinWithTypeTableTestGenerated.java @@ -433,6 +433,11 @@ public class LoadKotlinWithTypeTableTestGenerated extends AbstractLoadKotlinWith runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt"); } + @TestMetadata("SourceRetention.kt") + public void testSourceRetention() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.kt"); + } + @TestMetadata("SupertypesAndBounds.kt") public void testSupertypesAndBounds() throws Exception { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SupertypesAndBounds.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java index fa362dc29dc..a97c1249bb4 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/javac/LoadJavaUsingJavacTestGenerated.java @@ -2089,6 +2089,11 @@ public class LoadJavaUsingJavacTestGenerated extends AbstractLoadJavaUsingJavacT runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt"); } + @TestMetadata("SourceRetention.kt") + public void testSourceRetention() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.kt"); + } + @TestMetadata("SupertypesAndBounds.kt") public void testSupertypesAndBounds() throws Exception { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SupertypesAndBounds.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerTest.kt index 611c0ea9f84..6afe4049332 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerTest.kt @@ -104,4 +104,12 @@ class BuiltInsSerializerTest : TestCaseWithTmpdir() { fun testVarArgs() { doTest("annotationArguments/varargs.kt") } + + fun testSourceRetainedAnnotation() { + doTest("sourceRetainedAnnotation.kt") + } + + fun testBinaryRetainedAnnotation() { + doTest("binaryRetainedAnnotation.kt") + } } diff --git a/core/descriptors.runtime/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java b/core/descriptors.runtime/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java index b0298c2a544..b33bf825af8 100644 --- a/core/descriptors.runtime/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java +++ b/core/descriptors.runtime/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java @@ -435,6 +435,11 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt"); } + @TestMetadata("SourceRetention.kt") + public void testSourceRetention() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.kt"); + } + @TestMetadata("SupertypesAndBounds.kt") public void testSupertypesAndBounds() throws Exception { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SupertypesAndBounds.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt index bb9bea4eb38..07baa77e14e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt @@ -23,7 +23,13 @@ interface Annotated { } interface Annotations : Iterable { - + /** + * @return `true` iff there are no "direct" annotations applicable to this declaration. Note that even if [isEmpty] is `true`, + * there may be use-site-targeted annotations applicable to the declaration! + * + * @see getUseSiteTargetedAnnotations + * @see getAllAnnotations + */ fun isEmpty(): Boolean fun findAnnotation(fqName: FqName): AnnotationDescriptor? = firstOrNull { it.fqName == fqName } @@ -32,7 +38,9 @@ interface Annotations : Iterable { fun getUseSiteTargetedAnnotations(): List - // Returns both targeted and annotations without target. Annotation order is preserved. + /** + * @return both targeted and annotations without target. Annotation order is preserved. + */ fun getAllAnnotations(): List companion object { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt index 830d643ad11..b00d57375ba 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt @@ -218,6 +218,18 @@ fun Annotated.getAnnotationRetention(): KotlinRetention? { return KotlinRetention.valueOf(retentionArgumentValue.enumEntryName.asString()) } +val Annotated.nonSourceAnnotations: List + get() = annotations.filterOutSourceAnnotations() + +fun Iterable.filterOutSourceAnnotations(): List = + filterNot(AnnotationDescriptor::isSourceAnnotation) + +val AnnotationDescriptor.isSourceAnnotation: Boolean + get() { + val classDescriptor = annotationClass + return classDescriptor == null || classDescriptor.getAnnotationRetention() == KotlinRetention.SOURCE + } + val DeclarationDescriptor.parentsWithSelf: Sequence get() = generateSequence(this, { it.containingDeclaration }) diff --git a/idea/testData/decompiler/decompiledTextJs/TypeAliases.expected.kt b/idea/testData/decompiler/decompiledTextJs/TypeAliases.expected.kt index e6d0e9d23e2..95f092f235b 100644 --- a/idea/testData/decompiler/decompiledTextJs/TypeAliases.expected.kt +++ b/idea/testData/decompiler/decompiledTextJs/TypeAliases.expected.kt @@ -9,15 +9,15 @@ package test public final class Outer public constructor() { public final inner class Inner public constructor() { - @kotlin.Suppress public typealias TA = kotlin.collections.Map, kotlin.collections.Map> + public typealias TA = kotlin.collections.Map, kotlin.collections.Map> } } public final class TypeAliases public constructor() { public final fun foo(a: dependency.A /* = () -> kotlin.Unit */, b: test.TypeAliases.B /* = (dependency.A /* = () -> kotlin.Unit */) -> kotlin.Unit */, ta: test.Outer.Inner.TA /* = kotlin.collections.Map, kotlin.collections.Map> */): kotlin.Unit { /* compiled code */ } - @kotlin.Suppress public typealias B = (dependency.A) -> kotlin.Unit + public typealias B = (dependency.A) -> kotlin.Unit - @test.Ann @kotlin.Suppress private typealias Parametrized = kotlin.collections.Map + @test.Ann private typealias Parametrized = kotlin.collections.Map } diff --git a/idea/testData/decompiler/decompiledTextJvm/TypeAliases.expected.kt b/idea/testData/decompiler/decompiledTextJvm/TypeAliases.expected.kt index 009a90b4109..d23de240446 100644 --- a/idea/testData/decompiler/decompiledTextJvm/TypeAliases.expected.kt +++ b/idea/testData/decompiler/decompiledTextJvm/TypeAliases.expected.kt @@ -6,8 +6,8 @@ package test public final class TypeAliases public constructor() { public final fun foo(a: dependency.A /* = () -> kotlin.Unit */, b: test.TypeAliases.B /* = (dependency.A /* = () -> kotlin.Unit */) -> kotlin.Unit */, ta: test.Outer.Inner.TA /* = kotlin.collections.Map, kotlin.collections.Map> */): kotlin.Unit { /* compiled code */ } - @kotlin.Suppress public typealias B = (dependency.A) -> kotlin.Unit + public typealias B = (dependency.A) -> kotlin.Unit - @test.Ann @kotlin.Suppress private typealias Parametrized = kotlin.collections.Map + @test.Ann private typealias Parametrized = kotlin.collections.Map } diff --git a/idea/testData/decompiler/stubBuilder/Annotations/Annotations.txt b/idea/testData/decompiler/stubBuilder/Annotations/Annotations.txt index fb04faceb90..b67877f58c2 100644 --- a/idea/testData/decompiler/stubBuilder/Annotations/Annotations.txt +++ b/idea/testData/decompiler/stubBuilder/Annotations/Annotations.txt @@ -268,11 +268,6 @@ PsiJetFileStubImpl[package=] TYPE_REFERENCE USER_TYPE REFERENCE_EXPRESSION[referencedName=a] - ANNOTATION_ENTRY[hasValueArguments=false, shortName=b] - CONSTRUCTOR_CALLEE - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION[referencedName=b] USER_TYPE USER_TYPE USER_TYPE @@ -286,11 +281,6 @@ PsiJetFileStubImpl[package=] TYPE_REFERENCE USER_TYPE REFERENCE_EXPRESSION[referencedName=a] - ANNOTATION_ENTRY[hasValueArguments=false, shortName=b] - CONSTRUCTOR_CALLEE - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION[referencedName=b] USER_TYPE USER_TYPE REFERENCE_EXPRESSION[referencedName=kotlin] diff --git a/idea/testData/decompiler/stubBuilder/TypeAliases/TypeAliases.txt b/idea/testData/decompiler/stubBuilder/TypeAliases/TypeAliases.txt index dfe3a14b92a..2cc7d31e187 100644 --- a/idea/testData/decompiler/stubBuilder/TypeAliases/TypeAliases.txt +++ b/idea/testData/decompiler/stubBuilder/TypeAliases/TypeAliases.txt @@ -97,13 +97,6 @@ PsiJetFileStubImpl[package=test] REFERENCE_EXPRESSION[referencedName=Unit] TYPEALIAS[fqName=test.TypeAliases.B, isTopLevel=false, name=B] MODIFIER_LIST[public] - ANNOTATION_ENTRY[hasValueArguments=false, shortName=Suppress] - CONSTRUCTOR_CALLEE - TYPE_REFERENCE - USER_TYPE - USER_TYPE - REFERENCE_EXPRESSION[referencedName=kotlin] - REFERENCE_EXPRESSION[referencedName=Suppress] TYPE_REFERENCE FUNCTION_TYPE VALUE_PARAMETER_LIST @@ -127,13 +120,6 @@ PsiJetFileStubImpl[package=test] USER_TYPE REFERENCE_EXPRESSION[referencedName=test] REFERENCE_EXPRESSION[referencedName=Ann] - ANNOTATION_ENTRY[hasValueArguments=false, shortName=Suppress] - CONSTRUCTOR_CALLEE - TYPE_REFERENCE - USER_TYPE - USER_TYPE - REFERENCE_EXPRESSION[referencedName=kotlin] - REFERENCE_EXPRESSION[referencedName=Suppress] TYPE_PARAMETER_LIST TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=E] TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=F] diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/LoadJavaClsStubTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/LoadJavaClsStubTestGenerated.java index 4b4f79e8ba4..bb0518e8bdd 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/LoadJavaClsStubTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/LoadJavaClsStubTestGenerated.java @@ -433,6 +433,11 @@ public class LoadJavaClsStubTestGenerated extends AbstractLoadJavaClsStubTest { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt"); } + @TestMetadata("SourceRetention.kt") + public void testSourceRetention() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.kt"); + } + @TestMetadata("SupertypesAndBounds.kt") public void testSupertypesAndBounds() throws Exception { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SupertypesAndBounds.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractResolveByStubTest.kt b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractResolveByStubTest.kt index 2b77c2bdc0d..f3eb8a62ba4 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractResolveByStubTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractResolveByStubTest.kt @@ -24,21 +24,26 @@ import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.util.DescriptorValidator.ValidationVisitor.errorTypesForbidden import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator import org.junit.Assert import java.io.File abstract class AbstractResolveByStubTest : KotlinLightCodeInsightFixtureTestCase() { - @Throws(Exception::class) protected fun doTest(testFileName: String) { doTest(testFileName, true, true) } override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE - @Throws(Exception::class) private fun doTest(path: String, checkPrimaryConstructors: Boolean, checkPropertyAccessors: Boolean) { + if (InTextDirectivesUtils.isDirectiveDefined(File(path).readText(), "NO_CHECK_SOURCE_VS_BINARY")) { + // If NO_CHECK_SOURCE_VS_BINARY is enabled, source vs binary descriptors differ, which means that we should not run this test: + // it would compare descriptors resolved from sources (by stubs) with .txt, which describes binary descriptors + return + } + myFixture.configureByFile(path) val shouldFail = getTestName(false) == "ClassWithConstVal" AstAccessControl.testWithControlledAccessToAst(shouldFail, project, testRootDisposable) { diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java index 55369efb542..ab679c09bfd 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java @@ -433,6 +433,11 @@ public class ResolveByStubTestGenerated extends AbstractResolveByStubTest { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt"); } + @TestMetadata("SourceRetention.kt") + public void testSourceRetention() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SourceRetention.kt"); + } + @TestMetadata("SupertypesAndBounds.kt") public void testSupertypesAndBounds() throws Exception { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/SupertypesAndBounds.kt"); diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt index 85eade564ce..9511d51cb5c 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.protobuf.CodedInputStream import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.descriptorUtil.filterOutSourceAnnotations import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -250,7 +251,7 @@ object KotlinJavascriptSerializationUtil { is KotlinPsiFileMetadata -> file.ktFile.annotationEntries.map { bindingContext[BindingContext.ANNOTATION, it]!! } is KotlinDeserializedFileMetadata -> file.packageFragment.fileMap[file.fileId]!!.annotations } - for (annotation in annotations) { + for (annotation in annotations.filterOutSourceAnnotations()) { fileProto.addAnnotation(serializer.serializeAnnotation(annotation)) } filesProto.addFile(fileProto)