Convert EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR into deprecation error

#KT-28078 Fixed
This commit is contained in:
Mikhail Glukhikh
2021-10-21 12:40:55 +03:00
parent a969e5af50
commit 8bd0b237b7
22 changed files with 150 additions and 32 deletions
@@ -10377,6 +10377,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/exposed/propertyInPrivateConstructor.kt");
}
@Test
@TestMetadata("propertyInPrivateConstructorError.kt")
public void testPropertyInPrivateConstructorError() throws Exception {
runTest("compiler/testData/diagnostics/tests/exposed/propertyInPrivateConstructorError.kt");
}
@Test
@TestMetadata("propertyInSimpleConstructor.kt")
public void testPropertyInSimpleConstructor() throws Exception {
@@ -10377,6 +10377,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/exposed/propertyInPrivateConstructor.kt");
}
@Test
@TestMetadata("propertyInPrivateConstructorError.kt")
public void testPropertyInPrivateConstructorError() throws Exception {
runTest("compiler/testData/diagnostics/tests/exposed/propertyInPrivateConstructorError.kt");
}
@Test
@TestMetadata("propertyInSimpleConstructor.kt")
public void testPropertyInSimpleConstructor() throws Exception {
@@ -326,7 +326,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val EXPOSED_FUNCTION_RETURN_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
val EXPOSED_RECEIVER_TYPE by exposedVisibilityError<KtTypeReference>()
val EXPOSED_PROPERTY_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
val EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR by exposedVisibilityWarning<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
val EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR by exposedVisibilityDeprecationError<KtNamedDeclaration>(
LanguageFeature.ForbidExposingTypesInPrimaryConstructorProperties, PositioningStrategy.DECLARATION_NAME
)
val EXPOSED_PARAMETER_TYPE by exposedVisibilityError<KtParameter>(/* // NB: for parameter FE 1.0 reports not on a name for some reason */)
val EXPOSED_SUPER_INTERFACE by exposedVisibilityError<KtTypeReference>()
val EXPOSED_SUPER_CLASS by exposedVisibilityError<KtTypeReference>()
@@ -1378,4 +1380,11 @@ private inline fun <reified P : PsiElement> AbstractDiagnosticGroup.exposedVisib
return warning<P>(positioningStrategy, exposedVisibilityDiagnosticInit)
}
private inline fun <reified P : PsiElement> AbstractDiagnosticGroup.exposedVisibilityDeprecationError(
languageFeature: LanguageFeature,
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT
): PropertyDelegateProvider<Any?, ReadOnlyProperty<AbstractDiagnosticGroup, DeprecationDiagnosticData>> {
return deprecationError<P>(languageFeature, positioningStrategy, exposedVisibilityDiagnosticInit)
}
typealias Symbol = FirBasedSymbol<*>
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageFeature.ForbidExposingTypesInPrimaryConstructorProperties
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitConfusingSyntaxInWhenBranches
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitInvisibleAbstractMethodsInSuperclasses
@@ -266,7 +267,7 @@ object FirErrors {
val EXPOSED_FUNCTION_RETURN_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_RECEIVER_TYPE by error3<KtTypeReference, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>()
val EXPOSED_PROPERTY_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR by warning3<KtNamedDeclaration, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR by deprecationError3<KtNamedDeclaration, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>(ForbidExposingTypesInPrimaryConstructorProperties, SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_PARAMETER_TYPE by error3<KtParameter, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>()
val EXPOSED_SUPER_INTERFACE by error3<KtTypeReference, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>()
val EXPOSED_SUPER_CLASS by error3<KtTypeReference, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>()
@@ -145,19 +145,25 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
if (propertyVisibility == EffectiveVisibility.Local) return
declaration.returnTypeRef.coneTypeSafe<ConeKotlinType>()
?.findVisibilityExposure(context, propertyVisibility)?.let { (restricting, restrictingVisibility) ->
val diagnostic = if (declaration.fromPrimaryConstructor == true) {
FirErrors.EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR
if (declaration.fromPrimaryConstructor == true) {
reporter.reportOn(
declaration.source,
FirErrors.EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR,
propertyVisibility,
restricting,
restrictingVisibility,
context
)
} else {
FirErrors.EXPOSED_PROPERTY_TYPE
reporter.reportOn(
declaration.source,
FirErrors.EXPOSED_PROPERTY_TYPE,
propertyVisibility,
restricting,
restrictingVisibility,
context
)
}
reporter.reportOn(
declaration.source,
diagnostic,
propertyVisibility,
restricting,
restrictingVisibility,
context
)
}
checkMemberReceiver(declaration.receiverTypeRef, declaration, reporter, context)
}
@@ -141,7 +141,7 @@ public interface Errors {
// Exposed visibility group
DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_PROPERTY_TYPE = DiagnosticFactory3.create(ERROR);
DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR = DiagnosticFactory3.create(WARNING);
DiagnosticFactoryForDeprecation3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR = DiagnosticFactoryForDeprecation3.create(LanguageFeature.ForbidExposingTypesInPrimaryConstructorProperties);
DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_FUNCTION_RETURN_TYPE = DiagnosticFactory3.create(ERROR);
DiagnosticFactory3<KtParameter, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_PARAMETER_TYPE = DiagnosticFactory3.create(ERROR);
DiagnosticFactory3<KtTypeReference, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_RECEIVER_TYPE = DiagnosticFactory3.create(ERROR);
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
import org.jetbrains.kotlin.diagnostics.DiagnosticFactoryForDeprecation3
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
@@ -52,6 +53,17 @@ class ExposedVisibilityChecker(
}
}
private fun <E : PsiElement> reportExposureForDeprecation(
diagnostic: DiagnosticFactoryForDeprecation3<E, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility>,
element: E,
elementVisibility: EffectiveVisibility,
restrictingDescriptor: DescriptorWithRelation
) {
val trace = trace ?: return
val restrictingVisibility = restrictingDescriptor.effectiveVisibility()
trace.report(diagnostic.on(languageVersionSettings, element, elementVisibility, restrictingDescriptor, restrictingVisibility))
}
// NB: does not check any members
fun checkClassHeader(klass: KtClassOrObject, classDescriptor: ClassDescriptor): Boolean {
var result = checkSupertypes(klass, classDescriptor)
@@ -62,6 +74,8 @@ class ExposedVisibilityChecker(
return result and checkFunction(constructor, constructorDescriptor)
}
// IMPORTANT: please don't remove this function (it's used in IDE)
@Suppress("unused")
fun checkDeclarationWithVisibility(
modifierListOwner: KtModifierListOwner,
descriptor: DeclarationDescriptorWithVisibility,
@@ -119,8 +133,11 @@ class ExposedVisibilityChecker(
val propertyOrClassVisibility = (propertyDescriptor ?: functionDescriptor.constructedClass).effectiveVisibility()
val restrictingByProperty = parameterDescriptor.type.leastPermissiveDescriptor(propertyOrClassVisibility)
if (restrictingByProperty != null) {
reportExposure(
EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR, valueParameter, propertyOrClassVisibility, restrictingByProperty
reportExposureForDeprecation(
EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR,
valueParameter.nameIdentifier ?: valueParameter,
propertyOrClassVisibility,
restrictingByProperty
)
result = false
}
@@ -1,3 +0,0 @@
private enum class Foo { A, B }
class Bar private constructor(val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR!>foo<!>: Foo)
@@ -1,3 +1,6 @@
// FIR_IDENTICAL
// !LANGUAGE: -ForbidExposingTypesInPrimaryConstructorProperties
private enum class Foo { A, B }
class Bar private constructor(<!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR!>val foo: Foo<!>)
class Bar private constructor(val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR_WARNING!>foo<!>: Foo)
@@ -0,0 +1,6 @@
// FIR_IDENTICAL
// !LANGUAGE: +ForbidExposingTypesInPrimaryConstructorProperties
private enum class Foo { A, B }
class Bar private constructor(val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR_ERROR!>foo<!>: Foo)
@@ -0,0 +1,30 @@
package
public final class Bar {
private constructor Bar(/*0*/ foo: Foo)
public final val foo: Foo
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
}
private final enum class Foo : kotlin.Enum<Foo> {
enum entry A
enum entry B
private constructor Foo()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Foo): 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<Foo!>!
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): Foo
public final /*synthesized*/ fun values(): kotlin.Array<Foo>
}
@@ -1,3 +1,3 @@
private enum class Foo { A, B }
class Bar(<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR!>foo<!>: Foo<!>)
class Bar(<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR_WARNING!>foo<!>: Foo<!>)
+1 -1
View File
@@ -6,7 +6,7 @@ public interface Your: <!EXPOSED_SUPER_INTERFACE!>My<!> {
fun <T: Base> foo(): T
}
public class Derived<T: <!EXPOSED_TYPE_PARAMETER_BOUND!>My<!>>(<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR!>x<!>: My<!>): <!EXPOSED_SUPER_CLASS!>Base<!>() {
public class Derived<T: <!EXPOSED_TYPE_PARAMETER_BOUND!>My<!>>(<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR_WARNING!>x<!>: My<!>): <!EXPOSED_SUPER_CLASS!>Base<!>() {
constructor(<!EXPOSED_PARAMETER_TYPE!>xx: My?<!>, <!EXPOSED_PARAMETER_TYPE!>x: My<!>): this(xx ?: x)
@@ -4,13 +4,13 @@
private class Bar
sealed class SealedFoo(
<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR!>x<!>: Bar<!>,
<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR_WARNING!>x<!>: Bar<!>,
<!EXPOSED_PARAMETER_TYPE!>private val y: Bar<!>,
<!EXPOSED_PARAMETER_TYPE!>z: Bar<!>
)
abstract class AbstractFoo(
<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR!>x<!>: Bar<!>,
<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR_WARNING!>x<!>: Bar<!>,
<!EXPOSED_PARAMETER_TYPE!>private val y: Bar<!>,
<!EXPOSED_PARAMETER_TYPE!>z: Bar<!>
)
@@ -4,7 +4,7 @@
private class Bar
sealed class SealedFoo(
<!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR!>val x: Bar<!>,
val <!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR_WARNING!>x<!>: Bar,
private val y: Bar,
z: Bar
)
@@ -10383,6 +10383,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/exposed/propertyInPrivateConstructor.kt");
}
@Test
@TestMetadata("propertyInPrivateConstructorError.kt")
public void testPropertyInPrivateConstructorError() throws Exception {
runTest("compiler/testData/diagnostics/tests/exposed/propertyInPrivateConstructorError.kt");
}
@Test
@TestMetadata("propertyInSimpleConstructor.kt")
public void testPropertyInSimpleConstructor() throws Exception {
@@ -236,6 +236,7 @@ enum class LanguageFeature(
IgnoreNullabilityForErasedValueParameters(KOTLIN_1_7, kind = BUG_FIX),
ProperTypeInferenceConstraintsProcessing(KOTLIN_1_7, kind = BUG_FIX),
ProhibitNonExhaustiveIfInRhsOfElvis(KOTLIN_1_7, kind = BUG_FIX), // KT-44705
ForbidExposingTypesInPrimaryConstructorProperties(KOTLIN_1_7, kind = BUG_FIX),
// 1.8