Flexible types added to JDR
So far they act exactly like inflexible ones
This commit is contained in:
+4
-3
@@ -45,6 +45,7 @@ import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.ExternalSignatureResolver
|
||||
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.jet.utils.*
|
||||
import org.jetbrains.jet.lang.resolve.java.PLATFORM_TYPES
|
||||
|
||||
public abstract class LazyJavaMemberScope(
|
||||
protected val c: LazyJavaResolverContextWithTypes,
|
||||
@@ -180,12 +181,12 @@ public abstract class LazyJavaMemberScope(
|
||||
val paramType = javaParameter.getType()
|
||||
assert (paramType is JavaArrayType, "Vararg parameter should be an array: $paramType")
|
||||
val arrayType = c.typeResolver.transformArrayType(paramType as JavaArrayType, typeUsage, true)
|
||||
val outType = TypeUtils.makeNotNullable(arrayType)
|
||||
val outType = if (PLATFORM_TYPES) arrayType else TypeUtils.makeNotNullable(arrayType)
|
||||
Pair(outType, KotlinBuiltIns.getInstance().getArrayElementType(outType))
|
||||
}
|
||||
else {
|
||||
val jetType = c.typeResolver.transformJavaType(javaParameter.getType(), typeUsage)
|
||||
if (jetType.isNullable() && c.hasNotNullAnnotation(javaParameter))
|
||||
if (!PLATFORM_TYPES && jetType.isNullable() && c.hasNotNullAnnotation(javaParameter))
|
||||
Pair(TypeUtils.makeNotNullable(jetType), null)
|
||||
else Pair(jetType, null)
|
||||
}
|
||||
@@ -285,7 +286,7 @@ public abstract class LazyJavaMemberScope(
|
||||
private fun getPropertyType(field: JavaField): JetType {
|
||||
// Fields do not have their own generic parameters
|
||||
val propertyType = c.typeResolver.transformJavaType(field.getType(), LazyJavaTypeAttributes(c, field, TypeUsage.MEMBER_SIGNATURE_INVARIANT))
|
||||
if (field.isFinal() && field.isStatic()) {
|
||||
if (!PLATFORM_TYPES && field.isFinal() && field.isStatic()) {
|
||||
return TypeUtils.makeNotNullable(propertyType)
|
||||
}
|
||||
return propertyType
|
||||
|
||||
+62
-3
@@ -31,6 +31,8 @@ import org.jetbrains.jet.lang.resolve.java.lazy.*
|
||||
import org.jetbrains.jet.storage.*
|
||||
import java.util.HashSet
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||
import org.jetbrains.jet.lang.resolve.java.PLATFORM_TYPES
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.types.Flexibility.*
|
||||
|
||||
class LazyJavaTypeResolver(
|
||||
private val c: LazyJavaResolverContext,
|
||||
@@ -45,7 +47,9 @@ class LazyJavaTypeResolver(
|
||||
assert(jetType != null, "Primitive type is not found: " + canonicalText)
|
||||
return jetType!!
|
||||
}
|
||||
is JavaClassifierType -> LazyJavaClassifierType(javaType, attr)
|
||||
is JavaClassifierType -> if (PLATFORM_TYPES)
|
||||
LazyFlexibleJavaClassifierType(javaType, attr)
|
||||
else LazyJavaClassifierType(javaType, attr)
|
||||
is JavaArrayType -> transformArrayType(javaType, attr)
|
||||
else -> throw UnsupportedOperationException("Unsupported type: " + javaType)
|
||||
}
|
||||
@@ -62,7 +66,16 @@ class LazyJavaTypeResolver(
|
||||
|
||||
val howArgumentTypeIsUsed = if (isVararg) MEMBER_SIGNATURE_CONTRAVARIANT else TYPE_ARGUMENT
|
||||
val componentType = transformJavaType(javaComponentType, howArgumentTypeIsUsed.toAttributes())
|
||||
return TypeUtils.makeNullableAsSpecified(KotlinBuiltIns.getInstance().getArrayType(projectionKind, componentType), !attr.isMarkedNotNull)
|
||||
val result = KotlinBuiltIns.getInstance().getArrayType(projectionKind, componentType)
|
||||
return if (PLATFORM_TYPES)
|
||||
DelegatingFlexibleType(
|
||||
KotlinBuiltIns.getInstance().getArrayType(INVARIANT, componentType),
|
||||
TypeUtils.makeNullable(
|
||||
KotlinBuiltIns.getInstance().getArrayType(OUT_VARIANCE, componentType)
|
||||
)
|
||||
)
|
||||
else
|
||||
TypeUtils.makeNullableAsSpecified(result, !attr.isMarkedNotNull)
|
||||
}
|
||||
|
||||
private class LazyStarProjection(
|
||||
@@ -95,6 +108,9 @@ class LazyJavaTypeResolver(
|
||||
|
||||
val javaToKotlinClassMap = JavaToKotlinClassMap.getInstance()
|
||||
val howThisTypeIsUsedEffectively = when {
|
||||
attr.flexibility == FLEXIBLE_LOWER_BOUND -> MEMBER_SIGNATURE_COVARIANT
|
||||
attr.flexibility == FLEXIBLE_UPPER_BOUND -> MEMBER_SIGNATURE_CONTRAVARIANT
|
||||
|
||||
// This case has to be checked before isMarkedReadOnly/isMarkedMutable, because those two are slow
|
||||
// not mapped, we don't care about being marked mutable/read-only
|
||||
javaToKotlinClassMap.mapPlatformClass(fqName).isEmpty() -> attr.howThisTypeIsUsed
|
||||
@@ -220,7 +236,12 @@ class LazyJavaTypeResolver(
|
||||
return (descriptor as ClassDescriptor).getMemberScope(getArguments())
|
||||
}
|
||||
|
||||
private val _nullable = c.storageManager.createLazyValue {
|
||||
private val _nullable = c.storageManager.createLazyValue @nullable{
|
||||
(): Boolean ->
|
||||
when (attr.flexibility) {
|
||||
FLEXIBLE_LOWER_BOUND -> return@nullable false
|
||||
FLEXIBLE_UPPER_BOUND -> return@nullable true
|
||||
}
|
||||
!attr.isMarkedNotNull &&
|
||||
// 'L extends List<T>' in Java is a List<T> in Kotlin, not a List<T?>
|
||||
// nullability will be taken care of in individual member signatures
|
||||
@@ -238,12 +259,45 @@ class LazyJavaTypeResolver(
|
||||
}
|
||||
override fun isNullable(): Boolean = _nullable()
|
||||
}
|
||||
|
||||
private open class DelegatingFlexibleType(
|
||||
override val lowerBound: JetType,
|
||||
override val upperBound: JetType
|
||||
) : DelegatingType(), FlexibleType {
|
||||
|
||||
override fun getDelegate() = lowerBound
|
||||
|
||||
override fun toString() = "('$lowerBound'..'$upperBound')"
|
||||
}
|
||||
|
||||
/*
|
||||
* For a java type like java.util.List<Foo>
|
||||
* lowerBound = MutableList<Foo>
|
||||
* upperBound = List<Foo?>
|
||||
*/
|
||||
private inner class LazyFlexibleJavaClassifierType(
|
||||
javaType: JavaClassifierType,
|
||||
attr: JavaTypeAttributes
|
||||
) : DelegatingFlexibleType(
|
||||
LazyJavaClassifierType(javaType, attr.toFlexible(FLEXIBLE_LOWER_BOUND)),
|
||||
LazyJavaClassifierType(javaType, attr.toFlexible(FLEXIBLE_UPPER_BOUND))
|
||||
)
|
||||
}
|
||||
|
||||
trait JavaTypeAttributes {
|
||||
val howThisTypeIsUsed: TypeUsage
|
||||
val howThisTypeIsUsedAccordingToAnnotations: TypeUsage
|
||||
val isMarkedNotNull: Boolean
|
||||
open val flexibility: Flexibility
|
||||
get() = INFLEXIBLE
|
||||
}
|
||||
|
||||
fun JavaTypeAttributes.isFlexible() = flexibility != INFLEXIBLE
|
||||
|
||||
enum class Flexibility {
|
||||
INFLEXIBLE
|
||||
FLEXIBLE_UPPER_BOUND
|
||||
FLEXIBLE_LOWER_BOUND
|
||||
}
|
||||
|
||||
class LazyJavaTypeAttributes(
|
||||
@@ -266,3 +320,8 @@ fun TypeUsage.toAttributes() = object : JavaTypeAttributes {
|
||||
get() = howThisTypeIsUsed
|
||||
override val isMarkedNotNull: Boolean = false
|
||||
}
|
||||
|
||||
fun JavaTypeAttributes.toFlexible(flexibility: Flexibility) =
|
||||
object : JavaTypeAttributes by this {
|
||||
override val flexibility = flexibility
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user