Refactoring: make AnnotatedElementDescriptor hierarchy sealed

This commit is contained in:
Alexey Tsvetkov
2016-04-15 14:36:46 +03:00
parent 26781bc139
commit 3ef21a941c
5 changed files with 35 additions and 35 deletions
@@ -0,0 +1,23 @@
package org.jetbrains.kotlin.annotation
sealed class AnnotatedElementDescriptor(val classFqName: String) {
class Class(classFqName: String) : AnnotatedElementDescriptor(classFqName) {
// use referential equality
}
class Method(classFqName: String, val methodName: String) : AnnotatedElementDescriptor(classFqName) {
override fun equals(other: Any?) = other is Method && methodName == other.methodName && classFqName == other.classFqName
override fun hashCode() = 31 * classFqName.hashCode() + methodName.hashCode()
}
class Constructor(classFqName: String) : AnnotatedElementDescriptor(classFqName) {
// use referential equality
}
class Field(classFqName: String, val fieldName: String) : AnnotatedElementDescriptor(classFqName) {
override fun equals(other: Any?) = other is Field && fieldName == other.fieldName && classFqName == other.classFqName
override fun hashCode() = 31 * classFqName.hashCode() + fieldName.hashCode()
}
}
@@ -30,27 +30,6 @@ public class AnnotationProcessorStub : AbstractProcessor() {
override fun process(annotations: Set<TypeElement>?, roundEnv: RoundEnvironment?) = true override fun process(annotations: Set<TypeElement>?, roundEnv: RoundEnvironment?) = true
} }
abstract class AnnotatedElementDescriptor(public val classFqName: String)
class AnnotatedClassDescriptor(classFqName: String) : AnnotatedElementDescriptor(classFqName) {
// use referential equality
}
class AnnotatedMethodDescriptor(classFqName: String, public val methodName: String) : AnnotatedElementDescriptor(classFqName) {
override fun equals(other: Any?) = other is AnnotatedMethodDescriptor && methodName == other.methodName && classFqName == other.classFqName
override fun hashCode() = 31 * classFqName.hashCode() + methodName.hashCode()
}
class AnnotatedConstructorDescriptor(classFqName: String) : AnnotatedElementDescriptor(classFqName) {
// use referential equality
}
class AnnotatedFieldDescriptor(classFqName: String, public val fieldName: String) : AnnotatedElementDescriptor(classFqName) {
override fun equals(other: Any?) = other is AnnotatedFieldDescriptor && fieldName == other.fieldName && classFqName == other.classFqName
override fun hashCode() = 31 * classFqName.hashCode() + fieldName.hashCode()
}
public abstract class AnnotationProcessorWrapper( public abstract class AnnotationProcessorWrapper(
private val processorFqName: String, private val processorFqName: String,
private val taskQualifier: String private val taskQualifier: String
@@ -94,18 +94,18 @@ class KotlinAnnotationProvider(annotationsReader: Reader) {
val set = annotatedKotlinElementsInternal.getOrPut(annotationName) { hashSetOf() } val set = annotatedKotlinElementsInternal.getOrPut(annotationName) { hashSetOf() }
set.add(when (type) { set.add(when (type) {
ANNOTATED_CLASS -> AnnotatedClassDescriptor(classFqName) ANNOTATED_CLASS -> AnnotatedElementDescriptor.Class(classFqName)
ANNOTATED_FIELD -> { ANNOTATED_FIELD -> {
val name = elementName ?: throw AssertionError("Name for field must be provided") val name = elementName ?: throw AssertionError("Name for field must be provided")
AnnotatedFieldDescriptor(classFqName, name) AnnotatedElementDescriptor.Field(classFqName, name)
} }
ANNOTATED_METHOD -> { ANNOTATED_METHOD -> {
val name = elementName ?: throw AssertionError("Name for method must be provided") val name = elementName ?: throw AssertionError("Name for method must be provided")
if ("<init>" == name) if ("<init>" == name)
AnnotatedConstructorDescriptor(classFqName) AnnotatedElementDescriptor.Constructor(classFqName)
else else
AnnotatedMethodDescriptor(classFqName, name) AnnotatedElementDescriptor.Method(classFqName, name)
} }
else -> throw AssertionError("Unknown type: $type") else -> throw AssertionError("Unknown type: $type")
}) })
@@ -7,7 +7,6 @@ import javax.lang.model.element.Element
import javax.lang.model.element.ElementKind import javax.lang.model.element.ElementKind
import javax.lang.model.element.TypeElement import javax.lang.model.element.TypeElement
import javax.lang.model.type.NoType import javax.lang.model.type.NoType
import javax.lang.model.type.TypeVisitor
internal class RoundEnvironmentWrapper( internal class RoundEnvironmentWrapper(
val processingEnv: ProcessingEnvironment, val processingEnv: ProcessingEnvironment,
@@ -67,16 +66,16 @@ internal class RoundEnvironmentWrapper(
val descriptorsWithKotlin = descriptors.fold(hashSetOf<Element>()) { set, descriptor -> val descriptorsWithKotlin = descriptors.fold(hashSetOf<Element>()) { set, descriptor ->
val clazz = processingEnv.elementUtils.getTypeElement(descriptor.classFqName) ?: return@fold set val clazz = processingEnv.elementUtils.getTypeElement(descriptor.classFqName) ?: return@fold set
when (descriptor) { when (descriptor) {
is AnnotatedClassDescriptor -> set.add(clazz) is AnnotatedElementDescriptor.Class -> set.add(clazz)
is AnnotatedConstructorDescriptor -> { is AnnotatedElementDescriptor.Constructor -> {
set.addAll(clazz.filterEnclosedElements(ElementKind.CONSTRUCTOR) set.addAll(clazz.filterEnclosedElements(ElementKind.CONSTRUCTOR)
.filter { it.hasAnnotation(annotationFqName) }) .filter { it.hasAnnotation(annotationFqName) })
} }
is AnnotatedFieldDescriptor -> { is AnnotatedElementDescriptor.Field -> {
set.addAll(clazz.filterEnclosedElements(ElementKind.FIELD, descriptor.fieldName) set.addAll(clazz.filterEnclosedElements(ElementKind.FIELD, descriptor.fieldName)
.filter { it.hasAnnotation(annotationFqName) }) .filter { it.hasAnnotation(annotationFqName) })
} }
is AnnotatedMethodDescriptor -> { is AnnotatedElementDescriptor.Method -> {
set.addAll(clazz.filterEnclosedElements(ElementKind.METHOD, descriptor.methodName) set.addAll(clazz.filterEnclosedElements(ElementKind.METHOD, descriptor.methodName)
.filter { it.hasAnnotation(annotationFqName) }) .filter { it.hasAnnotation(annotationFqName) })
} }
@@ -61,11 +61,10 @@ public class AnnotationListParseTest {
for (element in it.value) { for (element in it.value) {
actualAnnotations.append(it.key).append(' ').append(element.classFqName) actualAnnotations.append(it.key).append(' ').append(element.classFqName)
when (element) { when (element) {
is AnnotatedMethodDescriptor -> actualAnnotations.append(' ').append(element.methodName) is AnnotatedElementDescriptor.Method -> actualAnnotations.append(' ').append(element.methodName)
is AnnotatedFieldDescriptor -> actualAnnotations.append(' ').append(element.fieldName) is AnnotatedElementDescriptor.Field -> actualAnnotations.append(' ').append(element.fieldName)
is AnnotatedConstructorDescriptor -> actualAnnotations.append(" <init>") is AnnotatedElementDescriptor.Constructor -> actualAnnotations.append(" <init>")
is AnnotatedClassDescriptor -> {} is AnnotatedElementDescriptor.Class -> {}
else -> Assert.fail("Unknown element type: $element")
} }
actualAnnotations.append('\n') actualAnnotations.append('\n')
} }