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);
|
addToValuesIfDifferent(superTypeOfNumberLowerBounds, values);
|
||||||
|
|
||||||
if (superTypeOfLowerBounds != null && superTypeOfNumberLowerBounds != null) {
|
if (superTypeOfLowerBounds != null && superTypeOfNumberLowerBounds != null) {
|
||||||
JetType superTypeOfAllLowerBounds =
|
JetType superTypeOfAllLowerBounds = commonSupertype(Lists.newArrayList(superTypeOfLowerBounds, superTypeOfNumberLowerBounds));
|
||||||
commonSupertype(Lists.newArrayList(superTypeOfLowerBounds, superTypeOfNumberLowerBounds));
|
|
||||||
if (trySuggestion(superTypeOfAllLowerBounds, typeConstraints)) {
|
if (trySuggestion(superTypeOfAllLowerBounds, typeConstraints)) {
|
||||||
return Collections.singleton(superTypeOfAllLowerBounds);
|
return Collections.singleton(superTypeOfAllLowerBounds);
|
||||||
}
|
}
|
||||||
@@ -116,22 +115,7 @@ public class ConstraintsUtil {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private static JetType commonSupertypeForNumberTypes(@NotNull Collection<JetType> numberLowerBounds) {
|
private static JetType commonSupertypeForNumberTypes(@NotNull Collection<JetType> numberLowerBounds) {
|
||||||
if (numberLowerBounds.isEmpty()) return null;
|
if (numberLowerBounds.isEmpty()) return null;
|
||||||
Set<Long> numbers = Sets.newHashSet();
|
return TypeUtils.commonSupertypeForNumberTypes(numberLowerBounds);
|
||||||
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(
|
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.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
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.expressions.OperatorConventions;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
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.*;
|
||||||
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.BYTE;
|
|
||||||
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.INT;
|
|
||||||
|
|
||||||
public class ConstantUtils {
|
public class ConstantUtils {
|
||||||
|
|
||||||
@@ -80,24 +75,12 @@ public class ConstantUtils {
|
|||||||
@NotNull JetExpression expression,
|
@NotNull JetExpression expression,
|
||||||
@NotNull ResolutionContext<?> context
|
@NotNull ResolutionContext<?> context
|
||||||
) {
|
) {
|
||||||
CompileTimeConstantResolver compileTimeConstantResolver = new CompileTimeConstantResolver();
|
|
||||||
CompileTimeConstant<?> value = compileTimeConstantResolver.getIntegerValue(numberValueTypeConstructor.getValue(), expectedType);
|
|
||||||
JetTypeInfo recordedTypeInfo = BindingContextUtils.getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
JetTypeInfo recordedTypeInfo = BindingContextUtils.getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
||||||
assert recordedTypeInfo != null : "Expression " + expression + " should have been analyzed";
|
assert recordedTypeInfo != null : "Expression " + expression + " should have been analyzed";
|
||||||
JetScope resolutionScope = context.trace.get(BindingContext.RESOLUTION_SCOPE, expression);
|
JetScope resolutionScope = context.trace.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||||
assert resolutionScope != null : "Expression " + expression + " should have been analyzed";
|
assert resolutionScope != null : "Expression " + expression + " should have been analyzed";
|
||||||
|
|
||||||
JetType type;
|
JetType type = TypeUtils.getPrimitiveNumberType(numberValueTypeConstructor, expectedType);
|
||||||
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());
|
|
||||||
}
|
|
||||||
BindingContextUtils.recordExpressionType(expression, context.trace, resolutionScope,
|
BindingContextUtils.recordExpressionType(expression, context.trace, resolutionScope,
|
||||||
JetTypeInfo.create(type, recordedTypeInfo.getDataFlowInfo()));
|
JetTypeInfo.create(type, recordedTypeInfo.getDataFlowInfo()));
|
||||||
return type;
|
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.ConstraintSystemSolution;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemWithPriorities;
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemWithPriorities;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType;
|
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.ChainedScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
@@ -551,4 +552,68 @@ public class TypeUtils {
|
|||||||
|
|
||||||
return builder.toString();
|
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