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
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.inference.*;
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
@@ -49,6 +50,8 @@ import java.util.Set;
import static org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.*;
import static org.jetbrains.jet.lang.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND;
import static org.jetbrains.jet.lang.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION;
public class Renderers {
private static final Logger LOG = Logger.getInstance(Renderers.class);
@@ -250,13 +253,13 @@ public class Renderers {
if (valueParameterDescriptor.getIndex() >= inferenceErrorData.valueArgumentsTypes.size()) continue;
JetType actualType = inferenceErrorData.valueArgumentsTypes.get(valueParameterDescriptor.getIndex());
if (!JetTypeChecker.DEFAULT.isSubtypeOf(actualType, valueParameterDescriptor.getType())) {
errorPositions.add(ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex()));
errorPositions.add(VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.getIndex()));
}
}
if (receiverType != null && inferenceErrorData.receiverArgumentType != null &&
!JetTypeChecker.DEFAULT.isSubtypeOf(inferenceErrorData.receiverArgumentType, receiverType)) {
errorPositions.add(ConstraintPosition.RECEIVER_POSITION);
errorPositions.add(RECEIVER_POSITION.position());
}
Predicate<ConstraintPosition> isErrorPosition = new Predicate<ConstraintPosition>() {
@@ -26,7 +26,7 @@ import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.Tab
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.FunctionArgumentsRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.TableRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TextRenderer.TextElement;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import org.jetbrains.jet.renderer.Renderer;
@@ -23,7 +23,6 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.rendering.Renderers;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemCompleter;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
@@ -49,6 +48,7 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.psi.PsiPackage.JetPsiFactory;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage.getCalleeExpressionIfAny;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.FROM_COMPLETER;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType;
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.createFakeExpressionOfType;
@@ -330,7 +330,7 @@ public class DelegatedPropertyResolver {
FunctionDescriptor descriptor = getMethodResults.getResultingDescriptor();
JetType returnTypeOfGetMethod = descriptor.getReturnType();
if (returnTypeOfGetMethod != null) {
constraintSystem.addSupertypeConstraint(expectedType, returnTypeOfGetMethod, ConstraintPosition.FROM_COMPLETER);
constraintSystem.addSupertypeConstraint(expectedType, returnTypeOfGetMethod, FROM_COMPLETER.position());
}
addConstraintForThisValue(constraintSystem, descriptor);
}
@@ -355,7 +355,7 @@ public class DelegatedPropertyResolver {
if (!noExpectedType(expectedType)) {
constraintSystem.addSubtypeConstraint(
expectedType, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER);
expectedType, valueParameterForThis.getType(), FROM_COMPLETER.position());
}
addConstraintForThisValue(constraintSystem, descriptor);
}
@@ -380,7 +380,7 @@ public class DelegatedPropertyResolver {
if (valueParameters.isEmpty()) return;
ValueParameterDescriptor valueParameterForThis = valueParameters.get(0);
constraintSystem.addSubtypeConstraint(typeOfThis, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER);
constraintSystem.addSubtypeConstraint(typeOfThis, valueParameterForThis.getType(), FROM_COMPLETER.position());
}
};
}
@@ -25,11 +25,9 @@ import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.resolve.BindingTrace
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition.EXPECTED_TYPE_POSITION
import org.jetbrains.jet.lang.types.TypeUtils
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl
import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus
@@ -46,15 +44,14 @@ import org.jetbrains.jet.lang.resolve.BindingContextUtils
import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils
import org.jetbrains.jet.lang.psi.JetExpression
import org.jetbrains.jet.lang.psi.Call
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils
import org.jetbrains.jet.lang.psi.JetBlockExpression
import org.jetbrains.jet.lang.psi.JetPsiUtil
import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace
import org.jetbrains.jet.lang.psi.JetQualifiedExpression
import java.util.ArrayList
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
public class CallCompleter(
val argumentTypeResolver: ArgumentTypeResolver,
@@ -142,12 +139,12 @@ public class CallCompleter(
val returnType = getCandidateDescriptor().getReturnType()
if (returnType != null) {
getConstraintSystem()!!.addSupertypeConstraint(expectedType, returnType, EXPECTED_TYPE_POSITION)
getConstraintSystem()!!.addSupertypeConstraint(expectedType, returnType, EXPECTED_TYPE_POSITION.position())
if (expectedType === TypeUtils.UNIT_EXPECTED_TYPE) {
updateSystemIfSuccessful {
system ->
system.addSupertypeConstraint(KotlinBuiltIns.getInstance().getUnitType(), returnType, EXPECTED_TYPE_POSITION)
system.addSupertypeConstraint(KotlinBuiltIns.getInstance().getUnitType(), returnType, EXPECTED_TYPE_POSITION.position())
system.getStatus().isSuccessful()
}
}
@@ -159,7 +156,7 @@ public class CallCompleter(
updateSystemIfSuccessful {
system ->
constraintSystemCompleter.completeConstraintSystem(system, this)
!system.getStatus().hasOnlyErrorsFromPosition(ConstraintPosition.FROM_COMPLETER)
!system.getStatus().hasOnlyErrorsFromPosition(FROM_COMPLETER.position())
}
}
@@ -20,7 +20,6 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
@@ -30,6 +29,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION;
import static org.jetbrains.jet.lang.types.TypeUtils.DONT_CARE;
public class CallResolverUtil {
@@ -95,7 +95,7 @@ public class CallResolverUtil {
if (hasReturnTypeDependentOnUninferredParams(candidateDescriptor, constraintSystem)) return false;
// Expected type mismatch was reported before as 'TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH'
if (constraintSystem.getStatus().hasOnlyErrorsFromPosition(ConstraintPosition.EXPECTED_TYPE_POSITION)) return false;
if (constraintSystem.getStatus().hasOnlyErrorsFromPosition(EXPECTED_TYPE_POSITION.position())) return false;
return true;
}
@@ -28,9 +28,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.psi.psiUtil.PsiUtilPackage;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.context.*;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
import org.jetbrains.jet.lang.resolve.calls.inference.*;
import org.jetbrains.jet.lang.resolve.calls.model.*;
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowInfo;
@@ -57,6 +55,8 @@ import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgum
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS;
import static org.jetbrains.jet.lang.resolve.calls.CallTransformer.CallForImplicitInvoke;
import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.INDEPENDENT;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION;
import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.*;
import static org.jetbrains.jet.lang.types.TypeUtils.*;
@@ -288,7 +288,7 @@ public class CandidateResolver {
argumentExpression, functionLiteralExpression, newContext, RESOLVE_FUNCTION_ARGUMENTS).getType();
if (!mismatch[0]) {
constraintSystem.addSubtypeConstraint(
type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex()));
type, effectiveExpectedType, VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.getIndex()));
temporaryToResolveFunctionLiteral.commit();
return;
}
@@ -300,7 +300,7 @@ public class CandidateResolver {
JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteralExpression, newContext,
RESOLVE_FUNCTION_ARGUMENTS).getType();
constraintSystem.addSubtypeConstraint(
type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex()));
type, effectiveExpectedType, VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.getIndex()));
}
private <D extends CallableDescriptor> ResolutionStatus inferTypeArguments(CallCandidateResolutionContext<D> context) {
@@ -356,7 +356,7 @@ public class CandidateResolver {
receiverType = updateResultTypeForSmartCasts(receiverType, ((ExpressionReceiver) receiverArgument).getExpression(),
context.dataFlowInfo, context.trace);
}
constraintSystem.addSubtypeConstraint(receiverType, receiverParameter.getType(), ConstraintPosition.RECEIVER_POSITION);
constraintSystem.addSubtypeConstraint(receiverType, receiverParameter.getType(), RECEIVER_POSITION.position());
}
// Restore type variables before alpha-conversion
@@ -399,8 +399,8 @@ public class CandidateResolver {
context.candidateCall.getDataFlowInfoForArguments().updateInfo(valueArgument, typeInfoForCall.getDataFlowInfo());
JetType type = updateResultTypeForSmartCasts(typeInfoForCall.getType(), argumentExpression, dataFlowInfoForArgument, context.trace);
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(
valueParameterDescriptor.getIndex()));
constraintSystem.addSubtypeConstraint(
type, effectiveExpectedType, VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.getIndex()));
}
@Nullable
@@ -42,6 +42,7 @@ import java.util.List;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqNameFromTopLevelClass;
import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType;
@@ -213,12 +214,12 @@ public abstract class AbstractTracingStrategy implements TracingStrategy {
// (it's useful, when the arguments, e.g. lambdas or calls are incomplete)
return;
}
if (status.hasOnlyErrorsFromPosition(ConstraintPosition.EXPECTED_TYPE_POSITION)) {
if (status.hasOnlyErrorsFromPosition(EXPECTED_TYPE_POSITION.position())) {
JetType declaredReturnType = data.descriptor.getReturnType();
if (declaredReturnType == null) return;
ConstraintSystem systemWithoutExpectedTypeConstraint =
((ConstraintSystemImpl) constraintSystem).filterConstraintsOut(ConstraintPosition.EXPECTED_TYPE_POSITION);
((ConstraintSystemImpl) constraintSystem).filterConstraintsOut(EXPECTED_TYPE_POSITION.position());
JetType substitutedReturnType = systemWithoutExpectedTypeConstraint.getResultingSubstitutor().substitute(declaredReturnType, Variance.INVARIANT);
assert substitutedReturnType != null; //todo
@@ -33,6 +33,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.inference.*;
import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
@@ -51,6 +52,7 @@ import java.util.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.CALL;
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION;
public class ControlStructureTypingUtils {
private static final Logger LOG = Logger.getInstance(ControlStructureTypingUtils.class);
@@ -363,7 +365,7 @@ public class ControlStructureTypingUtils {
return;
}
JetExpression expression = (JetExpression) call.getCallElement();
if (status.hasOnlyErrorsFromPosition(ConstraintPosition.EXPECTED_TYPE_POSITION) || status.hasConflictingConstraints()) {
if (status.hasOnlyErrorsFromPosition(EXPECTED_TYPE_POSITION.position()) || status.hasConflictingConstraints()) {
expression.accept(checkTypeVisitor, new CheckTypeContext(trace, data.expectedType));
return;
}
@@ -4,7 +4,7 @@ SUBTYPE T Int
type parameter bounds:
T <: kotlin.Int(SPECIAL)
P <: ???(TYPE_BOUND_POSITION(1)), <: kotlin.Int(COMPOUND_CONSTRAINT_POSITION)
P <: ???(TYPE_BOUND_POSITION(1)), <: kotlin.Int(COMPOUND_CONSTRAINT_POSITION(TYPE_BOUND_POSITION(1), SPECIAL)
status:
-hasConflictingConstraints: false
-hasContradiction: false
@@ -24,7 +24,6 @@ import org.jetbrains.jet.di.InjectorForTests
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
import org.jetbrains.jet.lang.diagnostics.rendering.Renderers
import org.jetbrains.jet.lang.resolve.*
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl
import org.jetbrains.jet.lang.types.Variance
import java.io.File
@@ -34,6 +33,7 @@ import org.jetbrains.jet.resolve.constraintSystem.AbstractConstraintSystemTest.M
import java.util.ArrayList
import java.util.LinkedHashMap
import org.jetbrains.jet.lang.resolve.lazy.JvmResolveUtil
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
abstract public class AbstractConstraintSystemTest() : JetLiteFixture() {
private val typePattern = """([\w|<|>|\(|\)]+)"""
@@ -95,7 +95,7 @@ abstract public class AbstractConstraintSystemTest() : JetLiteFixture() {
for (constraint in constraints) {
val firstType = myDeclarations.getType(constraint.firstType)
val secondType = myDeclarations.getType(constraint.secondType)
val position = if (constraint.isWeak) ConstraintPosition.getTypeBoundPosition(0)!! else ConstraintPosition.SPECIAL
val position = if (constraint.isWeak) TYPE_BOUND_POSITION.position(0) else SPECIAL.position()
when (constraint.kind) {
MyConstraintKind.SUBTYPE -> constraintSystem.addSubtypeConstraint(firstType, secondType, position)
MyConstraintKind.SUPERTYPE -> constraintSystem.addSupertypeConstraint(firstType, secondType, position)
@@ -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();
}
@@ -24,10 +24,11 @@ import java.util.HashSet
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl
import java.util.LinkedHashMap
import org.jetbrains.jet.lang.types.Variance
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil
import org.jetbrains.jet.lang.types.TypeSubstitutor
import org.jetbrains.jet.lang.types.typeUtil.isSubtypeOf
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind
fun CallableDescriptor.fuzzyReturnType(): FuzzyType? {
val returnType = getReturnType() ?: return null
@@ -97,8 +98,8 @@ class FuzzyType(
constraintSystem.registerTypeVariables(typeVariables)
when (matchKind) {
MatchKind.IS_SUBTYPE -> constraintSystem.addSubtypeConstraint(type, otherType, ConstraintPosition.SPECIAL)
MatchKind.IS_SUPERTYPE -> constraintSystem.addSubtypeConstraint(otherType, type, ConstraintPosition.SPECIAL)
MatchKind.IS_SUBTYPE -> constraintSystem.addSubtypeConstraint(type, otherType, ConstraintPositionKind.SPECIAL.position())
MatchKind.IS_SUPERTYPE -> constraintSystem.addSubtypeConstraint(otherType, type, ConstraintPositionKind.SPECIAL.position())
}
if (constraintSystem.getStatus().isSuccessful() && ConstraintsUtil.checkBoundsAreSatisfied(constraintSystem, true)) {
@@ -25,7 +25,7 @@ import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.DescriptorRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.FunctionArgumentsRow;
import org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TableRenderer.TableRow;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import org.jetbrains.jet.renderer.DescriptorRendererBuilder;
@@ -34,6 +34,8 @@ import org.jetbrains.jet.renderer.Renderer;
import java.util.Iterator;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION;
import static org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION;
import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.error;
import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.strong;
@@ -126,7 +128,7 @@ public class HtmlTabledDescriptorRenderer extends TabledDescriptorRenderer {
String receiver = "";
if (hasReceiver) {
boolean error = false;
if (isErrorPosition.apply(ConstraintPosition.RECEIVER_POSITION)) {
if (isErrorPosition.apply(RECEIVER_POSITION.position())) {
error = true;
}
receiver = "receiver: " + strong(getTypeRenderer().render(receiverType), error);
@@ -143,7 +145,7 @@ public class HtmlTabledDescriptorRenderer extends TabledDescriptorRenderer {
for (Iterator<JetType> iterator = argumentTypes.iterator(); iterator.hasNext(); ) {
JetType argumentType = iterator.next();
boolean error = false;
if (isErrorPosition.apply(ConstraintPosition.getValueParameterPosition(i))) {
if (isErrorPosition.apply(VALUE_PARAMETER_POSITION.position(i))) {
error = true;
}
String renderedArgument = getTypeRenderer().render(argumentType);