Added KT-4579 makeTypeExplicitInLambda and makeTypeImplicitInLambda intentions
This commit is contained in:
committed by
Alexander Udalov
parent
1ef785eb1a
commit
6066d19de5
@@ -409,6 +409,8 @@ fun main(args: Array<String>) {
|
||||
model("intentions/removeExplicitTypeArguments", testMethod = "doTestRemoveExplicitTypeArguments")
|
||||
model("intentions/convertAssertToIf", testMethod = "doTestConvertAssertToIfWithThrowIntention")
|
||||
model("intentions/convertIfToAssert", testMethod = "doTestConvertIfWithThrowToAssertIntention")
|
||||
model("intentions/makeTypeExplicitInLambda", testMethod = "doTestMakeTypeExplicitInLambda")
|
||||
model("intentions/makeTypeImplicitInLambda", testMethod = "doTestMakeTypeImplicitInLambda")
|
||||
}
|
||||
|
||||
testClass(javaClass<AbstractJetInspectionTest>()) {
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
foo(1, 2, <spot>{(a: Int, b: Int): Int -> a + b}</spot>)
|
||||
+1
@@ -0,0 +1 @@
|
||||
foo(1, 2, <spot>{a, b -> a + b}</spot>)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention makes types of parameters, receiver, and return type explicit in a lambda expression.
|
||||
</body>
|
||||
</html>
|
||||
+1
@@ -0,0 +1 @@
|
||||
foo(1, 2, <spot>{a, b -> a + b}</spot>)
|
||||
+1
@@ -0,0 +1 @@
|
||||
foo(1, 2, <spot>{(a: Int, b:Int): Int -> a + b}</spot>)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention makes types of parameters, receiver, and return type implicit in a lambda expression
|
||||
</body>
|
||||
</html>
|
||||
@@ -687,6 +687,16 @@
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.jet.plugin.intentions.MakeTypeExplicitInLambdaIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.jet.plugin.intentions.MakeTypeImplicitInLambdaIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.jet.plugin.inspections.ExplicitGetInspection"
|
||||
displayName="Explicit 'get'"
|
||||
groupName="Kotlin"
|
||||
|
||||
@@ -308,6 +308,10 @@ convert.assert.to.if.with.throw=Replace 'assert' with 'if' statement
|
||||
convert.assert.to.if.with.throw.family=Replace 'assert' with 'if' statement
|
||||
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.explicit.in.lambda=Make types explicit in lambda
|
||||
make.type.explicit.in.lambda.family=Make Types Explicit In Lambda
|
||||
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)
|
||||
|
||||
property.is.implemented.too.many=Has implementations
|
||||
property.is.overridden.too.many=Is overridden in subclasses
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.jet.plugin.intentions
|
||||
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import org.jetbrains.jet.plugin.codeInsight.ShortenReferences
|
||||
|
||||
public class MakeTypeExplicitInLambdaIntention : JetSelfTargetingIntention<JetFunctionLiteralExpression>(
|
||||
"make.type.explicit.in.lambda", javaClass()) {
|
||||
|
||||
override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean {
|
||||
throw IllegalStateException("isApplicableTo(JetExpressionImpl, Editor) should be called instead")
|
||||
}
|
||||
|
||||
override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean {
|
||||
val openBraceOffset = element.getLeftCurlyBrace().getStartOffset()
|
||||
val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset()
|
||||
val caretLocation = editor.getCaretModel().getOffset()
|
||||
val arrow = element.getFunctionLiteral().getArrowNode()
|
||||
if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) &&
|
||||
caretLocation != closeBraceOffset) return false
|
||||
else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false
|
||||
|
||||
val context = AnalyzerFacadeWithCache.getContextForElement(element)
|
||||
val func = context[BindingContext.FUNCTION, element.getFunctionLiteral()]
|
||||
if (func == null || ErrorUtils.containsErrorType(func)) return false
|
||||
|
||||
if (hasImplicitReturnType(element) && func.getReturnType() != null) return true
|
||||
if (hasImplicitReceiverType(element) && func.getReceiverParameter()?.getType() != null) return true
|
||||
|
||||
val params = element.getValueParameters()
|
||||
return params.any { it.getTypeReference() == null }
|
||||
}
|
||||
|
||||
override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) {
|
||||
val functionLiteral = element.getFunctionLiteral()
|
||||
val context = AnalyzerFacadeWithCache.getContextForElement(element)
|
||||
val func = context[BindingContext.FUNCTION, functionLiteral]!!
|
||||
|
||||
// Step 1: make the parameters types explicit
|
||||
val valueParameters = func.getValueParameters()
|
||||
val parameterString = valueParameters.map({descriptor -> "" + descriptor.getName() +
|
||||
": " + DescriptorRenderer.SOURCE_CODE.renderType(descriptor.getType())
|
||||
}).makeString(", ", "(", ")")
|
||||
val newParameterList = JetPsiFactory.createParameterList(element.getProject(), parameterString)
|
||||
val oldParameterList = functionLiteral.getValueParameterList()
|
||||
if (oldParameterList != null) {
|
||||
oldParameterList.replace(newParameterList)
|
||||
}
|
||||
else {
|
||||
val openBraceElement = functionLiteral.getOpenBraceNode().getPsi()
|
||||
val nextSibling = openBraceElement?.getNextSibling()
|
||||
val addNewline = nextSibling is PsiWhiteSpace && "\n" in nextSibling.getText()
|
||||
val whitespaceAndArrow = JetPsiFactory.createWhitespaceAndArrow(element.getProject())
|
||||
functionLiteral.addRangeAfter(whitespaceAndArrow.first, whitespaceAndArrow.second, openBraceElement)
|
||||
functionLiteral.addAfter(newParameterList, openBraceElement)
|
||||
if (addNewline) {
|
||||
functionLiteral.addAfter(JetPsiFactory.createNewLine(element.getProject()), openBraceElement)
|
||||
}
|
||||
}
|
||||
ShortenReferences.process(element.getValueParameters())
|
||||
|
||||
// Step 2: make the return type explicit
|
||||
val expectedReturnType = func.getReturnType()
|
||||
if (hasImplicitReturnType(element) && expectedReturnType != null) {
|
||||
val paramList = functionLiteral.getValueParameterList()
|
||||
val returnTypeColon = JetPsiFactory.createColon(element.getProject())
|
||||
val returnTypeExpr = JetPsiFactory.createType(element.getProject(), DescriptorRenderer.SOURCE_CODE.renderType(expectedReturnType))
|
||||
ShortenReferences.process(returnTypeExpr)
|
||||
functionLiteral.addAfter(returnTypeExpr, paramList)
|
||||
functionLiteral.addAfter(returnTypeColon, paramList)
|
||||
}
|
||||
|
||||
// Step 3: make the receiver type explicit
|
||||
val expectedReceiverType = func.getReceiverParameter()?.getType()
|
||||
if (hasImplicitReceiverType(element) && expectedReceiverType != null) {
|
||||
val receiverTypeString = DescriptorRenderer.SOURCE_CODE.renderType(expectedReceiverType)
|
||||
val paramListString = functionLiteral.getValueParameterList()?.getText()
|
||||
val paramListWithReceiver = JetPsiFactory.createExpression(element.getProject(), receiverTypeString + "." + paramListString)
|
||||
ShortenReferences.process(paramListWithReceiver)
|
||||
functionLiteral.getValueParameterList()?.replace(paramListWithReceiver)
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasImplicitReturnType(element: JetFunctionLiteralExpression): Boolean {
|
||||
return !element.hasDeclaredReturnType()
|
||||
}
|
||||
|
||||
private fun hasImplicitReceiverType(element: JetFunctionLiteralExpression): Boolean {
|
||||
return element.getFunctionLiteral().getReceiverTypeRef() == null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.jet.plugin.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||
import org.jetbrains.jet.lexer.JetTokens
|
||||
|
||||
public class MakeTypeImplicitInLambdaIntention : JetSelfTargetingIntention<JetFunctionLiteralExpression>(
|
||||
"make.type.implicit.in.lambda", javaClass()) {
|
||||
override fun isApplicableTo(element: JetFunctionLiteralExpression): Boolean {
|
||||
throw IllegalStateException("isApplicableTo(JetExpressionImpl, Editor) should be called instead")
|
||||
}
|
||||
|
||||
override fun isApplicableTo(element: JetFunctionLiteralExpression, editor: Editor): Boolean {
|
||||
val openBraceOffset = element.getLeftCurlyBrace().getStartOffset()
|
||||
val closeBraceOffset = element.getRightCurlyBrace()?.getStartOffset()
|
||||
val caretLocation = editor.getCaretModel().getOffset()
|
||||
val arrow = element.getFunctionLiteral().getArrowNode()
|
||||
if (arrow != null && !(openBraceOffset < caretLocation && caretLocation < arrow.getStartOffset() + 2) &&
|
||||
caretLocation != closeBraceOffset) return false
|
||||
else if (arrow == null && caretLocation != openBraceOffset + 1 && caretLocation != closeBraceOffset) return false
|
||||
return hasExplicitReturnType(element) || hasExplicitReceiverType(element) || hasExplicitParamType(element)
|
||||
}
|
||||
|
||||
override fun applyTo(element: JetFunctionLiteralExpression, editor: Editor) {
|
||||
val functionLiteral = element.getFunctionLiteral()
|
||||
val oldParameterList = functionLiteral.getValueParameterList()
|
||||
|
||||
if (hasExplicitReturnType(element)) {
|
||||
val childAfterParamList = oldParameterList?.getNextSibling()
|
||||
val arrow = functionLiteral.getArrowNode()?.getPsi()
|
||||
val childBeforeArrow = arrow?.getPrevSibling()
|
||||
functionLiteral.deleteChildRange(childAfterParamList, childBeforeArrow)
|
||||
val whiteSpaceBeforeArrow = JetPsiFactory.createWhiteSpace(element.getProject())
|
||||
functionLiteral.addBefore(whiteSpaceBeforeArrow, arrow)
|
||||
}
|
||||
|
||||
if (hasExplicitReceiverType(element)) {
|
||||
val childAfterBrace = functionLiteral.getOpenBraceNode().getPsi()?.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 = JetPsiFactory.createParameterList(element.getProject(), 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().getReceiverTypeRef() != 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
public class TestingUse {
|
||||
fun test5(coerced: (x: Int) -> Unit, a: Int): Unit {
|
||||
return coerced(5)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val coercion = TestingUse().test5({<caret>x -> x + 2}, 20)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
public class TestingUse {
|
||||
fun test5(coerced: (x: Int) -> Unit, a: Int): Unit {
|
||||
return coerced(5)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val coercion = TestingUse().test5({(x: Int): Unit -> x + 2}, 20)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
fun main() {
|
||||
val x = {<caret>(): Unit -> }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class TestingUse {
|
||||
fun test3(double: (a: Int) -> Int, b: Int): Int {
|
||||
return double(b)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val num = TestingUse().test3({<caret>it * 2}, 20)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class TestingUse {
|
||||
fun test3(double: (a: Int) -> Int, b: Int): Int {
|
||||
return double(b)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val num = TestingUse().test3({(it: Int): Int -> it * 2}, 20)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun main() {
|
||||
val oom: (Int)->Int = {<caret>
|
||||
it * 2
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
fun main() {
|
||||
val oom: (Int)->Int = {
|
||||
(it: Int): Int ->
|
||||
it * 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val oom = {<caret> -> 42}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val oom = {(): Int -> 42}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
fun main() {
|
||||
val sum : (Int, Int) -> Int = { (x, y) -> <caret>x + y }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
public class TestingUse {
|
||||
fun test6(funcLitfunc: ((x: Int) -> Int) -> Boolean, innerfunc: (y: Int) -> Int): Unit {
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val funcInfunc = TestingUse().test6({<caret>f -> f(5) > 20}, {x -> x + 2})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
public class TestingUse {
|
||||
fun test6(funcLitfunc: ((x: Int) -> Int) -> Boolean, innerfunc: (y: Int) -> Int): Unit {
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val funcInfunc = TestingUse().test6({(f: (Int) -> Int): Boolean -> f(5) > 20}, {x -> x + 2})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
val foo: (Long) -> String = {<caret>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
it.toString()
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
val foo: (Long) -> String = {
|
||||
(it: Long): String ->
|
||||
|
||||
|
||||
it.toString()
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class TestingUse {
|
||||
fun test4(printNum: (a: Int, b: String) -> Unit, c: Int): Int {
|
||||
printNum(c, "This number is")
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val num = TestingUse().test4({(<caret>x, str) -> }, 5)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class TestingUse {
|
||||
fun test4(printNum: (a: Int, b: String) -> Unit, c: Int): Int {
|
||||
printNum(c, "This number is")
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val num = TestingUse().test4({(x: Int, str: String): Unit -> }, 5)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val foo: (Int) -> String = {(x: Int) -> "This number is " + x<caret>}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val foo: (Int) -> String = {(x: Int): String -> "This number is " + x}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val bar: (Array<String>) -> Int = {<caret>(arr): Int -> arr.size}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val bar: (Array<String>) -> Int = {(arr: Array<String>): Int -> arr.size}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val randomFunction: (x: kotlin.Int, y: kotlin.String) -> kotlin.Int = {(<caret>x, str) -> x}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val randomFunction: (x: kotlin.Int, y: kotlin.String) -> kotlin.Int = {(x: Int, str: String): Int -> x}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val randomFunction: kotlin.Array<kotlin.Int>.(x: Int) -> Boolean = {<caret>y -> if (this[0] < y) true else false}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val randomFunction: kotlin.Array<kotlin.Int>.(x: Int) -> Boolean = { Array<Int>.(y: Int): Boolean -> if (this[0] < y) true else false}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class TestingUse {
|
||||
fun test3(double: (a: Int) -> Int, b: Int): Int {
|
||||
return double(b)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val num = TestingUse().test3({<caret>x -> 2*x}, 20)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class TestingUse {
|
||||
fun test3(double: (a: Int) -> Int, b: Int): Int {
|
||||
return double(b)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val num = TestingUse().test3({(x: Int): Int -> 2*x}, 20)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class TestingUse {
|
||||
fun test(sum: Int.(a: Int) -> Int, b: Int): Int {
|
||||
return b.sum(b)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val num = TestingUse().test({ <caret>x -> x + 2 }, 20)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
fun main() {
|
||||
val sum = { Int.(<caret>x: Int, y: Int) : Int -> x + y }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// IS_APPLICABLE: false
|
||||
// ERROR: Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) -> ...} notation
|
||||
// ERROR: Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) -> ...} notation
|
||||
fun main() {
|
||||
val sum = { (x, <caret>y) -> x + y // Type of x and y cannot be inferred, so intention can't be used
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val sum = { (<caret>x: Int, y: Int): Int -> x + y }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val sum = { x, y -> x + y }
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
fun main() {
|
||||
val sum = { (x: Int, y: Int) -> <caret>x + y }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
public class TestingUse {
|
||||
fun test6(funcLitfunc: ((x: Int) -> Int) -> Boolean, innerfunc: (y: Int) -> Int): Unit {
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val funcInfunc = TestingUse().test6({<caret>(f: (Int) -> Int): Boolean -> f(5) > 20}, {x -> x + 2})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
public class TestingUse {
|
||||
fun test6(funcLitfunc: ((x: Int) -> Int) -> Boolean, innerfunc: (y: Int) -> Int): Unit {
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val funcInfunc = TestingUse().test6({ f -> f(5) > 20}, {x -> x + 2})
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val f = {<caret> (x: Int, str: String): Unit -> x }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val f = { x, str -> x }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val foo: (Int) -> String = {(x: Int) -> "This number is " + x<caret>}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val foo: (Int) -> String = { x -> "This number is " + x}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val bar: (Array<String>) -> Int = {<caret>(arr): Int -> arr.size}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val bar: (Array<String>) -> Int = { arr -> arr.size}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val double = { (<caret>x: Int) -> x * 2 }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val double = { x -> x * 2 }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// IS_APPLICABLE: false
|
||||
fun testing(x: Int, y: Int, f: (a: Int, b: Int) -> Int): Int {
|
||||
return f(x, y)
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val num = testing(1, 2, { x, y -> x + y <caret>})
|
||||
}
|
||||
+4
@@ -1,6 +1,10 @@
|
||||
// "Change 'foo' function return type to '([ERROR : NoSuchType]) -> Int'" "false"
|
||||
// ACTION: Disable 'Make Types Implicit In Lambda (May Break Code)'
|
||||
// ACTION: Edit intention settings
|
||||
// ACTION: Make types implicit in lambda (may break code)
|
||||
// ERROR: <html>Type mismatch.<table><tr><td>Required:</td><td>kotlin.Int</td></tr><tr><td>Found:</td><td>([ERROR : NoSuchType]) → kotlin.Int</td></tr></table></html>
|
||||
// ERROR: Unresolved reference: NoSuchType
|
||||
|
||||
fun foo(): Int {
|
||||
return { (x: NoSuchType<caret>) -> 42 }
|
||||
}
|
||||
@@ -258,6 +258,14 @@ public abstract class AbstractCodeTransformationTest extends LightCodeInsightTes
|
||||
doTestIntention(path, new SimplifyBooleanWithConstantsIntention());
|
||||
}
|
||||
|
||||
public void doTestMakeTypeExplicitInLambda(@NotNull String path) throws Exception {
|
||||
doTestIntention(path, new MakeTypeExplicitInLambdaIntention());
|
||||
}
|
||||
|
||||
public void doTestMakeTypeImplicitInLambda(@NotNull String path) throws Exception {
|
||||
doTestIntention(path, new MakeTypeImplicitInLambdaIntention());
|
||||
}
|
||||
|
||||
private void doTestIntention(@NotNull String path, @NotNull IntentionAction intentionAction) throws Exception {
|
||||
configureByFile(path);
|
||||
|
||||
|
||||
+149
-1
@@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationTest;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@InnerTestClasses({CodeTransformationTestGenerated.DoubleBangToIfThen.class, CodeTransformationTestGenerated.IfThenToDoubleBang.class, CodeTransformationTestGenerated.ElvisToIfThen.class, CodeTransformationTestGenerated.IfThenToElvis.class, CodeTransformationTestGenerated.SafeAccessToIfThen.class, CodeTransformationTestGenerated.IfThenToSafeAccess.class, CodeTransformationTestGenerated.IfToAssignment.class, CodeTransformationTestGenerated.IfToReturn.class, CodeTransformationTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationTestGenerated.WhenToAssignment.class, CodeTransformationTestGenerated.WhenToReturn.class, CodeTransformationTestGenerated.AssignmentToIf.class, CodeTransformationTestGenerated.AssignmentToWhen.class, CodeTransformationTestGenerated.PropertyToIf.class, CodeTransformationTestGenerated.PropertyToWhen.class, CodeTransformationTestGenerated.ReturnToIf.class, CodeTransformationTestGenerated.ReturnToWhen.class, CodeTransformationTestGenerated.IfToWhen.class, CodeTransformationTestGenerated.WhenToIf.class, CodeTransformationTestGenerated.Flatten.class, CodeTransformationTestGenerated.Merge.class, CodeTransformationTestGenerated.IntroduceSubject.class, CodeTransformationTestGenerated.EliminateSubject.class, CodeTransformationTestGenerated.Split.class, CodeTransformationTestGenerated.Join.class, CodeTransformationTestGenerated.ConvertMemberToExtension.class, CodeTransformationTestGenerated.ReconstructedType.class, CodeTransformationTestGenerated.RemoveUnnecessaryParentheses.class, CodeTransformationTestGenerated.ReplaceWithDotQualifiedMethodCall.class, CodeTransformationTestGenerated.ReplaceWithInfixFunctionCall.class, CodeTransformationTestGenerated.RemoveCurlyBracesFromTemplate.class, CodeTransformationTestGenerated.MoveLambdaInsideParentheses.class, CodeTransformationTestGenerated.MoveLambdaOutsideParentheses.class, CodeTransformationTestGenerated.ReplaceExplicitFunctionLiteralParamWithIt.class, CodeTransformationTestGenerated.ReplaceItWithExplicitFunctionLiteralParam.class, CodeTransformationTestGenerated.RemoveBraces.class, CodeTransformationTestGenerated.AddBraces.class, CodeTransformationTestGenerated.ReplaceGetIntention.class, CodeTransformationTestGenerated.ReplaceContainsIntention.class, CodeTransformationTestGenerated.ReplaceBinaryInfixIntention.class, CodeTransformationTestGenerated.ReplaceUnaryPrefixIntention.class, CodeTransformationTestGenerated.ReplaceInvokeIntention.class, CodeTransformationTestGenerated.SimplifyNegatedBinaryExpressionIntention.class, CodeTransformationTestGenerated.ConvertNegatedBooleanSequence.class, CodeTransformationTestGenerated.ConvertNegatedExpressionWithDemorgansLaw.class, CodeTransformationTestGenerated.SwapBinaryExpression.class, CodeTransformationTestGenerated.SplitIf.class, CodeTransformationTestGenerated.ReplaceWithOperatorAssign.class, CodeTransformationTestGenerated.ReplaceWithTraditionalAssignment.class, CodeTransformationTestGenerated.SimplifyBooleanWithConstants.class, CodeTransformationTestGenerated.InsertExplicitTypeArguments.class, CodeTransformationTestGenerated.RemoveExplicitTypeArguments.class, CodeTransformationTestGenerated.ConvertAssertToIf.class, CodeTransformationTestGenerated.ConvertIfToAssert.class})
|
||||
@InnerTestClasses({CodeTransformationTestGenerated.DoubleBangToIfThen.class, CodeTransformationTestGenerated.IfThenToDoubleBang.class, CodeTransformationTestGenerated.ElvisToIfThen.class, CodeTransformationTestGenerated.IfThenToElvis.class, CodeTransformationTestGenerated.SafeAccessToIfThen.class, CodeTransformationTestGenerated.IfThenToSafeAccess.class, CodeTransformationTestGenerated.IfToAssignment.class, CodeTransformationTestGenerated.IfToReturn.class, CodeTransformationTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationTestGenerated.WhenToAssignment.class, CodeTransformationTestGenerated.WhenToReturn.class, CodeTransformationTestGenerated.AssignmentToIf.class, CodeTransformationTestGenerated.AssignmentToWhen.class, CodeTransformationTestGenerated.PropertyToIf.class, CodeTransformationTestGenerated.PropertyToWhen.class, CodeTransformationTestGenerated.ReturnToIf.class, CodeTransformationTestGenerated.ReturnToWhen.class, CodeTransformationTestGenerated.IfToWhen.class, CodeTransformationTestGenerated.WhenToIf.class, CodeTransformationTestGenerated.Flatten.class, CodeTransformationTestGenerated.Merge.class, CodeTransformationTestGenerated.IntroduceSubject.class, CodeTransformationTestGenerated.EliminateSubject.class, CodeTransformationTestGenerated.Split.class, CodeTransformationTestGenerated.Join.class, CodeTransformationTestGenerated.ConvertMemberToExtension.class, CodeTransformationTestGenerated.ReconstructedType.class, CodeTransformationTestGenerated.RemoveUnnecessaryParentheses.class, CodeTransformationTestGenerated.ReplaceWithDotQualifiedMethodCall.class, CodeTransformationTestGenerated.ReplaceWithInfixFunctionCall.class, CodeTransformationTestGenerated.RemoveCurlyBracesFromTemplate.class, CodeTransformationTestGenerated.MoveLambdaInsideParentheses.class, CodeTransformationTestGenerated.MoveLambdaOutsideParentheses.class, CodeTransformationTestGenerated.ReplaceExplicitFunctionLiteralParamWithIt.class, CodeTransformationTestGenerated.ReplaceItWithExplicitFunctionLiteralParam.class, CodeTransformationTestGenerated.RemoveBraces.class, CodeTransformationTestGenerated.AddBraces.class, CodeTransformationTestGenerated.ReplaceGetIntention.class, CodeTransformationTestGenerated.ReplaceContainsIntention.class, CodeTransformationTestGenerated.ReplaceBinaryInfixIntention.class, CodeTransformationTestGenerated.ReplaceUnaryPrefixIntention.class, CodeTransformationTestGenerated.ReplaceInvokeIntention.class, CodeTransformationTestGenerated.SimplifyNegatedBinaryExpressionIntention.class, CodeTransformationTestGenerated.ConvertNegatedBooleanSequence.class, CodeTransformationTestGenerated.ConvertNegatedExpressionWithDemorgansLaw.class, CodeTransformationTestGenerated.SwapBinaryExpression.class, CodeTransformationTestGenerated.SplitIf.class, CodeTransformationTestGenerated.ReplaceWithOperatorAssign.class, CodeTransformationTestGenerated.ReplaceWithTraditionalAssignment.class, CodeTransformationTestGenerated.SimplifyBooleanWithConstants.class, CodeTransformationTestGenerated.InsertExplicitTypeArguments.class, CodeTransformationTestGenerated.RemoveExplicitTypeArguments.class, CodeTransformationTestGenerated.ConvertAssertToIf.class, CodeTransformationTestGenerated.ConvertIfToAssert.class, CodeTransformationTestGenerated.MakeTypeExplicitInLambda.class, CodeTransformationTestGenerated.MakeTypeImplicitInLambda.class})
|
||||
public class CodeTransformationTestGenerated extends AbstractCodeTransformationTest {
|
||||
@TestMetadata("idea/testData/intentions/branched/doubleBangToIfThen")
|
||||
public static class DoubleBangToIfThen extends AbstractCodeTransformationTest {
|
||||
@@ -3957,6 +3957,152 @@ public class CodeTransformationTestGenerated extends AbstractCodeTransformationT
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/makeTypeExplicitInLambda")
|
||||
public static class MakeTypeExplicitInLambda extends AbstractCodeTransformationTest {
|
||||
public void testAllFilesPresentInMakeTypeExplicitInLambda() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/intentions/makeTypeExplicitInLambda"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("coercionToUnit.kt")
|
||||
public void testCoercionToUnit() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/coercionToUnit.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyParamListWithBrackets.kt")
|
||||
public void testEmptyParamListWithBrackets() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/emptyParamListWithBrackets.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyParamListWithIt.kt")
|
||||
public void testEmptyParamListWithIt() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/emptyParamListWithIt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyParamListWithWhiteSpace.kt")
|
||||
public void testEmptyParamListWithWhiteSpace() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/emptyParamListWithWhiteSpace.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyParamListWithoutItWithArrow.kt")
|
||||
public void testEmptyParamListWithoutItWithArrow() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/emptyParamListWithoutItWithArrow.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invalidCursorPosition.kt")
|
||||
public void testInvalidCursorPosition() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/invalidCursorPosition.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaWithLambdaAsParam.kt")
|
||||
public void testLambdaWithLambdaAsParam() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/lambdaWithLambdaAsParam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("manyNewlines.kt")
|
||||
public void testManyNewlines() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/manyNewlines.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleParam.kt")
|
||||
public void testMultipleParam() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/multipleParam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("paramDeclaredReturnNotDeclared.kt")
|
||||
public void testParamDeclaredReturnNotDeclared() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/paramDeclaredReturnNotDeclared.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnDeclaredParamNotDeclared.kt")
|
||||
public void testReturnDeclaredParamNotDeclared() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/returnDeclaredParamNotDeclared.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("shortenReferencesForParams.kt")
|
||||
public void testShortenReferencesForParams() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/shortenReferencesForParams.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("shortenReferencesForReceiver.kt")
|
||||
public void testShortenReferencesForReceiver() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/shortenReferencesForReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("singleParam.kt")
|
||||
public void testSingleParam() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/singleParam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("singleParamWithReceiver.kt")
|
||||
public void testSingleParamWithReceiver() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/singleParamWithReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typesAlreadyExplicit.kt")
|
||||
public void testTypesAlreadyExplicit() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/typesAlreadyExplicit.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typesNotInferable.kt")
|
||||
public void testTypesNotInferable() throws Exception {
|
||||
doTestMakeTypeExplicitInLambda("idea/testData/intentions/makeTypeExplicitInLambda/typesNotInferable.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/makeTypeImplicitInLambda")
|
||||
public static class MakeTypeImplicitInLambda extends AbstractCodeTransformationTest {
|
||||
public void testAllFilesPresentInMakeTypeImplicitInLambda() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/intentions/makeTypeImplicitInLambda"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("explicitReceiverType.kt")
|
||||
public void testExplicitReceiverType() throws Exception {
|
||||
doTestMakeTypeImplicitInLambda("idea/testData/intentions/makeTypeImplicitInLambda/explicitReceiverType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("explicitReturnType.kt")
|
||||
public void testExplicitReturnType() throws Exception {
|
||||
doTestMakeTypeImplicitInLambda("idea/testData/intentions/makeTypeImplicitInLambda/explicitReturnType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invalidCursorPosition.kt")
|
||||
public void testInvalidCursorPosition() throws Exception {
|
||||
doTestMakeTypeImplicitInLambda("idea/testData/intentions/makeTypeImplicitInLambda/invalidCursorPosition.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaWithLambdaAsParam.kt")
|
||||
public void testLambdaWithLambdaAsParam() throws Exception {
|
||||
doTestMakeTypeImplicitInLambda("idea/testData/intentions/makeTypeImplicitInLambda/lambdaWithLambdaAsParam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleExplicitParams.kt")
|
||||
public void testMultipleExplicitParams() throws Exception {
|
||||
doTestMakeTypeImplicitInLambda("idea/testData/intentions/makeTypeImplicitInLambda/multipleExplicitParams.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("paramDeclaredReturnNotDeclared.kt")
|
||||
public void testParamDeclaredReturnNotDeclared() throws Exception {
|
||||
doTestMakeTypeImplicitInLambda("idea/testData/intentions/makeTypeImplicitInLambda/paramDeclaredReturnNotDeclared.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnDeclaredParamNotDeclared.kt")
|
||||
public void testReturnDeclaredParamNotDeclared() throws Exception {
|
||||
doTestMakeTypeImplicitInLambda("idea/testData/intentions/makeTypeImplicitInLambda/returnDeclaredParamNotDeclared.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("singleExplicitParam.kt")
|
||||
public void testSingleExplicitParam() throws Exception {
|
||||
doTestMakeTypeImplicitInLambda("idea/testData/intentions/makeTypeImplicitInLambda/singleExplicitParam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typesAlreadyImplicit.kt")
|
||||
public void testTypesAlreadyImplicit() throws Exception {
|
||||
doTestMakeTypeImplicitInLambda("idea/testData/intentions/makeTypeImplicitInLambda/typesAlreadyImplicit.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite("CodeTransformationTestGenerated");
|
||||
suite.addTestSuite(DoubleBangToIfThen.class);
|
||||
@@ -4013,6 +4159,8 @@ public class CodeTransformationTestGenerated extends AbstractCodeTransformationT
|
||||
suite.addTestSuite(RemoveExplicitTypeArguments.class);
|
||||
suite.addTestSuite(ConvertAssertToIf.class);
|
||||
suite.addTestSuite(ConvertIfToAssert.class);
|
||||
suite.addTestSuite(MakeTypeExplicitInLambda.class);
|
||||
suite.addTestSuite(MakeTypeImplicitInLambda.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user