Enum replaced by a map

This commit is contained in:
Andrey Breslav
2014-01-09 18:52:59 +04:00
parent afc62dabd9
commit 01c6997fb7
2 changed files with 31 additions and 75 deletions
@@ -21,31 +21,6 @@ import org.jetbrains.annotations.Nullable;
public class KotlinClassHeader { 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 { public enum Kind {
CLASS, CLASS,
PACKAGE_FACADE, PACKAGE_FACADE,
@@ -58,7 +33,9 @@ public class KotlinClassHeader {
private final int version; private final int version;
private final String[] data; 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.kind = kind;
this.version = version; this.version = version;
this.data = annotationData; this.data = annotationData;
@@ -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.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass; 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 org.jetbrains.jet.lang.resolve.name.Name;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; 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.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.AnnotationArgumentVisitor;
import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationVisitor; 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 { 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 static final Map<JvmClassName, KotlinClassHeader.Kind> HEADER_KINDS = new HashMap<JvmClassName, KotlinClassHeader.Kind>();
private final JvmClassName annotation; static {
HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_CLASS), CLASS);
private HeaderType(@NotNull FqName annotation) { HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE), PACKAGE_FACADE);
this.annotation = JvmClassName.byFqNameWithoutInnerClasses(annotation); HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE_FRAGMENT), PACKAGE_FRAGMENT);
} HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_TRAIT_IMPL), TRAIT_IMPL);
//noinspection deprecation
@Nullable HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(OLD_JET_CLASS_ANNOTATION), INCOMPATIBLE_ABI_VERSION);
private static HeaderType byClassName(@NotNull JvmClassName className) { //noinspection deprecation
for (HeaderType headerType : HeaderType.values()) { HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(OLD_JET_PACKAGE_CLASS_ANNOTATION), INCOMPATIBLE_ABI_VERSION);
if (className.equals(headerType.annotation)) {
return headerType;
}
}
return null;
}
} }
private int version = AbiVersionUtil.INVALID_VERSION; private int version = AbiVersionUtil.INVALID_VERSION;
@Nullable @Nullable
private String[] annotationData = null; private String[] annotationData = null;
@Nullable @Nullable
private HeaderType foundType = null; private KotlinClassHeader.Kind headerKind = null;
private ReadKotlinClassHeaderAnnotationVisitor() { private ReadKotlinClassHeaderAnnotationVisitor() {
} }
@@ -78,49 +67,39 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Nullable @Nullable
public KotlinClassHeader createHeader() { public KotlinClassHeader createHeader() {
if (foundType == null) { if (headerKind == null) {
return null; return null;
} }
if (!AbiVersionUtil.isAbiVersionCompatible(version)) { if (!AbiVersionUtil.isAbiVersionCompatible(version)) {
return KotlinClassHeader.createIncompatibleVersionErrorHeader(version); return new KotlinClassHeader(INCOMPATIBLE_ABI_VERSION, version, null);
} }
switch (foundType) { if ((headerKind == CLASS || headerKind == PACKAGE_FACADE) && annotationData == null) {
case CLASS: // This means that the annotation is found and its ABI version is compatible, but there's no "data" string array in it.
// 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
// We tell the outside world that there's really no annotation at all return null;
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);
} }
return new KotlinClassHeader(headerKind, version, annotationData);
} }
@Nullable @Nullable
@Override @Override
public AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName annotationClassName) { public AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName annotationClassName) {
HeaderType newType = HeaderType.byClassName(annotationClassName); KotlinClassHeader.Kind newKind = HEADER_KINDS.get(annotationClassName);
if (newType == null) return null; if (newKind == null) return null;
if (foundType != null) { if (this.headerKind != null) {
// Ignore all Kotlin annotations except the first found // Ignore all Kotlin annotations except the first found
return null; return null;
} }
foundType = newType; headerKind = newKind;
if (newType == HeaderType.CLASS || newType == HeaderType.PACKAGE) { if (newKind == CLASS || newKind == PACKAGE_FACADE) {
return kotlinClassOrPackageVisitor(annotationClassName); return kotlinClassOrPackageVisitor(annotationClassName);
} }
else if (newType == HeaderType.PACKAGE_FRAGMENT || newType == HeaderType.TRAIT_IMPL) { else if (newKind == PACKAGE_FRAGMENT || newKind == TRAIT_IMPL) {
return annotationWithAbiVersionVisitor(annotationClassName); return annotationWithAbiVersionVisitor(annotationClassName);
} }