/* * Copyright 2010-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.diagnostics.Diagnostic; import org.jetbrains.kotlin.idea.KotlinBundle; import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil; import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinTypeKt; public class RemovePartsFromPropertyFix extends KotlinQuickFixAction<KtProperty> { private final boolean removeInitializer; private final boolean removeGetter; private final boolean removeSetter; private RemovePartsFromPropertyFix(@NotNull KtProperty element, boolean removeInitializer, boolean removeGetter, boolean removeSetter) { super(element); this.removeInitializer = removeInitializer; this.removeGetter = removeGetter; this.removeSetter = removeSetter; } private RemovePartsFromPropertyFix(@NotNull KtProperty element) { this(element, element.hasInitializer(), element.getGetter() != null && element.getGetter().getBodyExpression() != null, element.getSetter() != null && element.getSetter().getBodyExpression() != null); } private static String partsToRemove(boolean getter, boolean setter, boolean initializer) { StringBuilder sb = new StringBuilder(); if (getter) { sb.append("getter"); if (setter && initializer) { sb.append(", "); } else if (setter || initializer) { sb.append(" and "); } } if (setter) { sb.append("setter"); if (initializer) { sb.append(" and "); } } if (initializer) { sb.append("initializer"); } return sb.toString(); } @NotNull @Override public String getText() { return KotlinBundle.message("remove.parts.from.property", partsToRemove(removeGetter, removeSetter, removeInitializer)); } @NotNull @Override public String getFamilyName() { return KotlinBundle.message("remove.parts.from.property.family"); } @Override public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiFile file) { if (!super.isAvailable(project, editor, file)) return false; KotlinType type = QuickFixUtil.getDeclarationReturnType(getElement()); return type != null && !KotlinTypeKt.isError(type); } @Override public void invoke(@NotNull Project project, Editor editor, @NotNull KtFile file) throws IncorrectOperationException { KotlinType type = QuickFixUtil.getDeclarationReturnType(getElement()); KtProperty newElement = (KtProperty) getElement().copy(); KtPropertyAccessor getter = newElement.getGetter(); if (removeGetter && getter != null) { newElement.deleteChildInternal(getter.getNode()); } KtPropertyAccessor setter = newElement.getSetter(); if (removeSetter && setter != null) { newElement.deleteChildInternal(setter.getNode()); } KtExpression initializer = newElement.getInitializer(); KotlinType typeToAdd = null; if (removeInitializer && initializer != null) { PsiElement nameIdentifier = newElement.getNameIdentifier(); assert nameIdentifier != null; PsiElement nextSibling = nameIdentifier.getNextSibling(); assert nextSibling != null; newElement.deleteChildRange(nextSibling, initializer); if (newElement.getTypeReference() == null && type != null) { typeToAdd = type; } } newElement = (KtProperty) getElement().replace(newElement); if (typeToAdd != null) { SpecifyTypeExplicitlyIntention.Companion.addTypeAnnotation(editor, newElement, typeToAdd); } } public static KotlinSingleIntentionActionFactory createFactory() { return new KotlinSingleIntentionActionFactory() { @Override public KotlinQuickFixAction<KtProperty> createAction(@NotNull Diagnostic diagnostic) { PsiElement element = diagnostic.getPsiElement(); assert element instanceof KtElement; KtProperty property = PsiTreeUtil.getParentOfType(element, KtProperty.class); if (property == null) return null; return new RemovePartsFromPropertyFix(property); } }; } }