diff --git a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/ChangeVisibilityFixFactories.kt b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/ChangeVisibilityFixFactories.kt index 9ca9541b4613..13dbfd8268b3 100644 --- a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/ChangeVisibilityFixFactories.kt +++ b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/ChangeVisibilityFixFactories.kt @@ -7,6 +7,7 @@ import com.intellij.modcommand.ModPsiUpdater import com.intellij.modcommand.Presentation import com.intellij.psi.PsiElement import com.intellij.psi.util.parentOfTypes +import com.intellij.psi.util.parentsOfType import com.intellij.util.containers.addIfNotNull import org.jetbrains.kotlin.analysis.api.KaSession import org.jetbrains.kotlin.analysis.api.analyze @@ -50,7 +51,6 @@ import org.jetbrains.kotlin.psi.KtPropertyAccessor import org.jetbrains.kotlin.psi.KtTypeParameter import org.jetbrains.kotlin.psi.psiUtil.containingClass import org.jetbrains.kotlin.psi.psiUtil.isPrivate -import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -316,13 +316,18 @@ object ChangeVisibilityFixFactories { Visibilities.Private to Visibilities.Public } - val userDeclaration = element.parentsWithSelf.firstOrNull { it is KtDeclaration && it !is KtTypeParameter } as? KtDeclaration + val userDeclaration = element.parentsOfType(withSelf = true) + .filterNot { it is KtTypeParameter } + .filterNot { it is KtParameter && !it.hasValOrVar() } + .filterNot { it.isPrivate() } + .firstOrNull() + val exposedDeclaration = restrictingSymbol.psi val protectedAllowed = exposedDeclaration?.parent == userDeclaration?.parent val modCommandActions = arrayListOf() - if (userDeclaration != null && !userDeclaration.isPrivate()) { + if (userDeclaration != null) { if ((restrictingSymbol as? KaDeclarationSymbol)?.isVisible(element) == true) { addFixToTargetVisibility( symbol = restrictingSymbol, diff --git a/plugins/kotlin/code-insight/fixes-k2/tests/test/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/HighLevelQuickFixTestGenerated.java b/plugins/kotlin/code-insight/fixes-k2/tests/test/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/HighLevelQuickFixTestGenerated.java index fc6787342352..4c7212ab0584 100644 --- a/plugins/kotlin/code-insight/fixes-k2/tests/test/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/HighLevelQuickFixTestGenerated.java +++ b/plugins/kotlin/code-insight/fixes-k2/tests/test/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/HighLevelQuickFixTestGenerated.java @@ -7198,11 +7198,31 @@ public abstract class HighLevelQuickFixTestGenerated extends AbstractHighLevelQu KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } + @TestMetadata("exposedConstructorParameterType.kt") + public void testExposedConstructorParameterType() throws Exception { + runTest("../../../idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType.kt"); + } + + @TestMetadata("exposedConstructorParameterType_privateVal.kt") + public void testExposedConstructorParameterType_privateVal() throws Exception { + runTest("../../../idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_privateVal.kt"); + } + + @TestMetadata("exposedConstructorParameterType_val.kt") + public void testExposedConstructorParameterType_val() throws Exception { + runTest("../../../idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_val.kt"); + } + @TestMetadata("exposedParameterType.kt") public void testExposedParameterType() throws Exception { runTest("../../../idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType.kt"); } + @TestMetadata("exposedParameterType_privateType.kt") + public void testExposedParameterType_privateType() throws Exception { + runTest("../../../idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType_privateType.kt"); + } + @TestMetadata("exposedPropertyType.kt") public void testExposedPropertyType() throws Exception { runTest("../../../idea/tests/testData/quickfix/decreaseVisibility/exposedPropertyType.kt"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/K1QuickFixTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/K1QuickFixTestGenerated.java index feb044b01617..1af817e5552a 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/K1QuickFixTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/K1QuickFixTestGenerated.java @@ -7599,11 +7599,31 @@ public abstract class K1QuickFixTestGenerated extends AbstractK1QuickFixTest { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } + @TestMetadata("exposedConstructorParameterType.kt") + public void testExposedConstructorParameterType() throws Exception { + runTest("testData/quickfix/decreaseVisibility/exposedConstructorParameterType.kt"); + } + + @TestMetadata("exposedConstructorParameterType_privateVal.kt") + public void testExposedConstructorParameterType_privateVal() throws Exception { + runTest("testData/quickfix/decreaseVisibility/exposedConstructorParameterType_privateVal.kt"); + } + + @TestMetadata("exposedConstructorParameterType_val.kt") + public void testExposedConstructorParameterType_val() throws Exception { + runTest("testData/quickfix/decreaseVisibility/exposedConstructorParameterType_val.kt"); + } + @TestMetadata("exposedParameterType.kt") public void testExposedParameterType() throws Exception { runTest("testData/quickfix/decreaseVisibility/exposedParameterType.kt"); } + @TestMetadata("exposedParameterType_privateType.kt") + public void testExposedParameterType_privateType() throws Exception { + runTest("testData/quickfix/decreaseVisibility/exposedParameterType_privateType.kt"); + } + @TestMetadata("exposedPropertyType.kt") public void testExposedPropertyType() throws Exception { runTest("testData/quickfix/decreaseVisibility/exposedPropertyType.kt"); diff --git a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType.kt b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType.kt new file mode 100644 index 000000000000..ede0206a6052 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType.kt @@ -0,0 +1,15 @@ +// "Make '' private" "true" +// ACTION: Add 'val' or 'var' to parameter 'arg' +// ACTION: Convert to secondary constructor +// ACTION: Create test +// ACTION: Enable a trailing comma by default in the formatter +// ACTION: Make '' private +// ACTION: Make 'PrivateType' public +// ACTION: Remove parameter 'arg' + +private class PrivateType + +class Foo(arg: PrivateType) {} + +// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeVisibilityFix$ChangeToPrivateFix +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.ChangeVisibilityFixFactories$ChangeToPrivateModCommandAction \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType.kt.after b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType.kt.after new file mode 100644 index 000000000000..f92f184b32a7 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType.kt.after @@ -0,0 +1,15 @@ +// "Make '' private" "true" +// ACTION: Add 'val' or 'var' to parameter 'arg' +// ACTION: Convert to secondary constructor +// ACTION: Create test +// ACTION: Enable a trailing comma by default in the formatter +// ACTION: Make '' private +// ACTION: Make 'PrivateType' public +// ACTION: Remove parameter 'arg' + +private class PrivateType + +class Foo private constructor(arg: PrivateType) {} + +// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeVisibilityFix$ChangeToPrivateFix +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.ChangeVisibilityFixFactories$ChangeToPrivateModCommandAction \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_privateVal.kt b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_privateVal.kt new file mode 100644 index 000000000000..3241b655e1fe --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_privateVal.kt @@ -0,0 +1,14 @@ +// "Make '' private" "true" +// ACTION: Convert to secondary constructor +// ACTION: Create test +// ACTION: Enable a trailing comma by default in the formatter +// ACTION: Make 'PrivateType' public +// ACTION: Move to class body +// IGNORE_K1 +// ERROR: 'public' function exposes its 'private-in-file' parameter type PrivateType + +private class PrivateType + +class Foo(private val arg: PrivateType) {} + +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.ChangeVisibilityFixFactories$ChangeToPrivateModCommandAction \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_privateVal.kt.after b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_privateVal.kt.after new file mode 100644 index 000000000000..c527a12ca7bb --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_privateVal.kt.after @@ -0,0 +1,14 @@ +// "Make '' private" "true" +// ACTION: Convert to secondary constructor +// ACTION: Create test +// ACTION: Enable a trailing comma by default in the formatter +// ACTION: Make 'PrivateType' public +// ACTION: Move to class body +// IGNORE_K1 +// ERROR: 'public' function exposes its 'private-in-file' parameter type PrivateType + +private class PrivateType + +class Foo private constructor(private val arg: PrivateType) {} + +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.ChangeVisibilityFixFactories$ChangeToPrivateModCommandAction \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_val.kt b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_val.kt new file mode 100644 index 000000000000..293dbc1ac8cd --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_val.kt @@ -0,0 +1,14 @@ +// "Make 'arg' private" "true" +// ACTION: Convert to secondary constructor +// ACTION: Create test +// ACTION: Enable a trailing comma by default in the formatter +// ACTION: Make 'PrivateType' public +// ACTION: Move to class body +// ERROR: 'public' function exposes its 'private-in-file' parameter type PrivateType +// IGNORE_K1 + +private class PrivateType + +class Foo(val arg: PrivateType) {} + +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.ChangeVisibilityFixFactories$ChangeToPrivateModCommandAction \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_val.kt.after b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_val.kt.after new file mode 100644 index 000000000000..140fa30d0388 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedConstructorParameterType_val.kt.after @@ -0,0 +1,14 @@ +// "Make 'arg' private" "true" +// ACTION: Convert to secondary constructor +// ACTION: Create test +// ACTION: Enable a trailing comma by default in the formatter +// ACTION: Make 'PrivateType' public +// ACTION: Move to class body +// ERROR: 'public' function exposes its 'private-in-file' parameter type PrivateType +// IGNORE_K1 + +private class PrivateType + +class Foo(private val arg: PrivateType) {} + +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.ChangeVisibilityFixFactories$ChangeToPrivateModCommandAction \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType.kt b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType.kt index 8ab35f879dc3..4eb27c25e603 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType.kt @@ -1,16 +1,13 @@ -// "Make 'foo' private" "false" +// "Make 'foo' private" "true" // ACTION: Convert parameter to receiver // ACTION: Enable a trailing comma by default in the formatter -// ACTION: Make 'Nested' internal -// ACTION: Make 'Nested' public +// ACTION: Make 'PrivateType' public +// ACTION: Make 'foo' private // ACTION: Remove parameter 'arg' -// ERROR: 'internal' function exposes its 'private-in-class' parameter type argument Nested -// ERROR: Cannot access 'Nested': it is private in 'Outer' -class Outer { - private class Nested -} +private class PrivateType -class Generic +fun foo(arg: PrivateType) {} -internal fun foo(arg: Generic) {} +// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeVisibilityFix$ChangeToPrivateFix +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.ChangeVisibilityFixFactories$ChangeToPrivateModCommandAction \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType.kt.after b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType.kt.after new file mode 100644 index 000000000000..297173364009 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType.kt.after @@ -0,0 +1,13 @@ +// "Make 'foo' private" "true" +// ACTION: Convert parameter to receiver +// ACTION: Enable a trailing comma by default in the formatter +// ACTION: Make 'PrivateType' public +// ACTION: Make 'foo' private +// ACTION: Remove parameter 'arg' + +private class PrivateType + +private fun foo(arg: PrivateType) {} + +// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.ChangeVisibilityFix$ChangeToPrivateFix +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.ChangeVisibilityFixFactories$ChangeToPrivateModCommandAction \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType_privateType.kt b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType_privateType.kt new file mode 100644 index 000000000000..8ab35f879dc3 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/decreaseVisibility/exposedParameterType_privateType.kt @@ -0,0 +1,16 @@ +// "Make 'foo' private" "false" +// ACTION: Convert parameter to receiver +// ACTION: Enable a trailing comma by default in the formatter +// ACTION: Make 'Nested' internal +// ACTION: Make 'Nested' public +// ACTION: Remove parameter 'arg' +// ERROR: 'internal' function exposes its 'private-in-class' parameter type argument Nested +// ERROR: Cannot access 'Nested': it is private in 'Outer' + +class Outer { + private class Nested +} + +class Generic + +internal fun foo(arg: Generic) {}