Change Accessor Type Quick-Fix: Convert to Kotlin & refactor

This commit is contained in:
Alexey Sedunov
2015-12-25 15:53:09 +03:00
parent 54b149ce71
commit a696efc3ef
3 changed files with 46 additions and 80 deletions
@@ -1,8 +1,5 @@
#quick fix messages #quick fix messages
add.return.type=Add return type declaration add.return.type=Add return type declaration
change.accessor.type=Change accessor type
change.getter.type=Change getter type to {0}
change.setter.type=Change setter parameter type to {0}
remove.function.body=Remove function body remove.function.body=Remove function body
add.init.keyword=Add 'init' keyword add.init.keyword=Add 'init' keyword
add.init.keyword.family=Add 'init' keyword add.init.keyword.family=Add 'init' keyword
@@ -14,84 +14,54 @@
* 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.PsiFile; import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.kotlin.descriptors.VariableDescriptor
import com.intellij.util.IncorrectOperationException; import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic; import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.KotlinBundle; import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil; import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers; import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.idea.util.ShortenReferences; import org.jetbrains.kotlin.psi.KtPropertyAccessor
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.types.KotlinType
public class ChangeAccessorTypeFix extends KotlinQuickFixAction<KtPropertyAccessor> { class ChangeAccessorTypeFix(element: KtPropertyAccessor) : KotlinQuickFixAction<KtPropertyAccessor>(element) {
private KotlinType type; private fun getType(): KotlinType? {
val type = (element.property.resolveToDescriptor() as VariableDescriptor).type
public ChangeAccessorTypeFix(@NotNull KtPropertyAccessor element) { if (type.isError) return null
super(element); return type
} }
@Override override fun isAvailable(project: Project, editor: Editor?, file: PsiFile) = super.isAvailable(project, editor, file) && getType() != null
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiFile file) {
KtProperty property = PsiTreeUtil.getParentOfType(getElement(), KtProperty.class); override fun getFamilyName() = "Change accessor type"
if (property == null) return false;
KotlinType type = QuickFixUtil.getDeclarationReturnType(property); override fun getText(): String {
if (super.isAvailable(project, editor, file) && type != null && !type.isError()) { val type = getType() ?: return familyName
this.type = type; val renderedType = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)
return true; val target = if (element.isGetter) "getter" else "setter parameter"
return "Change $target type to $renderedType"
}
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val type = getType()!!
val newTypeReference = KtPsiFactory(file).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type))
val typeReference = if (element.isGetter) element.returnTypeReference else element.parameter!!.typeReference
val insertedTypeRef = typeReference!!.replaced(newTypeReference)
ShortenReferences.DEFAULT.process(insertedTypeRef)
}
companion object : KotlinSingleIntentionActionFactory() {
public override fun createAction(diagnostic: Diagnostic): ChangeAccessorTypeFix? {
return diagnostic.psiElement.getNonStrictParentOfType<KtPropertyAccessor>()?.let { ChangeAccessorTypeFix(it) }
} }
return false;
}
@NotNull
@Override
public String getText() {
return KotlinBundle.message(
getElement().isGetter() ? "change.getter.type" : "change.setter.type",
IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)
);
}
@NotNull
@Override
public String getFamilyName() {
return KotlinBundle.message("change.accessor.type");
}
@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull KtFile file) throws IncorrectOperationException {
KtTypeReference newTypeReference = KtPsiFactoryKt
.KtPsiFactory(file).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type));
KtTypeReference typeReference;
if (getElement().isGetter()) {
typeReference = getElement().getReturnTypeReference();
}
else {
KtParameter parameter = getElement().getParameter();
assert parameter != null;
typeReference = parameter.getTypeReference();
}
assert typeReference != null;
newTypeReference = (KtTypeReference) typeReference.replace(newTypeReference);
ShortenReferences.DEFAULT.process(newTypeReference);
}
public static KotlinSingleIntentionActionFactory createFactory() {
return new KotlinSingleIntentionActionFactory() {
@Override
public KotlinQuickFixAction<KtPropertyAccessor> createAction(@NotNull Diagnostic diagnostic) {
KtPropertyAccessor accessor = QuickFixUtil.getParentElementOfType(diagnostic, KtPropertyAccessor.class);
if (accessor == null) return null;
return new ChangeAccessorTypeFix(accessor);
}
};
} }
} }
@@ -96,9 +96,8 @@ class QuickFixRegistrar : QuickFixContributor {
USELESS_CAST.registerFactory(RemoveRightPartOfBinaryExpressionFix.createRemoveTypeFromBinaryExpressionFactory("Remove cast")) USELESS_CAST.registerFactory(RemoveRightPartOfBinaryExpressionFix.createRemoveTypeFromBinaryExpressionFactory("Remove cast"))
val changeAccessorTypeFactory = ChangeAccessorTypeFix.createFactory() WRONG_SETTER_PARAMETER_TYPE.registerFactory(ChangeAccessorTypeFix)
WRONG_SETTER_PARAMETER_TYPE.registerFactory(changeAccessorTypeFactory) WRONG_GETTER_RETURN_TYPE.registerFactory(ChangeAccessorTypeFix)
WRONG_GETTER_RETURN_TYPE.registerFactory(changeAccessorTypeFactory)
USELESS_ELVIS.registerFactory(RemoveRightPartOfBinaryExpressionFix.createRemoveElvisOperatorFactory()) USELESS_ELVIS.registerFactory(RemoveRightPartOfBinaryExpressionFix.createRemoveElvisOperatorFactory())