"Make types implicit in lambda" intention - adapted to new lambda syntax + do not work on closing brace

This commit is contained in:
Valentin Kipyatkov
2015-04-28 17:58:19 +03:00
parent c6b18efb15
commit 175806a902
17 changed files with 19 additions and 122 deletions
@@ -312,8 +312,6 @@ remove.explicit.type.arguments=Remove explicit type arguments
remove.explicit.type.arguments.family=Remove Explicit Type Arguments
convert.if.with.throw.to.assert=Replace 'if' with 'assert' statement
convert.if.with.throw.to.assert.family=Replace 'if' with 'assert' Statement
make.type.implicit.in.lambda=Make types implicit in lambda (may break code)
make.type.implicit.in.lambda.family=Make Types Implicit In Lambda (May Break Code)
replace.java.class.argument=Replace javaClass<T>() with T::class
replace.java.class.argument.family=Replace javaClass<T>() with T::class
@@ -21,71 +21,18 @@ import org.jetbrains.kotlin.psi.JetFunctionLiteralExpression
import org.jetbrains.kotlin.psi.JetPsiFactory
import org.jetbrains.kotlin.lexer.JetTokens
public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention<JetFunctionLiteralExpression>(
"make.type.implicit.in.lambda", javaClass()) {
public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention<JetFunctionLiteralExpression>(javaClass(), "Make types implicit in lambda (may break code)") {
override fun isApplicableTo(element: JetFunctionLiteralExpression, caretOffset: Int): Boolean {
val openBraceOffset = element.getLeftCurlyBrace().getStartOffset()
val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset()
val arrow = element.getFunctionLiteral().getArrowNode()
if (arrow != null && !(openBraceOffset < caretOffset && caretOffset < arrow.getStartOffset() + 2) &&
caretOffset != closeBraceOffset) return false
else if (arrow == null && caretOffset != openBraceOffset + 1 && caretOffset != closeBraceOffset) return false
return hasExplicitReturnType(element) || hasExplicitReceiverType(element) || hasExplicitParamType(element)
if (element.getValueParameters().none { it.getTypeReference() != null }) return false
val arrow = element.getFunctionLiteral().getArrowNode() ?: return false
return caretOffset <= arrow.getTextRange().getEndOffset()
}
override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) {
val functionLiteral = element.getFunctionLiteral()
val oldParameterList = functionLiteral.getValueParameterList()
val oldParameterList = element.getFunctionLiteral().getValueParameterList()!!
val psiFactory = JetPsiFactory(element)
if (hasExplicitReturnType(element)) {
val childAfterParamList = oldParameterList?.getNextSibling()
val arrow = functionLiteral.getArrowNode()?.getPsi()
val childBeforeArrow = arrow?.getPrevSibling()
functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow)
val whiteSpaceBeforeArrow = psiFactory.createWhiteSpace()
functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow)
}
if (hasExplicitReceiverType(element)) {
val childAfterBrace = functionLiteral.getLBrace()?.getNextSibling()
val childBeforeParamList = oldParameterList?.getPrevSibling()
functionLiteral.deleteChildRange(childAfterBrace, childBeforeParamList)
}
if (oldParameterList?.getParameters() != null && hasExplicitParamType(element)) {
val parameterString = oldParameterList!!.getParameters().map({ parameter ->
parameter.getNameIdentifier()!!.getText()
}).makeString(", ", "(", ")")
val newParameterList = psiFactory.createParameterList(parameterString)
oldParameterList.replace(newParameterList)
}
if (!hasExplicitParamType(element)) {
val currentParamList = element.getFunctionLiteral().getValueParameterList()
val firstChild = currentParamList?.getFirstChild()
if (firstChild?.getNode()?.getElementType() == JetTokens.LPAR) firstChild!!.delete()
val lastChild = currentParamList?.getLastChild()
if (lastChild?.getNode()?.getElementType() == JetTokens.RPAR) lastChild!!.delete()
}
}
private fun hasExplicitReturnType(element: JetFunctionLiteralExpression): Boolean {
return element.hasDeclaredReturnType()
}
private fun hasExplicitReceiverType(element: JetFunctionLiteralExpression): Boolean {
return element.getFunctionLiteral().getReceiverTypeReference() != null
}
private fun hasExplicitParamType(element: JetFunctionLiteralExpression): Boolean {
val parameters = element.getFunctionLiteral().getValueParameterList()?.getParameters()
if (parameters == null) return false
var hasExplicitParamType = false
for (param in parameters) {
if (param.getTypeReference() != null) hasExplicitParamType = true
if (param.getNameIdentifier()?.getText() == null) return false
}
return hasExplicitParamType
val parameterString = oldParameterList.getParameters().map { it.getName() }.joinToString(", ")
val newParameterList = JetPsiFactory(element).createFunctionLiteralParameterList(parameterString)
oldParameterList.replace(newParameterList)
}
}
@@ -1,9 +0,0 @@
public class TestingUse {
fun test(sum: Int.(a: Int) -> Int, b: Int): Int {
return b.sum(b)
}
}
fun main() {
val num = TestingUse().test({ Int.(x: Int): Int -> x + 2 <caret>}, 20)
}
@@ -1,9 +0,0 @@
public class TestingUse {
fun test(sum: Int.(a: Int) -> Int, b: Int): Int {
return b.sum(b)
}
}
fun main() {
val num = TestingUse().test({ x -> x + 2 }, 20)
}
@@ -1,3 +0,0 @@
fun main() {
val sum = { (<caret>x: Int, y: Int): Int -> x + y }
}
@@ -1,3 +0,0 @@
fun main() {
val sum = { x, y -> x + y }
}
@@ -1,4 +1,4 @@
// IS_APPLICABLE: false
fun main() {
val sum = { (x: Int, y: Int) -> <caret>x + y }
val sum = { x: Int, y: Int -> <caret>x + y }
}
@@ -4,5 +4,5 @@ public class TestingUse {
}
fun main() {
val funcInfunc = TestingUse().test6({<caret>(f: (Int) -> Int): Boolean -> f(5) > 20}, {x -> x + 2})
val funcInfunc = TestingUse().test6({<caret>f: (Int) -> Int -> f(5) > 20}, {x -> x + 2})
}
@@ -1,3 +1,3 @@
fun main() {
val f = {<caret> (x: Int, str: String): Unit -> x }
val f = {<caret> x: Int, str: String -> x }
}
@@ -1,3 +0,0 @@
fun main() {
val foo: (Int) -> String = {(x: Int) -> "This number is " + x<caret>}
}
@@ -0,0 +1,3 @@
fun main() {
val foo: (Int) -> String = {x: Int<caret> -> "This number is " + x}
}
@@ -1,3 +0,0 @@
fun main() {
val bar: (Array<String>) -> Int = {<caret>(arr): Int -> arr.size()}
}
@@ -1,3 +0,0 @@
fun main() {
val bar: (Array<String>) -> Int = { arr -> arr.size()}
}
@@ -1,3 +1,3 @@
fun main() {
val double = { (<caret>x: Int) -> x * 2 }
val double = { <caret>x: Int -> x * 2 }
}
@@ -4,5 +4,5 @@ fun testing(x: Int, y: Int, f: (a: Int, b: Int) -> Int): Int {
}
fun main() {
val num = testing(1, 2, { x, y -> x + y <caret>})
val num = testing(1, 2, {<caret> x, y -> x + y })
}
@@ -4357,18 +4357,6 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/makeTypeImplicitInLambda"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("explicitReceiverType.kt")
public void testExplicitReceiverType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/makeTypeImplicitInLambda/explicitReceiverType.kt");
doTest(fileName);
}
@TestMetadata("explicitReturnType.kt")
public void testExplicitReturnType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/makeTypeImplicitInLambda/explicitReturnType.kt");
doTest(fileName);
}
@TestMetadata("invalidCursorPosition.kt")
public void testInvalidCursorPosition() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/makeTypeImplicitInLambda/invalidCursorPosition.kt");
@@ -4387,15 +4375,9 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("paramDeclaredReturnNotDeclared.kt")
public void testParamDeclaredReturnNotDeclared() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/makeTypeImplicitInLambda/paramDeclaredReturnNotDeclared.kt");
doTest(fileName);
}
@TestMetadata("returnDeclaredParamNotDeclared.kt")
public void testReturnDeclaredParamNotDeclared() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/makeTypeImplicitInLambda/returnDeclaredParamNotDeclared.kt");
@TestMetadata("paramTypeDeclared.kt")
public void testParamTypeDeclared() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/makeTypeImplicitInLambda/paramTypeDeclared.kt");
doTest(fileName);
}