changed way to compute common supertype for number types
(using only supertypes, not exact value)
This commit is contained in:
+2
-18
@@ -84,8 +84,7 @@ public class ConstraintsUtil {
|
||||
addToValuesIfDifferent(superTypeOfNumberLowerBounds, values);
|
||||
|
||||
if (superTypeOfLowerBounds != null && superTypeOfNumberLowerBounds != null) {
|
||||
JetType superTypeOfAllLowerBounds =
|
||||
commonSupertype(Lists.newArrayList(superTypeOfLowerBounds, superTypeOfNumberLowerBounds));
|
||||
JetType superTypeOfAllLowerBounds = commonSupertype(Lists.newArrayList(superTypeOfLowerBounds, superTypeOfNumberLowerBounds));
|
||||
if (trySuggestion(superTypeOfAllLowerBounds, typeConstraints)) {
|
||||
return Collections.singleton(superTypeOfAllLowerBounds);
|
||||
}
|
||||
@@ -116,22 +115,7 @@ public class ConstraintsUtil {
|
||||
@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();
|
||||
return TypeUtils.commonSupertypeForNumberTypes(numberLowerBounds);
|
||||
}
|
||||
|
||||
private static boolean trySuggestion(
|
||||
|
||||
@@ -29,16 +29,11 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.ERROR_COMPILE_TIME_VALUE;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType;
|
||||
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.getDefaultType;
|
||||
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.*;
|
||||
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.BYTE;
|
||||
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.INT;
|
||||
|
||||
public class ConstantUtils {
|
||||
|
||||
@@ -80,24 +75,12 @@ public class ConstantUtils {
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull ResolutionContext<?> context
|
||||
) {
|
||||
CompileTimeConstantResolver compileTimeConstantResolver = new CompileTimeConstantResolver();
|
||||
CompileTimeConstant<?> value = compileTimeConstantResolver.getIntegerValue(numberValueTypeConstructor.getValue(), expectedType);
|
||||
JetTypeInfo recordedTypeInfo = BindingContextUtils.getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
||||
assert recordedTypeInfo != null : "Expression " + expression + " should have been analyzed";
|
||||
JetScope resolutionScope = context.trace.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||
assert resolutionScope != null : "Expression " + expression + " should have been analyzed";
|
||||
|
||||
JetType type;
|
||||
if (value instanceof ErrorValue) {
|
||||
ErrorValue errorValue = (ErrorValue) value;
|
||||
type = getDefaultType(expression.getNode().getElementType());
|
||||
if (!noExpectedType(context.expectedType) && JetTypeChecker.INSTANCE.isSubtypeOf(type, context.expectedType)) {
|
||||
context.trace.report(ERROR_COMPILE_TIME_VALUE.on(expression, errorValue.getMessage()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
type = value.getType(KotlinBuiltIns.getInstance());
|
||||
}
|
||||
JetType type = TypeUtils.getPrimitiveNumberType(numberValueTypeConstructor, expectedType);
|
||||
BindingContextUtils.recordExpressionType(expression, context.trace, resolutionScope,
|
||||
JetTypeInfo.create(type, recordedTypeInfo.getDataFlowInfo()));
|
||||
return type;
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListen
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemWithPriorities;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType;
|
||||
import org.jetbrains.jet.lang.resolve.constants.NumberValueTypeConstructor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
@@ -551,4 +552,68 @@ public class TypeUtils {
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetType commonSupertypeForNumberTypes(@NotNull Collection<JetType> numberLowerBounds) {
|
||||
assert !numberLowerBounds.isEmpty();
|
||||
Set<JetType> intersectionOfSupertypes = getIntersectionOfSupertypes(numberLowerBounds);
|
||||
JetType primitiveNumberType = getDefaultPrimitiveNumberType(intersectionOfSupertypes);
|
||||
if (primitiveNumberType != null) {
|
||||
return primitiveNumberType;
|
||||
}
|
||||
return CommonSupertypes.commonSupertype(numberLowerBounds);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<JetType> getIntersectionOfSupertypes(@NotNull Collection<JetType> types) {
|
||||
Set<JetType> upperBounds = Sets.newHashSet();
|
||||
for (JetType type : types) {
|
||||
Set<JetType> supertypes = Sets.newHashSet(type.getConstructor().getSupertypes());
|
||||
if (upperBounds.isEmpty()) {
|
||||
upperBounds.addAll(supertypes);
|
||||
}
|
||||
else {
|
||||
upperBounds = Sets.intersection(upperBounds, supertypes);
|
||||
}
|
||||
}
|
||||
return upperBounds;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JetType getDefaultPrimitiveNumberType(@NotNull NumberValueTypeConstructor numberValueTypeConstructor) {
|
||||
return getDefaultPrimitiveNumberType(numberValueTypeConstructor.getSupertypes());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JetType getDefaultPrimitiveNumberType(@NotNull Collection<JetType> supertypes) {
|
||||
JetType doubleType = KotlinBuiltIns.getInstance().getDoubleType();
|
||||
if (supertypes.contains(doubleType)) {
|
||||
return doubleType;
|
||||
}
|
||||
JetType intType = KotlinBuiltIns.getInstance().getIntType();
|
||||
if (supertypes.contains(intType)) {
|
||||
return intType;
|
||||
}
|
||||
JetType longType = KotlinBuiltIns.getInstance().getLongType();
|
||||
if (supertypes.contains(longType)) {
|
||||
return longType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JetType getPrimitiveNumberType(
|
||||
@NotNull NumberValueTypeConstructor numberValueTypeConstructor,
|
||||
@NotNull JetType expectedType
|
||||
) {
|
||||
if (noExpectedType(expectedType) || ErrorUtils.isErrorType(expectedType)) {
|
||||
return getDefaultPrimitiveNumberType(numberValueTypeConstructor);
|
||||
}
|
||||
for (JetType primitiveNumberType : numberValueTypeConstructor.getSupertypes()) {
|
||||
if (JetTypeChecker.INSTANCE.isSubtypeOf(primitiveNumberType, expectedType)) {
|
||||
return primitiveNumberType;
|
||||
}
|
||||
}
|
||||
return getDefaultPrimitiveNumberType(numberValueTypeConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user