From c7c28ac2e778cc0d8bd7c54aa1ca1e6e17d6e6c0 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 27 Jan 2011 16:47:22 +0300 Subject: [PATCH] Nullable and Nothing supported --- .../jet/lang/types/JetStandardClasses.java | 21 ++++++++++++++----- .../jet/lang/types/JetTypeChecker.java | 3 +++ .../jet/types/JetTypeCheckerTest.java | 21 +++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index 0dbddf910a7..983dbed30d9 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -8,12 +8,12 @@ import java.util.*; * @author abreslav */ public class JetStandardClasses { - private static final TypeConstructor NOTHING = new TypeConstructor( + + private static ClassDescriptor NOTHING_CLASS = new ClassDescriptor( Collections.emptyList(), "Nothing", Collections.emptyList(), new AbstractCollection() { - @Override public boolean contains(Object o) { return o instanceof Type; @@ -28,7 +28,8 @@ public class JetStandardClasses { public int size() { throw new UnsupportedOperationException(); } - }); + } + ); private static final ClassDescriptor ANY = new ClassDescriptor( Collections.emptyList(), @@ -85,8 +86,13 @@ public class JetStandardClasses { private static final Type BOOLEAN_TYPE = new TypeImpl(getBoolean().getTypeConstructor(), STUB); private static final Type STRING_TYPE = new TypeImpl(getString().getTypeConstructor(), STUB); private static final Type UNIT_TYPE = new TypeImpl(getTuple(0).getTypeConstructor(), STUB); - private static final Type NOTHING_TYPE = new TypeImpl(NOTHING, STUB); - private static final Type NULLABLE_NOTHING_TYPE = new TypeImpl(Collections.emptyList(), NOTHING, true, Collections.emptyList(), TypeMemberDomain.EMPTY); + private static final Type NOTHING_TYPE = new TypeImpl(getNothing().getTypeConstructor(), STUB); + private static final Type NULLABLE_NOTHING_TYPE = new TypeImpl( + Collections.emptyList(), + getNothing().getTypeConstructor(), + true, + Collections.emptyList(), + TypeMemberDomain.EMPTY); @NotNull public static ClassDescriptor getAny() { @@ -143,6 +149,11 @@ public class JetStandardClasses { return STRING; } + @NotNull + public static ClassDescriptor getNothing() { + return NOTHING_CLASS; + } + @NotNull public static ClassDescriptor getTuple(int size) { return TUPLE[size]; diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index 9da93fe2cb2..eed25a68259 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -75,6 +75,9 @@ public class JetTypeChecker { if (!supertype.isNullable() && subtype.isNullable()) { return false; } + if (subtype.getConstructor() == JetStandardClasses.getNothing().getTypeConstructor()) { + return true; + } @Nullable Type closestSupertype = findCorrespondingSupertype(subtype, supertype); if (closestSupertype == null) { return false; diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index cf290880b99..0c0e4dc2148 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -177,6 +177,25 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { assertSubtype("Derived_T", "Base_T"); } + public void testNullable() throws Exception { + assertSubtype("Any?", "Any?"); + assertSubtype("Any", "Any?"); + assertNotSubtype("Any?", "Any"); + assertSubtype("Int", "Any?"); + assertSubtype("Int?", "Any?"); + assertNotSubtype("Int?", "Any"); + } + + public void testNothing() throws Exception { + assertSubtype("Nothing", "Any"); + assertSubtype("Nothing?", "Any?"); + assertNotSubtype("Nothing?", "Any"); + + assertSubtype("Nothing", "Int"); + assertSubtype("Nothing?", "Int?"); + assertNotSubtype("Nothing?", "Int"); + } + public void testImplicitConversions() throws Exception { assertConvertibleTo("1", JetStandardClasses.getByteType()); } @@ -254,6 +273,8 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { return JetStandardClasses.getTuple(0); } else if ("Any".equals(name)) { return JetStandardClasses.getAny(); + } else if ("Nothing".equals(name)) { + return JetStandardClasses.getNothing(); } if (CLASSES.isEmpty()) { for (String classDeclaration : CLASS_DECLARATIONS) {