Added feature to "Convert to expression body" intention: selection for easier explicit type removal

This commit is contained in:
Valentin Kipyatkov
2014-10-23 11:08:12 +04:00
parent ea69f5a9a6
commit d13fd19a63
11 changed files with 46 additions and 5 deletions
@@ -25,6 +25,10 @@ import org.jetbrains.jet.plugin.JetBundle
import org.jetbrains.jet.lang.psi.*
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lexer.JetTokens
import com.intellij.openapi.util.TextRange
import org.jetbrains.jet.lang.psi.psiUtil.siblings
import org.jetbrains.jet.plugin.caches.resolve.getLazyResolveSession
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorWithVisibility
public class ConvertToExpressionBodyAction : PsiElementBaseIntentionAction() {
override fun getFamilyName(): String = JetBundle.message("convert.to.expression.body.action.family.name")
@@ -48,6 +52,19 @@ public class ConvertToExpressionBodyAction : PsiElementBaseIntentionAction() {
val body = declaration.getBodyExpression()!!
declaration.addBefore(JetPsiFactory(declaration).createEQ(), body)
body.replace(value)
if (declaration.hasDeclaredReturnType() && declaration is JetCallableDeclaration && canOmitType(declaration)) {
val typeRef = declaration.getTypeReference()!!
val colon = typeRef.siblings(forward = false, withItself = false).first { it.getNode().getElementType() == JetTokens.COLON }
val range = TextRange(colon.getTextRange().getStartOffset(), typeRef.getTextRange().getEndOffset())
editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset())
editor.getCaretModel().moveToOffset(range.getEndOffset())
}
}
private fun canOmitType(declaration: JetCallableDeclaration): Boolean {
val descriptor = declaration.getLazyResolveSession().resolveToDescriptor(declaration)
return !((descriptor as? DeclarationDescriptorWithVisibility)?.getVisibility()?.isPublicAPI() ?: false)
}
private data class Data(val declaration: JetDeclarationWithBody, val value: JetExpression)
@@ -2,7 +2,7 @@ trait I {
fun foo(): String
}
fun bar(): I = object: I {
fun bar()<selection>: I</selection> = object: I {
override fun foo(): String {
return "a"
}
@@ -1,3 +1,3 @@
// WITH_RUNTIME
fun foo(): Unit = throw UnsupportedOperationException()
fun foo()<selection>: Unit</selection> = throw UnsupportedOperationException()
@@ -1,3 +1,3 @@
// WITH_RUNTIME
fun foo(): Nothing = throw UnsupportedOperationException()
fun foo()<selection>: Nothing</selection> = throw UnsupportedOperationException()
@@ -1 +1 @@
fun foo(): String = "abc"
fun foo()<selection>: String</selection> = "abc"
@@ -1,3 +1,3 @@
// WITH_RUNTIME
fun foo(): Unit = throw UnsupportedOperationException()
fun foo()<selection>: Unit</selection> = throw UnsupportedOperationException()
@@ -0,0 +1,5 @@
open class A {
protected fun <caret>foo(): String {
return "abc"
}
}
@@ -0,0 +1,3 @@
open class A {
protected fun <caret>foo(): String = "abc"
}
@@ -0,0 +1,3 @@
public fun <caret>foo(): String {
return "abc"
}
@@ -0,0 +1 @@
public fun <caret>foo(): String = "abc"
@@ -3138,6 +3138,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("protectedFunNoSelection.kt")
public void testProtectedFunNoSelection() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/protectedFunNoSelection.kt");
doTest(fileName);
}
@TestMetadata("publicFunNoSelection.kt")
public void testPublicFunNoSelection() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/publicFunNoSelection.kt");
doTest(fileName);
}
@TestMetadata("returnWithNoValue.kt")
public void testReturnWithNoValue() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/returnWithNoValue.kt");