Refactoring. Remove type capability Flexibility.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -180,9 +180,9 @@ public abstract class AnnotationCodegen {
|
|||||||
|
|
||||||
if (FlexibleTypesKt.isFlexible(type)) {
|
if (FlexibleTypesKt.isFlexible(type)) {
|
||||||
// A flexible type whose lower bound in not-null and upper bound is nullable, should not be annotated
|
// A flexible type whose lower bound in not-null and upper bound is nullable, should not be annotated
|
||||||
Flexibility flexibility = FlexibleTypesKt.flexibility(type);
|
FlexibleType flexibleType = FlexibleTypesKt.asFlexibleType(type);
|
||||||
|
|
||||||
if (!TypeUtils.isNullableType(flexibility.getLowerBound()) && TypeUtils.isNullableType(flexibility.getUpperBound())) {
|
if (!TypeUtils.isNullableType(flexibleType.getLowerBound()) && TypeUtils.isNullableType(flexibleType.getUpperBound())) {
|
||||||
AnnotationDescriptor notNull = type.getAnnotations().findAnnotation(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION);
|
AnnotationDescriptor notNull = type.getAnnotations().findAnnotation(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION);
|
||||||
if (notNull != null) {
|
if (notNull != null) {
|
||||||
generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, NotNull.class);
|
generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, NotNull.class);
|
||||||
|
|||||||
+2
-2
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.resolve.jvm
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.flexibility
|
import org.jetbrains.kotlin.types.asFlexibleType
|
||||||
import org.jetbrains.kotlin.types.isFlexible
|
import org.jetbrains.kotlin.types.isFlexible
|
||||||
|
|
||||||
object JvmTypeSpecificityComparator : TypeSpecificityComparator {
|
object JvmTypeSpecificityComparator : TypeSpecificityComparator {
|
||||||
@@ -28,7 +28,7 @@ object JvmTypeSpecificityComparator : TypeSpecificityComparator {
|
|||||||
if (!specific.isFlexible() || general.isFlexible()) return false
|
if (!specific.isFlexible() || general.isFlexible()) return false
|
||||||
|
|
||||||
// general is inflexible
|
// general is inflexible
|
||||||
val flexibility = specific.flexibility()
|
val flexibility = specific.asFlexibleType()
|
||||||
|
|
||||||
// For primitive types we have to take care of the case when there are two overloaded methods like
|
// For primitive types we have to take care of the case when there are two overloaded methods like
|
||||||
// foo(int) and foo(Integer)
|
// foo(int) and foo(Integer)
|
||||||
|
|||||||
+2
-2
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.flexibility
|
import org.jetbrains.kotlin.types.asFlexibleType
|
||||||
import org.jetbrains.kotlin.types.isFlexible
|
import org.jetbrains.kotlin.types.isFlexible
|
||||||
|
|
||||||
class WhenByPlatformEnumChecker : AdditionalTypeChecker {
|
class WhenByPlatformEnumChecker : AdditionalTypeChecker {
|
||||||
@@ -34,7 +34,7 @@ class WhenByPlatformEnumChecker : AdditionalTypeChecker {
|
|||||||
if (expression is KtWhenExpression && expression.elseExpression == null) {
|
if (expression is KtWhenExpression && expression.elseExpression == null) {
|
||||||
// Check for conditionally-exhaustive when on platform enums, see KT-6399
|
// Check for conditionally-exhaustive when on platform enums, see KT-6399
|
||||||
val type = expression.subjectExpression?.let { c.trace.getType(it) } ?: return
|
val type = expression.subjectExpression?.let { c.trace.getType(it) } ?: return
|
||||||
if (type.isFlexible() && TypeUtils.isNullableType(type.flexibility().upperBound) && !type.annotations.isMarkedNotNull()) {
|
if (type.isFlexible() && TypeUtils.isNullableType(type.asFlexibleType().upperBound) && !type.annotations.isMarkedNotNull()) {
|
||||||
val enumClassDescriptor = WhenChecker.getClassDescriptorOfTypeIfEnum(type) ?: return
|
val enumClassDescriptor = WhenChecker.getClassDescriptorOfTypeIfEnum(type) ?: return
|
||||||
val context = c.trace.bindingContext
|
val context = c.trace.bindingContext
|
||||||
if (WhenChecker.getEnumMissingCases(expression, context, enumClassDescriptor).isEmpty()
|
if (WhenChecker.getEnumMissingCases(expression, context, enumClassDescriptor).isEmpty()
|
||||||
|
|||||||
+2
-2
@@ -45,8 +45,8 @@ object JavaGenericVarianceViolationTypeChecker : AdditionalTypeChecker {
|
|||||||
// optimization: if no arguments or flexibility, everything is OK
|
// optimization: if no arguments or flexibility, everything is OK
|
||||||
if (expectedType.arguments.isEmpty() || !expectedType.isFlexible()) return
|
if (expectedType.arguments.isEmpty() || !expectedType.isFlexible()) return
|
||||||
|
|
||||||
val lowerBound = expectedType.flexibility().lowerBound
|
val lowerBound = expectedType.asFlexibleType().lowerBound
|
||||||
val upperBound = expectedType.flexibility().upperBound
|
val upperBound = expectedType.asFlexibleType().upperBound
|
||||||
|
|
||||||
// Use site variance projection is always the same for flexible types
|
// Use site variance projection is always the same for flexible types
|
||||||
if (lowerBound.constructor == upperBound.constructor) return
|
if (lowerBound.constructor == upperBound.constructor) return
|
||||||
|
|||||||
@@ -1151,9 +1151,9 @@ public class DescriptorResolver {
|
|||||||
: "Flexible type cannot be denoted in Kotlin otherwise than as ft<T1, T2>, but was: "
|
: "Flexible type cannot be denoted in Kotlin otherwise than as ft<T1, T2>, but was: "
|
||||||
+ PsiUtilsKt.getElementTextWithContext(typeReference);
|
+ PsiUtilsKt.getElementTextWithContext(typeReference);
|
||||||
// it's really ft<Foo, Bar>
|
// it's really ft<Foo, Bar>
|
||||||
Flexibility flexibility = FlexibleTypesKt.flexibility(type);
|
FlexibleType flexibleType = FlexibleTypesKt.asFlexibleType(type);
|
||||||
checkBounds(jetTypeArguments.get(0), flexibility.getLowerBound(), trace);
|
checkBounds(jetTypeArguments.get(0), flexibleType.getLowerBound(), trace);
|
||||||
checkBounds(jetTypeArguments.get(1), flexibility.getUpperBound(), trace);
|
checkBounds(jetTypeArguments.get(1), flexibleType.getUpperBound(), trace);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -156,8 +156,8 @@ class TypeResolver(
|
|||||||
private fun forceResolveTypeContents(type: KotlinType) {
|
private fun forceResolveTypeContents(type: KotlinType) {
|
||||||
type.annotations // force read type annotations
|
type.annotations // force read type annotations
|
||||||
if (type.isFlexible()) {
|
if (type.isFlexible()) {
|
||||||
forceResolveTypeContents(type.flexibility().lowerBound)
|
forceResolveTypeContents(type.asFlexibleType().lowerBound)
|
||||||
forceResolveTypeContents(type.flexibility().upperBound)
|
forceResolveTypeContents(type.asFlexibleType().upperBound)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
type.constructor // force read type constructor
|
type.constructor // force read type constructor
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -98,8 +98,8 @@ public class ForceResolveUtil {
|
|||||||
|
|
||||||
forceResolveAllContents(type.getAnnotations());
|
forceResolveAllContents(type.getAnnotations());
|
||||||
if (FlexibleTypesKt.isFlexible(type)) {
|
if (FlexibleTypesKt.isFlexible(type)) {
|
||||||
forceResolveAllContents(FlexibleTypesKt.flexibility(type).getLowerBound());
|
forceResolveAllContents(FlexibleTypesKt.asFlexibleType(type).getLowerBound());
|
||||||
forceResolveAllContents(FlexibleTypesKt.flexibility(type).getUpperBound());
|
forceResolveAllContents(FlexibleTypesKt.asFlexibleType(type).getUpperBound());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
forceResolveAllContents(type.getConstructor());
|
forceResolveAllContents(type.getConstructor());
|
||||||
|
|||||||
@@ -91,9 +91,9 @@ public class CommonSupertypes {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
hasFlexible = true;
|
hasFlexible = true;
|
||||||
Flexibility flexibility = FlexibleTypesKt.flexibility(type);
|
FlexibleType flexibleType = FlexibleTypesKt.asFlexibleType(type);
|
||||||
upper.add(flexibility.getUpperBound());
|
upper.add(flexibleType.getUpperBound());
|
||||||
lower.add(flexibility.getLowerBound());
|
lower.add(flexibleType.getLowerBound());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
upper.add(KotlinTypeKt.asSimpleType(type));
|
upper.add(KotlinTypeKt.asSimpleType(type));
|
||||||
|
|||||||
+1
-1
@@ -506,7 +506,7 @@ public class DescriptorSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FlexibleTypesKt.isFlexible(type)) {
|
if (FlexibleTypesKt.isFlexible(type)) {
|
||||||
DelegatingFlexibleType flexibleType = (DelegatingFlexibleType) FlexibleTypesKt.flexibility(type);
|
DelegatingFlexibleType flexibleType = (DelegatingFlexibleType) FlexibleTypesKt.asFlexibleType(type);
|
||||||
|
|
||||||
ProtoBuf.Type.Builder lowerBound = type(flexibleType.getLowerBound());
|
ProtoBuf.Type.Builder lowerBound = type(flexibleType.getLowerBound());
|
||||||
ProtoBuf.Type.Builder upperBound = type(flexibleType.getUpperBound());
|
ProtoBuf.Type.Builder upperBound = type(flexibleType.getUpperBound());
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.serialization;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.types.DelegatingFlexibleType;
|
import org.jetbrains.kotlin.types.DelegatingFlexibleType;
|
||||||
import org.jetbrains.kotlin.types.Flexibility;
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
|
|
||||||
public abstract class SerializerExtension {
|
public abstract class SerializerExtension {
|
||||||
|
|||||||
+5
-5
@@ -49,12 +49,12 @@ object RawTypeCapabilities : TypeCapabilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderBounds(flexibility: Flexibility, renderer: DescriptorRenderer): Pair<String, String>? {
|
override fun renderBounds(flexibleType: FlexibleType, renderer: DescriptorRenderer): Pair<String, String>? {
|
||||||
val lowerArgs = renderer.renderArguments(flexibility.lowerBound)
|
val lowerArgs = renderer.renderArguments(flexibleType.lowerBound)
|
||||||
val upperArgs = renderer.renderArguments(flexibility.upperBound)
|
val upperArgs = renderer.renderArguments(flexibleType.upperBound)
|
||||||
|
|
||||||
val lowerRendered = renderer.renderType(flexibility.lowerBound)
|
val lowerRendered = renderer.renderType(flexibleType.lowerBound)
|
||||||
val upperRendered = renderer.renderType(flexibility.upperBound)
|
val upperRendered = renderer.renderType(flexibleType.upperBound)
|
||||||
|
|
||||||
if (!upperArgs.isNotEmpty()) return null
|
if (!upperArgs.isNotEmpty()) return null
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -58,7 +58,7 @@ private data class Result(val type: KotlinType, val subtreeSize: Int, val wereCh
|
|||||||
private fun KotlinType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result {
|
private fun KotlinType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result {
|
||||||
if (this.isError) return Result(this, 1, false)
|
if (this.isError) return Result(this, 1, false)
|
||||||
return if (this.isFlexible()) {
|
return if (this.isFlexible()) {
|
||||||
with(this.flexibility()) {
|
with(this.asFlexibleType()) {
|
||||||
val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER)
|
val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER)
|
||||||
val upperResult = upperBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_UPPER)
|
val upperResult = upperBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_UPPER)
|
||||||
assert(lowerResult.subtreeSize == upperResult.subtreeSize) {
|
assert(lowerResult.subtreeSize == upperResult.subtreeSize) {
|
||||||
@@ -227,7 +227,7 @@ internal object NotNullTypeParameterTypeCapability : CustomTypeVariable {
|
|||||||
if (!TypeUtils.isNullableType(replacement) && !replacement.isTypeParameter()) return replacement
|
if (!TypeUtils.isNullableType(replacement) && !replacement.isTypeParameter()) return replacement
|
||||||
|
|
||||||
if (replacement.isFlexible()) {
|
if (replacement.isFlexible()) {
|
||||||
with(replacement.flexibility()) {
|
with(replacement.asFlexibleType()) {
|
||||||
return KotlinTypeFactory.flexibleType(lowerBound.prepareReplacement().asSimpleType(), upperBound.prepareReplacement().asSimpleType())
|
return KotlinTypeFactory.flexibleType(lowerBound.prepareReplacement().asSimpleType(), upperBound.prepareReplacement().asSimpleType())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ class JavaTypeQualifiers internal constructor(
|
|||||||
private fun KotlinType.extractQualifiers(): JavaTypeQualifiers {
|
private fun KotlinType.extractQualifiers(): JavaTypeQualifiers {
|
||||||
val (lower, upper) =
|
val (lower, upper) =
|
||||||
if (this.isFlexible())
|
if (this.isFlexible())
|
||||||
flexibility().let { Pair(it.lowerBound, it.upperBound) }
|
asFlexibleType().let { Pair(it.lowerBound, it.upperBound) }
|
||||||
else Pair(this, this)
|
else Pair(this, this)
|
||||||
|
|
||||||
val mapping = JavaToKotlinClassMap.INSTANCE
|
val mapping = JavaToKotlinClassMap.INSTANCE
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ internal class DescriptorRendererImpl(
|
|||||||
}
|
}
|
||||||
if (type.isFlexible()) {
|
if (type.isFlexible()) {
|
||||||
if (debugMode) {
|
if (debugMode) {
|
||||||
return renderFlexibleTypeWithBothBounds(type.flexibility().lowerBound, type.flexibility().upperBound)
|
return renderFlexibleTypeWithBothBounds(type.asFlexibleType().lowerBound, type.asFlexibleType().upperBound)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return renderFlexibleType(type)
|
return renderFlexibleType(type)
|
||||||
@@ -194,10 +194,10 @@ internal class DescriptorRendererImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun renderFlexibleType(type: KotlinType): String {
|
private fun renderFlexibleType(type: KotlinType): String {
|
||||||
val lower = type.flexibility().lowerBound
|
val lower = type.asFlexibleType().lowerBound
|
||||||
val upper = type.flexibility().upperBound
|
val upper = type.asFlexibleType().upperBound
|
||||||
|
|
||||||
val (lowerRendered, upperRendered) = type.getCapability<RawTypeCapability>()?.renderBounds(type.flexibility(), this)
|
val (lowerRendered, upperRendered) = type.getCapability<RawTypeCapability>()?.renderBounds(type.asFlexibleType(), this)
|
||||||
?: Pair(renderInflexibleType(lower), renderInflexibleType(upper))
|
?: Pair(renderInflexibleType(lower), renderInflexibleType(upper))
|
||||||
|
|
||||||
if (differsOnlyInNullability(lowerRendered, upperRendered)) {
|
if (differsOnlyInNullability(lowerRendered, upperRendered)) {
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ interface RawTypeCapability : TypeCapability {
|
|||||||
val substitutionToComposeWith: TypeSubstitution?
|
val substitutionToComposeWith: TypeSubstitution?
|
||||||
|
|
||||||
fun renderInflexible(type: KotlinType, renderer: DescriptorRenderer): String?
|
fun renderInflexible(type: KotlinType, renderer: DescriptorRenderer): String?
|
||||||
fun renderBounds(flexibility: Flexibility, renderer: DescriptorRenderer): Pair<String, String>?
|
fun renderBounds(flexibleType: FlexibleType, renderer: DescriptorRenderer): Pair<String, String>?
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -140,11 +140,11 @@ public class TypeSubstitutor {
|
|||||||
TypeProjection replacement = substitution.get(type);
|
TypeProjection replacement = substitution.get(type);
|
||||||
Variance originalProjectionKind = originalProjection.getProjectionKind();
|
Variance originalProjectionKind = originalProjection.getProjectionKind();
|
||||||
if (replacement == null && FlexibleTypesKt.isFlexible(type) && !TypeCapabilitiesKt.isCustomTypeVariable(type)) {
|
if (replacement == null && FlexibleTypesKt.isFlexible(type) && !TypeCapabilitiesKt.isCustomTypeVariable(type)) {
|
||||||
Flexibility flexibility = FlexibleTypesKt.flexibility(type);
|
FlexibleType flexibleType = FlexibleTypesKt.asFlexibleType(type);
|
||||||
TypeProjection substitutedLower =
|
TypeProjection substitutedLower =
|
||||||
unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibility.getLowerBound()), recursionDepth + 1);
|
unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibleType.getLowerBound()), recursionDepth + 1);
|
||||||
TypeProjection substitutedUpper =
|
TypeProjection substitutedUpper =
|
||||||
unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibility.getUpperBound()), recursionDepth + 1);
|
unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibleType.getUpperBound()), recursionDepth + 1);
|
||||||
|
|
||||||
Variance substitutedProjectionKind = substitutedLower.getProjectionKind();
|
Variance substitutedProjectionKind = substitutedLower.getProjectionKind();
|
||||||
assert (substitutedProjectionKind == substitutedUpper.getProjectionKind()) &&
|
assert (substitutedProjectionKind == substitutedUpper.getProjectionKind()) &&
|
||||||
|
|||||||
@@ -135,12 +135,12 @@ public class TypeUtils {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static KotlinType makeNullableAsSpecified(@NotNull KotlinType type, boolean nullable) {
|
public static KotlinType makeNullableAsSpecified(@NotNull KotlinType type, boolean nullable) {
|
||||||
Flexibility flexibility = type.getCapability(Flexibility.class);
|
KotlinType unwrappedType = KotlinTypeKt.unwrap(type);
|
||||||
if (flexibility != null) {
|
if (unwrappedType instanceof FlexibleType) {
|
||||||
return flexibility.makeNullableAsSpecified(nullable);
|
return ((FlexibleType) unwrappedType).makeNullableAsSpecified(nullable);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SimpleType simpleType = KotlinTypeKt.asSimpleType(type);
|
SimpleType simpleType = (SimpleType) unwrappedType;
|
||||||
|
|
||||||
if (!(simpleType instanceof LazyType) && simpleType.isMarkedNullable() == nullable) return simpleType;
|
if (!(simpleType instanceof LazyType) && simpleType.isMarkedNullable() == nullable) return simpleType;
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ public class TypeUtils {
|
|||||||
if (type.isMarkedNullable()) {
|
if (type.isMarkedNullable()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (FlexibleTypesKt.isFlexible(type) && isNullableType(FlexibleTypesKt.flexibility(type).getUpperBound())) {
|
if (FlexibleTypesKt.isFlexible(type) && isNullableType(FlexibleTypesKt.asFlexibleType(type).getUpperBound())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isTypeParameter(type)) {
|
if (isTypeParameter(type)) {
|
||||||
@@ -336,7 +336,7 @@ public class TypeUtils {
|
|||||||
if (type.isMarkedNullable()) {
|
if (type.isMarkedNullable()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (FlexibleTypesKt.isFlexible(type) && acceptsNullable(FlexibleTypesKt.flexibility(type).getUpperBound())) {
|
if (FlexibleTypesKt.isFlexible(type) && acceptsNullable(FlexibleTypesKt.asFlexibleType(type).getUpperBound())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -436,9 +436,11 @@ public class TypeUtils {
|
|||||||
) {
|
) {
|
||||||
if (type == null) return false;
|
if (type == null) return false;
|
||||||
if (isSpecialType.invoke(type)) return true;
|
if (isSpecialType.invoke(type)) return true;
|
||||||
Flexibility flexibility = type.getCapability(Flexibility.class);
|
|
||||||
if (flexibility != null
|
KotlinType unwrappedType = KotlinTypeKt.unwrap(type);
|
||||||
&& (contains(flexibility.getLowerBound(), isSpecialType) || contains(flexibility.getUpperBound(), isSpecialType))) {
|
FlexibleType flexibleType = unwrappedType instanceof FlexibleType ? (FlexibleType) unwrappedType : null;
|
||||||
|
if (flexibleType != null
|
||||||
|
&& (contains(flexibleType.getLowerBound(), isSpecialType) || contains(flexibleType.getUpperBound(), isSpecialType))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (TypeProjection projection : type.getArguments()) {
|
for (TypeProjection projection : type.getArguments()) {
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ fun TypeProjection.substitute(doSubstitute: (KotlinType) -> KotlinType): TypePro
|
|||||||
|
|
||||||
fun KotlinType.replaceAnnotations(newAnnotations: Annotations): KotlinType {
|
fun KotlinType.replaceAnnotations(newAnnotations: Annotations): KotlinType {
|
||||||
if (annotations.isEmpty() && newAnnotations.isEmpty()) return this
|
if (annotations.isEmpty() && newAnnotations.isEmpty()) return this
|
||||||
if (isFlexible()) return flexibility().replaceAnnotations(newAnnotations)
|
if (isFlexible()) return asFlexibleType().replaceAnnotations(newAnnotations)
|
||||||
|
|
||||||
return asSimpleType().lazyReplaceAnnotations(newAnnotations)
|
return asSimpleType().lazyReplaceAnnotations(newAnnotations)
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ private fun constituentTypes(result: MutableSet<KotlinType>, types: Collection<K
|
|||||||
result.addAll(types)
|
result.addAll(types)
|
||||||
for (type in types) {
|
for (type in types) {
|
||||||
if (type.isFlexible()) {
|
if (type.isFlexible()) {
|
||||||
with (type.flexibility()) { constituentTypes(result, setOf(lowerBound, upperBound)) }
|
with (type.asFlexibleType()) { constituentTypes(result, setOf(lowerBound, upperBound)) }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
constituentTypes(result, type.arguments.filterNot { it.isStarProjection }.map { it.type })
|
constituentTypes(result, type.arguments.filterNot { it.isStarProjection }.map { it.type })
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -20,12 +20,9 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
import org.jetbrains.kotlin.types.*;
|
import org.jetbrains.kotlin.types.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.types.Variance.*;
|
import static org.jetbrains.kotlin.types.Variance.*;
|
||||||
@@ -124,8 +121,8 @@ public class TypeCheckingProcedure {
|
|||||||
protected boolean heterogeneousEquivalence(KotlinType inflexibleType, KotlinType flexibleType) {
|
protected boolean heterogeneousEquivalence(KotlinType inflexibleType, KotlinType flexibleType) {
|
||||||
// This is to account for the case when we have Collection<X> vs (Mutable)Collection<X>! or K(java.util.Collection<? extends X>)
|
// This is to account for the case when we have Collection<X> vs (Mutable)Collection<X>! or K(java.util.Collection<? extends X>)
|
||||||
assert !FlexibleTypesKt.isFlexible(inflexibleType) : "Only inflexible types are allowed here: " + inflexibleType;
|
assert !FlexibleTypesKt.isFlexible(inflexibleType) : "Only inflexible types are allowed here: " + inflexibleType;
|
||||||
return isSubtypeOf(FlexibleTypesKt.flexibility(flexibleType).getLowerBound(), inflexibleType)
|
return isSubtypeOf(FlexibleTypesKt.asFlexibleType(flexibleType).getLowerBound(), inflexibleType)
|
||||||
&& isSubtypeOf(inflexibleType, FlexibleTypesKt.flexibility(flexibleType).getUpperBound());
|
&& isSubtypeOf(inflexibleType, FlexibleTypesKt.asFlexibleType(flexibleType).getUpperBound());
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EnrichedProjectionKind {
|
public enum EnrichedProjectionKind {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
|
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
|
||||||
|
|
||||||
interface Flexibility : TypeCapability, SubtypingRepresentatives {
|
interface FlexibleType : SubtypingRepresentatives {
|
||||||
// lowerBound is a subtype of upperBound
|
// lowerBound is a subtype of upperBound
|
||||||
val lowerBound: SimpleType
|
val lowerBound: SimpleType
|
||||||
val upperBound: SimpleType
|
val upperBound: SimpleType
|
||||||
@@ -39,11 +39,11 @@ interface Flexibility : TypeCapability, SubtypingRepresentatives {
|
|||||||
fun replaceAnnotations(newAnnotations: Annotations): KotlinType
|
fun replaceAnnotations(newAnnotations: Annotations): KotlinType
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KotlinType.isFlexible(): Boolean = this.getCapability(Flexibility::class.java) != null
|
fun KotlinType.isFlexible(): Boolean = unwrap() is FlexibleType
|
||||||
fun KotlinType.flexibility(): Flexibility = this.getCapability(Flexibility::class.java)!!
|
fun KotlinType.asFlexibleType(): FlexibleType = unwrap() as FlexibleType
|
||||||
|
|
||||||
fun KotlinType.isNullabilityFlexible(): Boolean {
|
fun KotlinType.isNullabilityFlexible(): Boolean {
|
||||||
val flexibility = this.getCapability(Flexibility::class.java) ?: return false
|
val flexibility = unwrap() as? FlexibleType ?: return false
|
||||||
return TypeUtils.isNullableType(flexibility.lowerBound) != TypeUtils.isNullableType(flexibility.upperBound)
|
return TypeUtils.isNullableType(flexibility.lowerBound) != TypeUtils.isNullableType(flexibility.upperBound)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,13 +81,13 @@ fun Collection<TypeProjection>.singleBestRepresentative(): TypeProjection? {
|
|||||||
return TypeProjectionImpl(projectionKinds.single(), bestType)
|
return TypeProjectionImpl(projectionKinds.single(), bestType)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KotlinType.lowerIfFlexible(): SimpleType = (if (this.isFlexible()) this.flexibility().lowerBound else this).asSimpleType()
|
fun KotlinType.lowerIfFlexible(): SimpleType = (if (this.isFlexible()) this.asFlexibleType().lowerBound else this).asSimpleType()
|
||||||
fun KotlinType.upperIfFlexible(): SimpleType = (if (this.isFlexible()) this.flexibility().upperBound else this).asSimpleType()
|
fun KotlinType.upperIfFlexible(): SimpleType = (if (this.isFlexible()) this.asFlexibleType().upperBound else this).asSimpleType()
|
||||||
|
|
||||||
abstract class DelegatingFlexibleType protected constructor(
|
abstract class DelegatingFlexibleType protected constructor(
|
||||||
override val lowerBound: SimpleType,
|
override val lowerBound: SimpleType,
|
||||||
override val upperBound: SimpleType
|
override val upperBound: SimpleType
|
||||||
) : DelegatingType(), Flexibility {
|
) : DelegatingType(), FlexibleType {
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
var RUN_SLOW_ASSERTIONS = false
|
var RUN_SLOW_ASSERTIONS = false
|
||||||
@@ -118,7 +118,7 @@ abstract class DelegatingFlexibleType protected constructor(
|
|||||||
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>): T? {
|
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>): T? {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return when(capabilityClass) {
|
return when(capabilityClass) {
|
||||||
Flexibility::class.java, SubtypingRepresentatives::class.java -> this as T
|
SubtypingRepresentatives::class.java -> this as T
|
||||||
else -> super.getCapability(capabilityClass)
|
else -> super.getCapability(capabilityClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ fun KotlinType.approximateFlexibleTypes(preferNotNull: Boolean = false): KotlinT
|
|||||||
|
|
||||||
private fun KotlinType.approximateNonDynamicFlexibleTypes(preferNotNull: Boolean = false): SimpleType {
|
private fun KotlinType.approximateNonDynamicFlexibleTypes(preferNotNull: Boolean = false): SimpleType {
|
||||||
if (isFlexible()) {
|
if (isFlexible()) {
|
||||||
val flexible = flexibility()
|
val flexible = asFlexibleType()
|
||||||
val lowerClass = flexible.lowerBound.constructor.declarationDescriptor as? ClassDescriptor?
|
val lowerClass = flexible.lowerBound.constructor.declarationDescriptor as? ClassDescriptor?
|
||||||
val isCollection = lowerClass != null && JavaToKotlinClassMap.INSTANCE.isMutable(lowerClass)
|
val isCollection = lowerClass != null && JavaToKotlinClassMap.INSTANCE.isMutable(lowerClass)
|
||||||
// (Mutable)Collection<T>! -> MutableCollection<T>?
|
// (Mutable)Collection<T>! -> MutableCollection<T>?
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -23,9 +23,10 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
|||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.types.Flexibility
|
import org.jetbrains.kotlin.types.FlexibleType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
|
import org.jetbrains.kotlin.types.unwrap
|
||||||
|
|
||||||
fun KtFunctionLiteral.findLabelAndCall(): Pair<Name?, KtCallExpression?> {
|
fun KtFunctionLiteral.findLabelAndCall(): Pair<Name?, KtCallExpression?> {
|
||||||
val literalParent = (this.parent as KtLambdaExpression).parent
|
val literalParent = (this.parent as KtLambdaExpression).parent
|
||||||
@@ -77,11 +78,11 @@ private fun chooseMoreSpecific(type1: KotlinType, type2: KotlinType): KotlinType
|
|||||||
!type1IsSubtype && !type2IsSubtype -> return null
|
!type1IsSubtype && !type2IsSubtype -> return null
|
||||||
|
|
||||||
else -> { // type1IsSubtype && type2IsSubtype
|
else -> { // type1IsSubtype && type2IsSubtype
|
||||||
val flexibility1 = type1.getCapability(Flexibility::class.java)
|
val flexible1 = type1.unwrap() as? FlexibleType
|
||||||
val flexibility2 = type2.getCapability(Flexibility::class.java)
|
val flexible2 = type2.unwrap() as? FlexibleType
|
||||||
when {
|
when {
|
||||||
flexibility1 != null && flexibility2 == null -> return type2
|
flexible1 != null && flexible2 == null -> return type2
|
||||||
flexibility2 != null && flexibility1 == null -> return type1
|
flexible2 != null && flexible1 == null -> return type1
|
||||||
else -> return null //TODO?
|
else -> return null //TODO?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.idea.decompiler.textBuilder.defaultDecompilerRendere
|
|||||||
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
|
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.types.flexibility
|
import org.jetbrains.kotlin.types.asFlexibleType
|
||||||
import org.jetbrains.kotlin.types.isFlexible
|
import org.jetbrains.kotlin.types.isFlexible
|
||||||
|
|
||||||
class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
|
class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
|
||||||
@@ -63,7 +63,7 @@ class KtClsFile(provider: KotlinDecompiledFileViewProvider) : KtDecompiledFile(p
|
|||||||
|
|
||||||
private val decompilerRendererForClassFiles = DescriptorRenderer.withOptions {
|
private val decompilerRendererForClassFiles = DescriptorRenderer.withOptions {
|
||||||
defaultDecompilerRendererOptions()
|
defaultDecompilerRendererOptions()
|
||||||
typeNormalizer = { type -> if (type.isFlexible()) type.flexibility().lowerBound else type }
|
typeNormalizer = { type -> if (type.isFlexible()) type.asFlexibleType().lowerBound else type }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildDecompiledTextForClassFile(
|
fun buildDecompiledTextForClassFile(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.flexibility
|
import org.jetbrains.kotlin.types.asFlexibleType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
|
|
||||||
class CastExpressionFix(element: KtExpression, type: KotlinType) : KotlinQuickFixAction<KtExpression>(element) {
|
class CastExpressionFix(element: KtExpression, type: KotlinType) : KotlinQuickFixAction<KtExpression>(element) {
|
||||||
@@ -65,7 +65,7 @@ class CastExpressionFix(element: KtExpression, type: KotlinType) : KotlinQuickFi
|
|||||||
|
|
||||||
object GenericVarianceConversion : Factory() {
|
object GenericVarianceConversion : Factory() {
|
||||||
override fun extractFixData(element: KtExpression, diagnostic: Diagnostic): KotlinType? {
|
override fun extractFixData(element: KtExpression, diagnostic: Diagnostic): KotlinType? {
|
||||||
return ErrorsJvm.JAVA_TYPE_MISMATCH.cast(diagnostic).b.flexibility().upperBound
|
return ErrorsJvm.JAVA_TYPE_MISMATCH.cast(diagnostic).b.asFlexibleType().upperBound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -334,7 +334,7 @@ val ControlFlow.possibleReturnTypes: List<KotlinType>
|
|||||||
returnType.isAnnotatedNotNull() || returnType.isAnnotatedNullable() ->
|
returnType.isAnnotatedNotNull() || returnType.isAnnotatedNullable() ->
|
||||||
listOf(returnType.approximateFlexibleTypes())
|
listOf(returnType.approximateFlexibleTypes())
|
||||||
else ->
|
else ->
|
||||||
returnType.getCapability(Flexibility::class.java).let { listOf(it!!.upperBound, it.lowerBound) }
|
(returnType.unwrap() as FlexibleType).let { listOf(it.upperBound, it.lowerBound) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -518,7 +518,7 @@ internal class MutableParameter(
|
|||||||
val typePredicate = and(typePredicates)
|
val typePredicate = and(typePredicates)
|
||||||
|
|
||||||
val typeSet = if (defaultType.isFlexible()) {
|
val typeSet = if (defaultType.isFlexible()) {
|
||||||
val bounds = defaultType.getCapability(Flexibility::class.java)!!
|
val bounds = defaultType.asFlexibleType()
|
||||||
LinkedHashSet<KotlinType>().apply {
|
LinkedHashSet<KotlinType>().apply {
|
||||||
if (typePredicate(bounds.upperBound)) add(bounds.upperBound)
|
if (typePredicate(bounds.upperBound)) add(bounds.upperBound)
|
||||||
if (typePredicate(bounds.lowerBound)) add(bounds.lowerBound)
|
if (typePredicate(bounds.lowerBound)) add(bounds.lowerBound)
|
||||||
|
|||||||
Reference in New Issue
Block a user