Drop outdated stuff from metadata annotations

Make KotlinLocalClass and KotlinInterfaceDefaultImpls not retained at runtime,
to be maybe deleted in the future
This commit is contained in:
Alexander Udalov
2015-12-24 05:05:01 +03:00
parent 0ecf04dcc5
commit 0685f06200
17 changed files with 42 additions and 75 deletions
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.name.Name;
@@ -62,8 +61,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.types.KotlinType;
@@ -247,11 +246,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Override
protected void generateKotlinAnnotation() {
if (!isTopLevelOrInnerClass(descriptor)) {
AnnotationVisitor av = v.getVisitor().visitAnnotation(
asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true
);
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
av.visitEnd();
v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true).visitEnd();
}
DescriptorSerializer serializer =
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_INTERFACE_DEFAULT_IMPLS
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.name.Name
@@ -151,9 +150,7 @@ public class InterfaceImplBodyCodegen(
override fun generateKotlinAnnotation() {
(v as InterfaceImplClassBuilder).stopCounting()
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true)
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray())
av.visitEnd()
v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true).visitEnd()
AsmUtil.writeKotlinSyntheticClassAnnotation(v, state)
}
@@ -18,9 +18,9 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import kotlin.CollectionsKt;
import kotlin.StringsKt;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
@@ -224,9 +224,6 @@ public class JvmCodegenUtil {
public static void writeAbiVersion(@NotNull AnnotationVisitor av) {
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
// TODO: drop after some time
av.visit(JvmAnnotationNames.OLD_ABI_VERSION_FIELD_NAME, 32);
}
public static void writeModuleName(@NotNull AnnotationVisitor av, @NotNull GenerationState state) {
@@ -117,14 +117,10 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
}
private void doTestKotlinClass(@NotNull String code, @NotNull String classFilePart) {
doTest(code, classFilePart, KOTLIN_CLASS, KOTLIN_LOCAL_CLASS);
doTest(code, classFilePart, KOTLIN_CLASS);
}
private void doTest(
@NotNull String code,
@NotNull final String classFilePart,
@NotNull FqName... annotationFqNames
) {
private void doTest(@NotNull String code, @NotNull final String classFilePart, @NotNull FqName annotationFqName) {
loadText("package " + PACKAGE_NAME + "\n\n" + code);
List<OutputFile> output = generateClassesInFile().asList();
Collection<OutputFile> files = Collections2.filter(output, new Predicate<OutputFile>() {
@@ -139,9 +135,7 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
String path = files.iterator().next().getRelativePath();
String fqName = path.substring(0, path.length() - ".class".length()).replace('/', '.');
Class<?> aClass = generateClass(fqName);
for (FqName annotationFqName : annotationFqNames) {
assertAnnotatedWith(aClass, annotationFqName.asString());
}
assertAnnotatedWith(aClass, annotationFqName.asString());
}
private void assertAnnotatedWith(@NotNull Class<?> aClass, @NotNull String annotationFqName) {
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.jvm.runtime
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAllTo
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.GenerationUtils
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.descriptors.*
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.jvm.compiler.ExpectedLoadErrorsUtil
import org.jetbrains.kotlin.jvm.compiler.LoadDescriptorUtil
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_LOCAL_CLASS
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.structure.reflect.classId
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
@@ -48,6 +50,10 @@ import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.Configuratio
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.sure
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import java.io.File
import java.net.URLClassLoader
import java.util.*
@@ -104,7 +110,7 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
}
val expected = LoadDescriptorUtil.loadTestPackageAndBindingContextFromJavaRoot(
tmpdir, getTestRootDisposable(), jdkKind, ConfigurationKind.ALL, true
tmpdir, testRootDisposable, jdkKind, ConfigurationKind.ALL, true
).first
RecursiveDescriptorComparator.validateAndCompareDescriptors(expected, actual, comparatorConfiguration, null)
@@ -112,13 +118,11 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
private fun DeclarationDescriptor.isJavaAnnotationConstructor() =
this is ConstructorDescriptor &&
getContainingDeclaration().let { container ->
container is JavaClassDescriptor &&
container.getKind() == ClassKind.ANNOTATION_CLASS
}
containingDeclaration is JavaClassDescriptor &&
containingDeclaration.kind == ClassKind.ANNOTATION_CLASS
private fun compileFile(file: File, text: String, jdkKind: TestJdkKind) {
val fileName = file.getName()
val fileName = file.name
when {
fileName.endsWith(".java") -> {
val sources = KotlinTestUtils.createTestFiles(fileName, text, object : TestFileFactoryNoModules<File>() {
@@ -134,7 +138,7 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
val environment = KotlinTestUtils.createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(
myTestRootDisposable, ConfigurationKind.ALL, jdkKind
)
val jetFile = KotlinTestUtils.createFile(file.getPath(), text, environment.project)
val jetFile = KotlinTestUtils.createFile(file.path, text, environment.project)
GenerationUtils.compileFileGetClassFileFactoryForTest(jetFile, environment).writeAllTo(tmpdir)
}
}
@@ -145,17 +149,17 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
moduleData.packageFacadeProvider.registerModule(moduleName)
val module = moduleData.module
val generatedPackageDir = File(tmpdir, LoadDescriptorUtil.TEST_PACKAGE_FQNAME.pathSegments().single().asString())
val allClassFiles = FileUtil.findFilesByMask(Pattern.compile(".*\\.class"), generatedPackageDir)
val packageScopes = arrayListOf<MemberScope>()
val classes = arrayListOf<ClassDescriptor>()
for (classFile in allClassFiles) {
val className = classFile.relativeTo(tmpdir).substringBeforeLast(".class").replace('/', '.').replace('\\', '.')
val className = classFile.toRelativeString(tmpdir).substringBeforeLast(".class").replace('/', '.').replace('\\', '.')
val klass = classLoader.loadClass(className).sure { "Couldn't load class $className" }
val header = ReflectKotlinClass.create(klass)?.getClassHeader()
val binaryClass = ReflectKotlinClass.create(klass)
val header = binaryClass?.classHeader
if (header?.kind == KotlinClassHeader.Kind.FILE_FACADE || header?.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS) {
val packageView = module.getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME)
@@ -163,7 +167,7 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
packageScopes.add(packageView.memberScope)
}
}
else if (header == null || (header.kind == KotlinClassHeader.Kind.CLASS && !header.isLocalClass)) {
else if (header == null || (header.kind == KotlinClassHeader.Kind.CLASS && !classFile.isLocalClass())) {
// Either a normal Kotlin class or a Java class
val classId = klass.classId
if (!classId.isLocal) {
@@ -180,6 +184,21 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
return SyntheticPackageViewForTest(module, packageScopes, classes)
}
private fun File.isLocalClass(): Boolean {
var result = false
ClassReader(inputStream()).accept(object : ClassVisitor(Opcodes.ASM5) {
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? {
if (desc == AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_LOCAL_CLASS)) {
result = true
}
return super.visitAnnotation(desc, visible)
}
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
return result
}
private fun adaptJavaSource(text: String): String {
val typeAnnotations = arrayOf("NotNull", "Nullable", "ReadOnly", "Mutable")
return typeAnnotations.fold(text) { text, annotation -> text.replace("@$annotation", "") }.replace(
@@ -81,8 +81,5 @@ public abstract class AbstractLocalClassProtoTest : TestCaseWithTmpdir() {
checkNotNull(clazz.getAnnotation(
clazz.classLoader.loadClass(JvmAnnotationNames.KOTLIN_CLASS.asString()) as Class<Annotation>
)) { "KotlinClass annotation is not found for class $clazz" }
checkNotNull(clazz.getAnnotation(
clazz.classLoader.loadClass(JvmAnnotationNames.KOTLIN_LOCAL_CLASS.asString()) as Class<Annotation>
)) { "KotlinLocalClass annotation is not found for class $clazz" }
}
}
@@ -62,8 +62,6 @@ public final class JvmAnnotationNames {
public static final FqName ENHANCED_NULLABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedNullability");
public static final FqName ENHANCED_MUTABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedMutability");
public static final String OLD_ABI_VERSION_FIELD_NAME = "abiVersion";
// When these annotations appear on a declaration, they are copied to the _type_ of the declaration, becoming type annotations
// See also DescriptorRendererOptions#excludedTypeAnnotationClasses
public static final Set<FqName> ANNOTATIONS_COPIED_TO_TYPES = SetsKt.setOf(
@@ -136,11 +136,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
else if (MULTIFILE_CLASS_NAME_FIELD_NAME.equals(string)) {
multifileClassName = value instanceof String ? (String) value : null;
}
else if (OLD_ABI_VERSION_FIELD_NAME.equals(string)) {
if (version == AbiVersionUtil.INVALID_VERSION && value instanceof Integer && (Integer) value > 0) {
version = BinaryVersion.create(0, (Integer) value, 0);
}
}
}
@Override
@@ -24,9 +24,6 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface KotlinClass {
@Deprecated
int abiVersion() default 32;
int[] version() default {};
String moduleName() default "main";
@@ -24,9 +24,6 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface KotlinFileFacade {
@Deprecated
int abiVersion() default 32;
int[] version() default {};
String moduleName() default "main";
@@ -24,9 +24,6 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface KotlinFunction {
@Deprecated
int abiVersion() default 32;
int[] version() default {};
String moduleName() default "main";
@@ -21,8 +21,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface KotlinInterfaceDefaultImpls {
int[] version() default {};
}
@@ -21,8 +21,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface KotlinLocalClass {
int[] version() default {};
}
@@ -24,9 +24,6 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface KotlinMultifileClass {
@Deprecated
int abiVersion() default 32;
int[] version() default {};
String moduleName() default "main";
@@ -24,9 +24,6 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface KotlinMultifileClassPart {
@Deprecated
int abiVersion() default 32;
int[] version() default {};
String multifileClassName();
@@ -24,9 +24,6 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface KotlinSyntheticClass {
@Deprecated
int abiVersion() default 32;
int[] version() default {};
String moduleName() default "main";
@@ -59,13 +59,8 @@ public object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinAbiVersion
annotationPresent = true
return object : AnnotationVisitor(Opcodes.ASM5) {
override fun visit(name: String, value: Any) {
when (name) {
VERSION_FIELD_NAME -> if (value is IntArray) {
version = BinaryVersion.create(value)
}
OLD_ABI_VERSION_FIELD_NAME -> if (version == null && value is Int) {
version = BinaryVersion.create(0, value, 0)
}
if (name == VERSION_FIELD_NAME && value is IntArray) {
version = BinaryVersion.create(value)
}
}
}