Remove Function Body Quick-Fix: Convert to Kotlin & refactor. Add tests with comments
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
#quick fix messages
|
#quick fix messages
|
||||||
add.return.type=Add return type declaration
|
add.return.type=Add return type declaration
|
||||||
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
|
||||||
add.init.keyword.in.whole.project=Add 'init' keyword in whole project
|
add.init.keyword.in.whole.project=Add 'init' keyword in whole project
|
||||||
|
|||||||
@@ -78,8 +78,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
|
|
||||||
ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.registerFactory(removeAbstractModifierFactory, addAbstractToClassFactory)
|
ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.registerFactory(removeAbstractModifierFactory, addAbstractToClassFactory)
|
||||||
|
|
||||||
val removeFunctionBodyFactory = RemoveFunctionBodyFix.createFactory()
|
ABSTRACT_FUNCTION_WITH_BODY.registerFactory(removeAbstractModifierFactory, RemoveFunctionBodyFix)
|
||||||
ABSTRACT_FUNCTION_WITH_BODY.registerFactory(removeAbstractModifierFactory, removeFunctionBodyFactory)
|
|
||||||
|
|
||||||
NON_ABSTRACT_FUNCTION_WITH_NO_BODY.registerFactory(addAbstractModifierFactory, AddFunctionBodyFix)
|
NON_ABSTRACT_FUNCTION_WITH_NO_BODY.registerFactory(addAbstractModifierFactory, AddFunctionBodyFix)
|
||||||
|
|
||||||
|
|||||||
@@ -14,88 +14,44 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.quickfix;
|
package org.jetbrains.kotlin.idea.quickfix
|
||||||
|
|
||||||
import com.intellij.extapi.psi.ASTDelegatePsiElement;
|
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.PsiElement;
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import com.intellij.psi.PsiFile;
|
import org.jetbrains.kotlin.idea.util.CommentSaver
|
||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement;
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import com.intellij.util.IncorrectOperationException;
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.kotlin.psi.psiUtil.PsiChildRange
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle;
|
|
||||||
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil;
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression;
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile;
|
|
||||||
import org.jetbrains.kotlin.psi.KtFunction;
|
|
||||||
|
|
||||||
public class RemoveFunctionBodyFix extends KotlinQuickFixAction<KtFunction> {
|
class RemoveFunctionBodyFix(element: KtFunction) : KotlinQuickFixAction<KtFunction>(element) {
|
||||||
|
override fun getFamilyName() = "Remove function body"
|
||||||
|
|
||||||
public RemoveFunctionBodyFix(@NotNull KtFunction element) {
|
override fun getText() = familyName
|
||||||
super(element);
|
|
||||||
|
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||||
|
return super.isAvailable(project, editor, file) && element.hasBody()
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
@Override
|
val bodyExpression = element.bodyExpression!!
|
||||||
public String getText() {
|
val equalsToken = element.equalsToken
|
||||||
return KotlinBundle.message("remove.function.body");
|
if (equalsToken != null) {
|
||||||
}
|
val commentSaver = CommentSaver(PsiChildRange(equalsToken.nextSibling, bodyExpression.prevSibling), true)
|
||||||
|
element.deleteChildRange(equalsToken, bodyExpression)
|
||||||
@NotNull
|
commentSaver.restore(element)
|
||||||
@Override
|
|
||||||
public String getFamilyName() {
|
|
||||||
return KotlinBundle.message("remove.function.body");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiFile file) {
|
|
||||||
return super.isAvailable(project, editor, file) && getElement().hasBody();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invoke(@NotNull Project project, Editor editor, @NotNull KtFile file) throws IncorrectOperationException {
|
|
||||||
KtFunction function = (KtFunction) getElement().copy();
|
|
||||||
assert function instanceof ASTDelegatePsiElement;
|
|
||||||
ASTDelegatePsiElement functionElementWithAst = (ASTDelegatePsiElement) function;
|
|
||||||
KtExpression bodyExpression = function.getBodyExpression();
|
|
||||||
assert bodyExpression != null;
|
|
||||||
if (function.hasBlockBody()) {
|
|
||||||
PsiElement prevElement = bodyExpression.getPrevSibling();
|
|
||||||
QuickFixUtil.removePossiblyWhiteSpace(functionElementWithAst, prevElement);
|
|
||||||
functionElementWithAst.deleteChildInternal(bodyExpression.getNode());
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PsiElement prevElement = bodyExpression.getPrevSibling();
|
bodyExpression.delete()
|
||||||
PsiElement prevPrevElement = prevElement.getPrevSibling();
|
|
||||||
QuickFixUtil.removePossiblyWhiteSpace(functionElementWithAst, prevElement);
|
|
||||||
removePossiblyEquationSign(functionElementWithAst, prevElement);
|
|
||||||
removePossiblyEquationSign(functionElementWithAst, prevPrevElement);
|
|
||||||
functionElementWithAst.deleteChildInternal(bodyExpression.getNode());
|
|
||||||
}
|
}
|
||||||
getElement().replace(function);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean removePossiblyEquationSign(@NotNull ASTDelegatePsiElement element, @Nullable PsiElement possiblyEq) {
|
companion object : KotlinSingleIntentionActionFactory() {
|
||||||
if (possiblyEq instanceof LeafPsiElement && ((LeafPsiElement)possiblyEq).getElementType() == KtTokens.EQ) {
|
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtFunction>? {
|
||||||
QuickFixUtil.removePossiblyWhiteSpace(element, possiblyEq.getNextSibling());
|
val function = diagnostic.psiElement.getNonStrictParentOfType<KtFunction>() ?: return null
|
||||||
element.deleteChildInternal(possiblyEq.getNode());
|
return RemoveFunctionBodyFix(function)
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static KotlinSingleIntentionActionFactory createFactory() {
|
|
||||||
return new KotlinSingleIntentionActionFactory() {
|
|
||||||
@Override
|
|
||||||
public KotlinQuickFixAction<KtFunction> createAction(@NotNull Diagnostic diagnostic) {
|
|
||||||
KtFunction function = QuickFixUtil.getParentElementOfType(diagnostic, KtFunction.class);
|
|
||||||
if (function == null) return null;
|
|
||||||
return new RemoveFunctionBodyFix(function);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Remove function body" "true"
|
||||||
|
abstract class A() {
|
||||||
|
<caret>abstract fun foo() /*1*/ { // 2
|
||||||
|
// 3
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// "Remove function body" "true"
|
||||||
|
abstract class A() {
|
||||||
|
<caret>abstract fun foo() /*1*/
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// "Remove function body" "true"
|
||||||
|
abstract class A() {
|
||||||
|
<caret>abstract fun foo() = /*1*/
|
||||||
|
{ "" /*2*/ } // 3
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// "Remove function body" "true"
|
||||||
|
abstract class A() {
|
||||||
|
<caret>abstract fun foo() // 3/*1*/
|
||||||
|
}
|
||||||
@@ -63,6 +63,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("abstractFunctionWithBodyWithComments.kt")
|
||||||
|
public void testAbstractFunctionWithBodyWithComments() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/abstract/abstractFunctionWithBodyWithComments.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("abstractFunctionWithBodyWithComments2.kt")
|
||||||
|
public void testAbstractFunctionWithBodyWithComments2() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/abstract/abstractFunctionWithBodyWithComments2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("abstractPropertyInNonAbstractClass1.kt")
|
@TestMetadata("abstractPropertyInNonAbstractClass1.kt")
|
||||||
public void testAbstractPropertyInNonAbstractClass1() throws Exception {
|
public void testAbstractPropertyInNonAbstractClass1() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/abstract/abstractPropertyInNonAbstractClass1.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/abstract/abstractPropertyInNonAbstractClass1.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user