Rewritten ConstraintPosition to Kotlin

Added ConstraintPositionKind
 (to be able to use enum constants from Java code)
This commit is contained in:
Svetlana Isakova
2014-07-21 15:49:12 +04:00
parent 578f6d4811
commit a2fa38a7f9
19 changed files with 106 additions and 122 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
* 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.
@@ -14,87 +14,53 @@
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.calls.inference;
package org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public enum class ConstraintPositionKind {
RECEIVER_POSITION
EXPECTED_TYPE_POSITION
VALUE_PARAMETER_POSITION
TYPE_BOUND_POSITION
COMPOUND_CONSTRAINT_POSITION
FROM_COMPLETER
SPECIAL
public class ConstraintPosition {
public static final ConstraintPosition RECEIVER_POSITION = new ConstraintPosition("RECEIVER_POSITION", true);
public static final ConstraintPosition EXPECTED_TYPE_POSITION = new ConstraintPosition("EXPECTED_TYPE_POSITION", true);
public static final ConstraintPosition FROM_COMPLETER = new ConstraintPosition("FROM_COMPLETER", true);
public static final ConstraintPosition SPECIAL = new ConstraintPosition("SPECIAL", true);
private static final Map<Integer, ConstraintPosition> valueParameterPositions = new HashMap<Integer, ConstraintPosition>();
private static final Map<Integer, ConstraintPosition> typeBoundPositions = new HashMap<Integer, ConstraintPosition>();
@NotNull
public static ConstraintPosition getValueParameterPosition(int index) {
ConstraintPosition position = valueParameterPositions.get(index);
if (position == null) {
position = new ConstraintPosition("VALUE_PARAMETER_POSITION(" + index + ")", true);
valueParameterPositions.put(index, position);
}
return position;
public fun position(): ConstraintPosition {
assert(this in setOf(RECEIVER_POSITION, EXPECTED_TYPE_POSITION, FROM_COMPLETER, SPECIAL))
return ConstraintPositionImpl(this)
}
@NotNull
public static ConstraintPosition getTypeBoundPosition(int index) {
ConstraintPosition position = typeBoundPositions.get(index);
if (position == null) {
position = new ConstraintPosition("TYPE_BOUND_POSITION(" + index + ")", false);
typeBoundPositions.put(index, position);
}
return position;
}
public static class CompoundConstraintPosition extends ConstraintPosition {
private final Collection<ConstraintPosition> positions;
public CompoundConstraintPosition(Collection<ConstraintPosition> positions) {
super("COMPOUND_CONSTRAINT_POSITION", hasConstraint(positions, /*strong=*/true));
this.positions = positions;
}
public boolean consistsOfOnlyStrongConstraints() {
return !hasConstraint(positions, /*strong=*/false);
}
private static boolean hasConstraint(@NotNull Collection<ConstraintPosition> positions, final boolean strong) {
return KotlinPackage.any(positions, new Function1<ConstraintPosition, Boolean>() {
@Override
public Boolean invoke(ConstraintPosition constraintPosition) {
return constraintPosition.isStrong() == strong;
}
});
}
}
@NotNull
public static ConstraintPosition getCompoundConstraintPosition(ConstraintPosition... positions) {
return new CompoundConstraintPosition(Arrays.asList(positions));
}
private final String debugName;
private final boolean isStrong;
private ConstraintPosition(String name, boolean isStrong) {
debugName = name;
this.isStrong = isStrong;
}
public boolean isStrong() {
return isStrong;
}
@Override
public String toString() {
return debugName;
public fun position(index: Int): ConstraintPosition {
assert(this in setOf(VALUE_PARAMETER_POSITION, TYPE_BOUND_POSITION))
return ConstraintPositionWithIndex(this, index)
}
}
public trait ConstraintPosition {
val kind: ConstraintPositionKind
fun isStrong(): Boolean = kind != TYPE_BOUND_POSITION
}
private open data class ConstraintPositionImpl(override val kind: ConstraintPositionKind) : ConstraintPosition {
override fun toString() = "$kind"
}
private data class ConstraintPositionWithIndex(override val kind: ConstraintPositionKind, val index: Int) : ConstraintPosition {
override fun toString() = "$kind($index)"
}
class CompoundConstraintPosition(
val positions: Collection<ConstraintPosition>
) : ConstraintPositionImpl(ConstraintPositionKind.COMPOUND_CONSTRAINT_POSITION) {
override fun isStrong() = positions.any { it.isStrong() }
override fun toString() = "$kind(${positions.joinToString()}"
}
public fun getCompoundConstraintPosition(vararg positions: ConstraintPosition): ConstraintPosition {
return CompoundConstraintPosition(positions.toList())
}
@@ -20,6 +20,7 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
import org.jetbrains.jet.lang.types.Variance
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.types.TypeSubstitutor
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition
public trait ConstraintSystem {
@@ -37,6 +37,11 @@ import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl.Const
import java.util.HashMap
import java.util.ArrayList
import org.jetbrains.kotlin.util.sure
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.CompoundConstraintPosition
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.getCompoundConstraintPosition
public class ConstraintSystemImpl : ConstraintSystem {
@@ -138,7 +143,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
if (KotlinBuiltIns.getInstance().getNullableAnyType() == declaredUpperBound) continue //todo remove this line (?)
val substitutedBound = constantSubstitutor?.substitute(declaredUpperBound, Variance.INVARIANT)
if (substitutedBound != null) {
typeBounds.addBound(UPPER_BOUND, substitutedBound, ConstraintPosition.getTypeBoundPosition(typeVariable.getIndex()))
typeBounds.addBound(UPPER_BOUND, substitutedBound, TYPE_BOUND_POSITION.position(typeVariable.getIndex()))
}
}
}
@@ -165,9 +170,8 @@ public class ConstraintSystemImpl : ConstraintSystem {
constraintPosition ->
// 'isStrong' for compound means 'has some strong constraints'
// but for testing absence of weak constraints we need 'has only strong constraints' here
if (constraintPosition is ConstraintPosition.CompoundConstraintPosition) {
val position = constraintPosition as ConstraintPosition.CompoundConstraintPosition
position.consistsOfOnlyStrongConstraints()
if (constraintPosition is CompoundConstraintPosition) {
constraintPosition.positions.all { it.isStrong() }
}
else {
constraintPosition.isStrong()
@@ -334,7 +338,8 @@ public class ConstraintSystemImpl : ConstraintSystem {
val bounds = ArrayList(typeBounds.bounds)
for (bound in bounds) {
if (bound.kind == LOWER_BOUND || bound.kind == EXACT_BOUND) {
val position = ConstraintPosition.getCompoundConstraintPosition(ConstraintPosition.getTypeBoundPosition(typeParameterDescriptor.getIndex()), bound.position)
val position = getCompoundConstraintPosition(
TYPE_BOUND_POSITION.position(typeParameterDescriptor.getIndex()), bound.position)
addSubtypeConstraint(bound.constrainingType, declaredUpperBound, position)
}
}
@@ -343,7 +348,8 @@ public class ConstraintSystemImpl : ConstraintSystem {
val typeBoundsForUpperBound = typeParameterBounds.get(declarationDescriptor)
for (bound in typeBoundsForUpperBound!!.bounds) {
if (bound.kind == UPPER_BOUND || bound.kind == EXACT_BOUND) {
val position = ConstraintPosition.getCompoundConstraintPosition(ConstraintPosition.getTypeBoundPosition(typeParameterDescriptor.getIndex()), bound.position)
val position = getCompoundConstraintPosition(
TYPE_BOUND_POSITION.position(typeParameterDescriptor.getIndex()), bound.position)
typeBounds.addBound(UPPER_BOUND, bound.constrainingType, position)
}
}
@@ -16,6 +16,8 @@
package org.jetbrains.jet.lang.resolve.calls.inference
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition
public trait ConstraintSystemStatus {
/**
* Returns <tt>true</tt> if constraint system has a solution (has no contradiction and has enough information to infer each registered type variable).
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.calls.inference
import org.jetbrains.jet.lang.types.Variance
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition
public trait TypeBounds {
public val varianceOfPosition: Variance
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker
import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstructor
import java.util.LinkedHashSet
import org.jetbrains.jet.lang.resolve.calls.inference.TypeBounds.BoundKind.*
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.jet.utils.addIfNotNull
public class TypeBoundsImpl(
@@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstructor;
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope;
@@ -38,6 +37,8 @@ import org.jetbrains.jet.utils.UtilsPackage;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*;
public class TypeUtils {
public static final JetType DONT_CARE = ErrorUtils.createErrorTypeWithCustomDebugName("DONT_CARE");
public static final JetType PLACEHOLDER_FUNCTION_TYPE = ErrorUtils.createErrorTypeWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE");
@@ -282,7 +283,7 @@ public class TypeUtils {
processAllTypeParameters(expected, Variance.INVARIANT, processor);
ConstraintSystemImpl constraintSystem = new ConstraintSystemImpl();
constraintSystem.registerTypeVariables(parameters);
constraintSystem.addSubtypeConstraint(withParameters, expected, ConstraintPosition.SPECIAL);
constraintSystem.addSubtypeConstraint(withParameters, expected, SPECIAL.position());
return constraintSystem.getStatus().isSuccessful();
}