Use TypeSystemCommonBackendContext in KotlinTypeMapper.writeGenericArguments
This commit is contained in:
@@ -352,26 +352,9 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
parameters: List<TypeParameterDescriptor>,
|
parameters: List<TypeParameterDescriptor>,
|
||||||
mode: TypeMappingMode
|
mode: TypeMappingMode
|
||||||
) {
|
) {
|
||||||
for ((parameter, argument) in parameters.zip(arguments)) {
|
with(SimpleClassicTypeSystemContext) {
|
||||||
if (argument.isStarProjection ||
|
writeGenericArguments(signatureVisitor, arguments, parameters, mode) { type, sw, mode ->
|
||||||
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
|
mapType(type as KotlinType, sw, mode)
|
||||||
KotlinBuiltIns.isNothing(argument.type) && parameter.variance === Variance.IN_VARIANCE
|
|
||||||
) {
|
|
||||||
signatureVisitor.writeUnboundedWildcard()
|
|
||||||
} else {
|
|
||||||
val argumentMode = mode.updateArgumentModeFromAnnotations(argument.type)
|
|
||||||
val projectionKind = getVarianceForWildcard(parameter, argument, argumentMode)
|
|
||||||
|
|
||||||
signatureVisitor.writeTypeArgument(projectionKind)
|
|
||||||
|
|
||||||
mapType(
|
|
||||||
argument.type, signatureVisitor,
|
|
||||||
argumentMode.toGenericArgumentMode(
|
|
||||||
getEffectiveVariance(parameter.variance, argument.projectionKind)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
signatureVisitor.writeTypeArgumentEnd()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1502,6 +1485,37 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
return Variance.OUT_VARIANCE
|
return Variance.OUT_VARIANCE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun TypeSystemCommonBackendContext.writeGenericArguments(
|
||||||
|
signatureVisitor: JvmSignatureWriter,
|
||||||
|
arguments: List<TypeArgumentMarker>,
|
||||||
|
parameters: List<TypeParameterMarker>,
|
||||||
|
mode: TypeMappingMode,
|
||||||
|
mapType: (KotlinTypeMarker, JvmSignatureWriter, TypeMappingMode) -> Type
|
||||||
|
) {
|
||||||
|
for ((parameter, argument) in parameters.zip(arguments)) {
|
||||||
|
if (argument.isStarProjection() ||
|
||||||
|
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
|
||||||
|
argument.getType().isNothing() && parameter.getVariance() == TypeVariance.IN
|
||||||
|
) {
|
||||||
|
signatureVisitor.writeUnboundedWildcard()
|
||||||
|
} else {
|
||||||
|
val argumentMode = mode.updateArgumentModeFromAnnotations(argument.getType(), this)
|
||||||
|
val projectionKind = getVarianceForWildcard(parameter, argument, argumentMode)
|
||||||
|
|
||||||
|
signatureVisitor.writeTypeArgument(projectionKind)
|
||||||
|
|
||||||
|
mapType(
|
||||||
|
argument.getType(), signatureVisitor,
|
||||||
|
argumentMode.toGenericArgumentMode(
|
||||||
|
getEffectiveVariance(parameter.getVariance().convertVariance(), argument.getVariance().convertVariance())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
signatureVisitor.writeTypeArgumentEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//NB: similar platform agnostic code in DescriptorUtils.unwrapFakeOverride
|
//NB: similar platform agnostic code in DescriptorUtils.unwrapFakeOverride
|
||||||
private fun findSuperDeclaration(descriptor: FunctionDescriptor, isSuperCall: Boolean): FunctionDescriptor {
|
private fun findSuperDeclaration(descriptor: FunctionDescriptor, isSuperCall: Boolean): FunctionDescriptor {
|
||||||
var current = descriptor
|
var current = descriptor
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@file:JvmName("TypeMappingUtil")
|
@file:JvmName("TypeMappingUtil")
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.state
|
package org.jetbrains.kotlin.codegen.state
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
@@ -32,6 +33,7 @@ import org.jetbrains.kotlin.resolve.isInlineClassType
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
|
||||||
import org.jetbrains.kotlin.types.checker.convertVariance
|
import org.jetbrains.kotlin.types.checker.convertVariance
|
||||||
import org.jetbrains.kotlin.types.getEffectiveVariance
|
import org.jetbrains.kotlin.types.getEffectiveVariance
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
@@ -82,8 +84,10 @@ private val METHODS_WITH_DECLARATION_SITE_WILDCARDS = setOf(
|
|||||||
BUILTIN_NAMES.mutableMap.child("putAll")
|
BUILTIN_NAMES.mutableMap.child("putAll")
|
||||||
)
|
)
|
||||||
|
|
||||||
fun TypeMappingMode.updateArgumentModeFromAnnotations(type: KotlinType): TypeMappingMode {
|
fun TypeMappingMode.updateArgumentModeFromAnnotations(
|
||||||
type.suppressWildcardsMode()?.let {
|
type: KotlinTypeMarker, typeSystem: TypeSystemCommonBackendContext
|
||||||
|
): TypeMappingMode {
|
||||||
|
type.suppressWildcardsMode(typeSystem)?.let {
|
||||||
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
|
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
|
||||||
skipDeclarationSiteWildcards = it,
|
skipDeclarationSiteWildcards = it,
|
||||||
isForAnnotationParameter = isForAnnotationParameter,
|
isForAnnotationParameter = isForAnnotationParameter,
|
||||||
@@ -91,12 +95,12 @@ fun TypeMappingMode.updateArgumentModeFromAnnotations(type: KotlinType): TypeMap
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.annotations.hasAnnotation(JVM_WILDCARD_ANNOTATION_FQ_NAME)) {
|
if (with(typeSystem) { type.hasAnnotation(JVM_WILDCARD_ANNOTATION_FQ_NAME) }) {
|
||||||
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
|
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
|
||||||
skipDeclarationSiteWildcards = false,
|
skipDeclarationSiteWildcards = false,
|
||||||
isForAnnotationParameter = isForAnnotationParameter,
|
isForAnnotationParameter = isForAnnotationParameter,
|
||||||
fallbackMode = this,
|
fallbackMode = this,
|
||||||
needInlineClassWrapping = needInlineClassWrapping
|
needInlineClassWrapping = needInlineClassWrapping
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +112,7 @@ internal fun extractTypeMappingModeFromAnnotation(
|
|||||||
outerType: KotlinType,
|
outerType: KotlinType,
|
||||||
isForAnnotationParameter: Boolean
|
isForAnnotationParameter: Boolean
|
||||||
): TypeMappingMode? =
|
): TypeMappingMode? =
|
||||||
(outerType.suppressWildcardsMode() ?: callableDescriptor?.suppressWildcardsMode())?.let {
|
(outerType.suppressWildcardsMode(SimpleClassicTypeSystemContext) ?: callableDescriptor?.suppressWildcardsMode())?.let {
|
||||||
if (outerType.arguments.isNotEmpty())
|
if (outerType.arguments.isNotEmpty())
|
||||||
TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
|
TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
|
||||||
skipDeclarationSiteWildcards = it,
|
skipDeclarationSiteWildcards = it,
|
||||||
@@ -122,14 +126,17 @@ internal fun extractTypeMappingModeFromAnnotation(
|
|||||||
private fun DeclarationDescriptor.suppressWildcardsMode(): Boolean? =
|
private fun DeclarationDescriptor.suppressWildcardsMode(): Boolean? =
|
||||||
parentsWithSelf.mapNotNull {
|
parentsWithSelf.mapNotNull {
|
||||||
it.annotations.findAnnotation(JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME)
|
it.annotations.findAnnotation(JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME)
|
||||||
}.firstOrNull().suppressWildcardsMode()
|
}.firstOrNull()?.suppressWildcardsMode()
|
||||||
|
|
||||||
private fun KotlinType.suppressWildcardsMode(): Boolean? =
|
private fun KotlinTypeMarker.suppressWildcardsMode(typeSystem: TypeSystemCommonBackendContext): Boolean? =
|
||||||
annotations.findAnnotation(JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME).suppressWildcardsMode()
|
with(typeSystem) {
|
||||||
|
if (hasAnnotation(JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME))
|
||||||
|
getAnnotationFirstArgumentValue(JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME) as? Boolean ?: true
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
private fun AnnotationDescriptor?.suppressWildcardsMode(): Boolean? {
|
private fun AnnotationDescriptor.suppressWildcardsMode(): Boolean? =
|
||||||
return (this ?: return null).allValueArguments.values.firstOrNull()?.value as? Boolean ?: true
|
allValueArguments.values.firstOrNull()?.value as? Boolean ?: true
|
||||||
}
|
|
||||||
|
|
||||||
val JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmSuppressWildcards")
|
val JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmSuppressWildcards")
|
||||||
val JVM_WILDCARD_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmWildcard")
|
val JVM_WILDCARD_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmWildcard")
|
||||||
|
|||||||
@@ -5,9 +5,23 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.types
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeSystemContext
|
import org.jetbrains.kotlin.types.model.TypeSystemContext
|
||||||
|
|
||||||
interface TypeSystemCommonBackendContext : TypeSystemContext {
|
interface TypeSystemCommonBackendContext : TypeSystemContext {
|
||||||
fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean
|
fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean
|
||||||
|
|
||||||
|
fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return value of the first argument of the annotation with the given [fqName], if the annotation is present and
|
||||||
|
* the argument is of a primitive type or a String, or null otherwise.
|
||||||
|
*
|
||||||
|
* Note that this method returns null if no arguments are provided, even if the corresponding annotation parameter has a default value.
|
||||||
|
*
|
||||||
|
* TODO: provide a more granular & elaborate API here to reduce confusion
|
||||||
|
*/
|
||||||
|
fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
|
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasExactAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.hasExactAnnotation
|
||||||
@@ -485,6 +486,15 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
return this is NewCapturedTypeConstructor
|
return this is NewCapturedTypeConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean {
|
||||||
|
require(this is KotlinType, this::errorMessage)
|
||||||
|
return annotations.hasAnnotation(fqName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any? {
|
||||||
|
require(this is KotlinType, this::errorMessage)
|
||||||
|
return annotations.findAnnotation(fqName)?.allValueArguments?.values?.firstOrNull()?.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TypeVariance.convertVariance(): Variance {
|
fun TypeVariance.convertVariance(): Variance {
|
||||||
|
|||||||
+2
-1
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
|
||||||
|
|
||||||
private typealias SubstitutionMap = Map<String, Pair<KtTypeParameter, KtTypeProjection>>
|
private typealias SubstitutionMap = Map<String, Pair<KtTypeParameter, KtTypeProjection>>
|
||||||
|
|
||||||
@@ -145,7 +146,7 @@ class ErrorTypeCorrector(
|
|||||||
RETURN_TYPE -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
|
RETURN_TYPE -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
|
||||||
METHOD_PARAMETER_TYPE -> TypeMappingMode.getOptimalModeForValueParameter(kotlinType)
|
METHOD_PARAMETER_TYPE -> TypeMappingMode.getOptimalModeForValueParameter(kotlinType)
|
||||||
SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
|
SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
|
||||||
}.updateArgumentModeFromAnnotations(kotlinType)
|
}.updateArgumentModeFromAnnotations(kotlinType, SimpleClassicTypeSystemContext)
|
||||||
|
|
||||||
val typeParameters = (target as? ClassifierDescriptor)?.typeConstructor?.parameters
|
val typeParameters = (target as? ClassifierDescriptor)?.typeConstructor?.parameters
|
||||||
return treeMaker.TypeApply(baseExpression, mapJListIndexed(arguments) { index, projection ->
|
return treeMaker.TypeApply(baseExpression, mapJListIndexed(arguments) { index, projection ->
|
||||||
|
|||||||
Reference in New Issue
Block a user