Change Visibility Modifier Quick-Fix: Convert to Kotlin & refactor

This commit is contained in:
Alexey Sedunov
2016-01-06 12:07:18 +03:00
parent 1e77caedbc
commit b8a8f1638f
11 changed files with 28 additions and 109 deletions
@@ -90,7 +90,6 @@ livetemplate.description.anonymous=Anonymous class
livetemplate.description.exfun=Extension function
livetemplate.description.exval=Extension read-only 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.string.escape=Escape in string and template braces
@@ -14,108 +14,28 @@
* 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.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
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;
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
public class ChangeVisibilityModifierFix extends KotlinQuickFixAction<KtDeclaration> {
public ChangeVisibilityModifierFix(@NotNull KtDeclaration element) {
super(element);
class ChangeVisibilityModifierFix(element: KtDeclaration) : KotlinQuickFixAction<KtDeclaration>(element) {
override fun getFamilyName() = "Use inherited visibility"
override fun getText() = familyName
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
element.removeModifier(element.visibilityModifierType()!!)
}
@NotNull
@Override
public String getText() {
return KotlinBundle.message("change.visibility.modifier");
}
@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());
companion object : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtDeclaration>? {
val element = diagnostic.psiElement as? KtDeclaration ?: return null
return ChangeVisibilityModifierFix(element)
}
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)
FUNCTION_CALL_EXPECTED.registerFactory(ChangeToFunctionInvocationFix)
CANNOT_CHANGE_ACCESS_PRIVILEGE.registerFactory(ChangeVisibilityModifierFix.createFactory())
CANNOT_WEAKEN_ACCESS_PRIVILEGE.registerFactory(ChangeVisibilityModifierFix.createFactory())
CANNOT_CHANGE_ACCESS_PRIVILEGE.registerFactory(ChangeVisibilityModifierFix)
CANNOT_WEAKEN_ACCESS_PRIVILEGE.registerFactory(ChangeVisibilityModifierFix)
INVISIBLE_REFERENCE.registerFactory(ChangePrivateTopLevelToInternalFix)
INVISIBLE_MEMBER.registerFactory(ChangePrivateTopLevelToInternalFix)
+1 -1
View File
@@ -1,4 +1,4 @@
// "Change visibility modifier" "true"
// "Use inherited visibility" "true"
open class A {
protected open fun run() {}
}
@@ -1,4 +1,4 @@
// "Change visibility modifier" "true"
// "Use inherited visibility" "true"
open class A {
protected open fun run() {}
}
+1 -1
View File
@@ -1,4 +1,4 @@
// "Change visibility modifier" "true"
// "Use inherited visibility" "true"
open class A {
protected open fun run() {}
}
@@ -1,4 +1,4 @@
// "Change visibility modifier" "true"
// "Use inherited visibility" "true"
open class A {
protected open fun run() {}
}
@@ -1,4 +1,4 @@
// "Change visibility modifier" "true"
// "Use inherited visibility" "true"
abstract class C : ClassLoader() {
<caret>private override fun findClass(var1: String): Class<*> {
throw ClassNotFoundException(var1)
@@ -1,4 +1,4 @@
// "Change visibility modifier" "true"
// "Use inherited visibility" "true"
abstract class C : ClassLoader() {
<caret>override fun findClass(var1: String): Class<*> {
throw ClassNotFoundException(var1)
@@ -1,4 +1,4 @@
// "Change visibility modifier" "true"
// "Use inherited visibility" "true"
interface ParseResult<out T> {
public val success : Boolean
public val value : T
@@ -1,4 +1,4 @@
// "Change visibility modifier" "true"
// "Use inherited visibility" "true"
interface ParseResult<out T> {
public val success : Boolean
public val value : T