diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties index 44cdc4aa6ea..381d1b95957 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties @@ -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() with T::class replace.java.class.argument.family=Replace javaClass() with T::class diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/MakeTypeImplicitInLambdaIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/MakeTypeImplicitInLambdaIntention.kt index e6c9999cd3a..1645eef68a3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/MakeTypeImplicitInLambdaIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/MakeTypeImplicitInLambdaIntention.kt @@ -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( - "make.type.implicit.in.lambda", javaClass()) { +public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention(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) } } diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/explicitReceiverType.kt b/idea/testData/intentions/makeTypeImplicitInLambda/explicitReceiverType.kt deleted file mode 100644 index 7d143d8eb18..00000000000 --- a/idea/testData/intentions/makeTypeImplicitInLambda/explicitReceiverType.kt +++ /dev/null @@ -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 }, 20) -} \ No newline at end of file diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/explicitReceiverType.kt.after b/idea/testData/intentions/makeTypeImplicitInLambda/explicitReceiverType.kt.after deleted file mode 100644 index a98cfa2f954..00000000000 --- a/idea/testData/intentions/makeTypeImplicitInLambda/explicitReceiverType.kt.after +++ /dev/null @@ -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) -} \ No newline at end of file diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/explicitReturnType.kt b/idea/testData/intentions/makeTypeImplicitInLambda/explicitReturnType.kt deleted file mode 100644 index ebc5bb8a3f4..00000000000 --- a/idea/testData/intentions/makeTypeImplicitInLambda/explicitReturnType.kt +++ /dev/null @@ -1,3 +0,0 @@ -fun main() { - val sum = { (x: Int, y: Int): Int -> x + y } -} diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/explicitReturnType.kt.after b/idea/testData/intentions/makeTypeImplicitInLambda/explicitReturnType.kt.after deleted file mode 100644 index f40b050385f..00000000000 --- a/idea/testData/intentions/makeTypeImplicitInLambda/explicitReturnType.kt.after +++ /dev/null @@ -1,3 +0,0 @@ -fun main() { - val sum = { x, y -> x + y } -} diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/invalidCursorPosition.kt b/idea/testData/intentions/makeTypeImplicitInLambda/invalidCursorPosition.kt index 8d8ab10de0a..bb27b205126 100644 --- a/idea/testData/intentions/makeTypeImplicitInLambda/invalidCursorPosition.kt +++ b/idea/testData/intentions/makeTypeImplicitInLambda/invalidCursorPosition.kt @@ -1,4 +1,4 @@ // IS_APPLICABLE: false fun main() { - val sum = { (x: Int, y: Int) -> x + y } + val sum = { x: Int, y: Int -> x + y } } diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/lambdaWithLambdaAsParam.kt b/idea/testData/intentions/makeTypeImplicitInLambda/lambdaWithLambdaAsParam.kt index 4eeb70c0333..a377f8a644c 100644 --- a/idea/testData/intentions/makeTypeImplicitInLambda/lambdaWithLambdaAsParam.kt +++ b/idea/testData/intentions/makeTypeImplicitInLambda/lambdaWithLambdaAsParam.kt @@ -4,5 +4,5 @@ public class TestingUse { } fun main() { - val funcInfunc = TestingUse().test6({(f: (Int) -> Int): Boolean -> f(5) > 20}, {x -> x + 2}) + val funcInfunc = TestingUse().test6({f: (Int) -> Int -> f(5) > 20}, {x -> x + 2}) } diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/multipleExplicitParams.kt b/idea/testData/intentions/makeTypeImplicitInLambda/multipleExplicitParams.kt index 128bdc826ee..c70e095464e 100644 --- a/idea/testData/intentions/makeTypeImplicitInLambda/multipleExplicitParams.kt +++ b/idea/testData/intentions/makeTypeImplicitInLambda/multipleExplicitParams.kt @@ -1,3 +1,3 @@ fun main() { - val f = { (x: Int, str: String): Unit -> x } + val f = { x: Int, str: String -> x } } diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/paramDeclaredReturnNotDeclared.kt b/idea/testData/intentions/makeTypeImplicitInLambda/paramDeclaredReturnNotDeclared.kt deleted file mode 100644 index 5e6a7954e0c..00000000000 --- a/idea/testData/intentions/makeTypeImplicitInLambda/paramDeclaredReturnNotDeclared.kt +++ /dev/null @@ -1,3 +0,0 @@ -fun main() { - val foo: (Int) -> String = {(x: Int) -> "This number is " + x} -} diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/paramTypeDeclared.kt b/idea/testData/intentions/makeTypeImplicitInLambda/paramTypeDeclared.kt new file mode 100644 index 00000000000..7e16596908d --- /dev/null +++ b/idea/testData/intentions/makeTypeImplicitInLambda/paramTypeDeclared.kt @@ -0,0 +1,3 @@ +fun main() { + val foo: (Int) -> String = {x: Int -> "This number is " + x} +} diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/paramDeclaredReturnNotDeclared.kt.after b/idea/testData/intentions/makeTypeImplicitInLambda/paramTypeDeclared.kt.after similarity index 100% rename from idea/testData/intentions/makeTypeImplicitInLambda/paramDeclaredReturnNotDeclared.kt.after rename to idea/testData/intentions/makeTypeImplicitInLambda/paramTypeDeclared.kt.after diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/returnDeclaredParamNotDeclared.kt b/idea/testData/intentions/makeTypeImplicitInLambda/returnDeclaredParamNotDeclared.kt deleted file mode 100644 index e3ea2cf2faa..00000000000 --- a/idea/testData/intentions/makeTypeImplicitInLambda/returnDeclaredParamNotDeclared.kt +++ /dev/null @@ -1,3 +0,0 @@ -fun main() { - val bar: (Array) -> Int = {(arr): Int -> arr.size()} -} diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/returnDeclaredParamNotDeclared.kt.after b/idea/testData/intentions/makeTypeImplicitInLambda/returnDeclaredParamNotDeclared.kt.after deleted file mode 100644 index ade25630210..00000000000 --- a/idea/testData/intentions/makeTypeImplicitInLambda/returnDeclaredParamNotDeclared.kt.after +++ /dev/null @@ -1,3 +0,0 @@ -fun main() { - val bar: (Array) -> Int = { arr -> arr.size()} -} diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/singleExplicitParam.kt b/idea/testData/intentions/makeTypeImplicitInLambda/singleExplicitParam.kt index cfd7e850334..7f1920df3f7 100644 --- a/idea/testData/intentions/makeTypeImplicitInLambda/singleExplicitParam.kt +++ b/idea/testData/intentions/makeTypeImplicitInLambda/singleExplicitParam.kt @@ -1,3 +1,3 @@ fun main() { - val double = { (x: Int) -> x * 2 } + val double = { x: Int -> x * 2 } } diff --git a/idea/testData/intentions/makeTypeImplicitInLambda/typesAlreadyImplicit.kt b/idea/testData/intentions/makeTypeImplicitInLambda/typesAlreadyImplicit.kt index 9a0731949b6..ec1d85fca9a 100644 --- a/idea/testData/intentions/makeTypeImplicitInLambda/typesAlreadyImplicit.kt +++ b/idea/testData/intentions/makeTypeImplicitInLambda/typesAlreadyImplicit.kt @@ -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 }) + val num = testing(1, 2, { x, y -> x + y }) } diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 6afba0b33bf..13b4c7247ca 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -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); }