process number value types properly in constraint system
the case when type parameter has number value types (constants) as lower bounds should be handled specially, because upper bound for primitive number types is 'Number', but by default we want Int (or Long)
This commit is contained in:
+7
-12
@@ -29,14 +29,12 @@ import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode;
|
import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
|
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode;
|
import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.*;
|
import org.jetbrains.jet.lang.resolve.constants.*;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
@@ -71,16 +69,13 @@ public class ArgumentTypeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSubtypeOfForArgumentType(
|
public static boolean isSubtypeOfForArgumentType(
|
||||||
@NotNull JetType subtype,
|
@NotNull JetType actualType,
|
||||||
@NotNull JetType supertype
|
@NotNull JetType expectedType
|
||||||
) {
|
) {
|
||||||
if (subtype == PLACEHOLDER_FUNCTION_TYPE) {
|
if (actualType == PLACEHOLDER_FUNCTION_TYPE) {
|
||||||
return isFunctionOrErrorType(supertype) || KotlinBuiltIns.getInstance().isAny(supertype); //todo function type extends
|
return isFunctionOrErrorType(expectedType) || KotlinBuiltIns.getInstance().isAny(expectedType); //todo function type extends
|
||||||
}
|
}
|
||||||
if (supertype == PLACEHOLDER_FUNCTION_TYPE) {
|
return JetTypeChecker.INSTANCE.isSubtypeOf(actualType, expectedType);
|
||||||
return isFunctionOrErrorType(subtype); //todo extends function type
|
|
||||||
}
|
|
||||||
return JetTypeChecker.INSTANCE.isSubtypeOf(subtype, supertype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isFunctionOrErrorType(@NotNull JetType supertype) {
|
private static boolean isFunctionOrErrorType(@NotNull JetType supertype) {
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
|
|||||||
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask;
|
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer;
|
import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor;
|
import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.constants.ConstantUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.constants.NumberValueTypeConstructor;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
@@ -356,6 +358,12 @@ public class CandidateResolver {
|
|||||||
if (dataFlowInfoForValueArgument != null) {
|
if (dataFlowInfoForValueArgument != null) {
|
||||||
newContext = newContext.replaceDataFlowInfo(dataFlowInfoForValueArgument);
|
newContext = newContext.replaceDataFlowInfo(dataFlowInfoForValueArgument);
|
||||||
}
|
}
|
||||||
|
if (type != null && !type.getConstructor().isDenotable()) {
|
||||||
|
if (type.getConstructor() instanceof NumberValueTypeConstructor) {
|
||||||
|
NumberValueTypeConstructor constructor = (NumberValueTypeConstructor) type.getConstructor();
|
||||||
|
type = ConstantUtils.updateConstantValueType(constructor, expectedType, expression, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
DataFlowUtils.checkType(type, expression, newContext);
|
DataFlowUtils.checkType(type, expression, newContext);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -655,7 +663,7 @@ public class CandidateResolver {
|
|||||||
List<ReceiverValue> variants = AutoCastUtils.getAutoCastVariants(context.trace.getBindingContext(), context.dataFlowInfo, receiverToCast);
|
List<ReceiverValue> variants = AutoCastUtils.getAutoCastVariants(context.trace.getBindingContext(), context.dataFlowInfo, receiverToCast);
|
||||||
for (ReceiverValue receiverValue : variants) {
|
for (ReceiverValue receiverValue : variants) {
|
||||||
JetType possibleType = receiverValue.getType();
|
JetType possibleType = receiverValue.getType();
|
||||||
if (ArgumentTypeResolver.isSubtypeOfForArgumentType(possibleType, expectedType)) {
|
if (JetTypeChecker.INSTANCE.isSubtypeOf(possibleType, expectedType)) {
|
||||||
return possibleType;
|
return possibleType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+125
-45
@@ -16,16 +16,17 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.calls.inference;
|
package org.jetbrains.jet.lang.resolve.calls.inference;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Collections2;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.constants.NumberValueTypeConstructor;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -34,54 +35,124 @@ public class ConstraintsUtil {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static Set<JetType> getValues(@Nullable TypeConstraints typeConstraints) {
|
public static Set<JetType> getValues(@Nullable TypeConstraints typeConstraints) {
|
||||||
Set<JetType> values = Sets.newLinkedHashSet();
|
Set<JetType> values = Sets.newLinkedHashSet();
|
||||||
if (typeConstraints != null && !typeConstraints.isEmpty()) {
|
if (typeConstraints == null || typeConstraints.isEmpty()) {
|
||||||
if (typeConstraints.getExactBounds().size() == 1) {
|
return values;
|
||||||
if (verifyOneExactBound(typeConstraints)) {
|
}
|
||||||
JetType exactBound = typeConstraints.getExactBounds().iterator().next();
|
TypeConstraints typeConstraintsWithoutErrorTypes = filterNotContainingErrorType(typeConstraints, values);
|
||||||
return Collections.singleton(exactBound);
|
Collection<JetType> exactBounds = typeConstraintsWithoutErrorTypes.getExactBounds();
|
||||||
|
if (exactBounds.size() == 1) {
|
||||||
|
JetType exactBound = exactBounds.iterator().next();
|
||||||
|
if (trySuggestion(exactBound, typeConstraints)) {
|
||||||
|
return Collections.singleton(exactBound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
values.addAll(exactBounds);
|
||||||
|
|
||||||
|
Collection<JetType> lowerBounds = Sets.newHashSet();
|
||||||
|
Collection<JetType> numberLowerBounds = Sets.newHashSet();
|
||||||
|
for (JetType lowerBound : typeConstraintsWithoutErrorTypes.getLowerBounds()) {
|
||||||
|
if (lowerBound.getConstructor() instanceof NumberValueTypeConstructor) {
|
||||||
|
numberLowerBounds.add(lowerBound);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lowerBounds.add(lowerBound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JetType superTypeOfLowerBounds = commonSupertype(lowerBounds);
|
||||||
|
if (trySuggestion(superTypeOfLowerBounds, typeConstraints)) {
|
||||||
|
return Collections.singleton(superTypeOfLowerBounds);
|
||||||
|
}
|
||||||
|
addToValuesIfDifferent(superTypeOfLowerBounds, values);
|
||||||
|
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
Collection<JetType> upperBounds = typeConstraintsWithoutErrorTypes.getUpperBounds();
|
||||||
|
for (JetType upperBound : upperBounds) {
|
||||||
|
if (trySuggestion(upperBound, typeConstraints)) {
|
||||||
|
return Collections.singleton(upperBound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
values.addAll(typeConstraints.getExactBounds());
|
}
|
||||||
Collection<JetType> lowerBounds = filterNotContainingErrorType(typeConstraints.getLowerBounds());
|
|
||||||
if (!lowerBounds.isEmpty()) {
|
for (JetType upperBound : typeConstraintsWithoutErrorTypes.getUpperBounds()) {
|
||||||
JetType superTypeOfLowerBounds = CommonSupertypes.commonSupertype(lowerBounds);
|
addToValuesIfDifferent(upperBound, values);
|
||||||
for (JetType value : values) {
|
}
|
||||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(superTypeOfLowerBounds, value)) {
|
|
||||||
values.add(superTypeOfLowerBounds);
|
JetType superTypeOfNumberLowerBounds = commonSupertypeForNumberTypes(numberLowerBounds);
|
||||||
break;
|
if (trySuggestion(superTypeOfNumberLowerBounds, typeConstraints)) {
|
||||||
}
|
return Collections.singleton(superTypeOfNumberLowerBounds);
|
||||||
}
|
}
|
||||||
if (values.isEmpty()) {
|
addToValuesIfDifferent(superTypeOfNumberLowerBounds, values);
|
||||||
values.add(superTypeOfLowerBounds);
|
|
||||||
}
|
if (superTypeOfLowerBounds != null && superTypeOfNumberLowerBounds != null) {
|
||||||
}
|
JetType superTypeOfAllLowerBounds =
|
||||||
Collection<JetType> upperBounds = filterNotContainingErrorType(typeConstraints.getUpperBounds());
|
commonSupertype(Lists.newArrayList(superTypeOfLowerBounds, superTypeOfNumberLowerBounds));
|
||||||
if (!upperBounds.isEmpty()) {
|
if (trySuggestion(superTypeOfAllLowerBounds, typeConstraints)) {
|
||||||
//todo subTypeOfUpperBounds
|
return Collections.singleton(superTypeOfAllLowerBounds);
|
||||||
JetType subTypeOfUpperBounds = upperBounds.iterator().next(); //todo
|
|
||||||
for (JetType value : values) {
|
|
||||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(value, subTypeOfUpperBounds)) {
|
|
||||||
values.add(subTypeOfUpperBounds);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (values.isEmpty()) {
|
|
||||||
values.add(subTypeOfUpperBounds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean verifyOneExactBound(@NotNull TypeConstraints typeConstraints) {
|
private static void addToValuesIfDifferent(@Nullable JetType type, @NotNull Set<JetType> values) {
|
||||||
JetType exactBound = typeConstraints.getExactBounds().iterator().next();
|
if (type == null) return;
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
values.add(type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (JetType value : values) {
|
||||||
|
if (!JetTypeChecker.INSTANCE.equalTypes(type, value)) {
|
||||||
|
values.add(type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static JetType commonSupertype(@NotNull Collection<JetType> lowerBounds) {
|
||||||
|
if (lowerBounds.isEmpty()) return null;
|
||||||
|
return CommonSupertypes.commonSupertype(lowerBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static JetType commonSupertypeForNumberTypes(@NotNull Collection<JetType> numberLowerBounds) {
|
||||||
|
if (numberLowerBounds.isEmpty()) return null;
|
||||||
|
Set<Long> numbers = Sets.newHashSet();
|
||||||
|
for (JetType numberLowerBound : numberLowerBounds) {
|
||||||
|
assert numberLowerBound.getConstructor() instanceof NumberValueTypeConstructor;
|
||||||
|
numbers.add(((NumberValueTypeConstructor) numberLowerBound.getConstructor()).getValue());
|
||||||
|
}
|
||||||
|
assert !numbers.isEmpty();
|
||||||
|
return getDefaultNumberType(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JetType getDefaultNumberType(Collection<Long> values) {
|
||||||
|
for (Long value : values) {
|
||||||
|
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
|
||||||
|
return KotlinBuiltIns.getInstance().getLongType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return KotlinBuiltIns.getInstance().getIntType();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean trySuggestion(
|
||||||
|
@Nullable JetType suggestion,
|
||||||
|
@NotNull TypeConstraints typeConstraints
|
||||||
|
) {
|
||||||
|
if (suggestion == null) return false;
|
||||||
|
if (typeConstraints.getExactBounds().size() > 1) return false;
|
||||||
|
|
||||||
|
for (JetType exactBound : typeConstraints.getExactBounds()) {
|
||||||
|
if (!JetTypeChecker.INSTANCE.equalTypes(exactBound, suggestion)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (JetType lowerBound : typeConstraints.getLowerBounds()) {
|
for (JetType lowerBound : typeConstraints.getLowerBounds()) {
|
||||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(lowerBound, exactBound)) {
|
if (!JetTypeChecker.INSTANCE.isSubtypeOf(lowerBound, suggestion)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (JetType upperBound : typeConstraints.getUpperBounds()) {
|
for (JetType upperBound : typeConstraints.getUpperBounds()) {
|
||||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(exactBound, upperBound)) {
|
if (!JetTypeChecker.INSTANCE.isSubtypeOf(suggestion, upperBound)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,14 +160,23 @@ public class ConstraintsUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static Collection<JetType> filterNotContainingErrorType(@NotNull Collection<JetType> types) {
|
private static TypeConstraints filterNotContainingErrorType(
|
||||||
return Collections2.filter(types, new Predicate<JetType>() {
|
@NotNull TypeConstraints typeConstraints,
|
||||||
@Override
|
@NotNull Collection<JetType> values
|
||||||
public boolean apply(@Nullable JetType type) {
|
) {
|
||||||
if (ErrorUtils.containsErrorType(type)) return false;
|
TypeConstraintsImpl typeConstraintsWithoutErrorType = new TypeConstraintsImpl(typeConstraints.getVarianceOfPosition());
|
||||||
return true;
|
Collection<Pair<TypeConstraintsImpl.BoundKind, JetType>> allBounds = ((TypeConstraintsImpl) typeConstraints).getAllBounds();
|
||||||
|
for (Pair<TypeConstraintsImpl.BoundKind, JetType> pair : allBounds) {
|
||||||
|
TypeConstraintsImpl.BoundKind boundKind = pair.getFirst();
|
||||||
|
JetType type = pair.getSecond();
|
||||||
|
if (ErrorUtils.containsErrorType(type)) {
|
||||||
|
values.add(type);
|
||||||
}
|
}
|
||||||
});
|
else {
|
||||||
|
typeConstraintsWithoutErrorType.addBound(boundKind, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeConstraintsWithoutErrorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
+17
@@ -16,11 +16,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.calls.inference;
|
package org.jetbrains.jet.lang.resolve.calls.inference;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.Variance;
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class TypeConstraintsImpl implements TypeConstraints {
|
public class TypeConstraintsImpl implements TypeConstraints {
|
||||||
@@ -86,4 +89,18 @@ public class TypeConstraintsImpl implements TypeConstraints {
|
|||||||
public static enum BoundKind {
|
public static enum BoundKind {
|
||||||
LOWER_BOUND, UPPER_BOUND, EXACT_BOUND
|
LOWER_BOUND, UPPER_BOUND, EXACT_BOUND
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<Pair<BoundKind, JetType>> getAllBounds() {
|
||||||
|
Collection<Pair<BoundKind, JetType>> result = Lists.newArrayList();
|
||||||
|
for (JetType exactBound : exactBounds) {
|
||||||
|
result.add(Pair.create(BoundKind.EXACT_BOUND, exactBound));
|
||||||
|
}
|
||||||
|
for (JetType exactBound : upperBounds) {
|
||||||
|
result.add(Pair.create(BoundKind.UPPER_BOUND, exactBound));
|
||||||
|
}
|
||||||
|
for (JetType exactBound : lowerBounds) {
|
||||||
|
result.add(Pair.create(BoundKind.LOWER_BOUND, exactBound));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-12
@@ -16,25 +16,37 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.constants;
|
package org.jetbrains.jet.lang.resolve.constants;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
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.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class NumberValueTypeConstructor implements TypeConstructor {
|
public class NumberValueTypeConstructor implements TypeConstructor {
|
||||||
private final Long value;
|
private final long value;
|
||||||
|
private final Collection<JetType> supertypes = Lists.newArrayList();
|
||||||
|
|
||||||
public NumberValueTypeConstructor(Long value) {
|
public NumberValueTypeConstructor(long value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
||||||
|
checkBoundsAndSuperType((long)Byte.MIN_VALUE, (long)Byte.MAX_VALUE, KotlinBuiltIns.getInstance().getByteType());
|
||||||
|
checkBoundsAndSuperType((long)Short.MIN_VALUE, (long)Short.MAX_VALUE, KotlinBuiltIns.getInstance().getShortType());
|
||||||
|
checkBoundsAndSuperType((long)Integer.MIN_VALUE, (long)Integer.MAX_VALUE, KotlinBuiltIns.getInstance().getIntType());
|
||||||
|
supertypes.add(KotlinBuiltIns.getInstance().getLongType());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkBoundsAndSuperType(long minValue, long maxValue, JetType kotlinType) {
|
||||||
|
if (value > minValue && value < maxValue) {
|
||||||
|
supertypes.add(kotlinType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getValue() {
|
public Long getValue() {
|
||||||
@@ -44,18 +56,18 @@ public class NumberValueTypeConstructor implements TypeConstructor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<TypeParameterDescriptor> getParameters() {
|
public List<TypeParameterDescriptor> getParameters() {
|
||||||
throw new IllegalStateException();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<JetType> getSupertypes() {
|
public Collection<JetType> getSupertypes() {
|
||||||
throw new IllegalStateException();
|
return supertypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSealed() {
|
public boolean isSealed() {
|
||||||
throw new IllegalStateException();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -66,12 +78,12 @@ public class NumberValueTypeConstructor implements TypeConstructor {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public ClassifierDescriptor getDeclarationDescriptor() {
|
public ClassifierDescriptor getDeclarationDescriptor() {
|
||||||
throw new IllegalStateException();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AnnotationDescriptor> getAnnotations() {
|
public List<AnnotationDescriptor> getAnnotations() {
|
||||||
throw new IllegalStateException();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,15 +91,20 @@ public class NumberValueTypeConstructor implements TypeConstructor {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NumberValueTypeConstructor type = (NumberValueTypeConstructor) o;
|
NumberValueTypeConstructor that = (NumberValueTypeConstructor) o;
|
||||||
|
|
||||||
if (!value.equals(type.value)) return false;
|
if (value != that.value) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return value.hashCode();
|
return (int) (value ^ (value >>> 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "NumberValueTypeConstructor(" + value + ')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
fun <T> id(t: T): T = t
|
||||||
|
|
||||||
|
fun <T> either(t1: T, <!UNUSED_PARAMETER!>t2<!>: T): T = t1
|
||||||
|
|
||||||
|
fun other(<!UNUSED_PARAMETER!>s<!>: String) {}
|
||||||
|
|
||||||
|
fun <T> otherGeneric(<!UNUSED_PARAMETER!>l<!>: List<T>) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val <!UNUSED_VARIABLE!>a<!>: Byte = id(1)
|
||||||
|
|
||||||
|
val <!UNUSED_VARIABLE!>b<!>: Byte = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>id<!>(300)
|
||||||
|
|
||||||
|
val <!UNUSED_VARIABLE!>c<!>: Int = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>id<!>(9223372036854775807)
|
||||||
|
|
||||||
|
val d = id(22)
|
||||||
|
d: Int
|
||||||
|
|
||||||
|
val e = id(9223372036854775807)
|
||||||
|
<!TYPE_MISMATCH!>e<!>: Int
|
||||||
|
e: Long
|
||||||
|
|
||||||
|
val <!UNUSED_VARIABLE!>f<!>: Byte = either(1, 2)
|
||||||
|
|
||||||
|
val <!UNUSED_VARIABLE!>g<!>: Byte = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>either<!>(1, 300)
|
||||||
|
|
||||||
|
other(<!TYPE_MISMATCH!>11<!>)
|
||||||
|
|
||||||
|
<!TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH!>otherGeneric<!>(<!TYPE_MISMATCH!>1<!>)
|
||||||
|
|
||||||
|
val r = either(1, "")
|
||||||
|
<!TYPE_MISMATCH!>r<!>: Int
|
||||||
|
<!TYPE_MISMATCH!>r<!>: String
|
||||||
|
r: Any
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Inv<T>
|
||||||
|
|
||||||
|
fun <T> exactBound(<!UNUSED_PARAMETER!>t<!>: T, <!UNUSED_PARAMETER!>l<!>: Inv<T>) {}
|
||||||
|
|
||||||
|
fun testExactBound(invS: Inv<String>, invI: Inv<Int>) {
|
||||||
|
<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>exactBound<!>(1, invS)
|
||||||
|
exactBound(1, invI)
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Cov<out T>
|
||||||
|
|
||||||
|
fun <T> lowerBound(t: T, <!UNUSED_PARAMETER!>l<!>: Cov<T>) = t
|
||||||
|
|
||||||
|
fun testLowerBound(cov: Cov<String>) {
|
||||||
|
val r = lowerBound(1, cov)
|
||||||
|
r: Any
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Contr<in T>
|
||||||
|
|
||||||
|
fun <T> upperBound(t: T, <!UNUSED_PARAMETER!>l<!>: Contr<T>) = t
|
||||||
|
|
||||||
|
fun testUpperBound(contrS: Contr<String>, contrB: Contr<Byte>, contrN: Contr<Number>) {
|
||||||
|
<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>upperBound<!>(1, contrS)
|
||||||
|
|
||||||
|
upperBound(1, contrN)
|
||||||
|
upperBound(1, contrB)
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve;
|
|||||||
@InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class})
|
@InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class})
|
||||||
public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEagerResolve {
|
public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEagerResolve {
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests")
|
@TestMetadata("compiler/testData/diagnostics/tests")
|
||||||
@InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.CallableReference.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.DelegatedProperty.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Recovery.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.ThisAndSuper.class, Tests.Varargs.class})
|
@InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.CallableReference.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.DelegatedProperty.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Numbers.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Recovery.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.ThisAndSuper.class, Tests.Varargs.class})
|
||||||
public static class Tests extends AbstractDiagnosticsTestWithEagerResolve {
|
public static class Tests extends AbstractDiagnosticsTestWithEagerResolve {
|
||||||
@TestMetadata("Abstract.kt")
|
@TestMetadata("Abstract.kt")
|
||||||
public void testAbstract() throws Exception {
|
public void testAbstract() throws Exception {
|
||||||
@@ -3778,6 +3778,19 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/numbers")
|
||||||
|
public static class Numbers extends AbstractDiagnosticsTestWithEagerResolve {
|
||||||
|
public void testAllFilesPresentInNumbers() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/numbers"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("numbersInSimpleConstraints.kt")
|
||||||
|
public void testNumbersInSimpleConstraints() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/numbers/numbersInSimpleConstraints.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/objects")
|
@TestMetadata("compiler/testData/diagnostics/tests/objects")
|
||||||
public static class Objects extends AbstractDiagnosticsTestWithEagerResolve {
|
public static class Objects extends AbstractDiagnosticsTestWithEagerResolve {
|
||||||
public void testAllFilesPresentInObjects() throws Exception {
|
public void testAllFilesPresentInObjects() throws Exception {
|
||||||
@@ -5305,6 +5318,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
suite.addTestSuite(Library.class);
|
suite.addTestSuite(Library.class);
|
||||||
suite.addTestSuite(NullabilityAndAutoCasts.class);
|
suite.addTestSuite(NullabilityAndAutoCasts.class);
|
||||||
suite.addTestSuite(NullableTypes.class);
|
suite.addTestSuite(NullableTypes.class);
|
||||||
|
suite.addTestSuite(Numbers.class);
|
||||||
suite.addTestSuite(Objects.class);
|
suite.addTestSuite(Objects.class);
|
||||||
suite.addTestSuite(OperatorsOverloading.class);
|
suite.addTestSuite(OperatorsOverloading.class);
|
||||||
suite.addTestSuite(Overload.class);
|
suite.addTestSuite(Overload.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user