From 57bffaf8fa5119d9f3d9a864612c7aa78bcb8a2c Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 24 Sep 2014 20:23:07 +0400 Subject: [PATCH] All JetType subinterfaces migrated to capabilities --- .../smartcasts/DataFlowValueFactory.java | 1 + .../lang/resolve/lazy/ForceResolveUtil.java | 7 ++-- .../calls/inference/ConstraintSystemImpl.java | 10 ++--- .../jet/lang/types/AbstractJetType.java | 2 +- .../jet/lang/types/CommonSupertypes.java | 8 ++-- .../jet/lang/types/CustomTypeVariable.kt | 35 ----------------- .../jet/lang/types/DelegatingType.java | 17 --------- .../jetbrains/jet/lang/types/ErrorUtils.java | 2 +- .../jet/lang/types/InflexibleType.java | 38 ------------------- .../org/jetbrains/jet/lang/types/JetType.java | 10 ----- .../jet/lang/types/TypeCapabilities.kt | 19 +++++++++- .../jet/lang/types/TypeSubstitutor.java | 9 +++-- .../jetbrains/jet/lang/types/TypeUtils.java | 9 +++-- .../types/checker/TypeCheckingProcedure.java | 23 +++++------ .../jetbrains/jet/lang/types/flexibleTypes.kt | 19 +++++++--- .../jet/renderer/DescriptorRendererImpl.java | 11 +++--- .../jetbrains/jet/plugin/util/TypeUtils.kt | 9 +++-- 17 files changed, 81 insertions(+), 148 deletions(-) delete mode 100644 core/descriptors/src/org/jetbrains/jet/lang/types/CustomTypeVariable.kt delete mode 100644 core/descriptors/src/org/jetbrains/jet/lang/types/InflexibleType.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/smartcasts/DataFlowValueFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/smartcasts/DataFlowValueFactory.java index 405a45379da..020c4a906c4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/smartcasts/DataFlowValueFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/smartcasts/DataFlowValueFactory.java @@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.scopes.receivers.*; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.lang.types.TypesPackage; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java index ad1fec8a8d3..ba6ae512e4c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeConstructor; import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.TypesPackage; import java.util.Collection; @@ -86,9 +87,9 @@ public class ForceResolveUtil { public static JetType forceResolveAllContents(@Nullable JetType type) { if (type == null) return null; - if (type.isFlexible()) { - forceResolveAllContents(type.getLowerBound()); - forceResolveAllContents(type.getUpperBound()); + if (TypesPackage.isFlexible(type)) { + forceResolveAllContents(TypesPackage.flexibility(type).getLowerBound()); + forceResolveAllContents(TypesPackage.flexibility(type).getUpperBound()); } else { forceResolveAllContents(type.getConstructor()); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java index 2394e91f85d..6fe21e61495 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java @@ -421,12 +421,10 @@ public class ConstraintSystemImpl implements ConstraintSystem { // Foo? <: T! // Foo >: T! // both Foo and Foo? transform to Foo! here - if (parameterType.isFlexible()) { - if (parameterType instanceof CustomTypeVariable) { - CustomTypeVariable typeVariable = (CustomTypeVariable) parameterType; - if (typeVariable.getIsTypeVariable()) { - constrainingType = typeVariable.substitutionResult(constrainingType); - } + if (TypesPackage.isFlexible(parameterType)) { + CustomTypeVariable typeVariable = parameterType.getCapability(CustomTypeVariable.class); + if (typeVariable != null && typeVariable.getIsTypeVariable()) { + constrainingType = typeVariable.substitutionResult(constrainingType); } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java index 12083b48c02..7d7f7070d67 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java @@ -23,7 +23,7 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import java.util.Iterator; import java.util.List; -public abstract class AbstractJetType extends InflexibleType { +public abstract class AbstractJetType implements JetType { @Nullable @Override public T getCapability(@NotNull Class capabilityClass) { diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/CommonSupertypes.java b/core/descriptors/src/org/jetbrains/jet/lang/types/CommonSupertypes.java index 694e45395d2..5b7e7cbcfde 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/CommonSupertypes.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/CommonSupertypes.java @@ -81,10 +81,10 @@ public class CommonSupertypes { List upper = new ArrayList(types.size()); List lower = new ArrayList(types.size()); for (JetType type : types) { - if (type.isFlexible()) { + if (TypesPackage.isFlexible(type)) { hasFlexible = true; - upper.add(type.getUpperBound()); - lower.add(type.getLowerBound()); + upper.add(TypesPackage.flexibility(type).getUpperBound()); + lower.add(TypesPackage.flexibility(type).getLowerBound()); } else { upper.add(type); @@ -111,7 +111,7 @@ public class CommonSupertypes { for (Iterator iterator = typeSet.iterator(); iterator.hasNext();) { JetType type = iterator.next(); assert type != null; - assert !type.isFlexible() : "Flexible type " + type + " passed to commonSuperTypeForInflexible"; + assert !TypesPackage.isFlexible(type) : "Flexible type " + type + " passed to commonSuperTypeForInflexible"; if (KotlinBuiltIns.getInstance().isNothingOrNullableNothing(type)) { iterator.remove(); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/CustomTypeVariable.kt b/core/descriptors/src/org/jetbrains/jet/lang/types/CustomTypeVariable.kt deleted file mode 100644 index 30e933a0e3d..00000000000 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/CustomTypeVariable.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2010-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.lang.types - -import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor - -// To facilitate laziness, any JetType implementation may inherit from this trait, -// even if it turns out that the type an instance represents is not actually a type variable -// (i.e. it is not derived from a type parameter), see isTypeVariable -public trait CustomTypeVariable : JetType { - public val isTypeVariable: Boolean - - // If typeParameterDescriptor != null <=> isTypeVariable == true, this is not a type variable - public val typeParameterDescriptor: TypeParameterDescriptor? - - - // Throws an exception when isTypeVariable == false - public fun substitutionResult(replacement: JetType): JetType -} - -fun JetType.isCustomTypeVariable() = (this as? CustomTypeVariable)?.isTypeVariable ?: false \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java index c0206fbad3d..73382ef1968 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java @@ -32,23 +32,6 @@ public abstract class DelegatingType implements JetType { return getDelegate().getConstructor(); } - @Override - @NotNull - public JetType getUpperBound() { - return getDelegate().getUpperBound(); - } - - @Override - @NotNull - public JetType getLowerBound() { - return getDelegate().getLowerBound(); - } - - @Override - public boolean isFlexible() { - return getDelegate().isFlexible(); - } - @NotNull @Override public List getArguments() { diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java index 559faa8421e..ade6cdf10c0 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -378,7 +378,7 @@ public class ErrorUtils { ); } - private static class ErrorTypeImpl extends InflexibleType implements JetType { + private static class ErrorTypeImpl implements JetType { private final TypeConstructor constructor; private final JetScope memberScope; diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/InflexibleType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/InflexibleType.java deleted file mode 100644 index a988d86f979..00000000000 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/InflexibleType.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2010-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.lang.types; - -import org.jetbrains.annotations.NotNull; - -public abstract class InflexibleType implements JetType { - @NotNull - @Override - public JetType getUpperBound() { - return this; - } - - @NotNull - @Override - public JetType getLowerBound() { - return this; - } - - @Override - public boolean isFlexible() { - return false; - } -} diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java index 0e0a58d75f4..9bdf3bab518 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java @@ -45,16 +45,6 @@ public interface JetType extends Annotated { @Override boolean equals(Object other); - // lowerBound is a subtype of upperBound - @NotNull - JetType getUpperBound(); - - @NotNull - JetType getLowerBound(); - - // isFlexible() == false <=> getLowerBound() == getUpperBound() - boolean isFlexible(); - @Nullable T getCapability(@NotNull Class capabilityClass); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeCapabilities.kt b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeCapabilities.kt index 8c186980f94..fbefc322258 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeCapabilities.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeCapabilities.kt @@ -16,6 +16,8 @@ package org.jetbrains.jet.lang.types +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor + public trait TypeCapability public trait Specificity : TypeCapability { @@ -29,4 +31,19 @@ public trait Specificity : TypeCapability { public fun getSpecificityRelationTo(otherType: JetType): Relation } -fun JetType.getSpecificityRelationTo(otherType: JetType) = this.getCapability(javaClass())?.getSpecificityRelationTo(otherType) ?: Specificity.Relation.DONT_KNOW \ No newline at end of file +fun JetType.getSpecificityRelationTo(otherType: JetType) = this.getCapability(javaClass())?.getSpecificityRelationTo(otherType) ?: Specificity.Relation.DONT_KNOW + +// To facilitate laziness, any JetType implementation may inherit from this trait, +// even if it turns out that the type an instance represents is not actually a type variable +// (i.e. it is not derived from a type parameter), see isTypeVariable +public trait CustomTypeVariable : TypeCapability { + public val isTypeVariable: Boolean + + // If typeParameterDescriptor != null <=> isTypeVariable == true, this is not a type variable + public val typeParameterDescriptor: TypeParameterDescriptor? + + // Throws an exception when isTypeVariable == false + public fun substitutionResult(replacement: JetType): JetType +} + +public fun JetType.isCustomTypeVariable(): Boolean = this.getCapability(javaClass())?.isTypeVariable ?: false \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java index 2bf5a63b270..a8e16bd9cc0 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java @@ -155,11 +155,11 @@ public class TypeSubstitutor { // The type is within the substitution range, i.e. T or T? JetType type = originalProjection.getType(); Variance originalProjectionKind = originalProjection.getProjectionKind(); - if (type.isFlexible() && !TypesPackage.isCustomTypeVariable(type)) { + if (TypesPackage.isFlexible(type) && !TypesPackage.isCustomTypeVariable(type)) { TypeProjection substitutedLower = - unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, type.getLowerBound()), recursionDepth + 1); + unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, TypesPackage.flexibility(type).getLowerBound()), recursionDepth + 1); TypeProjection substitutedUpper = - unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, type.getUpperBound()), recursionDepth + 1); + unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, TypesPackage.flexibility(type).getUpperBound()), recursionDepth + 1); // todo: projection kind is neglected return new TypeProjectionImpl(originalProjectionKind, DelegatingFlexibleType.OBJECT$.create( @@ -186,7 +186,8 @@ public class TypeSubstitutor { case NO_CONFLICT: JetType substitutedType; if (TypesPackage.isCustomTypeVariable(type)) { - CustomTypeVariable typeVariable = (CustomTypeVariable) type; + CustomTypeVariable typeVariable = type.getCapability(CustomTypeVariable.class); + assert typeVariable != null; substitutedType = typeVariable.substitutionResult(replacement.getType()); } else { diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java index 8208b931b9c..b97e9501aef 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -44,7 +44,7 @@ public class TypeUtils { public static final JetType CANT_INFER_LAMBDA_PARAM_TYPE = ErrorUtils.createErrorType("Cannot be inferred"); - public static class SpecialType extends InflexibleType implements JetType { + public static class SpecialType implements JetType { private final String name; public SpecialType(String name) { @@ -117,8 +117,9 @@ public class TypeUtils { @NotNull public static JetType makeNullableAsSpecified(@NotNull JetType type, boolean nullable) { - if (type instanceof NullAwareType) { - return ((NullAwareType) type).makeNullableAsSpecified(nullable); + NullAwareness nullAwareness = type.getCapability(NullAwareness.class); + if (nullAwareness != null) { + return nullAwareness.makeNullableAsSpecified(nullable); } // Wrapping serves two purposes here @@ -430,7 +431,7 @@ public class TypeUtils { if (type.isNullable()) { return true; } - if (type.isFlexible() && isNullableType(type.getUpperBound())) { + if (TypesPackage.isFlexible(type) && isNullableType(TypesPackage.flexibility(type).getUpperBound())) { return true; } if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java index a4aa359d309..c937aeea481 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java @@ -69,14 +69,14 @@ public class TypeCheckingProcedure { } public boolean equalTypes(@NotNull JetType type1, @NotNull JetType type2) { - if (type1.isFlexible()) { - if (type2.isFlexible()) { - return equalTypes(type1.getLowerBound(), type2.getLowerBound()) - && equalTypes(type1.getUpperBound(), type2.getUpperBound()); + if (TypesPackage.isFlexible(type1)) { + if (TypesPackage.isFlexible(type2)) { + return equalTypes(TypesPackage.flexibility(type1).getLowerBound(), TypesPackage.flexibility(type2).getLowerBound()) + && equalTypes(TypesPackage.flexibility(type1).getUpperBound(), TypesPackage.flexibility(type2).getUpperBound()); } return heterogeneousEquivalence(type2, type1); } - else if (type2.isFlexible()) { + else if (TypesPackage.isFlexible(type2)) { return heterogeneousEquivalence(type1, type2); } @@ -120,8 +120,9 @@ public class TypeCheckingProcedure { private boolean heterogeneousEquivalence(JetType inflexibleType, JetType flexibleType) { // This is to account for the case when we have Collection vs (Mutable)Collection! or K(java.util.Collection) - assert !inflexibleType.isFlexible() : "Only inflexible types are allowed here: " + inflexibleType; - return isSubtypeOf(flexibleType.getLowerBound(), inflexibleType) && isSubtypeOf(inflexibleType, flexibleType.getUpperBound()); + assert !TypesPackage.isFlexible(inflexibleType) : "Only inflexible types are allowed here: " + inflexibleType; + return isSubtypeOf(TypesPackage.flexibility(flexibleType).getLowerBound(), inflexibleType) + && isSubtypeOf(inflexibleType, TypesPackage.flexibility(flexibleType).getUpperBound()); } public enum EnrichedProjectionKind { @@ -180,11 +181,11 @@ public class TypeCheckingProcedure { } public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) { - if (subtype.isFlexible()) { - return isSubtypeOf(subtype.getLowerBound(), supertype); + if (TypesPackage.isFlexible(subtype)) { + return isSubtypeOf(TypesPackage.flexibility(subtype).getLowerBound(), supertype); } - if (supertype.isFlexible()) { - return isSubtypeOf(subtype, supertype.getUpperBound()); + if (TypesPackage.isFlexible(supertype)) { + return isSubtypeOf(subtype, TypesPackage.flexibility(supertype).getUpperBound()); } if (subtype.isError() || supertype.isError()) { return true; diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/flexibleTypes.kt b/core/descriptors/src/org/jetbrains/jet/lang/types/flexibleTypes.kt index 0ef5eee499f..2f91c2745b6 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/flexibleTypes.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/flexibleTypes.kt @@ -18,16 +18,26 @@ package org.jetbrains.jet.lang.types import org.jetbrains.jet.lang.types.checker.JetTypeChecker -public trait NullAwareType { - public fun makeNullableAsSpecified(nullable: Boolean): JetType +public trait Flexibility : TypeCapability { + // lowerBound is a subtype of upperBound + public fun getUpperBound(): JetType + + public fun getLowerBound(): JetType } -public fun JetType.lowerIfFlexible(): JetType = if (this.isFlexible()) getLowerBound() else this +public fun JetType.isFlexible(): Boolean = this.getCapability(javaClass()) != null +public fun JetType.flexibility(): Flexibility = this.getCapability(javaClass())!! + +public fun JetType.lowerIfFlexible(): JetType = if (this.isFlexible()) this.flexibility().getLowerBound() else this + +public trait NullAwareness : TypeCapability { + public fun makeNullableAsSpecified(nullable: Boolean): JetType +} public open class DelegatingFlexibleType protected ( private val _lowerBound: JetType, private val _upperBound: JetType -) : DelegatingType(), NullAwareType { +) : DelegatingType(), NullAwareness, Flexibility { class object { public fun create(lowerBound: JetType, upperBound: JetType): JetType { if (lowerBound == upperBound) return lowerBound @@ -44,7 +54,6 @@ public open class DelegatingFlexibleType protected ( } } - override fun isFlexible(): Boolean = true override fun getUpperBound(): JetType = _upperBound override fun getLowerBound(): JetType = _lowerBound diff --git a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java index ed258d3e5d8..d8989c6205c 100644 --- a/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java @@ -301,19 +301,20 @@ public class DescriptorRendererImpl implements DescriptorRenderer { @NotNull private String renderNormalizedType(@NotNull JetType type) { - if (type.isFlexible()) { + if (TypesPackage.isFlexible(type)) { if (!debugMode) { return renderFlexibleType(type); } else { - return "(" + renderNormalizedType(type.getLowerBound()) + ".." + renderNormalizedType(type.getUpperBound()) + ")"; + return "(" + renderNormalizedType(TypesPackage.flexibility(type).getLowerBound()) + ".." + + renderNormalizedType(TypesPackage.flexibility(type).getUpperBound()) + ")"; } } return renderInflexibleType(type); } private String renderInflexibleType(@NotNull JetType type) { - assert !type.isFlexible() : "Flexible types not allowed here: " + renderNormalizedType(type); + assert !TypesPackage.isFlexible(type) : "Flexible types not allowed here: " + renderNormalizedType(type); if (type == CANT_INFER_LAMBDA_PARAM_TYPE || type == DONT_CARE) { return "???"; @@ -338,8 +339,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer { @NotNull private String renderFlexibleType(@NotNull JetType type) { - JetType lower = type.getLowerBound(); - JetType upper = type.getUpperBound(); + JetType lower = TypesPackage.flexibility(type).getLowerBound(); + JetType upper = TypesPackage.flexibility(type).getUpperBound(); String lowerRendered = renderInflexibleType(lower); String upperRendered = renderInflexibleType(upper); diff --git a/idea/src/org/jetbrains/jet/plugin/util/TypeUtils.kt b/idea/src/org/jetbrains/jet/plugin/util/TypeUtils.kt index bcc549e42bf..1d9a07567fc 100644 --- a/idea/src/org/jetbrains/jet/plugin/util/TypeUtils.kt +++ b/idea/src/org/jetbrains/jet/plugin/util/TypeUtils.kt @@ -25,6 +25,8 @@ import org.jetbrains.jet.lang.types.ErrorUtils import org.jetbrains.jet.lang.resolve.java.kotlinSignature.CollectionClassMapping import org.jetbrains.jet.lang.descriptors.ClassDescriptor import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames +import org.jetbrains.jet.lang.types.isFlexible +import org.jetbrains.jet.lang.types.flexibility fun JetType.makeNullable() = TypeUtils.makeNullable(this) fun JetType.makeNotNullable() = TypeUtils.makeNotNullable(this) @@ -35,7 +37,8 @@ fun JetType.isUnit(): Boolean = KotlinBuiltIns.getInstance().isUnit(this) public fun approximateFlexibleTypes(jetType: JetType, outermost: Boolean = true): JetType { if (jetType.isFlexible()) { - val lowerClass = jetType.getLowerBound().getConstructor().getDeclarationDescriptor() as? ClassDescriptor? + val flexible = jetType.flexibility() + val lowerClass = flexible.getLowerBound().getConstructor().getDeclarationDescriptor() as? ClassDescriptor? val isCollection = lowerClass != null && CollectionClassMapping.getInstance().isMutableCollection(lowerClass) // (Mutable)Collection! -> MutableCollection? // Foo<(Mutable)Collection!>! -> Foo>? @@ -43,9 +46,9 @@ public fun approximateFlexibleTypes(jetType: JetType, outermost: Boolean = true) // Foo! -> Foo? val approximation = if (isCollection) - TypeUtils.makeNullableAsSpecified(if (jetType.isMarkedReadOnly()) jetType.getUpperBound() else jetType.getLowerBound(), outermost) + TypeUtils.makeNullableAsSpecified(if (jetType.isMarkedReadOnly()) flexible.getUpperBound() else flexible.getLowerBound(), outermost) else - if (outermost) jetType.getUpperBound() else jetType.getLowerBound() + if (outermost) flexible.getUpperBound() else flexible.getLowerBound() val approximated = approximateFlexibleTypes(approximation) return if (jetType.isMarkedNotNull()) approximated.makeNotNullable() else approximated }