[FE 1.0] Fix reporting of UNINITIALIZED_ENUM_ENTRY on qualified enums

^KT-41124
^KT-50758 Fixed
This commit is contained in:
Dmitriy Novozhilov
2022-01-12 17:03:30 +03:00
committed by teamcity
parent 50f6825775
commit bb6c6dc45d
9 changed files with 254 additions and 1 deletions
@@ -5859,6 +5859,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt");
}
@Test
@TestMetadata("uninitializedQualifiedEnumEntry.kt")
public void testUninitializedQualifiedEnumEntry() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedQualifiedEnumEntry.kt");
}
@Test
@TestMetadata("unmappedArgs.kt")
public void testUnmappedArgs() throws Exception {
@@ -5859,6 +5859,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt");
}
@Test
@TestMetadata("uninitializedQualifiedEnumEntry.kt")
public void testUninitializedQualifiedEnumEntry() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedQualifiedEnumEntry.kt");
}
@Test
@TestMetadata("unmappedArgs.kt")
public void testUnmappedArgs() throws Exception {
@@ -5859,6 +5859,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt");
}
@Test
@TestMetadata("uninitializedQualifiedEnumEntry.kt")
public void testUninitializedQualifiedEnumEntry() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedQualifiedEnumEntry.kt");
}
@Test
@TestMetadata("unmappedArgs.kt")
public void testUnmappedArgs() throws Exception {
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.AccessTarget
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.InstructionWithValue
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitQualifiedAccessToUninitializedEnumEntry
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
import org.jetbrains.kotlin.contracts.description.canBeRevisited
@@ -283,7 +284,12 @@ class ControlFlowProcessor(
generateCall(resolvedCall.variableCall)
} else {
if (resolvedCall == null) {
val qualifier = trace.bindingContext[BindingContext.QUALIFIER, expression]
val qualifierExpression =
when (languageVersionSettings.supportsFeature(ProhibitQualifiedAccessToUninitializedEnumEntry)) {
true -> expression.getTopmostParentQualifiedExpressionForSelector() ?: expression
false -> expression
}
val qualifier = trace.bindingContext[BindingContext.QUALIFIER, qualifierExpression]
if (qualifier != null && generateQualifier(expression, qualifier)) return
}
if (!generateCall(expression) && expression.parent !is KtCallExpression) {
@@ -0,0 +1,55 @@
// LANGUAGE: +ProhibitQualifiedAccessToUninitializedEnumEntry
// ISSUE: KT-41124
enum class SomeEnum11(var x: Int) {
A(1),
B(2);
init {
A.x = 10 // Error
}
}
enum class SomeEnum12(var x: Int) {
A(1),
B(2);
init {
SomeEnum12.A.x = 10 // Error
}
}
enum class SomeEnum21(var x: Int) {
A(1) {
init {
A.x = 10 // OK
SomeEnum21.A.x = 10 // OK
B.x = 10 // Error
}
},
B(2)
}
enum class SomeEnum22(var x: Int) {
A(1) {
init {
A.x = 10 // OK
SomeEnum22.A.x = 10 // OK
SomeEnum22.B.x = 10 // Migration error
}
},
B(2)
}
enum class SomeEnum3(var x: Int) {
A(1),
B(2) {
init {
A.x = 10 // OK
SomeEnum3.A.x = 10 // OK
B.x = 10 // OK
SomeEnum3.B.x = 10 // OK
}
};
}
@@ -0,0 +1,55 @@
// LANGUAGE: +ProhibitQualifiedAccessToUninitializedEnumEntry
// ISSUE: KT-41124
enum class SomeEnum11(var x: Int) {
A(1),
B(2);
init {
<!UNINITIALIZED_ENUM_ENTRY!>A<!>.x = 10 // Error
}
}
enum class SomeEnum12(var x: Int) {
A(1),
B(2);
init {
SomeEnum12.<!UNINITIALIZED_ENUM_ENTRY!>A<!>.x = 10 // Error
}
}
enum class SomeEnum21(var x: Int) {
A(1) {
init {
A.x = 10 // OK
SomeEnum21.A.x = 10 // OK
<!UNINITIALIZED_ENUM_ENTRY!>B<!>.x = 10 // Error
}
},
B(2)
}
enum class SomeEnum22(var x: Int) {
A(1) {
init {
A.x = 10 // OK
SomeEnum22.A.x = 10 // OK
SomeEnum22.<!UNINITIALIZED_ENUM_ENTRY!>B<!>.x = 10 // Migration error
}
},
B(2)
}
enum class SomeEnum3(var x: Int) {
A(1),
B(2) {
init {
A.x = 10 // OK
SomeEnum3.A.x = 10 // OK
B.x = 10 // OK
SomeEnum3.B.x = 10 // OK
}
};
}
@@ -0,0 +1,112 @@
package
public final enum class SomeEnum11 : kotlin.Enum<SomeEnum11> {
enum entry A
enum entry B
private constructor SomeEnum11(/*0*/ x: kotlin.Int)
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
public final var x: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum11): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<SomeEnum11!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum11
public final /*synthesized*/ fun values(): kotlin.Array<SomeEnum11>
}
public final enum class SomeEnum12 : kotlin.Enum<SomeEnum12> {
enum entry A
enum entry B
private constructor SomeEnum12(/*0*/ x: kotlin.Int)
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
public final var x: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum12): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<SomeEnum12!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum12
public final /*synthesized*/ fun values(): kotlin.Array<SomeEnum12>
}
public final enum class SomeEnum21 : kotlin.Enum<SomeEnum21> {
enum entry A
enum entry B
private constructor SomeEnum21(/*0*/ x: kotlin.Int)
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
public final var x: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum21): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<SomeEnum21!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum21
public final /*synthesized*/ fun values(): kotlin.Array<SomeEnum21>
}
public final enum class SomeEnum22 : kotlin.Enum<SomeEnum22> {
enum entry A
enum entry B
private constructor SomeEnum22(/*0*/ x: kotlin.Int)
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
public final var x: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum22): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<SomeEnum22!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum22
public final /*synthesized*/ fun values(): kotlin.Array<SomeEnum22>
}
public final enum class SomeEnum3 : kotlin.Enum<SomeEnum3> {
enum entry A
enum entry B
private constructor SomeEnum3(/*0*/ x: kotlin.Int)
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
public final var x: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum3): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<SomeEnum3!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum3
public final /*synthesized*/ fun values(): kotlin.Array<SomeEnum3>
}
@@ -5865,6 +5865,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt");
}
@Test
@TestMetadata("uninitializedQualifiedEnumEntry.kt")
public void testUninitializedQualifiedEnumEntry() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedQualifiedEnumEntry.kt");
}
@Test
@TestMetadata("unmappedArgs.kt")
public void testUnmappedArgs() throws Exception {
@@ -244,6 +244,7 @@ enum class LanguageFeature(
QualifiedSupertypeMayBeExtendedByOtherSupertype(KOTLIN_1_7),
YieldIsNoMoreReserved(KOTLIN_1_7),
NoDeprecationOnDeprecatedEnumEntries(KOTLIN_1_7), // KT-37975
ProhibitQualifiedAccessToUninitializedEnumEntry(KOTLIN_1_7, kind = BUG_FIX), // KT-41124
// 1.8