Change Visibility Modifier Quick-Fix: Convert to Kotlin & refactor
This commit is contained in:
@@ -90,7 +90,6 @@ livetemplate.description.anonymous=Anonymous class
|
|||||||
livetemplate.description.exfun=Extension function
|
livetemplate.description.exfun=Extension function
|
||||||
livetemplate.description.exval=Extension read-only property
|
livetemplate.description.exval=Extension read-only property
|
||||||
livetemplate.description.exvar=Extension read-write property
|
livetemplate.description.exvar=Extension read-write property
|
||||||
change.visibility.modifier=Change visibility modifier
|
|
||||||
|
|
||||||
options.kotlin.attribute.descriptor.builtin.annotation=Built-in annotation
|
options.kotlin.attribute.descriptor.builtin.annotation=Built-in annotation
|
||||||
options.kotlin.attribute.descriptor.string.escape=Escape in string and template braces
|
options.kotlin.attribute.descriptor.string.escape=Escape in string and template braces
|
||||||
|
|||||||
@@ -14,108 +14,28 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.quickfix;
|
package org.jetbrains.kotlin.idea.quickfix
|
||||||
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement;
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import com.intellij.psi.PsiFile;
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import com.intellij.util.IncorrectOperationException;
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities;
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility;
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle;
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
|
|
||||||
import org.jetbrains.kotlin.idea.core.DescriptorUtilsKt;
|
|
||||||
import org.jetbrains.kotlin.idea.core.PsiModificationUtilsKt;
|
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
|
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration;
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile;
|
|
||||||
import org.jetbrains.kotlin.psi.KtParameter;
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
|
||||||
|
|
||||||
public class ChangeVisibilityModifierFix extends KotlinQuickFixAction<KtDeclaration> {
|
class ChangeVisibilityModifierFix(element: KtDeclaration) : KotlinQuickFixAction<KtDeclaration>(element) {
|
||||||
public ChangeVisibilityModifierFix(@NotNull KtDeclaration element) {
|
override fun getFamilyName() = "Use inherited visibility"
|
||||||
super(element);
|
|
||||||
|
override fun getText() = familyName
|
||||||
|
|
||||||
|
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
|
element.removeModifier(element.visibilityModifierType()!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
companion object : KotlinSingleIntentionActionFactory() {
|
||||||
@Override
|
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtDeclaration>? {
|
||||||
public String getText() {
|
val element = diagnostic.psiElement as? KtDeclaration ?: return null
|
||||||
return KotlinBundle.message("change.visibility.modifier");
|
return ChangeVisibilityModifierFix(element)
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getFamilyName() {
|
|
||||||
return KotlinBundle.message("change.visibility.modifier");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiFile file) {
|
|
||||||
if (!(file instanceof KtFile)) return false;
|
|
||||||
return super.isAvailable(project, editor, file) && (findVisibilityChangeTo() != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invoke(@NotNull Project project, Editor editor, @NotNull KtFile file) throws IncorrectOperationException {
|
|
||||||
KtModifierKeywordToken modifier = findVisibilityChangeTo();
|
|
||||||
assert modifier != null;
|
|
||||||
PsiModificationUtilsKt.setVisibility(getElement(), modifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private KtModifierKeywordToken findVisibilityChangeTo() {
|
|
||||||
BindingContext bindingContext = ResolutionUtils.analyze(getElement());
|
|
||||||
DeclarationDescriptor descriptor;
|
|
||||||
if (getElement() instanceof KtParameter) {
|
|
||||||
descriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, getElement());
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, getElement());
|
|
||||||
}
|
|
||||||
if (!(descriptor instanceof CallableMemberDescriptor)) return null;
|
|
||||||
|
|
||||||
CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor)descriptor;
|
|
||||||
Visibility maxVisibility = null;
|
|
||||||
for (CallableMemberDescriptor overriddenDescriptor : memberDescriptor.getOverriddenDescriptors()) {
|
|
||||||
Visibility overriddenDescriptorVisibility = overriddenDescriptor.getVisibility();
|
|
||||||
if (maxVisibility == null) {
|
|
||||||
maxVisibility = overriddenDescriptorVisibility;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Integer compare = Visibilities.compare(maxVisibility, overriddenDescriptorVisibility);
|
|
||||||
if (compare == null) {
|
|
||||||
maxVisibility = Visibilities.PUBLIC;
|
|
||||||
}
|
|
||||||
else if (compare < 0) {
|
|
||||||
maxVisibility = overriddenDescriptorVisibility;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (maxVisibility == memberDescriptor.getVisibility()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxVisibility == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DescriptorUtilsKt.toKeywordToken(maxVisibility);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static KotlinSingleIntentionActionFactory createFactory() {
|
|
||||||
return new KotlinSingleIntentionActionFactory() {
|
|
||||||
@Override
|
|
||||||
public KotlinQuickFixAction<KtDeclaration> createAction(@NotNull Diagnostic diagnostic) {
|
|
||||||
PsiElement element = diagnostic.getPsiElement();
|
|
||||||
if (!(element instanceof KtDeclaration)) return null;
|
|
||||||
return new ChangeVisibilityModifierFix((KtDeclaration)element);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,8 +143,8 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
SUPERTYPE_NOT_INITIALIZED.registerFactory(SuperClassNotInitialized)
|
SUPERTYPE_NOT_INITIALIZED.registerFactory(SuperClassNotInitialized)
|
||||||
FUNCTION_CALL_EXPECTED.registerFactory(ChangeToFunctionInvocationFix)
|
FUNCTION_CALL_EXPECTED.registerFactory(ChangeToFunctionInvocationFix)
|
||||||
|
|
||||||
CANNOT_CHANGE_ACCESS_PRIVILEGE.registerFactory(ChangeVisibilityModifierFix.createFactory())
|
CANNOT_CHANGE_ACCESS_PRIVILEGE.registerFactory(ChangeVisibilityModifierFix)
|
||||||
CANNOT_WEAKEN_ACCESS_PRIVILEGE.registerFactory(ChangeVisibilityModifierFix.createFactory())
|
CANNOT_WEAKEN_ACCESS_PRIVILEGE.registerFactory(ChangeVisibilityModifierFix)
|
||||||
|
|
||||||
INVISIBLE_REFERENCE.registerFactory(ChangePrivateTopLevelToInternalFix)
|
INVISIBLE_REFERENCE.registerFactory(ChangePrivateTopLevelToInternalFix)
|
||||||
INVISIBLE_MEMBER.registerFactory(ChangePrivateTopLevelToInternalFix)
|
INVISIBLE_MEMBER.registerFactory(ChangePrivateTopLevelToInternalFix)
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Change visibility modifier" "true"
|
// "Use inherited visibility" "true"
|
||||||
open class A {
|
open class A {
|
||||||
protected open fun run() {}
|
protected open fun run() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// "Change visibility modifier" "true"
|
// "Use inherited visibility" "true"
|
||||||
open class A {
|
open class A {
|
||||||
protected open fun run() {}
|
protected open fun run() {}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Change visibility modifier" "true"
|
// "Use inherited visibility" "true"
|
||||||
open class A {
|
open class A {
|
||||||
protected open fun run() {}
|
protected open fun run() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// "Change visibility modifier" "true"
|
// "Use inherited visibility" "true"
|
||||||
open class A {
|
open class A {
|
||||||
protected open fun run() {}
|
protected open fun run() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// "Change visibility modifier" "true"
|
// "Use inherited visibility" "true"
|
||||||
abstract class C : ClassLoader() {
|
abstract class C : ClassLoader() {
|
||||||
<caret>private override fun findClass(var1: String): Class<*> {
|
<caret>private override fun findClass(var1: String): Class<*> {
|
||||||
throw ClassNotFoundException(var1)
|
throw ClassNotFoundException(var1)
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Change visibility modifier" "true"
|
// "Use inherited visibility" "true"
|
||||||
abstract class C : ClassLoader() {
|
abstract class C : ClassLoader() {
|
||||||
<caret>override fun findClass(var1: String): Class<*> {
|
<caret>override fun findClass(var1: String): Class<*> {
|
||||||
throw ClassNotFoundException(var1)
|
throw ClassNotFoundException(var1)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// "Change visibility modifier" "true"
|
// "Use inherited visibility" "true"
|
||||||
interface ParseResult<out T> {
|
interface ParseResult<out T> {
|
||||||
public val success : Boolean
|
public val success : Boolean
|
||||||
public val value : T
|
public val value : T
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// "Change visibility modifier" "true"
|
// "Use inherited visibility" "true"
|
||||||
interface ParseResult<out T> {
|
interface ParseResult<out T> {
|
||||||
public val success : Boolean
|
public val success : Boolean
|
||||||
public val value : T
|
public val value : T
|
||||||
|
|||||||
Reference in New Issue
Block a user