From b42a3e6f6c55e3961144f6b49a3062f06271aa41 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 19 Sep 2013 21:29:35 +0400 Subject: [PATCH] Write KotlinPackageFragment annotation to package$src classes --- .../jet/codegen/NamespaceCodegen.java | 8 +++ .../KotlinPackageFragmentAnnotationTest.java | 58 +++++++++++++++++++ .../lang/resolve/java/JvmAnnotationNames.java | 3 + runtime/src/jet/KotlinPackageFragment.java | 25 ++++++++ 4 files changed, 94 insertions(+) create mode 100644 compiler/tests/org/jetbrains/jet/codegen/KotlinPackageFragmentAnnotationTest.java create mode 100644 runtime/src/jet/KotlinPackageFragment.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index e1e829f0be7..d152d38cd2c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -194,6 +194,8 @@ public class NamespaceCodegen extends MemberCodegen { ); builder.visitSource(file.getName(), null); + writeKotlinPackageFragmentAnnotation(builder); + FieldOwnerContext nameSpaceContext = CodegenContext.STATIC.intoNamespace(descriptor); FieldOwnerContext nameSpacePart = CodegenContext.STATIC.intoNamespacePart(className, descriptor); @@ -212,6 +214,12 @@ public class NamespaceCodegen extends MemberCodegen { return builder; } + private static void writeKotlinPackageFragmentAnnotation(@NotNull ClassBuilder builder) { + AnnotationVisitor av = builder.newAnnotation(JvmAnnotationNames.KOTLIN_PACKAGE_FRAGMENT.getDescriptor(), true); + av.visit(JvmAnnotationNames.ABI_VERSION_FIELD_NAME, JvmAbi.VERSION); + av.visitEnd(); + } + public void generateClassOrObject(@NotNull JetClassOrObject classOrObject) { CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); genClassOrObject(context, classOrObject); diff --git a/compiler/tests/org/jetbrains/jet/codegen/KotlinPackageFragmentAnnotationTest.java b/compiler/tests/org/jetbrains/jet/codegen/KotlinPackageFragmentAnnotationTest.java new file mode 100644 index 00000000000..370c03a6a12 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/KotlinPackageFragmentAnnotationTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.codegen; + +import jet.KotlinPackageFragment; +import org.jetbrains.jet.ConfigurationKind; +import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; +import org.jetbrains.jet.lang.resolve.name.FqName; + +public class KotlinPackageFragmentAnnotationTest extends CodegenTestCase { + public static final FqName NAMESPACE_NAME = new FqName("test"); + + @Override + protected void setUp() throws Exception { + super.setUp(); + createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); + } + + public void testKotlinPackageFragmentIsWritten() throws Exception { + loadText("package " + NAMESPACE_NAME + "\n\nfun foo() = 42\n"); + String facadeFileName = JvmClassName.byFqNameWithoutInnerClasses(PackageClassUtils.getPackageClassFqName(NAMESPACE_NAME)).getInternalName() + ".class"; + + ClassFileFactory factory = generateClassesInFile(); + for (String fileName : factory.files()) { + if (!fileName.equals(facadeFileName)) { + // The file which is not a facade is a package fragment + String fqName = fileName.substring(0, fileName.length() - ".class".length()).replace('/', '.'); + Class aClass = generateClass(fqName); + assertTrue("No KotlinPackageFragment annotation on a package fragment", + aClass.isAnnotationPresent(KotlinPackageFragment.class)); + + KotlinPackageFragment annotation = (KotlinPackageFragment) aClass.getAnnotation(KotlinPackageFragment.class); + assertTrue("KotlinPackageFragment annotation is written with an unsupported format", + AbiVersionUtil.isAbiVersionCompatible(annotation.abiVersion())); + + return; + } + } + + fail("No package fragment was found: " + factory.files()); + } +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JvmAnnotationNames.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JvmAnnotationNames.java index 148d2f8fd8d..1f0ed1b5ae3 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JvmAnnotationNames.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JvmAnnotationNames.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java; import jet.KotlinClass; import jet.KotlinPackage; +import jet.KotlinPackageFragment; import jet.runtime.typeinfo.KotlinSignature; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.name.Name; @@ -28,6 +29,8 @@ public final class JvmAnnotationNames { public static final JvmClassName KOTLIN_PACKAGE = JvmClassName.byClass(KotlinPackage.class); + public static final JvmClassName KOTLIN_PACKAGE_FRAGMENT = JvmClassName.byClass(KotlinPackageFragment.class); + public static final String ABI_VERSION_FIELD_NAME = "abiVersion"; public static final String DATA_FIELD_NAME = "data"; diff --git a/runtime/src/jet/KotlinPackageFragment.java b/runtime/src/jet/KotlinPackageFragment.java new file mode 100644 index 00000000000..0b5b0e17430 --- /dev/null +++ b/runtime/src/jet/KotlinPackageFragment.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package jet; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface KotlinPackageFragment { + int abiVersion(); +}