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:
Svetlana Isakova
2013-07-22 13:17:03 +04:00
parent 517c24c8f6
commit 80eb45b793
7 changed files with 268 additions and 71 deletions
@@ -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.ResolutionContext;
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.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.ErrorUtils;
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.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -71,16 +69,13 @@ public class ArgumentTypeResolver {
}
public static boolean isSubtypeOfForArgumentType(
@NotNull JetType subtype,
@NotNull JetType supertype
@NotNull JetType actualType,
@NotNull JetType expectedType
) {
if (subtype == PLACEHOLDER_FUNCTION_TYPE) {
return isFunctionOrErrorType(supertype) || KotlinBuiltIns.getInstance().isAny(supertype); //todo function type extends
if (actualType == PLACEHOLDER_FUNCTION_TYPE) {
return isFunctionOrErrorType(expectedType) || KotlinBuiltIns.getInstance().isAny(expectedType); //todo function type extends
}
if (supertype == PLACEHOLDER_FUNCTION_TYPE) {
return isFunctionOrErrorType(subtype); //todo extends function type
}
return JetTypeChecker.INSTANCE.isSubtypeOf(subtype, supertype);
return JetTypeChecker.INSTANCE.isSubtypeOf(actualType, expectedType);
}
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.TaskPrioritizer;
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.ReceiverValue;
import org.jetbrains.jet.lang.types.*;
@@ -356,6 +358,12 @@ public class CandidateResolver {
if (dataFlowInfoForValueArgument != null) {
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);
continue;
}
@@ -655,7 +663,7 @@ public class CandidateResolver {
List<ReceiverValue> variants = AutoCastUtils.getAutoCastVariants(context.trace.getBindingContext(), context.dataFlowInfo, receiverToCast);
for (ReceiverValue receiverValue : variants) {
JetType possibleType = receiverValue.getType();
if (ArgumentTypeResolver.isSubtypeOfForArgumentType(possibleType, expectedType)) {
if (JetTypeChecker.INSTANCE.isSubtypeOf(possibleType, expectedType)) {
return possibleType;
}
}
@@ -16,16 +16,17 @@
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.Maps;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.*;
@@ -34,54 +35,124 @@ public class ConstraintsUtil {
@NotNull
public static Set<JetType> getValues(@Nullable TypeConstraints typeConstraints) {
Set<JetType> values = Sets.newLinkedHashSet();
if (typeConstraints != null && !typeConstraints.isEmpty()) {
if (typeConstraints.getExactBounds().size() == 1) {
if (verifyOneExactBound(typeConstraints)) {
JetType exactBound = typeConstraints.getExactBounds().iterator().next();
return Collections.singleton(exactBound);
if (typeConstraints == null || typeConstraints.isEmpty()) {
return values;
}
TypeConstraints typeConstraintsWithoutErrorTypes = filterNotContainingErrorType(typeConstraints, values);
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()) {
JetType superTypeOfLowerBounds = CommonSupertypes.commonSupertype(lowerBounds);
for (JetType value : values) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(superTypeOfLowerBounds, value)) {
values.add(superTypeOfLowerBounds);
break;
}
}
if (values.isEmpty()) {
values.add(superTypeOfLowerBounds);
}
}
Collection<JetType> upperBounds = filterNotContainingErrorType(typeConstraints.getUpperBounds());
if (!upperBounds.isEmpty()) {
//todo subTypeOfUpperBounds
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);
}
}
for (JetType upperBound : typeConstraintsWithoutErrorTypes.getUpperBounds()) {
addToValuesIfDifferent(upperBound, values);
}
JetType superTypeOfNumberLowerBounds = commonSupertypeForNumberTypes(numberLowerBounds);
if (trySuggestion(superTypeOfNumberLowerBounds, typeConstraints)) {
return Collections.singleton(superTypeOfNumberLowerBounds);
}
addToValuesIfDifferent(superTypeOfNumberLowerBounds, values);
if (superTypeOfLowerBounds != null && superTypeOfNumberLowerBounds != null) {
JetType superTypeOfAllLowerBounds =
commonSupertype(Lists.newArrayList(superTypeOfLowerBounds, superTypeOfNumberLowerBounds));
if (trySuggestion(superTypeOfAllLowerBounds, typeConstraints)) {
return Collections.singleton(superTypeOfAllLowerBounds);
}
}
return values;
}
private static boolean verifyOneExactBound(@NotNull TypeConstraints typeConstraints) {
JetType exactBound = typeConstraints.getExactBounds().iterator().next();
private static void addToValuesIfDifferent(@Nullable JetType type, @NotNull Set<JetType> values) {
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()) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(lowerBound, exactBound)) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(lowerBound, suggestion)) {
return false;
}
}
for (JetType upperBound : typeConstraints.getUpperBounds()) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(exactBound, upperBound)) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(suggestion, upperBound)) {
return false;
}
}
@@ -89,14 +160,23 @@ public class ConstraintsUtil {
}
@NotNull
private static Collection<JetType> filterNotContainingErrorType(@NotNull Collection<JetType> types) {
return Collections2.filter(types, new Predicate<JetType>() {
@Override
public boolean apply(@Nullable JetType type) {
if (ErrorUtils.containsErrorType(type)) return false;
return true;
private static TypeConstraints filterNotContainingErrorType(
@NotNull TypeConstraints typeConstraints,
@NotNull Collection<JetType> values
) {
TypeConstraintsImpl typeConstraintsWithoutErrorType = new TypeConstraintsImpl(typeConstraints.getVarianceOfPosition());
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
@@ -16,11 +16,14 @@
package org.jetbrains.jet.lang.resolve.calls.inference;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.Variance;
import java.util.Collection;
import java.util.Set;
public class TypeConstraintsImpl implements TypeConstraints {
@@ -86,4 +89,18 @@ public class TypeConstraintsImpl implements TypeConstraints {
public static enum BoundKind {
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;
}
}
@@ -16,25 +16,37 @@
package org.jetbrains.jet.lang.resolve.constants;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
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.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
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;
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() {
@@ -44,18 +56,18 @@ public class NumberValueTypeConstructor implements TypeConstructor {
@NotNull
@Override
public List<TypeParameterDescriptor> getParameters() {
throw new IllegalStateException();
return Collections.emptyList();
}
@NotNull
@Override
public Collection<JetType> getSupertypes() {
throw new IllegalStateException();
return supertypes;
}
@Override
public boolean isSealed() {
throw new IllegalStateException();
return false;
}
@Override
@@ -66,12 +78,12 @@ public class NumberValueTypeConstructor implements TypeConstructor {
@Nullable
@Override
public ClassifierDescriptor getDeclarationDescriptor() {
throw new IllegalStateException();
return null;
}
@Override
public List<AnnotationDescriptor> getAnnotations() {
throw new IllegalStateException();
return Collections.emptyList();
}
@Override
@@ -79,15 +91,20 @@ public class NumberValueTypeConstructor implements TypeConstructor {
if (this == o) return true;
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;
}
@Override
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})
public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEagerResolve {
@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 {
@TestMetadata("Abstract.kt")
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")
public static class Objects extends AbstractDiagnosticsTestWithEagerResolve {
public void testAllFilesPresentInObjects() throws Exception {
@@ -5305,6 +5318,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
suite.addTestSuite(Library.class);
suite.addTestSuite(NullabilityAndAutoCasts.class);
suite.addTestSuite(NullableTypes.class);
suite.addTestSuite(Numbers.class);
suite.addTestSuite(Objects.class);
suite.addTestSuite(OperatorsOverloading.class);
suite.addTestSuite(Overload.class);