[FE 1.0] Prohibit access to members of companion of enum from enum entry initializer
^KT-49461 Fixed ^KT-49110
This commit is contained in:
committed by
TeamCityServer
parent
4f0c3c3c0d
commit
58889a2b5c
+9
-1
@@ -407,7 +407,15 @@ class ControlFlowInformationProviderImpl private constructor(
|
|||||||
report(Errors.UNINITIALIZED_ENUM_ENTRY.on(element, classDescriptor), ctxt)
|
report(Errors.UNINITIALIZED_ENUM_ENTRY.on(element, classDescriptor), ctxt)
|
||||||
ClassKind.OBJECT -> if (classDescriptor.isCompanionObject) {
|
ClassKind.OBJECT -> if (classDescriptor.isCompanionObject) {
|
||||||
val container = classDescriptor.containingDeclaration
|
val container = classDescriptor.containingDeclaration
|
||||||
if (container is ClassDescriptor && container.kind == ClassKind.ENUM_CLASS) {
|
/*
|
||||||
|
* ProhibitAccessToEnumCompanionMembersInEnumConstructorCall feature enabled then UNINITIALIZED_ENUM_COMPANION
|
||||||
|
* will be reported from EnumCompanionInEnumConstructorCallChecker
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
container is ClassDescriptor &&
|
||||||
|
container.kind == ClassKind.ENUM_CLASS &&
|
||||||
|
!languageVersionSettings.supportsFeature(LanguageFeature.ProhibitAccessToEnumCompanionMembersInEnumConstructorCall)
|
||||||
|
) {
|
||||||
report(Errors.UNINITIALIZED_ENUM_COMPANION.on(element, container), ctxt)
|
report(Errors.UNINITIALIZED_ENUM_COMPANION.on(element, container), ctxt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -964,7 +964,8 @@ public interface Errors {
|
|||||||
DiagnosticFactory1<KtSimpleNameExpression, VariableDescriptor> UNINITIALIZED_VARIABLE = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<KtSimpleNameExpression, VariableDescriptor> UNINITIALIZED_VARIABLE = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<KtSimpleNameExpression, ValueParameterDescriptor> UNINITIALIZED_PARAMETER = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<KtSimpleNameExpression, ValueParameterDescriptor> UNINITIALIZED_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<KtSimpleNameExpression, ClassDescriptor> UNINITIALIZED_ENUM_ENTRY = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<KtSimpleNameExpression, ClassDescriptor> UNINITIALIZED_ENUM_ENTRY = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<KtSimpleNameExpression, ClassDescriptor> UNINITIALIZED_ENUM_COMPANION = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<KtExpression, ClassDescriptor> UNINITIALIZED_ENUM_COMPANION = DiagnosticFactory1.create(ERROR);
|
||||||
|
DiagnosticFactory1<KtExpression, ClassDescriptor> UNINITIALIZED_ENUM_COMPANION_WARNING = DiagnosticFactory1.create(WARNING);
|
||||||
|
|
||||||
DiagnosticFactory1<KtNamedDeclaration, VariableDescriptor> UNUSED_VARIABLE = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
|
DiagnosticFactory1<KtNamedDeclaration, VariableDescriptor> UNUSED_VARIABLE = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
|
||||||
DiagnosticFactory1<KtParameter, VariableDescriptor> UNUSED_PARAMETER = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
|
DiagnosticFactory1<KtParameter, VariableDescriptor> UNUSED_PARAMETER = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
|
||||||
|
|||||||
+1
@@ -346,6 +346,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(UNINITIALIZED_PARAMETER, "Parameter ''{0}'' is uninitialized here", NAME);
|
MAP.put(UNINITIALIZED_PARAMETER, "Parameter ''{0}'' is uninitialized here", NAME);
|
||||||
MAP.put(UNINITIALIZED_ENUM_ENTRY, "Enum entry ''{0}'' is uninitialized here", NAME);
|
MAP.put(UNINITIALIZED_ENUM_ENTRY, "Enum entry ''{0}'' is uninitialized here", NAME);
|
||||||
MAP.put(UNINITIALIZED_ENUM_COMPANION, "Companion object of enum class ''{0}'' is uninitialized here", NAME);
|
MAP.put(UNINITIALIZED_ENUM_COMPANION, "Companion object of enum class ''{0}'' is uninitialized here", NAME);
|
||||||
|
MAP.put(UNINITIALIZED_ENUM_COMPANION_WARNING, "Companion object of enum class ''{0}'' is uninitialized here. This warning will became error in future releases", NAME);
|
||||||
MAP.put(UNUSED_VARIABLE, "Variable ''{0}'' is never used", NAME);
|
MAP.put(UNUSED_VARIABLE, "Variable ''{0}'' is never used", NAME);
|
||||||
MAP.put(UNUSED_PARAMETER, "Parameter ''{0}'' is never used", NAME);
|
MAP.put(UNUSED_PARAMETER, "Parameter ''{0}'' is never used", NAME);
|
||||||
MAP.put(UNUSED_ANONYMOUS_PARAMETER, "Parameter ''{0}'' is never used, could be renamed to _", NAME);
|
MAP.put(UNUSED_ANONYMOUS_PARAMETER, "Parameter ''{0}'' is never used, could be renamed to _", NAME);
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
|||||||
SealedInheritorInSameModuleChecker,
|
SealedInheritorInSameModuleChecker,
|
||||||
SealedInterfaceAllowedChecker,
|
SealedInterfaceAllowedChecker,
|
||||||
SuspendFunctionAsSupertypeChecker,
|
SuspendFunctionAsSupertypeChecker,
|
||||||
|
EnumCompanionInEnumConstructorCallChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val DEFAULT_CALL_CHECKERS = listOf(
|
private val DEFAULT_CALL_CHECKERS = listOf(
|
||||||
|
|||||||
+109
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.resolve.checkers
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassValueReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
|
|
||||||
|
object EnumCompanionInEnumConstructorCallChecker : DeclarationChecker {
|
||||||
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
|
if (declaration !is KtEnumEntry || descriptor !is ClassDescriptor) return
|
||||||
|
if (descriptor.kind != ClassKind.ENUM_ENTRY) return
|
||||||
|
val enumDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return
|
||||||
|
val enumCompanion = enumDescriptor.companionObjectDescriptor ?: return
|
||||||
|
val initializer = declaration.initializerList?.initializers?.firstIsInstanceOrNull<KtSuperTypeCallEntry>() ?: return
|
||||||
|
val bindingTrace = context.trace
|
||||||
|
val visitor = Visitor(
|
||||||
|
enumDescriptor,
|
||||||
|
enumCompanion,
|
||||||
|
bindingTrace.bindingContext,
|
||||||
|
bindingTrace,
|
||||||
|
reportError = context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitAccessToEnumCompanionMembersInEnumConstructorCall)
|
||||||
|
)
|
||||||
|
initializer.acceptChildren(visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Visitor(
|
||||||
|
val enumDescriptor: ClassDescriptor,
|
||||||
|
val companionDescriptor: ClassDescriptor,
|
||||||
|
val context: BindingContext,
|
||||||
|
val reporter: DiagnosticSink,
|
||||||
|
val reportError: Boolean
|
||||||
|
) : KtVisitorVoid() {
|
||||||
|
override fun visitElement(element: PsiElement) {
|
||||||
|
element.acceptChildren(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitExpression(expression: KtExpression) {
|
||||||
|
val needAnalyzeReceiver = analyzeExpression(expression)
|
||||||
|
if (needAnalyzeReceiver) {
|
||||||
|
expression.acceptChildren(this)
|
||||||
|
} else if (expression is KtCallExpression) {
|
||||||
|
expression.valueArgumentList?.acceptChildren(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun analyzeExpression(expression: KtExpression): Boolean {
|
||||||
|
if (expression.parent is KtCallExpression) return true
|
||||||
|
val resolvedCall = expression.getResolvedCall(context) ?: return true
|
||||||
|
|
||||||
|
val dispatchDescriptor = resolvedCall.dispatchReceiver.resolvedDescriptor
|
||||||
|
val extensionDescriptor = resolvedCall.extensionReceiver.resolvedDescriptor
|
||||||
|
val dispatchIsCompanion = dispatchDescriptor == companionDescriptor
|
||||||
|
val extensionIsCompanion = extensionDescriptor == companionDescriptor
|
||||||
|
|
||||||
|
val dispatchIsImplicit = resolvedCall.dispatchReceiver is ImplicitClassReceiver
|
||||||
|
val extensionIsImplicit = resolvedCall.extensionReceiver is ImplicitClassReceiver
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ControlFlowInformationProviderImpl already reports UNINITIALIZED_ENUM_COMPANION for extension function calls
|
||||||
|
* with implicit companion receiver, so we should skip reporting a warning
|
||||||
|
*
|
||||||
|
* If feature is enabled then ControlFlowInformationProviderImpl won't report an error, to keep all checks
|
||||||
|
* in one place (in this checker)
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
!reportError &&
|
||||||
|
expression is KtCallExpression &&
|
||||||
|
(dispatchIsCompanion && dispatchIsImplicit || extensionIsCompanion && extensionIsImplicit)
|
||||||
|
) return false
|
||||||
|
|
||||||
|
if (dispatchIsCompanion || extensionIsCompanion) {
|
||||||
|
val reportOn = when (val receiverExpression = (expression as? KtQualifiedExpression)?.receiverExpression) {
|
||||||
|
is KtSimpleNameExpression -> receiverExpression
|
||||||
|
is KtQualifiedExpression -> receiverExpression.selectorExpression
|
||||||
|
else -> null
|
||||||
|
} ?: expression
|
||||||
|
val factory = if (reportError) {
|
||||||
|
Errors.UNINITIALIZED_ENUM_COMPANION
|
||||||
|
} else {
|
||||||
|
Errors.UNINITIALIZED_ENUM_COMPANION_WARNING
|
||||||
|
}
|
||||||
|
reporter.report(factory.on(reportOn, enumDescriptor))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val ReceiverValue?.resolvedDescriptor: DeclarationDescriptor?
|
||||||
|
get() {
|
||||||
|
if (this !is ClassValueReceiver && this !is ImplicitClassReceiver) return null
|
||||||
|
return this.type.unwrap().constructor.declarationDescriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
// SKIP_TXT
|
// SKIP_TXT
|
||||||
|
|
||||||
enum class A(val z: Any) {
|
enum class A(val z: Any) {
|
||||||
Y(<!UNINITIALIZED_VARIABLE!>x<!>);
|
Y(<!UNINITIALIZED_ENUM_COMPANION_WARNING, UNINITIALIZED_VARIABLE!>x<!>);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val x = A.Y.ordinal
|
val x = A.Y.ordinal
|
||||||
@@ -9,7 +9,7 @@ enum class A(val z: Any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class B(val z: Any) {
|
enum class B(val z: Any) {
|
||||||
Y(B.x);
|
Y(<!UNINITIALIZED_ENUM_COMPANION_WARNING!>B<!>.x);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val x = B.Y.ordinal
|
val x = B.Y.ordinal
|
||||||
|
|||||||
+2
-2
@@ -9,7 +9,7 @@ enum class B(val x: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class C(val x: Int) {
|
enum class C(val x: Int) {
|
||||||
C1(<!UNINITIALIZED_VARIABLE!>SUM<!>),
|
C1(<!UNINITIALIZED_ENUM_COMPANION_WARNING, UNINITIALIZED_VARIABLE!>SUM<!>),
|
||||||
C2(1);
|
C2(1);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -32,7 +32,7 @@ enum class Fruit(personal: Int) {
|
|||||||
|
|
||||||
// Another example from KT-11769
|
// Another example from KT-11769
|
||||||
enum class EnumCompanion1(val x: Int) {
|
enum class EnumCompanion1(val x: Int) {
|
||||||
INSTANCE(<!UNINITIALIZED_ENUM_COMPANION!>Companion<!>.foo()),
|
INSTANCE(<!UNINITIALIZED_ENUM_COMPANION, UNINITIALIZED_ENUM_COMPANION_WARNING!>Companion<!>.foo()),
|
||||||
ANOTHER(foo());
|
ANOTHER(foo());
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
Vendored
+40
@@ -0,0 +1,40 @@
|
|||||||
|
// LANGUAGE: +ProhibitAccessToEnumCompanionMembersInEnumConstructorCall
|
||||||
|
// FIR_IDENTICAL
|
||||||
|
// ISSUE: KT-49110
|
||||||
|
|
||||||
|
enum class SomeEnum(val x: Int) {
|
||||||
|
A(<!UNINITIALIZED_ENUM_COMPANION!>companionFun()<!>.length),// UNINITIALIZED_ENUM_COMPANION
|
||||||
|
B(<!UNINITIALIZED_ENUM_COMPANION, UNINITIALIZED_VARIABLE!>companionProp<!>.length), // UNINITIALIZED_VARIABLE
|
||||||
|
|
||||||
|
C(<!UNINITIALIZED_ENUM_COMPANION!>SomeEnum<!>.companionFun().length),
|
||||||
|
D(<!UNINITIALIZED_ENUM_COMPANION!>SomeEnum<!>.companionProp.length),
|
||||||
|
|
||||||
|
E(SomeEnum.<!UNINITIALIZED_ENUM_COMPANION!>Companion<!>.companionFun().length),
|
||||||
|
F(SomeEnum.<!UNINITIALIZED_ENUM_COMPANION!>Companion<!>.<!UNINITIALIZED_VARIABLE!>companionProp<!>.length); // UNINITIALIZED_VARIABLE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val companionProp = "someString"
|
||||||
|
fun companionFun(): String = "someString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class OtherEnum(val x: Int) {
|
||||||
|
G(<!UNINITIALIZED_ENUM_COMPANION!>extensionFun()<!>.length), // UNINITIALIZED_ENUM_COMPANION
|
||||||
|
H(<!UNINITIALIZED_ENUM_COMPANION!>extensionProp<!>.length),
|
||||||
|
|
||||||
|
I(<!UNINITIALIZED_ENUM_COMPANION!>OtherEnum<!>.extensionFun().length),
|
||||||
|
J(<!UNINITIALIZED_ENUM_COMPANION!>OtherEnum<!>.extensionProp.length),
|
||||||
|
|
||||||
|
K(OtherEnum.<!UNINITIALIZED_ENUM_COMPANION!>Companion<!>.extensionFun().length),
|
||||||
|
L(OtherEnum.<!UNINITIALIZED_ENUM_COMPANION!>Companion<!>.extensionProp.length);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val companionProp = "someString"
|
||||||
|
fun companionFun(): String = "someString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun OtherEnum.Companion.extensionFun(): String = companionFun()
|
||||||
|
val OtherEnum.Companion.extensionProp: String
|
||||||
|
get() = companionProp
|
||||||
|
|
||||||
Vendored
+82
@@ -0,0 +1,82 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val OtherEnum.Companion.extensionProp: kotlin.String
|
||||||
|
public fun OtherEnum.Companion.extensionFun(): kotlin.String
|
||||||
|
|
||||||
|
public final enum class OtherEnum : kotlin.Enum<OtherEnum> {
|
||||||
|
enum entry G
|
||||||
|
|
||||||
|
enum entry H
|
||||||
|
|
||||||
|
enum entry I
|
||||||
|
|
||||||
|
enum entry J
|
||||||
|
|
||||||
|
enum entry K
|
||||||
|
|
||||||
|
enum entry L
|
||||||
|
|
||||||
|
private constructor OtherEnum(/*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 val x: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: OtherEnum): 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<OtherEnum!>!
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
public final val companionProp: kotlin.String = "someString"
|
||||||
|
public final fun companionFun(): kotlin.String
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): OtherEnum
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<OtherEnum>
|
||||||
|
}
|
||||||
|
|
||||||
|
public final enum class SomeEnum : kotlin.Enum<SomeEnum> {
|
||||||
|
enum entry A
|
||||||
|
|
||||||
|
enum entry B
|
||||||
|
|
||||||
|
enum entry C
|
||||||
|
|
||||||
|
enum entry D
|
||||||
|
|
||||||
|
enum entry E
|
||||||
|
|
||||||
|
enum entry F
|
||||||
|
|
||||||
|
private constructor SomeEnum(/*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 val x: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum): 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<SomeEnum!>!
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
public final val companionProp: kotlin.String = "someString"
|
||||||
|
public final fun companionFun(): kotlin.String
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<SomeEnum>
|
||||||
|
}
|
||||||
Vendored
+39
@@ -0,0 +1,39 @@
|
|||||||
|
// LANGUAGE: -ProhibitAccessToEnumCompanionMembersInEnumConstructorCall
|
||||||
|
// ISSUE: KT-49110
|
||||||
|
|
||||||
|
enum class SomeEnum(val x: Int) {
|
||||||
|
A(<!UNINITIALIZED_ENUM_COMPANION!>companionFun<!>().length),// UNINITIALIZED_ENUM_COMPANION
|
||||||
|
B(<!UNINITIALIZED_VARIABLE!>companionProp<!>.length), // UNINITIALIZED_VARIABLE
|
||||||
|
|
||||||
|
C(SomeEnum.<!UNINITIALIZED_ENUM_COMPANION!>companionFun<!>().length),
|
||||||
|
D(<!UNINITIALIZED_VARIABLE!>SomeEnum.companionProp<!>.length),
|
||||||
|
|
||||||
|
E(SomeEnum.<!UNINITIALIZED_ENUM_COMPANION!>Companion<!>.companionFun().length),
|
||||||
|
F(<!UNINITIALIZED_VARIABLE!>SomeEnum.Companion.companionProp<!>.length); // UNINITIALIZED_VARIABLE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val companionProp = "someString"
|
||||||
|
fun companionFun(): String = "someString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class OtherEnum(val x: Int) {
|
||||||
|
G(extensionFun().length), // UNINITIALIZED_ENUM_COMPANION
|
||||||
|
H(extensionProp.length),
|
||||||
|
|
||||||
|
I(OtherEnum.extensionFun().length),
|
||||||
|
J(OtherEnum.extensionProp.length),
|
||||||
|
|
||||||
|
K(OtherEnum.Companion.extensionFun().length),
|
||||||
|
L(OtherEnum.Companion.extensionProp.length);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val companionProp = "someString"
|
||||||
|
fun companionFun(): String = "someString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun OtherEnum.Companion.extensionFun(): String = companionFun()
|
||||||
|
val OtherEnum.Companion.extensionProp: String
|
||||||
|
get() = companionProp
|
||||||
|
|
||||||
Vendored
+39
@@ -0,0 +1,39 @@
|
|||||||
|
// LANGUAGE: -ProhibitAccessToEnumCompanionMembersInEnumConstructorCall
|
||||||
|
// ISSUE: KT-49110
|
||||||
|
|
||||||
|
enum class SomeEnum(val x: Int) {
|
||||||
|
A(<!UNINITIALIZED_ENUM_COMPANION!>companionFun<!>().length),// UNINITIALIZED_ENUM_COMPANION
|
||||||
|
B(<!UNINITIALIZED_ENUM_COMPANION_WARNING, UNINITIALIZED_VARIABLE!>companionProp<!>.length), // UNINITIALIZED_VARIABLE
|
||||||
|
|
||||||
|
C(<!UNINITIALIZED_ENUM_COMPANION_WARNING!>SomeEnum<!>.companionFun().length),
|
||||||
|
D(<!UNINITIALIZED_ENUM_COMPANION_WARNING!>SomeEnum<!>.companionProp.length),
|
||||||
|
|
||||||
|
E(SomeEnum.<!UNINITIALIZED_ENUM_COMPANION_WARNING!>Companion<!>.companionFun().length),
|
||||||
|
F(SomeEnum.<!UNINITIALIZED_ENUM_COMPANION_WARNING!>Companion<!>.<!UNINITIALIZED_VARIABLE!>companionProp<!>.length); // UNINITIALIZED_VARIABLE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val companionProp = "someString"
|
||||||
|
fun companionFun(): String = "someString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class OtherEnum(val x: Int) {
|
||||||
|
G(<!UNINITIALIZED_ENUM_COMPANION!>extensionFun<!>().length), // UNINITIALIZED_ENUM_COMPANION
|
||||||
|
H(<!UNINITIALIZED_ENUM_COMPANION_WARNING!>extensionProp<!>.length),
|
||||||
|
|
||||||
|
I(<!UNINITIALIZED_ENUM_COMPANION_WARNING!>OtherEnum<!>.extensionFun().length),
|
||||||
|
J(<!UNINITIALIZED_ENUM_COMPANION_WARNING!>OtherEnum<!>.extensionProp.length),
|
||||||
|
|
||||||
|
K(OtherEnum.<!UNINITIALIZED_ENUM_COMPANION_WARNING!>Companion<!>.extensionFun().length),
|
||||||
|
L(OtherEnum.<!UNINITIALIZED_ENUM_COMPANION_WARNING!>Companion<!>.extensionProp.length);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val companionProp = "someString"
|
||||||
|
fun companionFun(): String = "someString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun OtherEnum.Companion.extensionFun(): String = companionFun()
|
||||||
|
val OtherEnum.Companion.extensionProp: String
|
||||||
|
get() = companionProp
|
||||||
|
|
||||||
Vendored
+83
@@ -0,0 +1,83 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val OtherEnum.Companion.extensionProp: kotlin.String
|
||||||
|
public fun OtherEnum.Companion.extensionFun(): kotlin.String
|
||||||
|
|
||||||
|
public final enum class OtherEnum : kotlin.Enum<OtherEnum> {
|
||||||
|
enum entry G
|
||||||
|
|
||||||
|
enum entry H
|
||||||
|
|
||||||
|
enum entry I
|
||||||
|
|
||||||
|
enum entry J
|
||||||
|
|
||||||
|
enum entry K
|
||||||
|
|
||||||
|
enum entry L
|
||||||
|
|
||||||
|
private constructor OtherEnum(/*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 val x: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: OtherEnum): 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<OtherEnum!>!
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
public final val companionProp: kotlin.String = "someString"
|
||||||
|
public final fun companionFun(): kotlin.String
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): OtherEnum
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<OtherEnum>
|
||||||
|
}
|
||||||
|
|
||||||
|
public final enum class SomeEnum : kotlin.Enum<SomeEnum> {
|
||||||
|
enum entry A
|
||||||
|
|
||||||
|
enum entry B
|
||||||
|
|
||||||
|
enum entry C
|
||||||
|
|
||||||
|
enum entry D
|
||||||
|
|
||||||
|
enum entry E
|
||||||
|
|
||||||
|
enum entry F
|
||||||
|
|
||||||
|
private constructor SomeEnum(/*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 val x: kotlin.Int
|
||||||
|
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum): 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<SomeEnum!>!
|
||||||
|
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
public final val companionProp: kotlin.String = "someString"
|
||||||
|
public final fun companionFun(): kotlin.String
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<SomeEnum>
|
||||||
|
}
|
||||||
|
|
||||||
Generated
+12
@@ -5757,6 +5757,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/tryWithAssignmentUsedInCatch.kt");
|
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/tryWithAssignmentUsedInCatch.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("uninitializedCompanionOfEnum_after.kt")
|
||||||
|
public void testUninitializedCompanionOfEnum_after() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_after.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("uninitializedCompanionOfEnum_before.kt")
|
||||||
|
public void testUninitializedCompanionOfEnum_before() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("UninitializedEnumCompanionVals.kt")
|
@TestMetadata("UninitializedEnumCompanionVals.kt")
|
||||||
public void testUninitializedEnumCompanionVals() throws Exception {
|
public void testUninitializedEnumCompanionVals() throws Exception {
|
||||||
|
|||||||
@@ -237,6 +237,7 @@ enum class LanguageFeature(
|
|||||||
ProperTypeInferenceConstraintsProcessing(KOTLIN_1_7, kind = BUG_FIX),
|
ProperTypeInferenceConstraintsProcessing(KOTLIN_1_7, kind = BUG_FIX),
|
||||||
ProhibitNonExhaustiveIfInRhsOfElvis(KOTLIN_1_7, kind = BUG_FIX), // KT-44705
|
ProhibitNonExhaustiveIfInRhsOfElvis(KOTLIN_1_7, kind = BUG_FIX), // KT-44705
|
||||||
ForbidExposingTypesInPrimaryConstructorProperties(KOTLIN_1_7, kind = BUG_FIX),
|
ForbidExposingTypesInPrimaryConstructorProperties(KOTLIN_1_7, kind = BUG_FIX),
|
||||||
|
ProhibitAccessToEnumCompanionMembersInEnumConstructorCall(KOTLIN_1_7, kind = BUG_FIX),
|
||||||
|
|
||||||
// 1.8
|
// 1.8
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user