"is" over enum entry is now an error + new tests + test fixes
This commit is contained in:
@@ -600,6 +600,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory0<JetBinaryExpressionWithTypeRHS> USELESS_CAST = DiagnosticFactory0.create(WARNING, AS_TYPE);
|
DiagnosticFactory0<JetBinaryExpressionWithTypeRHS> USELESS_CAST = DiagnosticFactory0.create(WARNING, AS_TYPE);
|
||||||
DiagnosticFactory0<JetSimpleNameExpression> CAST_NEVER_SUCCEEDS = DiagnosticFactory0.create(WARNING);
|
DiagnosticFactory0<JetSimpleNameExpression> CAST_NEVER_SUCCEEDS = DiagnosticFactory0.create(WARNING);
|
||||||
DiagnosticFactory0<JetTypeReference> DYNAMIC_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<JetTypeReference> DYNAMIC_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
|
||||||
|
DiagnosticFactory0<JetTypeReference> IS_ENUM_ENTRY = DiagnosticFactory0.create(ERROR);
|
||||||
|
|
||||||
DiagnosticFactory1<JetExpression, JetType> IMPLICIT_CAST_TO_UNIT_OR_ANY = DiagnosticFactory1.create(WARNING);
|
DiagnosticFactory1<JetExpression, JetType> IMPLICIT_CAST_TO_UNIT_OR_ANY = DiagnosticFactory1.create(WARNING);
|
||||||
|
|
||||||
|
|||||||
+1
@@ -337,6 +337,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(USELESS_CAST, "No cast needed");
|
MAP.put(USELESS_CAST, "No cast needed");
|
||||||
MAP.put(CAST_NEVER_SUCCEEDS, "This cast can never succeed");
|
MAP.put(CAST_NEVER_SUCCEEDS, "This cast can never succeed");
|
||||||
MAP.put(DYNAMIC_NOT_ALLOWED, "Dynamic types are not allowed in this position");
|
MAP.put(DYNAMIC_NOT_ALLOWED, "Dynamic types are not allowed in this position");
|
||||||
|
MAP.put(IS_ENUM_ENTRY, "'is' over enum entry is not allowed, use comparison instead");
|
||||||
MAP.put(USELESS_NULLABLE_CHECK, "Non-null type is checked for instance of nullable type");
|
MAP.put(USELESS_NULLABLE_CHECK, "Non-null type is checked for instance of nullable type");
|
||||||
MAP.put(WRONG_SETTER_PARAMETER_TYPE, "Setter parameter type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
|
MAP.put(WRONG_SETTER_PARAMETER_TYPE, "Setter parameter type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
|
||||||
MAP.put(WRONG_GETTER_RETURN_TYPE, "Getter return type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
|
MAP.put(WRONG_GETTER_RETURN_TYPE, "Getter return type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE);
|
||||||
|
|||||||
+6
@@ -22,9 +22,11 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.cfg.WhenChecker;
|
import org.jetbrains.kotlin.cfg.WhenChecker;
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.PossiblyBareType;
|
import org.jetbrains.kotlin.resolve.PossiblyBareType;
|
||||||
import org.jetbrains.kotlin.resolve.TypeResolutionContext;
|
import org.jetbrains.kotlin.resolve.TypeResolutionContext;
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||||
@@ -311,6 +313,10 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
if (TypesPackage.isDynamic(targetType)) {
|
if (TypesPackage.isDynamic(targetType)) {
|
||||||
context.trace.report(DYNAMIC_NOT_ALLOWED.on(typeReferenceAfterIs));
|
context.trace.report(DYNAMIC_NOT_ALLOWED.on(typeReferenceAfterIs));
|
||||||
}
|
}
|
||||||
|
ClassDescriptor targetDescriptor = TypeUtils.getClassDescriptor(targetType);
|
||||||
|
if (targetDescriptor != null && DescriptorUtils.isEnumEntry(targetDescriptor)) {
|
||||||
|
context.trace.report(IS_ENUM_ENTRY.on(typeReferenceAfterIs));
|
||||||
|
}
|
||||||
|
|
||||||
if (!subjectType.isMarkedNullable() && targetType.isMarkedNullable()) {
|
if (!subjectType.isMarkedNullable() && targetType.isMarkedNullable()) {
|
||||||
JetTypeElement element = typeReferenceAfterIs.getTypeElement();
|
JetTypeElement element = typeReferenceAfterIs.getTypeElement();
|
||||||
|
|||||||
+7
-7
@@ -29,13 +29,13 @@ class TestLocal(val name: String, val executionType: ExecutionType) : Callable<S
|
|||||||
override fun call(): String {
|
override fun call(): String {
|
||||||
startSignal.await()
|
startSignal.await()
|
||||||
return when (executionType) {
|
return when (executionType) {
|
||||||
is ExecutionType.LOCAL -> local()
|
ExecutionType.LOCAL -> local()
|
||||||
is ExecutionType.NON_LOCAL_SIMPLE -> nonLocalSimple()
|
ExecutionType.NON_LOCAL_SIMPLE -> nonLocalSimple()
|
||||||
is ExecutionType.NON_LOCAL_EXCEPTION -> nonLocalWithException()
|
ExecutionType.NON_LOCAL_EXCEPTION -> nonLocalWithException()
|
||||||
is ExecutionType.NON_LOCAL_FINALLY -> nonLocalWithFinally()
|
ExecutionType.NON_LOCAL_FINALLY -> nonLocalWithFinally()
|
||||||
is ExecutionType.NON_LOCAL_EXCEPTION_AND_FINALLY -> nonLocalWithExceptionAndFinally()
|
ExecutionType.NON_LOCAL_EXCEPTION_AND_FINALLY -> nonLocalWithExceptionAndFinally()
|
||||||
is ExecutionType.NON_LOCAL_EXCEPTION_AND_FINALLY_WITH_RETURN -> nonLocalWithExceptionAndFinallyWithReturn()
|
ExecutionType.NON_LOCAL_EXCEPTION_AND_FINALLY_WITH_RETURN -> nonLocalWithExceptionAndFinallyWithReturn()
|
||||||
is ExecutionType.NON_LOCAL_NESTED -> nonLocalNested()
|
ExecutionType.NON_LOCAL_NESTED -> nonLocalNested()
|
||||||
else -> "fail"
|
else -> "fail"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
enum class MyEnum {
|
||||||
|
FIRST,
|
||||||
|
SECOND
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(me: MyEnum): Boolean = if (me is <!IS_ENUM_ENTRY!>MyEnum.FIRST<!>) true else false
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal fun foo(/*0*/ me: MyEnum): kotlin.Boolean
|
||||||
|
|
||||||
|
internal final enum class MyEnum : kotlin.Enum<MyEnum> {
|
||||||
|
public enum entry FIRST : MyEnum {
|
||||||
|
private constructor FIRST()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum entry SECOND : MyEnum {
|
||||||
|
private constructor SECOND()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor MyEnum()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): MyEnum
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<MyEnum>
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
enum class MyEnum {
|
||||||
|
FIRST,
|
||||||
|
SECOND
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(me: MyEnum): Boolean = me is <!IS_ENUM_ENTRY!>MyEnum.FIRST<!>
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal fun foo(/*0*/ me: MyEnum): kotlin.Boolean
|
||||||
|
|
||||||
|
internal final enum class MyEnum : kotlin.Enum<MyEnum> {
|
||||||
|
public enum entry FIRST : MyEnum {
|
||||||
|
private constructor FIRST()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum entry SECOND : MyEnum {
|
||||||
|
private constructor SECOND()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor MyEnum()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): MyEnum
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<MyEnum>
|
||||||
|
}
|
||||||
@@ -4,8 +4,8 @@ enum class MyEnum {
|
|||||||
|
|
||||||
fun foo(x: MyEnum): Int {
|
fun foo(x: MyEnum): Int {
|
||||||
return when (x) {
|
return when (x) {
|
||||||
is MyEnum.A -> 1
|
is <!IS_ENUM_ENTRY!>MyEnum.A<!> -> 1
|
||||||
is MyEnum.B -> 2
|
is <!IS_ENUM_ENTRY!>MyEnum.B<!> -> 2
|
||||||
is MyEnum.C -> 3
|
is <!IS_ENUM_ENTRY!>MyEnum.C<!> -> 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ enum class MyEnum {
|
|||||||
fun foo(x: MyEnum): Int {
|
fun foo(x: MyEnum): Int {
|
||||||
return when (x) {
|
return when (x) {
|
||||||
MyEnum.A -> 1
|
MyEnum.A -> 1
|
||||||
is MyEnum.B -> 2
|
is <!IS_ENUM_ENTRY!>MyEnum.B<!> -> 2
|
||||||
is MyEnum.C -> 3
|
is <!IS_ENUM_ENTRY!>MyEnum.C<!> -> 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4965,6 +4965,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ifEnumEntry.kt")
|
||||||
|
public void testIfEnumEntry() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/ifEnumEntry.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("importEnumFromJava.kt")
|
@TestMetadata("importEnumFromJava.kt")
|
||||||
public void testImportEnumFromJava() throws Exception {
|
public void testImportEnumFromJava() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/importEnumFromJava.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/importEnumFromJava.kt");
|
||||||
@@ -4995,6 +5001,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("isEnumEntry.kt")
|
||||||
|
public void testIsEnumEntry() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/isEnumEntry.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("javaEnumValueOfMethod.kt")
|
@TestMetadata("javaEnumValueOfMethod.kt")
|
||||||
public void testJavaEnumValueOfMethod() throws Exception {
|
public void testJavaEnumValueOfMethod() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/javaEnumValueOfMethod.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/javaEnumValueOfMethod.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user