Offer to make INVISIBLE_MEMBER protected if referenced from subclass
So #KT-19614 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
0adf1d210f
commit
f0f6a252a5
@@ -17,21 +17,25 @@
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities.*
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
object MakeVisibleFactory : KotlinIntentionActionsFactory() {
|
||||
object MakeVisibleFactory : KotlinIntentionActionsFactory() {
|
||||
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
|
||||
val element = diagnostic.psiElement as? KtElement ?: return emptyList()
|
||||
val context = element.analyze(BodyResolveMode.PARTIAL)
|
||||
@@ -44,7 +48,11 @@ object MakeVisibleFactory : KotlinIntentionActionsFactory() {
|
||||
|
||||
val module = DescriptorUtils.getContainingModule(descriptor)
|
||||
val targetVisibilities = when (descriptor.visibility) {
|
||||
PRIVATE, INVISIBLE_FAKE -> if (module != usageModule) listOf(PUBLIC) else listOf(PUBLIC, INTERNAL)
|
||||
PRIVATE, INVISIBLE_FAKE -> mutableListOf(PUBLIC).apply {
|
||||
if (module == usageModule) add(INTERNAL)
|
||||
val superClasses = (element.containingClass()?.descriptor as? ClassDescriptor)?.getAllSuperclassesWithoutAny()
|
||||
if (superClasses?.contains(declaration.containingClass()?.descriptor) == true) add(PROTECTED)
|
||||
}
|
||||
else -> listOf(PUBLIC)
|
||||
}
|
||||
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Make 'doSth' protected" "false"
|
||||
// ACTION: Make 'doSth' public
|
||||
// ACTION: Make 'doSth' internal
|
||||
// ERROR: Cannot access 'doSth': it is private in 'A'
|
||||
|
||||
class A {
|
||||
private fun doSth() {
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
fun bar() {
|
||||
A().<caret>doSth()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Make 'doSth' protected" "true"
|
||||
|
||||
open class A {
|
||||
private fun doSth() {
|
||||
}
|
||||
}
|
||||
|
||||
class B : A() {
|
||||
fun bar() {
|
||||
<caret>doSth()
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Make 'doSth' protected" "true"
|
||||
|
||||
open class A {
|
||||
protected fun doSth() {
|
||||
}
|
||||
}
|
||||
|
||||
class B : A() {
|
||||
fun bar() {
|
||||
doSth()
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Make 'doSth' protected" "true"
|
||||
|
||||
open class A {
|
||||
private fun doSth() {
|
||||
}
|
||||
}
|
||||
|
||||
open class B : A()
|
||||
|
||||
class C : B() {
|
||||
fun bar() {
|
||||
<caret>doSth()
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Make 'doSth' protected" "true"
|
||||
|
||||
open class A {
|
||||
protected fun doSth() {
|
||||
}
|
||||
}
|
||||
|
||||
open class B : A()
|
||||
|
||||
class C : B() {
|
||||
fun bar() {
|
||||
doSth()
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Make 'foo' protected" "false"
|
||||
// ACTION: Make 'foo' public
|
||||
// ACTION: Make 'foo' internal
|
||||
// ACTION: Introduce local variable
|
||||
// ERROR: Cannot access 'foo': it is private in 'A'
|
||||
|
||||
class A {
|
||||
private val foo = 1
|
||||
}
|
||||
|
||||
class B {
|
||||
fun bar() {
|
||||
A().<caret>foo
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Make 'foo' protected" "true"
|
||||
|
||||
open class A {
|
||||
private val foo = 1
|
||||
}
|
||||
|
||||
class B : A() {
|
||||
fun bar() {
|
||||
<caret>foo
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Make 'foo' protected" "true"
|
||||
|
||||
open class A {
|
||||
protected val foo = 1
|
||||
}
|
||||
|
||||
class B : A() {
|
||||
fun bar() {
|
||||
foo
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Make 'foo' protected" "true"
|
||||
|
||||
open class A {
|
||||
private val foo = 1
|
||||
}
|
||||
|
||||
open class B : A()
|
||||
|
||||
class C : B() {
|
||||
fun bar() {
|
||||
<caret>foo
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Make 'foo' protected" "true"
|
||||
|
||||
open class A {
|
||||
protected val foo = 1
|
||||
}
|
||||
|
||||
open class B : A()
|
||||
|
||||
class C : B() {
|
||||
fun bar() {
|
||||
foo
|
||||
}
|
||||
}
|
||||
@@ -6301,6 +6301,24 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("methodToNotProtected.kt")
|
||||
public void testMethodToNotProtected() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/invisibleFake/methodToNotProtected.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("methodToProtected.kt")
|
||||
public void testMethodToProtected() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/invisibleFake/methodToProtected.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("methodToProtected2.kt")
|
||||
public void testMethodToProtected2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/invisibleFake/methodToProtected2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("methodToPublic.kt")
|
||||
public void testMethodToPublic() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/invisibleFake/methodToPublic.kt");
|
||||
@@ -6313,6 +6331,24 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyToNotProtected.kt")
|
||||
public void testPropertyToNotProtected() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/invisibleFake/propertyToNotProtected.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyToProtected.kt")
|
||||
public void testPropertyToProtected() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/invisibleFake/propertyToProtected.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyToProtected2.kt")
|
||||
public void testPropertyToProtected2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/invisibleFake/propertyToProtected2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyToPublic.kt")
|
||||
public void testPropertyToPublic() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/increaseVisibility/invisibleFake/propertyToPublic.kt");
|
||||
|
||||
Reference in New Issue
Block a user