diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java index 792b45863f1..776376ee568 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java @@ -120,8 +120,8 @@ public abstract class ClassBodyCodegen extends MemberCodegen { } protected void generateDeclaration(KtDeclaration declaration) { - if (declaration instanceof KtProperty || declaration instanceof KtNamedFunction) { - genFunctionOrProperty(declaration); + if (declaration instanceof KtProperty || declaration instanceof KtNamedFunction || declaration instanceof KtTypeAlias) { + genSimpleMember(declaration); } else if (declaration instanceof KtClassOrObject) { if (declaration instanceof KtEnumEntry && !enumEntryNeedSubclass(bindingContext, (KtEnumEntry) declaration)) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 5421facebd5..ab9bc4d7c99 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -24,6 +24,7 @@ import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.CodegenUtil; +import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple; import org.jetbrains.kotlin.codegen.context.*; import org.jetbrains.kotlin.codegen.inline.*; import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension; @@ -56,10 +57,7 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.types.ErrorUtils; import org.jetbrains.kotlin.types.KotlinType; -import org.jetbrains.org.objectweb.asm.AnnotationVisitor; -import org.jetbrains.org.objectweb.asm.Label; -import org.jetbrains.org.objectweb.asm.MethodVisitor; -import org.jetbrains.org.objectweb.asm.Type; +import org.jetbrains.org.objectweb.asm.*; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.Method; @@ -67,6 +65,7 @@ import java.util.*; import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED; +import static org.jetbrains.kotlin.resolve.BindingContext.TYPE_ALIAS; import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*; @@ -182,10 +181,10 @@ public abstract class MemberCodegen Unit>() + private val delegateGenerationTasks = hashMapOf Unit>() private fun getSuperClassForPart(partInternalName: String) = if (shouldGeneratePartHierarchy) @@ -249,17 +246,17 @@ class MultifileClassCodegen( val facadeContext = state.rootContext.intoMultifileClass(packageFragment, facadeClassType, partType) val memberCodegen = createCodegenForDelegatesInMultifileFacade(facadeContext) for (declaration in file.declarations) { - if (declaration is KtNamedFunction || declaration is KtProperty) { + if (declaration is KtNamedFunction || declaration is KtProperty || declaration is KtTypeAlias) { val descriptor = state.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) - if (descriptor !is CallableMemberDescriptor) { + if (descriptor !is MemberDescriptor) { throw AssertionError("Expected callable member, was " + descriptor + " for " + declaration.text) } - addDelegateGenerationTaskIfNeeded(descriptor, { memberCodegen.genFunctionOrProperty(declaration) }) + addDelegateGenerationTaskIfNeeded(descriptor, { memberCodegen.genSimpleMember(declaration) }) } } } - private fun shouldGenerateInFacade(descriptor: CallableMemberDescriptor): Boolean { + private fun shouldGenerateInFacade(descriptor: MemberDescriptor): Boolean { if (Visibilities.isPrivate(descriptor.visibility)) return false if (AsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE) return false @@ -272,7 +269,7 @@ class MultifileClassCodegen( return true } - private fun addDelegateGenerationTaskIfNeeded(callable: CallableMemberDescriptor, task: () -> Unit) { + private fun addDelegateGenerationTaskIfNeeded(callable: MemberDescriptor, task: () -> Unit) { if (shouldGenerateInFacade(callable)) { delegateGenerationTasks[callable] = task } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt index 397de3899f3..ca6726322a4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.MultifileClassK import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.KtTypeAlias import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin @@ -127,8 +128,8 @@ class MultifileClassPartCodegen( override fun generateBody() { for (declaration in element.declarations) { - if (declaration is KtNamedFunction || declaration is KtProperty) { - genFunctionOrProperty(declaration) + if (declaration is KtNamedFunction || declaration is KtProperty || declaration is KtTypeAlias) { + genSimpleMember(declaration) } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java index 85a71cbb1da..bfb7b65e731 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java @@ -91,8 +91,8 @@ public class PackagePartCodegen extends MemberCodegen { @Override protected void generateBody() { for (KtDeclaration declaration : element.getDeclarations()) { - if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty) { - genFunctionOrProperty(declaration); + if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty || declaration instanceof KtTypeAlias) { + genSimpleMember(declaration); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.java index eb577094bba..66174606183 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.java @@ -224,8 +224,8 @@ public class ScriptCodegen extends MemberCodegen { private void genMembers() { for (KtDeclaration declaration : scriptDeclaration.getDeclarations()) { - if (declaration instanceof KtProperty || declaration instanceof KtNamedFunction) { - genFunctionOrProperty(declaration); + if (declaration instanceof KtProperty || declaration instanceof KtNamedFunction || declaration instanceof KtTypeAlias) { + genSimpleMember(declaration); } else if (declaration instanceof KtClassOrObject) { genClassOrObject((KtClassOrObject) declaration); diff --git a/compiler/testData/codegen/box/annotations/annotationsOnTypeAliases.kt b/compiler/testData/codegen/box/annotations/annotationsOnTypeAliases.kt new file mode 100644 index 00000000000..fe759e40760 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/annotationsOnTypeAliases.kt @@ -0,0 +1,31 @@ +// WITH_RUNTIME +// FULL_JDK + +import kotlin.annotation.AnnotationTarget.* +import kotlin.annotation.AnnotationRetention.* +import java.lang.Class + +@Target(TYPEALIAS) +@Retention(RUNTIME) +annotation class Ann(val x: Int) + +class C { + @Ann(1) + typealias TA = Any +} + +@Ann(2) +typealias TA = Any + +fun Class<*>.assertHasDeclaredMethodWithAnn() { + if (!declaredMethods.any { it.isSynthetic && it.getAnnotation(Ann::class.java) != null }) { + throw java.lang.AssertionError("Class ${this.simpleName} has no declared method with annotation @Ann") + } +} + +fun box(): String { + Class.forName("AnnotationsOnTypeAliasesKt").assertHasDeclaredMethodWithAnn() + Class.forName("C").assertHasDeclaredMethodWithAnn() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstKotlin/annotationsOnTypeAliases.kt b/compiler/testData/compileKotlinAgainstKotlin/annotationsOnTypeAliases.kt new file mode 100644 index 00000000000..5f543474085 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/annotationsOnTypeAliases.kt @@ -0,0 +1,34 @@ +// FILE: A.kt +package a + +import kotlin.annotation.AnnotationTarget.* +import kotlin.annotation.AnnotationRetention.* +import java.lang.Class + +@Target(TYPEALIAS) +@Retention(RUNTIME) +annotation class Ann(val x: Int) + +class C { + @Ann(1) + typealias TA = Any +} + +@Ann(2) +typealias TA = Any + +// FILE: B.kt +import a.Ann + +fun Class<*>.assertHasDeclaredMethodWithAnn() { + if (!declaredMethods.any { it.isSynthetic && it.getAnnotation(Ann::class.java) != null }) { + throw java.lang.AssertionError("Class ${this.simpleName} has no declared method with annotation @Ann") + } +} + +fun box(): String { + Class.forName("a.AKt").assertHasDeclaredMethodWithAnn() + Class.forName("a.C").assertHasDeclaredMethodWithAnn() + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 80418fd8c3f..1bed76f3870 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -73,6 +73,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("annotationsOnTypeAliases.kt") + public void testAnnotationsOnTypeAliases() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/annotations/annotationsOnTypeAliases.kt"); + doTest(fileName); + } + @TestMetadata("defaultParameterValues.kt") public void testDefaultParameterValues() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/annotations/defaultParameterValues.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java index 4777335f8ad..964e5dd1977 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java @@ -41,6 +41,12 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl doTest(fileName); } + @TestMetadata("annotationsOnTypeAliases.kt") + public void testAnnotationsOnTypeAliases() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/annotationsOnTypeAliases.kt"); + doTest(fileName); + } + @TestMetadata("callsToMultifileClassFromOtherPackage.kt") public void testCallsToMultifileClassFromOtherPackage() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/callsToMultifileClassFromOtherPackage.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAbi.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAbi.java index c298488b5af..56156c04917 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAbi.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAbi.java @@ -45,7 +45,9 @@ public final class JvmAbi { public static final String DELEGATED_PROPERTY_NAME_SUFFIX = "$delegate"; public static final String DELEGATED_PROPERTIES_ARRAY_NAME = "$$delegatedProperties"; public static final String DELEGATE_SUPER_FIELD_PREFIX = "$$delegate_"; - public static final String ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX = "$annotations"; + private static final String ANNOTATIONS_SUFFIX = "$annotations"; + public static final String ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX = ANNOTATIONS_SUFFIX; + public static final String ANNOTATED_TYPEALIAS_METHOD_NAME_SUFFIX = ANNOTATIONS_SUFFIX; public static final String INSTANCE_FIELD = "INSTANCE"; @@ -62,6 +64,11 @@ public final class JvmAbi { return propertyName.asString() + ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX; } + @NotNull + public static String getSyntheticMethodNameForAnnotatedTypeAlias(@NotNull Name typeAliasName) { + return typeAliasName.asString() + ANNOTATED_TYPEALIAS_METHOD_NAME_SUFFIX; + } + public static boolean isGetterName(@NotNull String name) { return name.startsWith(GET_PREFIX) || name.startsWith(IS_PREFIX); }