Add PrivateInFileEffectiveVisibility language feature (1.6)
This commit is contained in:
+6
@@ -9281,6 +9281,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/exposed/privateInFile.kt");
|
runTest("compiler/testData/diagnostics/tests/exposed/privateInFile.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateInFileDisabled.kt")
|
||||||
|
public void testPrivateInFileDisabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/exposed/privateInFileDisabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("privatePropertyInPrivateConstructor.kt")
|
@TestMetadata("privatePropertyInPrivateConstructor.kt")
|
||||||
public void testPrivatePropertyInPrivateConstructor() throws Exception {
|
public void testPrivatePropertyInPrivateConstructor() throws Exception {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ class DeclarationsChecker(
|
|||||||
|
|
||||||
private val modifiersChecker = modifiersChecker.withTrace(trace)
|
private val modifiersChecker = modifiersChecker.withTrace(trace)
|
||||||
|
|
||||||
private val exposedChecker = ExposedVisibilityChecker(trace)
|
private val exposedChecker = ExposedVisibilityChecker(languageVersionSettings, trace)
|
||||||
|
|
||||||
private val shadowedExtensionChecker = ShadowedExtensionChecker(typeSpecificityComparator, trace)
|
private val shadowedExtensionChecker = ShadowedExtensionChecker(typeSpecificityComparator, trace)
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.resolve
|
package org.jetbrains.kotlin.resolve
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
@@ -27,7 +29,10 @@ import org.jetbrains.kotlin.types.isError
|
|||||||
|
|
||||||
// Checker for all seven EXPOSED_* errors
|
// Checker for all seven EXPOSED_* errors
|
||||||
// All functions return true if everything is OK, or false in case of any errors
|
// All functions return true if everything is OK, or false in case of any errors
|
||||||
class ExposedVisibilityChecker(private val trace: BindingTrace? = null) {
|
class ExposedVisibilityChecker(
|
||||||
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
|
private val trace: BindingTrace? = null
|
||||||
|
) {
|
||||||
|
|
||||||
private fun <E : PsiElement> reportExposure(
|
private fun <E : PsiElement> reportExposure(
|
||||||
diagnostic: DiagnosticFactory3<E, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility>,
|
diagnostic: DiagnosticFactory3<E, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility>,
|
||||||
@@ -37,8 +42,10 @@ class ExposedVisibilityChecker(private val trace: BindingTrace? = null) {
|
|||||||
) {
|
) {
|
||||||
val trace = trace ?: return
|
val trace = trace ?: return
|
||||||
val restrictingVisibility = restrictingDescriptor.effectiveVisibility()
|
val restrictingVisibility = restrictingDescriptor.effectiveVisibility()
|
||||||
if (elementVisibility == EffectiveVisibility.PrivateInFile) {
|
|
||||||
// Deprecation: condition ^ should be changed to false after 1.6
|
if (!languageVersionSettings.supportsFeature(LanguageFeature.PrivateInFileEffectiveVisibility) &&
|
||||||
|
elementVisibility == EffectiveVisibility.PrivateInFile
|
||||||
|
) {
|
||||||
trace.report(EXPOSED_FROM_PRIVATE_IN_FILE.on(element, restrictingDescriptor, restrictingVisibility))
|
trace.report(EXPOSED_FROM_PRIVATE_IN_FILE.on(element, restrictingDescriptor, restrictingVisibility))
|
||||||
} else {
|
} else {
|
||||||
trace.report(diagnostic.on(element, elementVisibility, restrictingDescriptor, restrictingVisibility))
|
trace.report(diagnostic.on(element, elementVisibility, restrictingDescriptor, restrictingVisibility))
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// !LANGUAGE: +PrivateInFileEffectiveVisibility
|
||||||
|
|
||||||
class Public {
|
class Public {
|
||||||
private open class NestedPrivate
|
private open class NestedPrivate
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// !LANGUAGE: +PrivateInFileEffectiveVisibility
|
||||||
|
|
||||||
class Public {
|
class Public {
|
||||||
private open class NestedPrivate
|
private open class NestedPrivate
|
||||||
|
|
||||||
@@ -11,17 +13,17 @@ class Public {
|
|||||||
private class PrivateInFileClass {
|
private class PrivateInFileClass {
|
||||||
private open class NestedPrivate
|
private open class NestedPrivate
|
||||||
|
|
||||||
fun <!EXPOSED_FROM_PRIVATE_IN_FILE!>test1<!>() = NestedPrivate()
|
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>test1<!>() = NestedPrivate()
|
||||||
fun test2(<!EXPOSED_FROM_PRIVATE_IN_FILE!>p: NestedPrivate<!>) {}
|
fun test2(<!EXPOSED_PARAMETER_TYPE!>p: NestedPrivate<!>) {}
|
||||||
fun <!EXPOSED_FROM_PRIVATE_IN_FILE!>NestedPrivate<!>.test3() {}
|
fun <!EXPOSED_RECEIVER_TYPE!>NestedPrivate<!>.test3() {}
|
||||||
val <!EXPOSED_FROM_PRIVATE_IN_FILE!>test4<!> = NestedPrivate()
|
val <!EXPOSED_PROPERTY_TYPE!>test4<!> = NestedPrivate()
|
||||||
class Test5 : <!EXPOSED_FROM_PRIVATE_IN_FILE!>NestedPrivate()<!>
|
class Test5 : <!EXPOSED_SUPER_CLASS!>NestedPrivate()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface PrivateInFile {
|
private interface PrivateInFile {
|
||||||
private class Private
|
private class Private
|
||||||
|
|
||||||
fun <!EXPOSED_FROM_PRIVATE_IN_FILE!>expose<!>() = Private()
|
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>expose<!>() = Private()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exposes 'PrivateInFile$Private' via 'expose'
|
// Exposes 'PrivateInFile$Private' via 'expose'
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// !LANGUAGE: -PrivateInFileEffectiveVisibility
|
||||||
|
|
||||||
|
class Public {
|
||||||
|
private open class NestedPrivate
|
||||||
|
|
||||||
|
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>test1<!>() = NestedPrivate()
|
||||||
|
fun test2(<!EXPOSED_PARAMETER_TYPE!>p: NestedPrivate<!>) {}
|
||||||
|
fun <!EXPOSED_RECEIVER_TYPE!>NestedPrivate<!>.test3() {}
|
||||||
|
val <!EXPOSED_PROPERTY_TYPE!>test4<!> = NestedPrivate()
|
||||||
|
class Test5 : <!EXPOSED_SUPER_CLASS!>NestedPrivate<!>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PrivateInFileClass {
|
||||||
|
private open class NestedPrivate
|
||||||
|
|
||||||
|
fun test1() = NestedPrivate()
|
||||||
|
fun test2(p: NestedPrivate) {}
|
||||||
|
fun NestedPrivate.test3() {}
|
||||||
|
val test4 = NestedPrivate()
|
||||||
|
class Test5 : NestedPrivate()
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface PrivateInFile {
|
||||||
|
private class Private
|
||||||
|
|
||||||
|
fun expose() = Private()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exposes 'PrivateInFile$Private' via 'expose'
|
||||||
|
class Derived : PrivateInFile
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// !LANGUAGE: -PrivateInFileEffectiveVisibility
|
||||||
|
|
||||||
|
class Public {
|
||||||
|
private open class NestedPrivate
|
||||||
|
|
||||||
|
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>test1<!>() = NestedPrivate()
|
||||||
|
fun test2(<!EXPOSED_PARAMETER_TYPE!>p: NestedPrivate<!>) {}
|
||||||
|
fun <!EXPOSED_RECEIVER_TYPE!>NestedPrivate<!>.test3() {}
|
||||||
|
val <!EXPOSED_PROPERTY_TYPE!>test4<!> = NestedPrivate()
|
||||||
|
class Test5 : <!EXPOSED_SUPER_CLASS!>NestedPrivate()<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PrivateInFileClass {
|
||||||
|
private open class NestedPrivate
|
||||||
|
|
||||||
|
fun <!EXPOSED_FROM_PRIVATE_IN_FILE!>test1<!>() = NestedPrivate()
|
||||||
|
fun test2(<!EXPOSED_FROM_PRIVATE_IN_FILE!>p: NestedPrivate<!>) {}
|
||||||
|
fun <!EXPOSED_FROM_PRIVATE_IN_FILE!>NestedPrivate<!>.test3() {}
|
||||||
|
val <!EXPOSED_FROM_PRIVATE_IN_FILE!>test4<!> = NestedPrivate()
|
||||||
|
class Test5 : <!EXPOSED_FROM_PRIVATE_IN_FILE!>NestedPrivate()<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface PrivateInFile {
|
||||||
|
private class Private
|
||||||
|
|
||||||
|
fun <!EXPOSED_FROM_PRIVATE_IN_FILE!>expose<!>() = Private()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exposes 'PrivateInFile$Private' via 'expose'
|
||||||
|
class Derived : PrivateInFile
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class Derived : PrivateInFile {
|
||||||
|
public constructor Derived()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun expose(): PrivateInFile.Private
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface PrivateInFile {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun expose(): PrivateInFile.Private
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
private final class Private {
|
||||||
|
public constructor Private()
|
||||||
|
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 class PrivateInFileClass {
|
||||||
|
public constructor PrivateInFileClass()
|
||||||
|
public final val test4: PrivateInFileClass.NestedPrivate
|
||||||
|
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 final fun test1(): PrivateInFileClass.NestedPrivate
|
||||||
|
public final fun test2(/*0*/ p: PrivateInFileClass.NestedPrivate): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
public final fun PrivateInFileClass.NestedPrivate.test3(): kotlin.Unit
|
||||||
|
|
||||||
|
private open class NestedPrivate {
|
||||||
|
public constructor NestedPrivate()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Test5 : PrivateInFileClass.NestedPrivate {
|
||||||
|
public constructor Test5()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Public {
|
||||||
|
public constructor Public()
|
||||||
|
public final val test4: Public.NestedPrivate
|
||||||
|
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 final fun test1(): Public.NestedPrivate
|
||||||
|
public final fun test2(/*0*/ p: Public.NestedPrivate): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
public final fun Public.NestedPrivate.test3(): kotlin.Unit
|
||||||
|
|
||||||
|
private open class NestedPrivate {
|
||||||
|
public constructor NestedPrivate()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Test5 : Public.NestedPrivate {
|
||||||
|
public constructor Test5()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+6
@@ -9287,6 +9287,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/exposed/privateInFile.kt");
|
runTest("compiler/testData/diagnostics/tests/exposed/privateInFile.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateInFileDisabled.kt")
|
||||||
|
public void testPrivateInFileDisabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/exposed/privateInFileDisabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("privatePropertyInPrivateConstructor.kt")
|
@TestMetadata("privatePropertyInPrivateConstructor.kt")
|
||||||
public void testPrivatePropertyInPrivateConstructor() throws Exception {
|
public void testPrivatePropertyInPrivateConstructor() throws Exception {
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ enum class LanguageFeature(
|
|||||||
*/
|
*/
|
||||||
TypeEnhancementImprovementsInStrictMode(KOTLIN_1_6),
|
TypeEnhancementImprovementsInStrictMode(KOTLIN_1_6),
|
||||||
ProhibitJvmFieldOnOverrideFromInterfaceInPrimaryConstructor(KOTLIN_1_6, kind = BUG_FIX),
|
ProhibitJvmFieldOnOverrideFromInterfaceInPrimaryConstructor(KOTLIN_1_6, kind = BUG_FIX),
|
||||||
|
PrivateInFileEffectiveVisibility(KOTLIN_1_6, kind = BUG_FIX),
|
||||||
|
|
||||||
// Temporarily disabled, see KT-27084/KT-22379
|
// Temporarily disabled, see KT-27084/KT-22379
|
||||||
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
|
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.idea.core.canBeProtected
|
|||||||
import org.jetbrains.kotlin.idea.core.setVisibility
|
import org.jetbrains.kotlin.idea.core.setVisibility
|
||||||
import org.jetbrains.kotlin.idea.inspections.RemoveRedundantSetterFix
|
import org.jetbrains.kotlin.idea.inspections.RemoveRedundantSetterFix
|
||||||
import org.jetbrains.kotlin.idea.inspections.isRedundantSetter
|
import org.jetbrains.kotlin.idea.inspections.isRedundantSetter
|
||||||
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||||
import org.jetbrains.kotlin.idea.util.runOnExpectAndAllActuals
|
import org.jetbrains.kotlin.idea.util.runOnExpectAndAllActuals
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
@@ -106,7 +107,10 @@ open class ChangeVisibilityFix(
|
|||||||
descriptor: DeclarationDescriptorWithVisibility,
|
descriptor: DeclarationDescriptorWithVisibility,
|
||||||
targetVisibility: DescriptorVisibility
|
targetVisibility: DescriptorVisibility
|
||||||
): IntentionAction? {
|
): IntentionAction? {
|
||||||
if (!ExposedVisibilityChecker().checkDeclarationWithVisibility(declaration, descriptor, targetVisibility)) return null
|
if (!ExposedVisibilityChecker(declaration.languageVersionSettings).checkDeclarationWithVisibility(
|
||||||
|
declaration, descriptor, targetVisibility
|
||||||
|
)
|
||||||
|
) return null
|
||||||
|
|
||||||
val name = descriptor.name.asString()
|
val name = descriptor.name.asString()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user