Exhaustive when support for sealed classes #KT-7606 Fixed

When on sealed can use is (both for derived classes and objects) or just comparison (only for derived objects).
A pack of tests provided.
This commit is contained in:
Mikhail Glukhikh
2015-05-12 18:07:17 +03:00
parent 8d25c20169
commit f6872dfbea
39 changed files with 1368 additions and 8 deletions
@@ -24,10 +24,14 @@ import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilPackage;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeUtils;
import java.util.HashSet;
import java.util.Set;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumClass;
import static org.jetbrains.kotlin.types.TypesPackage.isFlexible;
@@ -82,8 +86,12 @@ public final class WhenChecker {
}
public static boolean isWhenOnEnumExhaustive(
@NotNull JetWhenExpression expression, @NotNull BindingTrace trace, @NotNull ClassDescriptor enumClassDescriptor) {
assert isEnumClass(enumClassDescriptor);
@NotNull JetWhenExpression expression,
@NotNull BindingTrace trace,
@NotNull ClassDescriptor enumClassDescriptor
) {
assert isEnumClass(enumClassDescriptor) :
"isWhenOnEnumExhaustive should be called with an enum class descriptor";
boolean notEmpty = false;
for (DeclarationDescriptor descriptor : enumClassDescriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors()) {
if (isEnumEntry(descriptor)) {
@@ -96,6 +104,35 @@ public final class WhenChecker {
return notEmpty;
}
private static void collectNestedSubclasses(
@NotNull ClassDescriptor baseDescriptor,
@NotNull ClassDescriptor currentDescriptor,
@NotNull Set<ClassDescriptor> subclasses
) {
for (DeclarationDescriptor descriptor : currentDescriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors()) {
if (descriptor instanceof ClassDescriptor) {
ClassDescriptor memberClassDescriptor = (ClassDescriptor) descriptor;
if (DescriptorUtils.isDirectSubclass(memberClassDescriptor, baseDescriptor)) {
subclasses.add(memberClassDescriptor);
}
collectNestedSubclasses(baseDescriptor, memberClassDescriptor, subclasses);
}
}
}
private static boolean isWhenOnSealedClassExhaustive(
@NotNull JetWhenExpression expression,
@NotNull BindingTrace trace,
@NotNull ClassDescriptor classDescriptor
) {
assert classDescriptor.getModality() == Modality.SEALED :
"isWhenOnSealedClassExhaustive should be called with a sealed class descriptor";
Set<ClassDescriptor> memberClassDescriptors = new HashSet<ClassDescriptor>();
collectNestedSubclasses(classDescriptor, classDescriptor, memberClassDescriptors);
// When on a sealed class without derived members is considered non-exhaustive (see test WhenOnEmptySealed)
return !memberClassDescriptors.isEmpty() && containsAllClassCases(expression, memberClassDescriptors, trace);
}
/**
* It's assumed that function is called for a final type. In this case the only possible smart cast is to not nullable type.
* @return true if type is nullable, and cannot be smart casted
@@ -128,8 +165,10 @@ public final class WhenChecker {
exhaustive = isWhenOnBooleanExhaustive(expression, trace);
}
else {
// TODO: sealed hierarchies, etc.
exhaustive = false;
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(type);
exhaustive = (classDescriptor != null
&& classDescriptor.getModality() == Modality.SEALED
&& isWhenOnSealedClassExhaustive(expression, trace, classDescriptor));
}
}
else {
@@ -167,6 +206,51 @@ public final class WhenChecker {
return false;
}
private static boolean containsAllClassCases(
@NotNull JetWhenExpression whenExpression,
@NotNull Set<ClassDescriptor> memberDescriptors,
@NotNull BindingTrace trace
) {
Set<ClassDescriptor> checkedDescriptors = new HashSet<ClassDescriptor>();
for (JetWhenEntry whenEntry : whenExpression.getEntries()) {
for (JetWhenCondition condition : whenEntry.getConditions()) {
boolean negated = false;
JetType checkedType = null;
if (condition instanceof JetWhenConditionIsPattern) {
JetWhenConditionIsPattern conditionIsPattern = (JetWhenConditionIsPattern) condition;
checkedType = trace.get(BindingContext.TYPE, conditionIsPattern.getTypeReference());
negated = conditionIsPattern.isNegated();
}
else if (condition instanceof JetWhenConditionWithExpression) {
JetWhenConditionWithExpression conditionWithExpression = (JetWhenConditionWithExpression) condition;
if (conditionWithExpression.getExpression() != null) {
checkedType = trace.getBindingContext().getType(conditionWithExpression.getExpression());
}
}
if (checkedType == null) {
continue;
}
ClassDescriptor checkedDescriptor = TypeUtils.getClassDescriptor(checkedType);
// Checks are important only for nested subclasses of the sealed class
// In additional, check without "is" is important only for objects
if (checkedDescriptor == null
|| !memberDescriptors.contains(checkedDescriptor)
|| (condition instanceof JetWhenConditionWithExpression && !DescriptorUtils.isObject(checkedDescriptor))) {
continue;
}
if (negated) {
if (checkedDescriptors.contains(checkedDescriptor)) return true; // all members are already there
checkedDescriptors.addAll(memberDescriptors);
checkedDescriptors.remove(checkedDescriptor);
}
else {
checkedDescriptors.add(checkedDescriptor);
}
}
}
return checkedDescriptors.containsAll(memberDescriptors);
}
public static boolean containsNullCase(@NotNull JetWhenExpression expression, @NotNull BindingTrace trace) {
for (JetWhenEntry entry : expression.getEntries()) {
for (JetWhenCondition condition : entry.getConditions()) {
@@ -0,0 +1,16 @@
sealed class Sealed(val x: Int) {
object First: Sealed(12)
open class NonFirst(x: Int, val y: Int): Sealed(x) {
object Second: NonFirst(34, 2)
object Third: NonFirst(56, 3)
}
}
fun foo(s: Sealed): Int {
return when(s) {
is Sealed.First -> 1
is Sealed.NonFirst -> 0
// no else required
}
}
@@ -0,0 +1,46 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,16 @@
sealed class Sealed() {
object First: Sealed()
open class NonFirst: Sealed() {
object Second: NonFirst()
object Third: NonFirst()
// It's ALLOWED to inherit Sealed also from here
object Fourth: Sealed()
}
}
fun foo(s: Sealed) = when(s) {
Sealed.First -> 1
is Sealed.NonFirst -> 2
Sealed.NonFirst.Fourth -> 4
// no else required
}
@@ -0,0 +1,45 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Fourth : Sealed {
private constructor Fourth()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Second : Sealed.NonFirst {
private constructor Second()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,47 @@
sealed class Sealed() {
object First: Sealed()
open class NonFirst: Sealed() {
class NonSecond: NonFirst() {
object Third: Sealed()
class NonThird: Sealed() {
object Fourth: NonFirst()
class Fifth: Sealed()
}
}
object Second: Sealed()
}
}
fun foo(s: Sealed) = when(s) {
Sealed.First -> 1
is Sealed.NonFirst -> 2
Sealed.NonFirst.Second -> 4
Sealed.NonFirst.NonSecond.Third -> 6
is Sealed.NonFirst.NonSecond.NonThird -> 8
is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10
// no else required
}
fun fooWithElse(s: Sealed) = when(s) {
Sealed.First -> 1
Sealed.NonFirst.NonSecond.Third -> 6
is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10
else -> 0
}
fun fooWithoutElse(s: Sealed) = <!NO_ELSE_IN_WHEN!>when<!>(s) {
Sealed.First -> 1
is Sealed.NonFirst -> 2
Sealed.NonFirst.NonSecond.Third -> 6
is Sealed.NonFirst.NonSecond.NonThird -> 8
is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10
}
fun barWithoutElse(s: Sealed) = <!NO_ELSE_IN_WHEN!>when<!>(s) {
Sealed.First -> 1
is Sealed.NonFirst -> 2
Sealed.NonFirst.Second -> 4
is Sealed.NonFirst.NonSecond.NonThird -> 8
is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10
}
@@ -0,0 +1,69 @@
package
internal fun barWithoutElse(/*0*/ s: Sealed): kotlin.Int
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal fun fooWithElse(/*0*/ s: Sealed): kotlin.Int
internal fun fooWithoutElse(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final class NonSecond : Sealed.NonFirst {
public constructor NonSecond()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final class NonThird : Sealed {
public constructor NonThird()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final class Fifth : Sealed {
public constructor Fifth()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Fourth : Sealed.NonFirst {
private constructor Fourth()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
internal object Third : Sealed {
private constructor Third()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
internal object Second : Sealed {
private constructor Second()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,16 @@
sealed class Sealed(val x: Int) {
object First: Sealed(12)
open class NonFirst(x: Int, val y: Int): Sealed(x) {
object Second: NonFirst(34, 2)
object Third: NonFirst(56, 3)
}
}
fun foo(s: Sealed): Int {
return when(s) {
is Sealed.First -> 1
!is Sealed.First -> 0
// no else required
}
}
@@ -0,0 +1,46 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,17 @@
sealed class Sealed(val x: Int) {
object First: Sealed(12)
open class NonFirst(x: Int, val y: Int): Sealed(x) {
object Second: NonFirst(34, 2)
object Third: NonFirst(56, 3)
}
object Last: Sealed(78)
}
fun foo(s: Sealed): Int {
return when(s) {
!is Sealed.First -> 1
!is Sealed.Last -> 0
// no else required
}
}
@@ -0,0 +1,54 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Last : Sealed {
private constructor Last()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,20 @@
sealed class Sealed {
object First: Sealed()
sealed class NonFirst {
object Second: NonFirst()
object Third: NonFirst()
object Fourth: Sealed()
}
}
fun foo(s: Sealed, nf: Sealed.NonFirst): Int {
val si = when(s) {
Sealed.First -> 1
Sealed.NonFirst.Fourth -> 4
}
val nfi = when(nf) {
Sealed.NonFirst.Second -> 2
Sealed.NonFirst.Third -> 3
}
return si + nfi
}
@@ -0,0 +1,45 @@
package
internal fun foo(/*0*/ s: Sealed, /*1*/ nf: Sealed.NonFirst): kotlin.Int
internal sealed class Sealed {
public constructor Sealed()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal sealed class NonFirst {
public constructor NonFirst()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Fourth : Sealed {
private constructor Fourth()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Second : Sealed.NonFirst {
private constructor Second()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,17 @@
sealed class Sealed(val x: Int) {
object First: Sealed(12)
open class NonFirst(x: Int, val y: Int): Sealed(x) {
object Second: NonFirst(34, 2)
object Third: NonFirst(56, 3)
}
}
fun foo(s: Sealed?): Int {
return when(s) {
is Sealed.First -> 1
is Sealed.NonFirst -> 0
null -> -1
// no else required
}
}
@@ -0,0 +1,46 @@
package
internal fun foo(/*0*/ s: Sealed?): kotlin.Int
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,18 @@
sealed class Sealed(val x: Int) {
data class Tuple(val x: Int, val y: Int)
object First: Sealed(12)
open class NonFirst(tuple: Tuple): Sealed(tuple.x) {
val y: Int = tuple.y
object Second: NonFirst(Tuple(34, 2))
object Third: NonFirst(Tuple(56, 3))
}
}
fun foo(s: Sealed): Int {
return when(s) {
is Sealed.First -> 1
is Sealed.NonFirst -> 0
// no else required
}
}
@@ -0,0 +1,58 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst(/*0*/ tuple: Sealed.Tuple)
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
kotlin.data() internal final class Tuple {
public constructor Tuple(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal final val x: kotlin.Int
internal final val y: kotlin.Int
internal final /*synthesized*/ fun component1(): kotlin.Int
internal final /*synthesized*/ fun component2(): kotlin.Int
public final /*synthesized*/ fun copy(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.Int = ...): Sealed.Tuple
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,15 @@
sealed class Sealed(val x: Int) {
object First: Sealed(12)
open class NonFirst(x: Int, val y: Int): Sealed(x) {
object Second: NonFirst(34, 2)
object Third: NonFirst(56, 3)
}
}
fun foo(s: Sealed): Int {
return when(s) {
is Sealed.NonFirst -> 0
else -> -1
}
}
@@ -0,0 +1,46 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,14 @@
sealed class Sealed(val x: Int) {
object First: Sealed(12)
open class NonFirst(x: Int, val y: Int): Sealed(x) {
object Second: NonFirst(34, 2)
object Third: NonFirst(56, 3)
}
}
fun foo(s: Sealed): Int {
return <!NO_ELSE_IN_WHEN!>when<!>(s) {
is Sealed.NonFirst -> 0
}
}
@@ -0,0 +1,46 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,14 @@
sealed class Sealed(val x: Int) {
object First: Sealed(12)
open class NonFirst(x: Int, val y: Int): Sealed(x) {
object Second: NonFirst(34, 2)
object Third: NonFirst(56, 3)
}
}
fun foo(s: Sealed): Int {
return <!NO_ELSE_IN_WHEN!>when<!>(s) {
!is Sealed.NonFirst -> 1
}
}
@@ -0,0 +1,46 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal final override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,22 @@
sealed class Sealed(val x: Int) {
interface ITuple {
val x: Int
val y: Int
}
class Tuple(override val x: Int, override val y: Int): ITuple
object First: Sealed(12)
open class NonFirst(tuple: Tuple): Sealed(tuple.x), ITuple {
override val y: Int = tuple.y
object Second: NonFirst(Tuple(34, 2))
class Third: NonFirst(Tuple(56, 3))
}
}
fun foo(s: Sealed): Int {
return <!NO_ELSE_IN_WHEN!>when<!>(s) {
is Sealed.First -> 1
!is <!INCOMPATIBLE_TYPES!>Sealed.ITuple<!> -> 0
// else required
}
}
@@ -0,0 +1,63 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal interface ITuple {
internal abstract val x: kotlin.Int
internal abstract val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed, Sealed.ITuple {
public constructor NonFirst(/*0*/ tuple: Sealed.Tuple)
internal final override /*2*/ /*fake_override*/ val x: kotlin.Int
internal open override /*1*/ val y: kotlin.Int
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal open override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Third : Sealed.NonFirst {
public constructor Third()
internal final override /*1*/ /*fake_override*/ val x: kotlin.Int
internal open override /*1*/ /*fake_override*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
internal final class Tuple : Sealed.ITuple {
public constructor Tuple(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
internal open override /*1*/ val x: kotlin.Int
internal open override /*1*/ val y: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,15 @@
sealed class Sealed {
object First: Sealed()
open class NonFirst: Sealed() {
object Second: NonFirst()
object Third: NonFirst()
}
}
fun foo(s: Sealed): Int {
return <!NO_ELSE_IN_WHEN!>when<!>(s) {
is Sealed.First -> 1
!is Any -> 0
}
}
@@ -0,0 +1,38 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object First : Sealed {
private constructor First()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal open class NonFirst : Sealed {
public constructor NonFirst()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Second : Sealed.NonFirst {
private constructor Second()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object Third : Sealed.NonFirst {
private constructor Third()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,20 @@
sealed class Operation(val left: Int, val right: Int) {
abstract fun exec(): Int
class Plus(left: Int, right: Int): Operation(left, right) {
override fun exec(): Int = left + right
}
class Minus(left: Int, right: Int): Operation(left, right) {
override fun exec(): Int = left - right
}
class Times(left: Int, right: Int): Operation(left, right) {
override fun exec(): Int = left * right
}
class Slash(left: Int, right: Int): Operation(left, right) {
override fun exec(): Int = left / right
}
}
fun priority(op: Operation) = when(op) {
is Operation.Plus, is Operation.Minus -> 1
is Operation.Times, is Operation.Slash -> 2
}
@@ -0,0 +1,53 @@
package
internal fun priority(/*0*/ op: Operation): kotlin.Int
internal sealed class Operation {
public constructor Operation(/*0*/ left: kotlin.Int, /*1*/ right: kotlin.Int)
internal final val left: kotlin.Int
internal final val right: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal abstract fun exec(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final class Minus : Operation {
public constructor Minus(/*0*/ left: kotlin.Int, /*1*/ right: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val left: kotlin.Int
internal final override /*1*/ /*fake_override*/ val right: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal open override /*1*/ fun exec(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Plus : Operation {
public constructor Plus(/*0*/ left: kotlin.Int, /*1*/ right: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val left: kotlin.Int
internal final override /*1*/ /*fake_override*/ val right: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal open override /*1*/ fun exec(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Slash : Operation {
public constructor Slash(/*0*/ left: kotlin.Int, /*1*/ right: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val left: kotlin.Int
internal final override /*1*/ /*fake_override*/ val right: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal open override /*1*/ fun exec(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Times : Operation {
public constructor Times(/*0*/ left: kotlin.Int, /*1*/ right: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val left: kotlin.Int
internal final override /*1*/ /*fake_override*/ val right: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal open override /*1*/ fun exec(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
+13
View File
@@ -0,0 +1,13 @@
sealed class Tree {
object Empty: Tree()
class Leaf(val x: Int): Tree()
class Node(val left: Tree, val right: Tree): Tree()
fun max(): Int {
when(this) {
is Empty -> return -1
is Leaf -> return <!DEBUG_INFO_SMARTCAST!>this<!>.x
is Node -> return <!DEBUG_INFO_SMARTCAST!>this<!>.left.max()
}
}
}
+36
View File
@@ -0,0 +1,36 @@
package
internal sealed class Tree {
public constructor Tree()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final fun max(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Empty : Tree {
private constructor Empty()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun max(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Leaf : Tree {
public constructor Leaf(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun max(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Node : Tree {
public constructor Node(/*0*/ left: Tree, /*1*/ right: Tree)
internal final val left: Tree
internal final val right: Tree
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun max(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,11 @@
sealed class Tree {
object Empty: Tree()
class Leaf(val x: Int): Tree()
class Node(val left: Tree, val right: Tree): Tree()
fun max(): Int = when(this) {
is Empty -> -1
is Leaf -> <!DEBUG_INFO_SMARTCAST!>this<!>.x
is Node -> <!DEBUG_INFO_SMARTCAST!>this<!>.left.max()
}
}
@@ -0,0 +1,36 @@
package
internal sealed class Tree {
public constructor Tree()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final fun max(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Empty : Tree {
private constructor Empty()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun max(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Leaf : Tree {
public constructor Leaf(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun max(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Node : Tree {
public constructor Node(/*0*/ left: Tree, /*1*/ right: Tree)
internal final val left: Tree
internal final val right: Tree
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun max(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,23 @@
sealed class Tree {
object Empty: Tree()
class Leaf(val x: Int): Tree()
class Node(val left: Tree, val right: Tree): Tree()
fun max(): Int = when(this) {
Empty -> -1
is Leaf -> <!DEBUG_INFO_SMARTCAST!>this<!>.x
is Node -> <!DEBUG_INFO_SMARTCAST!>this<!>.left.max()
}
fun maxIsClass(): Int = <!NO_ELSE_IN_WHEN!>when<!>(this) {
Empty -> -1
<!NO_COMPANION_OBJECT!>Leaf<!> -> 0
is Node -> <!DEBUG_INFO_SMARTCAST!>this<!>.left.max()
}
fun maxWithElse(): Int = when(this) {
is Leaf -> <!DEBUG_INFO_SMARTCAST!>this<!>.x
is Node -> <!DEBUG_INFO_SMARTCAST!>this<!>.left.max()
else -> -1
}
}
@@ -0,0 +1,44 @@
package
internal sealed class Tree {
public constructor Tree()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final fun max(): kotlin.Int
internal final fun maxIsClass(): kotlin.Int
internal final fun maxWithElse(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal object Empty : Tree {
private constructor Empty()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun max(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun maxIsClass(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun maxWithElse(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Leaf : Tree {
public constructor Leaf(/*0*/ x: kotlin.Int)
internal final val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun max(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun maxIsClass(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun maxWithElse(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class Node : Tree {
public constructor Node(/*0*/ left: Tree, /*1*/ right: Tree)
internal final val left: Tree
internal final val right: Tree
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun max(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun maxIsClass(): kotlin.Int
internal final override /*1*/ /*fake_override*/ fun maxWithElse(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,11 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION
sealed class Sealed {
}
fun foo(s: Sealed): Int {
return <!NO_ELSE_IN_WHEN!>when<!>(s) {
// We do not return anything, so else branch must be here
}
}
@@ -0,0 +1,10 @@
package
internal fun foo(/*0*/ s: Sealed): kotlin.Int
internal sealed class Sealed {
public constructor Sealed()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -11439,6 +11439,60 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("ExhaustiveWhen.kt")
public void testExhaustiveWhen() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/ExhaustiveWhen.kt");
doTest(fileName);
}
@TestMetadata("ExhaustiveWhenDoubleInner.kt")
public void testExhaustiveWhenDoubleInner() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenDoubleInner.kt");
doTest(fileName);
}
@TestMetadata("ExhaustiveWhenMultipleInner.kt")
public void testExhaustiveWhenMultipleInner() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenMultipleInner.kt");
doTest(fileName);
}
@TestMetadata("ExhaustiveWhenNegated.kt")
public void testExhaustiveWhenNegated() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenNegated.kt");
doTest(fileName);
}
@TestMetadata("ExhaustiveWhenNegatedTwice.kt")
public void testExhaustiveWhenNegatedTwice() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenNegatedTwice.kt");
doTest(fileName);
}
@TestMetadata("ExhaustiveWhenOnNestedSealed.kt")
public void testExhaustiveWhenOnNestedSealed() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenOnNestedSealed.kt");
doTest(fileName);
}
@TestMetadata("ExhaustiveWhenOnNullable.kt")
public void testExhaustiveWhenOnNullable() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenOnNullable.kt");
doTest(fileName);
}
@TestMetadata("ExhaustiveWhenWithAdditionalMember.kt")
public void testExhaustiveWhenWithAdditionalMember() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenWithAdditionalMember.kt");
doTest(fileName);
}
@TestMetadata("ExhaustiveWhenWithElse.kt")
public void testExhaustiveWhenWithElse() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenWithElse.kt");
doTest(fileName);
}
@TestMetadata("Local.kt")
public void testLocal() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/Local.kt");
@@ -11487,11 +11541,65 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("NonExhaustiveWhen.kt")
public void testNonExhaustiveWhen() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhen.kt");
doTest(fileName);
}
@TestMetadata("NonExhaustiveWhenNegated.kt")
public void testNonExhaustiveWhenNegated() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenNegated.kt");
doTest(fileName);
}
@TestMetadata("NonExhaustiveWhenWithAdditionalCase.kt")
public void testNonExhaustiveWhenWithAdditionalCase() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAdditionalCase.kt");
doTest(fileName);
}
@TestMetadata("NonExhaustiveWhenWithAnyCase.kt")
public void testNonExhaustiveWhenWithAnyCase() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.kt");
doTest(fileName);
}
@TestMetadata("OperationWhen.kt")
public void testOperationWhen() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/OperationWhen.kt");
doTest(fileName);
}
@TestMetadata("RedundantAbstract.kt")
public void testRedundantAbstract() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/RedundantAbstract.kt");
doTest(fileName);
}
@TestMetadata("TreeWhen.kt")
public void testTreeWhen() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/TreeWhen.kt");
doTest(fileName);
}
@TestMetadata("TreeWhenFunctional.kt")
public void testTreeWhenFunctional() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/TreeWhenFunctional.kt");
doTest(fileName);
}
@TestMetadata("TreeWhenFunctionalNoIs.kt")
public void testTreeWhenFunctionalNoIs() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/TreeWhenFunctionalNoIs.kt");
doTest(fileName);
}
@TestMetadata("WhenOnEmptySealed.kt")
public void testWhenOnEmptySealed() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/WhenOnEmptySealed.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/diagnostics/tests/secondaryConstructors")
@@ -234,21 +234,35 @@ public class DescriptorUtils {
return false;
}
public static boolean isDirectSubclass(@NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) {
for (JetType superType : subClass.getTypeConstructor().getSupertypes()) {
if (isSameClass(superType, superClass.getOriginal())) {
return true;
}
}
return false;
}
public static boolean isSubclass(@NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) {
return isSubtypeOfClass(subClass.getDefaultType(), superClass.getOriginal());
}
private static boolean isSubtypeOfClass(@NotNull JetType type, @NotNull DeclarationDescriptor superClass) {
private static boolean isSameClass(@NotNull JetType type, @NotNull DeclarationDescriptor other) {
DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor != null) {
DeclarationDescriptor originalDescriptor = descriptor.getOriginal();
if (originalDescriptor instanceof ClassifierDescriptor
&& superClass instanceof ClassifierDescriptor
&& ((ClassifierDescriptor) superClass).getTypeConstructor().equals(((ClassifierDescriptor) originalDescriptor).getTypeConstructor())) {
&& other instanceof ClassifierDescriptor
&& ((ClassifierDescriptor) other).getTypeConstructor().equals(
((ClassifierDescriptor) originalDescriptor).getTypeConstructor())) {
return true;
}
}
return false;
}
private static boolean isSubtypeOfClass(@NotNull JetType type, @NotNull DeclarationDescriptor superClass) {
if (isSameClass(type, superClass)) return true;
for (JetType superType : type.getConstructor().getSupertypes()) {
if (isSubtypeOfClass(superType, superClass)) {
return true;
@@ -446,7 +460,9 @@ public class DescriptorUtils {
}
public static boolean classCanHaveAbstractMembers(@NotNull ClassDescriptor classDescriptor) {
return classDescriptor.getModality() == Modality.ABSTRACT || classDescriptor.getKind() == ClassKind.ENUM_CLASS;
return classDescriptor.getModality() == Modality.ABSTRACT
|| classDescriptor.getModality() == Modality.SEALED
|| classDescriptor.getKind() == ClassKind.ENUM_CLASS;
}
public static boolean classCanHaveOpenMembers(@NotNull ClassDescriptor classDescriptor) {