All JetType subinterfaces migrated to capabilities
This commit is contained in:
+1
@@ -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.resolve.scopes.receivers.*;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
|
import org.jetbrains.jet.lang.types.TypesPackage;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||||
|
|||||||
@@ -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.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
|
import org.jetbrains.jet.lang.types.TypesPackage;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@@ -86,9 +87,9 @@ public class ForceResolveUtil {
|
|||||||
public static JetType forceResolveAllContents(@Nullable JetType type) {
|
public static JetType forceResolveAllContents(@Nullable JetType type) {
|
||||||
if (type == null) return null;
|
if (type == null) return null;
|
||||||
|
|
||||||
if (type.isFlexible()) {
|
if (TypesPackage.isFlexible(type)) {
|
||||||
forceResolveAllContents(type.getLowerBound());
|
forceResolveAllContents(TypesPackage.flexibility(type).getLowerBound());
|
||||||
forceResolveAllContents(type.getUpperBound());
|
forceResolveAllContents(TypesPackage.flexibility(type).getUpperBound());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
forceResolveAllContents(type.getConstructor());
|
forceResolveAllContents(type.getConstructor());
|
||||||
|
|||||||
+4
-6
@@ -421,12 +421,10 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
// Foo? <: T!
|
// Foo? <: T!
|
||||||
// Foo >: T!
|
// Foo >: T!
|
||||||
// both Foo and Foo? transform to Foo! here
|
// both Foo and Foo? transform to Foo! here
|
||||||
if (parameterType.isFlexible()) {
|
if (TypesPackage.isFlexible(parameterType)) {
|
||||||
if (parameterType instanceof CustomTypeVariable) {
|
CustomTypeVariable typeVariable = parameterType.getCapability(CustomTypeVariable.class);
|
||||||
CustomTypeVariable typeVariable = (CustomTypeVariable) parameterType;
|
if (typeVariable != null && typeVariable.getIsTypeVariable()) {
|
||||||
if (typeVariable.getIsTypeVariable()) {
|
constrainingType = typeVariable.substitutionResult(constrainingType);
|
||||||
constrainingType = typeVariable.substitutionResult(constrainingType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class AbstractJetType extends InflexibleType {
|
public abstract class AbstractJetType implements JetType {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
|
public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
|
||||||
|
|||||||
@@ -81,10 +81,10 @@ public class CommonSupertypes {
|
|||||||
List<JetType> upper = new ArrayList<JetType>(types.size());
|
List<JetType> upper = new ArrayList<JetType>(types.size());
|
||||||
List<JetType> lower = new ArrayList<JetType>(types.size());
|
List<JetType> lower = new ArrayList<JetType>(types.size());
|
||||||
for (JetType type : types) {
|
for (JetType type : types) {
|
||||||
if (type.isFlexible()) {
|
if (TypesPackage.isFlexible(type)) {
|
||||||
hasFlexible = true;
|
hasFlexible = true;
|
||||||
upper.add(type.getUpperBound());
|
upper.add(TypesPackage.flexibility(type).getUpperBound());
|
||||||
lower.add(type.getLowerBound());
|
lower.add(TypesPackage.flexibility(type).getLowerBound());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
upper.add(type);
|
upper.add(type);
|
||||||
@@ -111,7 +111,7 @@ public class CommonSupertypes {
|
|||||||
for (Iterator<JetType> iterator = typeSet.iterator(); iterator.hasNext();) {
|
for (Iterator<JetType> iterator = typeSet.iterator(); iterator.hasNext();) {
|
||||||
JetType type = iterator.next();
|
JetType type = iterator.next();
|
||||||
assert type != null;
|
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)) {
|
if (KotlinBuiltIns.getInstance().isNothingOrNullableNothing(type)) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -32,23 +32,6 @@ public abstract class DelegatingType implements JetType {
|
|||||||
return getDelegate().getConstructor();
|
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
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<TypeProjection> getArguments() {
|
public List<TypeProjection> getArguments() {
|
||||||
|
|||||||
@@ -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 TypeConstructor constructor;
|
||||||
private final JetScope memberScope;
|
private final JetScope memberScope;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -45,16 +45,6 @@ public interface JetType extends Annotated {
|
|||||||
@Override
|
@Override
|
||||||
boolean equals(Object other);
|
boolean equals(Object other);
|
||||||
|
|
||||||
// lowerBound is a subtype of upperBound
|
|
||||||
@NotNull
|
|
||||||
JetType getUpperBound();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
JetType getLowerBound();
|
|
||||||
|
|
||||||
// isFlexible() == false <=> getLowerBound() == getUpperBound()
|
|
||||||
boolean isFlexible();
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
<T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass);
|
<T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.types
|
package org.jetbrains.jet.lang.types
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
||||||
|
|
||||||
public trait TypeCapability
|
public trait TypeCapability
|
||||||
|
|
||||||
public trait Specificity : TypeCapability {
|
public trait Specificity : TypeCapability {
|
||||||
@@ -29,4 +31,19 @@ public trait Specificity : TypeCapability {
|
|||||||
public fun getSpecificityRelationTo(otherType: JetType): Relation
|
public fun getSpecificityRelationTo(otherType: JetType): Relation
|
||||||
}
|
}
|
||||||
|
|
||||||
fun JetType.getSpecificityRelationTo(otherType: JetType) = this.getCapability(javaClass<Specificity>())?.getSpecificityRelationTo(otherType) ?: Specificity.Relation.DONT_KNOW
|
fun JetType.getSpecificityRelationTo(otherType: JetType) = this.getCapability(javaClass<Specificity>())?.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<CustomTypeVariable>())?.isTypeVariable ?: false
|
||||||
@@ -155,11 +155,11 @@ public class TypeSubstitutor {
|
|||||||
// The type is within the substitution range, i.e. T or T?
|
// The type is within the substitution range, i.e. T or T?
|
||||||
JetType type = originalProjection.getType();
|
JetType type = originalProjection.getType();
|
||||||
Variance originalProjectionKind = originalProjection.getProjectionKind();
|
Variance originalProjectionKind = originalProjection.getProjectionKind();
|
||||||
if (type.isFlexible() && !TypesPackage.isCustomTypeVariable(type)) {
|
if (TypesPackage.isFlexible(type) && !TypesPackage.isCustomTypeVariable(type)) {
|
||||||
TypeProjection substitutedLower =
|
TypeProjection substitutedLower =
|
||||||
unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, type.getLowerBound()), recursionDepth + 1);
|
unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, TypesPackage.flexibility(type).getLowerBound()), recursionDepth + 1);
|
||||||
TypeProjection substitutedUpper =
|
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
|
// todo: projection kind is neglected
|
||||||
return new TypeProjectionImpl(originalProjectionKind,
|
return new TypeProjectionImpl(originalProjectionKind,
|
||||||
DelegatingFlexibleType.OBJECT$.create(
|
DelegatingFlexibleType.OBJECT$.create(
|
||||||
@@ -186,7 +186,8 @@ public class TypeSubstitutor {
|
|||||||
case NO_CONFLICT:
|
case NO_CONFLICT:
|
||||||
JetType substitutedType;
|
JetType substitutedType;
|
||||||
if (TypesPackage.isCustomTypeVariable(type)) {
|
if (TypesPackage.isCustomTypeVariable(type)) {
|
||||||
CustomTypeVariable typeVariable = (CustomTypeVariable) type;
|
CustomTypeVariable typeVariable = type.getCapability(CustomTypeVariable.class);
|
||||||
|
assert typeVariable != null;
|
||||||
substitutedType = typeVariable.substitutionResult(replacement.getType());
|
substitutedType = typeVariable.substitutionResult(replacement.getType());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class TypeUtils {
|
|||||||
|
|
||||||
public static final JetType CANT_INFER_LAMBDA_PARAM_TYPE = ErrorUtils.createErrorType("Cannot be inferred");
|
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;
|
private final String name;
|
||||||
|
|
||||||
public SpecialType(String name) {
|
public SpecialType(String name) {
|
||||||
@@ -117,8 +117,9 @@ public class TypeUtils {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JetType makeNullableAsSpecified(@NotNull JetType type, boolean nullable) {
|
public static JetType makeNullableAsSpecified(@NotNull JetType type, boolean nullable) {
|
||||||
if (type instanceof NullAwareType) {
|
NullAwareness nullAwareness = type.getCapability(NullAwareness.class);
|
||||||
return ((NullAwareType) type).makeNullableAsSpecified(nullable);
|
if (nullAwareness != null) {
|
||||||
|
return nullAwareness.makeNullableAsSpecified(nullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapping serves two purposes here
|
// Wrapping serves two purposes here
|
||||||
@@ -430,7 +431,7 @@ public class TypeUtils {
|
|||||||
if (type.isNullable()) {
|
if (type.isNullable()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (type.isFlexible() && isNullableType(type.getUpperBound())) {
|
if (TypesPackage.isFlexible(type) && isNullableType(TypesPackage.flexibility(type).getUpperBound())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
|
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
|
||||||
|
|||||||
+12
-11
@@ -69,14 +69,14 @@ public class TypeCheckingProcedure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean equalTypes(@NotNull JetType type1, @NotNull JetType type2) {
|
public boolean equalTypes(@NotNull JetType type1, @NotNull JetType type2) {
|
||||||
if (type1.isFlexible()) {
|
if (TypesPackage.isFlexible(type1)) {
|
||||||
if (type2.isFlexible()) {
|
if (TypesPackage.isFlexible(type2)) {
|
||||||
return equalTypes(type1.getLowerBound(), type2.getLowerBound())
|
return equalTypes(TypesPackage.flexibility(type1).getLowerBound(), TypesPackage.flexibility(type2).getLowerBound())
|
||||||
&& equalTypes(type1.getUpperBound(), type2.getUpperBound());
|
&& equalTypes(TypesPackage.flexibility(type1).getUpperBound(), TypesPackage.flexibility(type2).getUpperBound());
|
||||||
}
|
}
|
||||||
return heterogeneousEquivalence(type2, type1);
|
return heterogeneousEquivalence(type2, type1);
|
||||||
}
|
}
|
||||||
else if (type2.isFlexible()) {
|
else if (TypesPackage.isFlexible(type2)) {
|
||||||
return heterogeneousEquivalence(type1, type2);
|
return heterogeneousEquivalence(type1, type2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +120,9 @@ public class TypeCheckingProcedure {
|
|||||||
|
|
||||||
private boolean heterogeneousEquivalence(JetType inflexibleType, JetType flexibleType) {
|
private boolean heterogeneousEquivalence(JetType inflexibleType, JetType 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 !inflexibleType.isFlexible() : "Only inflexible types are allowed here: " + inflexibleType;
|
assert !TypesPackage.isFlexible(inflexibleType) : "Only inflexible types are allowed here: " + inflexibleType;
|
||||||
return isSubtypeOf(flexibleType.getLowerBound(), inflexibleType) && isSubtypeOf(inflexibleType, flexibleType.getUpperBound());
|
return isSubtypeOf(TypesPackage.flexibility(flexibleType).getLowerBound(), inflexibleType)
|
||||||
|
&& isSubtypeOf(inflexibleType, TypesPackage.flexibility(flexibleType).getUpperBound());
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EnrichedProjectionKind {
|
public enum EnrichedProjectionKind {
|
||||||
@@ -180,11 +181,11 @@ public class TypeCheckingProcedure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) {
|
public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||||
if (subtype.isFlexible()) {
|
if (TypesPackage.isFlexible(subtype)) {
|
||||||
return isSubtypeOf(subtype.getLowerBound(), supertype);
|
return isSubtypeOf(TypesPackage.flexibility(subtype).getLowerBound(), supertype);
|
||||||
}
|
}
|
||||||
if (supertype.isFlexible()) {
|
if (TypesPackage.isFlexible(supertype)) {
|
||||||
return isSubtypeOf(subtype, supertype.getUpperBound());
|
return isSubtypeOf(subtype, TypesPackage.flexibility(supertype).getUpperBound());
|
||||||
}
|
}
|
||||||
if (subtype.isError() || supertype.isError()) {
|
if (subtype.isError() || supertype.isError()) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -18,16 +18,26 @@ package org.jetbrains.jet.lang.types
|
|||||||
|
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||||
|
|
||||||
public trait NullAwareType {
|
public trait Flexibility : TypeCapability {
|
||||||
public fun makeNullableAsSpecified(nullable: Boolean): JetType
|
// 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<Flexibility>()) != null
|
||||||
|
public fun JetType.flexibility(): Flexibility = this.getCapability(javaClass<Flexibility>())!!
|
||||||
|
|
||||||
|
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 (
|
public open class DelegatingFlexibleType protected (
|
||||||
private val _lowerBound: JetType,
|
private val _lowerBound: JetType,
|
||||||
private val _upperBound: JetType
|
private val _upperBound: JetType
|
||||||
) : DelegatingType(), NullAwareType {
|
) : DelegatingType(), NullAwareness, Flexibility {
|
||||||
class object {
|
class object {
|
||||||
public fun create(lowerBound: JetType, upperBound: JetType): JetType {
|
public fun create(lowerBound: JetType, upperBound: JetType): JetType {
|
||||||
if (lowerBound == upperBound) return lowerBound
|
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 getUpperBound(): JetType = _upperBound
|
||||||
override fun getLowerBound(): JetType = _lowerBound
|
override fun getLowerBound(): JetType = _lowerBound
|
||||||
|
|
||||||
|
|||||||
@@ -301,19 +301,20 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private String renderNormalizedType(@NotNull JetType type) {
|
private String renderNormalizedType(@NotNull JetType type) {
|
||||||
if (type.isFlexible()) {
|
if (TypesPackage.isFlexible(type)) {
|
||||||
if (!debugMode) {
|
if (!debugMode) {
|
||||||
return renderFlexibleType(type);
|
return renderFlexibleType(type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "(" + renderNormalizedType(type.getLowerBound()) + ".." + renderNormalizedType(type.getUpperBound()) + ")";
|
return "(" + renderNormalizedType(TypesPackage.flexibility(type).getLowerBound()) + ".." +
|
||||||
|
renderNormalizedType(TypesPackage.flexibility(type).getUpperBound()) + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return renderInflexibleType(type);
|
return renderInflexibleType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String renderInflexibleType(@NotNull JetType 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) {
|
if (type == CANT_INFER_LAMBDA_PARAM_TYPE || type == DONT_CARE) {
|
||||||
return "???";
|
return "???";
|
||||||
@@ -338,8 +339,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private String renderFlexibleType(@NotNull JetType type) {
|
private String renderFlexibleType(@NotNull JetType type) {
|
||||||
JetType lower = type.getLowerBound();
|
JetType lower = TypesPackage.flexibility(type).getLowerBound();
|
||||||
JetType upper = type.getUpperBound();
|
JetType upper = TypesPackage.flexibility(type).getUpperBound();
|
||||||
|
|
||||||
String lowerRendered = renderInflexibleType(lower);
|
String lowerRendered = renderInflexibleType(lower);
|
||||||
String upperRendered = renderInflexibleType(upper);
|
String upperRendered = renderInflexibleType(upper);
|
||||||
|
|||||||
@@ -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.resolve.java.kotlinSignature.CollectionClassMapping
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames
|
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.makeNullable() = TypeUtils.makeNullable(this)
|
||||||
fun JetType.makeNotNullable() = TypeUtils.makeNotNullable(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 {
|
public fun approximateFlexibleTypes(jetType: JetType, outermost: Boolean = true): JetType {
|
||||||
if (jetType.isFlexible()) {
|
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)
|
val isCollection = lowerClass != null && CollectionClassMapping.getInstance().isMutableCollection(lowerClass)
|
||||||
// (Mutable)Collection<T>! -> MutableCollection<T>?
|
// (Mutable)Collection<T>! -> MutableCollection<T>?
|
||||||
// Foo<(Mutable)Collection<T>!>! -> Foo<Collection<T>>?
|
// Foo<(Mutable)Collection<T>!>! -> Foo<Collection<T>>?
|
||||||
@@ -43,9 +46,9 @@ public fun approximateFlexibleTypes(jetType: JetType, outermost: Boolean = true)
|
|||||||
// Foo<Bar!>! -> Foo<Bar>?
|
// Foo<Bar!>! -> Foo<Bar>?
|
||||||
val approximation =
|
val approximation =
|
||||||
if (isCollection)
|
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
|
else
|
||||||
if (outermost) jetType.getUpperBound() else jetType.getLowerBound()
|
if (outermost) flexible.getUpperBound() else flexible.getLowerBound()
|
||||||
val approximated = approximateFlexibleTypes(approximation)
|
val approximated = approximateFlexibleTypes(approximation)
|
||||||
return if (jetType.isMarkedNotNull()) approximated.makeNotNullable() else approximated
|
return if (jetType.isMarkedNotNull()) approximated.makeNotNullable() else approximated
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user