diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/KotlinClassHeader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/KotlinClassHeader.java index ab1e5d568c6..86f36b370c6 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/KotlinClassHeader.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/KotlinClassHeader.java @@ -21,31 +21,6 @@ import org.jetbrains.annotations.Nullable; public class KotlinClassHeader { - @NotNull - public static KotlinClassHeader createClassHeader(int version, @NotNull String[] annotationData) { - return new KotlinClassHeader(Kind.CLASS, version, annotationData); - } - - @NotNull - public static KotlinClassHeader createPackageFacadeHeader(int version, @NotNull String[] annotationData) { - return new KotlinClassHeader(Kind.PACKAGE_FACADE, version, annotationData); - } - - @NotNull - public static KotlinClassHeader createPackageFragmentHeader(int version) { - return new KotlinClassHeader(Kind.PACKAGE_FRAGMENT, version, null); - } - - @NotNull - public static KotlinClassHeader createTraitImplHeader(int version) { - return new KotlinClassHeader(Kind.TRAIT_IMPL, version, null); - } - - @NotNull - public static KotlinClassHeader createIncompatibleVersionErrorHeader(int version) { - return new KotlinClassHeader(Kind.INCOMPATIBLE_ABI_VERSION, version, null); - } - public enum Kind { CLASS, PACKAGE_FACADE, @@ -58,7 +33,9 @@ public class KotlinClassHeader { private final int version; private final String[] data; - private KotlinClassHeader(@NotNull Kind kind, int version, @Nullable String[] annotationData) { + public KotlinClassHeader(@NotNull Kind kind, int version, @Nullable String[] annotationData) { + assert (annotationData == null) == (kind != Kind.CLASS && kind != Kind.PACKAGE_FACADE) + : "Annotation data should be not null only for CLASS and PACKAGE_FACADE"; this.kind = kind; this.version = version; this.data = annotationData; diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java index 01a4bfee913..984d777facb 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java @@ -22,49 +22,38 @@ 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; import org.jetbrains.jet.lang.resolve.name.Name; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCompatible; +import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.*; import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationArgumentVisitor; import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationVisitor; +import static org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader.Kind.*; public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor { - @SuppressWarnings("deprecation") - private enum HeaderType { - CLASS(JvmAnnotationNames.KOTLIN_CLASS), - PACKAGE(JvmAnnotationNames.KOTLIN_PACKAGE), - PACKAGE_FRAGMENT(JvmAnnotationNames.KOTLIN_PACKAGE_FRAGMENT), - TRAIT_IMPL(JvmAnnotationNames.KOTLIN_TRAIT_IMPL), - OLD_CLASS(JvmAnnotationNames.OLD_JET_CLASS_ANNOTATION), - OLD_PACKAGE(JvmAnnotationNames.OLD_JET_PACKAGE_CLASS_ANNOTATION); - @NotNull - private final JvmClassName annotation; - - private HeaderType(@NotNull FqName annotation) { - this.annotation = JvmClassName.byFqNameWithoutInnerClasses(annotation); - } - - @Nullable - private static HeaderType byClassName(@NotNull JvmClassName className) { - for (HeaderType headerType : HeaderType.values()) { - if (className.equals(headerType.annotation)) { - return headerType; - } - } - return null; - } + private static final Map HEADER_KINDS = new HashMap(); + static { + HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_CLASS), CLASS); + HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE), PACKAGE_FACADE); + HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE_FRAGMENT), PACKAGE_FRAGMENT); + HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_TRAIT_IMPL), TRAIT_IMPL); + //noinspection deprecation + HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(OLD_JET_CLASS_ANNOTATION), INCOMPATIBLE_ABI_VERSION); + //noinspection deprecation + HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(OLD_JET_PACKAGE_CLASS_ANNOTATION), INCOMPATIBLE_ABI_VERSION); } private int version = AbiVersionUtil.INVALID_VERSION; @Nullable private String[] annotationData = null; @Nullable - private HeaderType foundType = null; + private KotlinClassHeader.Kind headerKind = null; private ReadKotlinClassHeaderAnnotationVisitor() { } @@ -78,49 +67,39 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor @Nullable public KotlinClassHeader createHeader() { - if (foundType == null) { + if (headerKind == null) { return null; } if (!AbiVersionUtil.isAbiVersionCompatible(version)) { - return KotlinClassHeader.createIncompatibleVersionErrorHeader(version); + return new KotlinClassHeader(INCOMPATIBLE_ABI_VERSION, version, null); } - switch (foundType) { - case CLASS: - // This means that the annotation is found and its ABI version is compatible, but there's no "data" string array in it. - // We tell the outside world that there's really no annotation at all - if (annotationData == null) return null; - return KotlinClassHeader.createClassHeader(version, annotationData); - case PACKAGE: - if (annotationData == null) return null; - return KotlinClassHeader.createPackageFacadeHeader(version, annotationData); - case PACKAGE_FRAGMENT: - return KotlinClassHeader.createPackageFragmentHeader(version); - case TRAIT_IMPL: - return KotlinClassHeader.createTraitImplHeader(version); - default: - throw new UnsupportedOperationException("Unknown compatible HeaderType: " + foundType); + if ((headerKind == CLASS || headerKind == PACKAGE_FACADE) && annotationData == null) { + // This means that the annotation is found and its ABI version is compatible, but there's no "data" string array in it. + // We tell the outside world that there's really no annotation at all + return null; } + return new KotlinClassHeader(headerKind, version, annotationData); } @Nullable @Override public AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName annotationClassName) { - HeaderType newType = HeaderType.byClassName(annotationClassName); - if (newType == null) return null; + KotlinClassHeader.Kind newKind = HEADER_KINDS.get(annotationClassName); + if (newKind == null) return null; - if (foundType != null) { + if (this.headerKind != null) { // Ignore all Kotlin annotations except the first found return null; } - foundType = newType; + headerKind = newKind; - if (newType == HeaderType.CLASS || newType == HeaderType.PACKAGE) { + if (newKind == CLASS || newKind == PACKAGE_FACADE) { return kotlinClassOrPackageVisitor(annotationClassName); } - else if (newType == HeaderType.PACKAGE_FRAGMENT || newType == HeaderType.TRAIT_IMPL) { + else if (newKind == PACKAGE_FRAGMENT || newKind == TRAIT_IMPL) { return annotationWithAbiVersionVisitor(annotationClassName); }