Load class kind in KotlinSyntheticClass annotation

Fix some of the usages of KotlinSyntheticClass header where really package
parts were meant (they were committed by mistake).

DescriptorResolverUtils.isCompiledKotlinPackageClass no longer checks for class
being a compiled package part, because PSI classes are not built for package
parts (according to EmptyPackageFragmentClsStubBuilderFactory)
This commit is contained in:
Alexander Udalov
2014-03-03 20:59:56 +04:00
parent ea40389e34
commit eb5aba560e
10 changed files with 93 additions and 78 deletions
@@ -23,7 +23,6 @@ import org.jetbrains.jet.lang.resolve.name.Name;
public final class JvmAnnotationNames {
public static final FqName KOTLIN_CLASS = new FqName("kotlin.jvm.internal.KotlinClass");
public static final FqName KOTLIN_PACKAGE = new FqName("kotlin.jvm.internal.KotlinPackage");
public static final FqName KOTLIN_SYNTHETIC_CLASS = new FqName("kotlin.jvm.internal.KotlinSyntheticClass");
public static final FqName KOTLIN_SIGNATURE = new FqName("kotlin.jvm.KotlinSignature");
public static final FqName OLD_KOTLIN_SIGNATURE = new FqName("jet.runtime.typeinfo.KotlinSignature");
@@ -37,6 +36,26 @@ public final class JvmAnnotationNames {
public static final FqName JETBRAINS_MUTABLE_ANNOTATION = new FqName("org.jetbrains.annotations.Mutable");
public static final FqName JETBRAINS_READONLY_ANNOTATION = new FqName("org.jetbrains.annotations.ReadOnly");
public static class KotlinSyntheticClass {
public static final FqName FQ_NAME = new FqName("kotlin.jvm.internal.KotlinSyntheticClass");
public static final String INTERNAL_NAME = JvmClassName.byFqNameWithoutInnerClasses(FQ_NAME).getInternalName();
public static final String KIND_INTERNAL_NAME = "kotlin/jvm/internal/KotlinSyntheticClass$Kind";
public static final Name KIND_FIELD_NAME = Name.identifier("kind");
/**
* This enum duplicates {@link kotlin.jvm.internal.KotlinSyntheticClass.Kind}, because this code can't depend on "runtime.jvm".
* Both places should be updated simultaneously
*/
public enum Kind {
PACKAGE_PART,
TRAIT_IMPL
}
private KotlinSyntheticClass() {
}
}
@Deprecated
public static final FqName OLD_JET_CLASS_ANNOTATION = new FqName("jet.runtime.typeinfo.JetClass");
@Deprecated
@@ -42,7 +42,7 @@ public class LazyJavaPackageFragmentProvider(
}
else {
val jClass = c.findJavaClass(fqName)
if (jClass != null && DescriptorResolverUtils.isJavaClassVisibleAsPackage(jClass)) {
if (jClass != null && DescriptorResolverUtils.hasStaticMembers(jClass)) {
val correspondingClass = c.javaClassResolver.resolveClass(jClass)
if (correspondingClass != null) LazyPackageFragmentForJavaClass(c, _module, jClass) else null
}
@@ -21,7 +21,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils;
import org.jetbrains.jet.lang.resolve.java.structure.*;
import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -35,6 +34,9 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KOTLIN_CLASS;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KOTLIN_PACKAGE;
public final class DescriptorResolverUtils {
public static final FqName OBJECT_FQ_NAME = new FqName("java.lang.Object");
@@ -42,22 +44,11 @@ public final class DescriptorResolverUtils {
}
public static boolean isCompiledKotlinPackageClass(@NotNull JavaClass javaClass) {
if (javaClass.getOriginKind() == JavaClass.OriginKind.COMPILED) {
return javaClass.findAnnotation(JvmAnnotationNames.KOTLIN_PACKAGE) != null
|| javaClass.findAnnotation(JvmAnnotationNames.KOTLIN_SYNTHETIC_CLASS) != null;
}
return false;
return javaClass.getOriginKind() == JavaClass.OriginKind.COMPILED && javaClass.findAnnotation(KOTLIN_PACKAGE) != null;
}
public static boolean isCompiledKotlinClass(@NotNull JavaClass javaClass) {
if (javaClass.getOriginKind() == JavaClass.OriginKind.COMPILED) {
return javaClass.findAnnotation(JvmAnnotationNames.KOTLIN_CLASS) != null;
}
return false;
}
private static boolean isCompiledKotlinClassOrPackageClass(@NotNull JavaClass javaClass) {
return isCompiledKotlinClass(javaClass) || isCompiledKotlinPackageClass(javaClass);
return javaClass.getOriginKind() == JavaClass.OriginKind.COMPILED && javaClass.findAnnotation(KOTLIN_CLASS) != null;
}
@NotNull
@@ -262,11 +253,7 @@ public final class DescriptorResolverUtils {
return TypeSubstitutor.create(typeSubstitutionContext);
}
public static boolean isJavaClassVisibleAsPackage(@NotNull JavaClass javaClass) {
return !isCompiledKotlinClassOrPackageClass(javaClass) && hasStaticMembers(javaClass);
}
private static boolean hasStaticMembers(@NotNull JavaClass javaClass) {
public static boolean hasStaticMembers(@NotNull JavaClass javaClass) {
for (JavaMethod method : javaClass.getMethods()) {
if (method.isStatic() && !shouldBeInEnumClassObject(method)) {
return true;
@@ -24,7 +24,8 @@ public class KotlinClassHeader {
public enum Kind {
CLASS,
PACKAGE_FACADE,
SYNTHETIC_CLASS,
PACKAGE_PART,
TRAIT_IMPL,
INCOMPATIBLE_ABI_VERSION
}
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.kotlin.header;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -34,18 +33,21 @@ import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.Annotat
import static org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader.Kind.*;
public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor {
private static final JvmClassName KOTLIN_CLASS_ANNOTATION = JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_CLASS);
private static final JvmClassName KOTLIN_PACKAGE_ANNOTATION = JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE);
private static final JvmClassName KOTLIN_SYNTHETIC_CLASS_ANNOTATION = JvmClassName.byInternalName(KotlinSyntheticClass.INTERNAL_NAME);
private static final Set<JvmClassName> ALL_SUPPORTED_ANNOTATIONS = new HashSet<JvmClassName>();
private static final Map<JvmClassName, KotlinClassHeader.Kind> HEADER_KINDS = new HashMap<JvmClassName, KotlinClassHeader.Kind>();
static {
HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_CLASS), CLASS);
HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE), PACKAGE_FACADE);
HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_SYNTHETIC_CLASS), SYNTHETIC_CLASS);
ALL_SUPPORTED_ANNOTATIONS.add(KOTLIN_CLASS_ANNOTATION);
ALL_SUPPORTED_ANNOTATIONS.add(KOTLIN_PACKAGE_ANNOTATION);
ALL_SUPPORTED_ANNOTATIONS.add(KOTLIN_SYNTHETIC_CLASS_ANNOTATION);
@SuppressWarnings("deprecation")
List<FqName> incompatible = Arrays.asList(OLD_JET_CLASS_ANNOTATION, OLD_JET_PACKAGE_CLASS_ANNOTATION, OLD_KOTLIN_CLASS,
OLD_KOTLIN_PACKAGE, OLD_KOTLIN_PACKAGE_FRAGMENT, OLD_KOTLIN_TRAIT_IMPL);
for (FqName fqName : incompatible) {
HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(fqName), INCOMPATIBLE_ABI_VERSION);
ALL_SUPPORTED_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(fqName));
}
}
@@ -85,22 +87,23 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Nullable
@Override
public AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName annotationClassName) {
KotlinClassHeader.Kind newKind = HEADER_KINDS.get(annotationClassName);
if (newKind == null) return null;
public AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName annotation) {
if (!ALL_SUPPORTED_ANNOTATIONS.contains(annotation)) return null;
if (this.headerKind != null) {
if (headerKind != null) {
// Ignore all Kotlin annotations except the first found
return null;
}
headerKind = newKind;
if (newKind == CLASS || newKind == PACKAGE_FACADE) {
return kotlinClassOrPackageVisitor(annotationClassName);
if (annotation.equals(KOTLIN_CLASS_ANNOTATION) || annotation.equals(KOTLIN_PACKAGE_ANNOTATION)) {
headerKind = annotation.equals(KOTLIN_CLASS_ANNOTATION) ? CLASS : PACKAGE_FACADE;
return kotlinClassOrPackageVisitor(annotation);
}
else if (newKind == SYNTHETIC_CLASS) {
return syntheticClassAnnotationVisitor(annotationClassName);
else if (annotation.equals(KOTLIN_SYNTHETIC_CLASS_ANNOTATION)) {
return syntheticClassAnnotationVisitor();
}
else {
headerKind = INCOMPATIBLE_ABI_VERSION;
}
return null;
@@ -126,7 +129,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Override
@Nullable
public AnnotationArgumentVisitor visitArray(@NotNull Name name) {
if (name.asString().equals(JvmAnnotationNames.DATA_FIELD_NAME)) {
if (name.asString().equals(DATA_FIELD_NAME)) {
return stringArrayVisitor();
}
else if (isAbiVersionCompatible(version)) {
@@ -174,22 +177,39 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
@NotNull
private AnnotationArgumentVisitor syntheticClassAnnotationVisitor(@NotNull final JvmClassName annotationClassName) {
private AnnotationArgumentVisitor syntheticClassAnnotationVisitor() {
return new AnnotationArgumentVisitor() {
@Override
public void visit(@Nullable Name name, @Nullable Object value) {
visitIntValueForSupportedAnnotation(name, value, annotationClassName);
visitIntValueForSupportedAnnotation(name, value, KOTLIN_SYNTHETIC_CLASS_ANNOTATION);
}
@Override
public void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
// TODO: save kind to somewhere
if (enumClassName.getInternalName().equals(KotlinSyntheticClass.KIND_INTERNAL_NAME) &&
name.equals(KotlinSyntheticClass.KIND_FIELD_NAME)) {
String value = enumEntryName.asString();
// Don't call KotlinSyntheticClass.Kind.valueOf() here, because it will throw an exception if there's no such value,
// but we don't want to fail if we're loading the header with an _incompatible_ ABI version
if (value.equals(KotlinSyntheticClass.Kind.PACKAGE_PART.toString())) {
headerKind = PACKAGE_PART;
return;
}
else if (value.equals(KotlinSyntheticClass.Kind.TRAIT_IMPL.toString())) {
headerKind = TRAIT_IMPL;
return;
}
}
if (isAbiVersionCompatible(version)) {
throw new IllegalStateException("Unexpected enum entry for synthetic class annotation: " +
name + "=" + enumClassName + "." + enumEntryName);
}
}
@Nullable
@Override
public AnnotationArgumentVisitor visitArray(@NotNull Name name) {
return unexpectedArgument(name, annotationClassName);
return unexpectedArgument(name, KOTLIN_SYNTHETIC_CLASS_ANNOTATION);
}
@Override
@@ -199,7 +219,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
private void visitIntValueForSupportedAnnotation(@Nullable Name name, @Nullable Object value, @NotNull JvmClassName className) {
if (name != null && name.asString().equals(JvmAnnotationNames.ABI_VERSION_FIELD_NAME)) {
if (name != null && name.asString().equals(ABI_VERSION_FIELD_NAME)) {
version = value == null ? AbiVersionUtil.INVALID_VERSION : (Integer) value;
}
else {