Refactor ReadKotlinClassHeaderAnnotationVisitor

Extract a hierarchy of four nested classes instead of anonymous
This commit is contained in:
Alexander Udalov
2015-02-14 01:43:02 +03:00
parent 5d8ae3ed6a
commit add9bb34cb
@@ -96,11 +96,11 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
switch (newKind) { switch (newKind) {
case CLASS: case CLASS:
return kotlinClassOrPackageVisitor(annotation); return new ClassHeaderReader();
case PACKAGE_FACADE: case PACKAGE_FACADE:
return kotlinClassOrPackageVisitor(annotation); return new PackageHeaderReader();
case SYNTHETIC_CLASS: case SYNTHETIC_CLASS:
return syntheticClassAnnotationVisitor(); return new SyntheticClassHeaderReader();
default: default:
throw new IllegalStateException("Unknown kind: " + newKind); throw new IllegalStateException("Unknown kind: " + newKind);
} }
@@ -118,17 +118,26 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
public void visitEnd() { public void visitEnd() {
} }
@NotNull private abstract class HeaderAnnotationArgumentVisitor implements AnnotationArgumentVisitor {
private AnnotationArgumentVisitor kotlinClassOrPackageVisitor(@NotNull final JvmClassName annotationClassName) { protected final JvmClassName annotationClassName;
return new AnnotationArgumentVisitor() {
public HeaderAnnotationArgumentVisitor(@NotNull JvmClassName annotationClassName) {
this.annotationClassName = annotationClassName;
}
@Override @Override
public void visit(@Nullable Name name, @Nullable Object value) { public void visit(@Nullable Name name, @Nullable Object value) {
visitIntValueForSupportedAnnotation(name, value, annotationClassName); if (name != null && name.asString().equals(ABI_VERSION_FIELD_NAME)) {
version = value == null ? AbiVersionUtil.INVALID_VERSION : (Integer) value;
}
else {
unexpectedArgument(name);
}
} }
@Override @Override
public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) { public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
unexpectedArgument(name, annotationClassName); unexpectedEnumArgument(name, enumClassId, enumEntryName);
} }
@Override @Override
@@ -159,7 +168,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Override @Override
public void visitEnum(@NotNull ClassId enumClassId, @NotNull Name enumEntryName) { public void visitEnum(@NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
unexpectedArgument(null, annotationClassName); unexpectedArgument(null);
} }
@Override @Override
@@ -170,18 +179,41 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}; };
} }
@Nullable
protected AnnotationArrayArgumentVisitor unexpectedArgument(@Nullable Name name) {
if (isAbiVersionCompatible(version)) {
throw new IllegalStateException("Unexpected argument " + name + " for annotation " + annotationClassName);
}
return null;
}
protected void unexpectedEnumArgument(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
if (isAbiVersionCompatible(version)) {
throw new IllegalStateException("Unexpected enum entry for class annotation " + annotationClassName + ": " +
name + "=" + enumClassId + "." + enumEntryName);
}
}
@Override @Override
public void visitEnd() { public void visitEnd() {
} }
};
} }
@NotNull private class ClassHeaderReader extends HeaderAnnotationArgumentVisitor {
private AnnotationArgumentVisitor syntheticClassAnnotationVisitor() { public ClassHeaderReader() {
return new AnnotationArgumentVisitor() { super(KotlinClass.CLASS_NAME);
@Override }
public void visit(@Nullable Name name, @Nullable Object value) { }
visitIntValueForSupportedAnnotation(name, value, KotlinSyntheticClass.CLASS_NAME);
private class PackageHeaderReader extends HeaderAnnotationArgumentVisitor {
public PackageHeaderReader() {
super(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE));
}
}
private class SyntheticClassHeaderReader extends HeaderAnnotationArgumentVisitor {
public SyntheticClassHeaderReader() {
super(KotlinSyntheticClass.CLASS_NAME);
} }
@Override @Override
@@ -190,41 +222,10 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
syntheticClassKind = valueOfOrNull(KotlinSyntheticClass.Kind.class, enumEntryName.asString()); syntheticClassKind = valueOfOrNull(KotlinSyntheticClass.Kind.class, enumEntryName.asString());
if (syntheticClassKind != null) return; if (syntheticClassKind != null) return;
} }
if (isAbiVersionCompatible(version)) { unexpectedEnumArgument(name, enumClassId, enumEntryName);
throw new IllegalStateException("Unexpected enum entry for synthetic class annotation: " +
name + "=" + enumClassId + "." + enumEntryName);
} }
} }
@Nullable
@Override
public AnnotationArrayArgumentVisitor visitArray(@NotNull Name name) {
return unexpectedArgument(name, KotlinSyntheticClass.CLASS_NAME);
}
@Override
public void visitEnd() {
}
};
}
private void visitIntValueForSupportedAnnotation(@Nullable Name name, @Nullable Object value, @NotNull JvmClassName className) {
if (name != null && name.asString().equals(ABI_VERSION_FIELD_NAME)) {
version = value == null ? AbiVersionUtil.INVALID_VERSION : (Integer) value;
}
else {
unexpectedArgument(name, className);
}
}
@Nullable
private AnnotationArrayArgumentVisitor unexpectedArgument(@Nullable Name name, @NotNull JvmClassName annotationClassName) {
if (isAbiVersionCompatible(version)) {
throw new IllegalStateException("Unexpected argument " + name + " for annotation " + annotationClassName);
}
return null;
}
// This function is needed here because Enum.valueOf() throws exception if there's no such value, // This function is needed here because Enum.valueOf() throws 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 // but we don't want to fail if we're loading the header with an _incompatible_ ABI version
@Nullable @Nullable