Refactor annotation and constant loader, simplify, drop some useless checks

This commit is contained in:
Alexander Udalov
2015-09-30 19:46:03 +03:00
parent ad735cd788
commit 14ec34e37c
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.Flags
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
@@ -64,7 +62,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
} }
override fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List<A> { override fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List<A> {
val classId = nameResolver.getClassId(classProto.getFqName()) val classId = nameResolver.getClassId(classProto.fqName)
val kotlinClass = kotlinClassFinder.findKotlinClass(classId) val kotlinClass = kotlinClassFinder.findKotlinClass(classId)
if (kotlinClass == null) { if (kotlinClass == null) {
// This means that the resource we're constructing the descriptor from is no longer present: KotlinClassFinder had found the // This means that the resource we're constructing the descriptor from is no longer present: KotlinClassFinder had found the
@@ -98,17 +96,17 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
val fieldSignature = getPropertySignature(proto, nameResolver, field = true) val fieldSignature = getPropertySignature(proto, nameResolver, field = true)
val propertyAnnotations = syntheticFunctionSignature?.let { sig -> val propertyAnnotations = syntheticFunctionSignature?.let { sig ->
findClassAndLoadMemberAnnotations(container, proto, nameResolver, kind, sig, false) findClassAndLoadMemberAnnotations(container, proto, nameResolver, sig)
} ?: listOf() } ?: listOf()
val fieldAnnotations = fieldSignature?.let { sig -> val fieldAnnotations = fieldSignature?.let { sig ->
findClassAndLoadMemberAnnotations(container, proto, nameResolver, kind, sig) findClassAndLoadMemberAnnotations(container, proto, nameResolver, sig, isStaticFieldInOuter(proto))
} ?: listOf() } ?: listOf()
return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations) return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations)
} }
val signature = getCallableSignature(proto, nameResolver, kind) ?: return listOf() val signature = getCallableSignature(proto, nameResolver, kind) ?: return listOf()
return transformAnnotations(findClassAndLoadMemberAnnotations(container, proto, nameResolver, kind, signature)) return transformAnnotations(findClassAndLoadMemberAnnotations(container, proto, nameResolver, signature))
} }
protected abstract fun loadPropertyAnnotations(propertyAnnotations: List<A>, fieldAnnotations: List<A>): List<T> protected abstract fun loadPropertyAnnotations(propertyAnnotations: List<A>, fieldAnnotations: List<A>): List<T>
@@ -119,11 +117,12 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
container: ProtoContainer, container: ProtoContainer,
proto: ProtoBuf.Callable, proto: ProtoBuf.Callable,
nameResolver: NameResolver, nameResolver: NameResolver,
kind: AnnotatedCallableKind,
signature: MemberSignature, signature: MemberSignature,
seekForStaticFieldInOuter: Boolean = true isStaticFieldInOuter: Boolean = false
): List<A> { ): List<A> {
val kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, kind, seekForStaticFieldInOuter) val kotlinClass = findClassWithAnnotationsAndInitializers(
container, nameResolver, getImplClassName(proto, nameResolver), isStaticFieldInOuter
)
if (kotlinClass == null) { if (kotlinClass == null) {
errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: ${container.getFqName(nameResolver)}", null) errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: ${container.getFqName(nameResolver)}", null)
return listOf() return listOf()
@@ -144,7 +143,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
if (methodSignature != null) { if (methodSignature != null) {
val index = if (proto.hasExtension(index)) proto.getExtension(index) else parameterIndex val index = if (proto.hasExtension(index)) proto.getExtension(index) else parameterIndex
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, index) val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, index)
return findClassAndLoadMemberAnnotations(container, callable, nameResolver, kind, paramSignature) return findClassAndLoadMemberAnnotations(container, callable, nameResolver, paramSignature)
} }
return listOf() return listOf()
@@ -160,7 +159,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
val methodSignature = getCallableSignature(callable, nameResolver, kind) val methodSignature = getCallableSignature(callable, nameResolver, kind)
if (methodSignature != null) { if (methodSignature != null) {
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, 0) val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, 0)
return findClassAndLoadMemberAnnotations(container, callable, nameResolver, kind, paramSignature) return findClassAndLoadMemberAnnotations(container, callable, nameResolver, paramSignature)
} }
return emptyList() return emptyList()
@@ -178,7 +177,9 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
): C? { ): C? {
val signature = getCallableSignature(proto, nameResolver, AnnotatedCallableKind.PROPERTY) ?: return null val signature = getCallableSignature(proto, nameResolver, AnnotatedCallableKind.PROPERTY) ?: return null
val kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, AnnotatedCallableKind.PROPERTY) val kotlinClass = findClassWithAnnotationsAndInitializers(
container, nameResolver, getImplClassName(proto, nameResolver), isStaticFieldInOuter(proto)
)
if (kotlinClass == null) { if (kotlinClass == null) {
errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.getFqName(nameResolver)}", null) errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.getFqName(nameResolver)}", null)
return null return null
@@ -189,52 +190,41 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
private fun findClassWithAnnotationsAndInitializers( private fun findClassWithAnnotationsAndInitializers(
container: ProtoContainer, container: ProtoContainer,
proto: ProtoBuf.Callable,
nameResolver: NameResolver, nameResolver: NameResolver,
annotatedCallableKind: AnnotatedCallableKind, implClassName: Name?,
seekForStaticFieldInOuter: Boolean = true isStaticFieldInOuter: Boolean
): KotlinJvmBinaryClass? { ): KotlinJvmBinaryClass? {
val packageFqName = container.packageFqName val (classProto, packageFqName) = container
if (packageFqName != null) { return when {
return findPackagePartClass(packageFqName, proto, nameResolver) packageFqName != null -> {
} implClassName?.let { kotlinClassFinder.findKotlinClass(ClassId(packageFqName, it)) }
val classProto = container.classProto!!
val classKind = Flags.CLASS_KIND[classProto.getFlags()]
val classId = nameResolver.getClassId(classProto.getFqName())
if (classKind == ProtoBuf.Class.Kind.COMPANION_OBJECT && isStaticFieldInOuter(proto) && seekForStaticFieldInOuter) {
// Backing fields of properties of a companion object are generated in the outer class
return kotlinClassFinder.findKotlinClass(classId.getOuterClassId())
}
else if (classKind == ProtoBuf.Class.Kind.INTERFACE && (annotatedCallableKind == AnnotatedCallableKind.PROPERTY)) {
if (proto.hasExtension(implClassName)) {
val parentPackageFqName = classId.getPackageFqName()
val tImplName = nameResolver.getName(proto.getExtension(implClassName))
// TODO: store accurate name for nested traits
return kotlinClassFinder.findKotlinClass(ClassId(parentPackageFqName, tImplName))
} }
return null classProto != null -> {
} val classId = nameResolver.getClassId(classProto.fqName)
return kotlinClassFinder.findKotlinClass(classId) if (implClassName != null) {
// TODO: store accurate name for nested traits
return kotlinClassFinder.findKotlinClass(ClassId(classId.packageFqName, implClassName))
}
if (isStaticFieldInOuter && classId.isNestedClass) {
// Backing fields of properties of a companion object are generated in the outer class
return kotlinClassFinder.findKotlinClass(classId.outerClassId)
}
kotlinClassFinder.findKotlinClass(classId)
}
else -> null
}
} }
private fun findPackagePartClass( private fun getImplClassName(proto: ProtoBuf.Callable, nameResolver: NameResolver): Name? {
packageFqName: FqName, return if (proto.hasExtension(implClassName)) nameResolver.getName(proto.getExtension(implClassName)) else null
proto: ProtoBuf.Callable,
nameResolver: NameResolver
): KotlinJvmBinaryClass? {
if (proto.hasExtension(implClassName)) {
val implClassName = nameResolver.getName(proto.getExtension(implClassName))
return kotlinClassFinder.findKotlinClass(ClassId(packageFqName, implClassName))
}
return null
} }
private fun isStaticFieldInOuter(proto: ProtoBuf.Callable): Boolean { private fun isStaticFieldInOuter(proto: ProtoBuf.Callable): Boolean {
if (!proto.hasExtension(propertySignature)) return false return proto.hasExtension(propertySignature) &&
val propertySignature = proto.getExtension(propertySignature) proto.getExtension(propertySignature).let { it.hasField() && it.field.isStaticInOuter }
return propertySignature.hasField() && propertySignature.getField().getIsStaticInOuter()
} }
private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): Storage<A, C> { private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): Storage<A, C> {