Introduce SignatureEnhancement component

It will depend on the AnnotationTypeQualifierResolver later
This commit is contained in:
Denis Zharkov
2017-06-13 15:43:24 +03:00
parent 21d1d16e74
commit b3caa1da34
5 changed files with 84 additions and 78 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.load.java.components.*
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
@@ -51,7 +52,8 @@ class JavaResolverComponents(
val lookupTracker: LookupTracker,
val module: ModuleDescriptor,
val reflectionTypes: ReflectionTypes,
val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver
val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver,
val signatureEnhancement: SignatureEnhancement
) {
fun replace(
javaResolverCache: JavaResolverCache = this.javaResolverCache
@@ -60,7 +62,7 @@ class JavaResolverComponents(
externalAnnotationResolver, signaturePropagator, errorReporter, javaResolverCache,
javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory,
moduleClassResolver, packageMapper, supertypeLoopChecker, lookupTracker, module, reflectionTypes,
annotationTypeQualifierResolver
annotationTypeQualifierResolver, signatureEnhancement
)
}
@@ -44,7 +44,6 @@ import org.jetbrains.kotlin.load.java.structure.JavaArrayType
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaConstructor
import org.jetbrains.kotlin.load.java.structure.JavaMethod
import org.jetbrains.kotlin.load.java.typeEnhancement.enhanceSignatures
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory
@@ -86,7 +85,7 @@ class LazyJavaClassMemberScope(
result.add(descriptor)
}
enhanceSignatures(
c.components.signatureEnhancement.enhanceSignatures(
result.ifEmpty { listOfNotNull(createDefaultConstructor()) }
).toList()
}
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.load.java.structure.JavaArrayType
import org.jetbrains.kotlin.load.java.structure.JavaField
import org.jetbrains.kotlin.load.java.structure.JavaMethod
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
import org.jetbrains.kotlin.load.java.typeEnhancement.enhanceSignatures
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.retainMostSpecificInEachOverridableGroup
@@ -88,7 +87,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
computeNonDeclaredFunctions(result, name)
enhanceSignatures(result).toList()
c.components.signatureEnhancement.enhanceSignatures(result).toList()
}
open protected fun JavaMethodDescriptor.isVisibleAsFunction() = true
@@ -240,7 +239,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
if (DescriptorUtils.isAnnotationClass(ownerDescriptor))
properties.toList()
else
enhanceSignatures(properties).toList()
c.components.signatureEnhancement.enhanceSignatures(properties).toList()
}
private fun resolveProperty(field: JavaField): PropertyDescriptor {
@@ -24,86 +24,90 @@ import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
import org.jetbrains.kotlin.types.KotlinType
fun <D : CallableMemberDescriptor> enhanceSignatures(platformSignatures: Collection<D>): Collection<D> {
return platformSignatures.map {
it.enhanceSignature()
}
}
private fun <D : CallableMemberDescriptor> D.enhanceSignature(): D {
// TODO type parameters
// TODO use new type parameters while enhancing other types
// TODO Propagation into generic type arguments
if (this !is JavaCallableMemberDescriptor) return this
// Fake overrides with one overridden has been enhanced before
if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE && original.overriddenDescriptors.size == 1) return this
val receiverTypeEnhancement =
if (extensionReceiverParameter != null)
parts(isCovariant = false) { it.extensionReceiverParameter!!.type }.enhance()
else null
val predefinedEnhancementInfo =
(this as? JavaMethodDescriptor)
?.run { SignatureBuildingComponents.signature(this.containingDeclaration as ClassDescriptor, this.computeJvmDescriptor()) }
?.let { signature -> PREDEFINED_FUNCTION_ENHANCEMENT_INFO_BY_SIGNATURE[signature] }
predefinedEnhancementInfo?.let {
assert(it.parametersInfo.size == valueParameters.size) {
"Predefined enhancement info for $this has ${it.parametersInfo.size}, but ${valueParameters.size} expected"
class SignatureEnhancement {
fun <D : CallableMemberDescriptor> enhanceSignatures(platformSignatures: Collection<D>): Collection<D> {
return platformSignatures.map {
it.enhanceSignature()
}
}
val valueParameterEnhancements = valueParameters.map {
p ->
parts(isCovariant = false) { it.valueParameters[p.index].type }
.enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index))
}
private fun <D : CallableMemberDescriptor> D.enhanceSignature(): D {
// TODO type parameters
// TODO use new type parameters while enhancing other types
// TODO Propagation into generic type arguments
val returnTypeEnhancement = parts(isCovariant = true) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
if (this !is JavaCallableMemberDescriptor) return this
if ((receiverTypeEnhancement?.wereChanges ?: false)
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges }) {
@Suppress("UNCHECKED_CAST")
return this.enhance(receiverTypeEnhancement?.type, valueParameterEnhancements.map { it.type }, returnTypeEnhancement.type) as D
}
// Fake overrides with one overridden has been enhanced before
if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE && original.overriddenDescriptors.size == 1) return this
return this
}
val receiverTypeEnhancement =
if (extensionReceiverParameter != null)
parts(isCovariant = false) { it.extensionReceiverParameter!!.type }.enhance()
else null
private class SignatureParts(
val fromOverride: KotlinType,
val fromOverridden: Collection<KotlinType>,
val isCovariant: Boolean
) {
fun enhance(predefined: TypeEnhancementInfo? = null): PartEnhancementResult {
val qualifiers = fromOverride.computeIndexedQualifiersForOverride(this.fromOverridden, isCovariant)
val qualifiersWithPredefined: ((Int) -> JavaTypeQualifiers)? = predefined?.let {
{
index -> predefined.map[index] ?: qualifiers(index)
val predefinedEnhancementInfo =
(this as? JavaMethodDescriptor)
?.run { SignatureBuildingComponents.signature(this.containingDeclaration as ClassDescriptor, this.computeJvmDescriptor()) }
?.let { signature -> PREDEFINED_FUNCTION_ENHANCEMENT_INFO_BY_SIGNATURE[signature] }
predefinedEnhancementInfo?.let {
assert(it.parametersInfo.size == valueParameters.size) {
"Predefined enhancement info for $this has ${it.parametersInfo.size}, but ${valueParameters.size} expected"
}
}
return fromOverride.enhance(qualifiersWithPredefined ?: qualifiers)?.let {
enhanced -> PartEnhancementResult(enhanced, wereChanges = true)
} ?: PartEnhancementResult(fromOverride, wereChanges = false)
val valueParameterEnhancements = valueParameters.map {
p ->
parts(isCovariant = false) { it.valueParameters[p.index].type }
.enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index))
}
val returnTypeEnhancement = parts(isCovariant = true) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
if ((receiverTypeEnhancement?.wereChanges ?: false)
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges }) {
@Suppress("UNCHECKED_CAST")
return this.enhance(receiverTypeEnhancement?.type, valueParameterEnhancements.map { it.type }, returnTypeEnhancement.type) as D
}
return this
}
private class SignatureParts(
val fromOverride: KotlinType,
val fromOverridden: Collection<KotlinType>,
val isCovariant: Boolean
) {
fun enhance(predefined: TypeEnhancementInfo? = null): PartEnhancementResult {
val qualifiers = fromOverride.computeIndexedQualifiersForOverride(this.fromOverridden, isCovariant)
val qualifiersWithPredefined: ((Int) -> JavaTypeQualifiers)? = predefined?.let {
{
index ->
predefined.map[index] ?: qualifiers(index)
}
}
return fromOverride.enhance(qualifiersWithPredefined ?: qualifiers)?.let {
enhanced ->
PartEnhancementResult(enhanced, wereChanges = true)
} ?: PartEnhancementResult(fromOverride, wereChanges = false)
}
}
private data class PartEnhancementResult(val type: KotlinType, val wereChanges: Boolean)
private fun <D : CallableMemberDescriptor> D.parts(isCovariant: Boolean, collector: (D) -> KotlinType): SignatureParts {
return SignatureParts(
collector(this),
this.overriddenDescriptors.map {
@Suppress("UNCHECKED_CAST")
collector(it as D)
},
isCovariant
)
}
}
private data class PartEnhancementResult(val type: KotlinType, val wereChanges: Boolean)
private fun <D : CallableMemberDescriptor> D.parts(isCovariant: Boolean, collector: (D) -> KotlinType): SignatureParts {
return SignatureParts(
collector(this),
this.overriddenDescriptors.map {
@Suppress("UNCHECKED_CAST")
collector(it as D)
},
isCovariant
)
}