From cfc16b410e9bda58f9603abba5fe679685cdf483 Mon Sep 17 00:00:00 2001 From: Tal Man Date: Fri, 28 Mar 2014 23:18:26 -0400 Subject: [PATCH] Intention for adding explicit type arguments at function calls --- .../jet/generators/tests/GenerateTests.kt | 1 + .../after.kt.template | 5 + .../before.kt.template | 5 + .../description.html | 5 + idea/src/META-INF/plugin.xml | 5 + .../jetbrains/jet/plugin/JetBundle.properties | 3 + .../intentions/InsertExplicitTypeArguments.kt | 67 ++++++++++++++ .../inapplicableAlreadyTyped.kt | 6 ++ .../inapplicableNotGeneric.kt | 6 ++ .../inapplicableTypeNotInferred.kt | 7 ++ .../insertManyTypes.kt | 6 ++ .../insertManyTypes.kt.after | 6 ++ .../insertManyTypesInDifferentOrder.kt | 6 ++ .../insertManyTypesInDifferentOrder.kt.after | 6 ++ .../insertMultipleSomeWithClashingName.kt | 10 ++ ...nsertMultipleSomeWithClashingName.kt.after | 10 ++ .../insertTwoTypesFun.kt | 6 ++ .../insertTwoTypesFun.kt.after | 6 ++ .../insertTypeAny.kt | 8 ++ .../insertTypeAny.kt.after | 8 ++ .../insertTypeThatIsAFunction.kt | 6 ++ .../insertTypeThatIsAFunction.kt.after | 6 ++ .../insertTypeThatIsATypeArg.kt | 6 ++ .../insertTypeThatIsATypeArg.kt.after | 6 ++ .../insertTypeWithClashingName.kt | 10 ++ .../insertTypeWithClashingName.kt.after | 10 ++ .../insertTypeWithLambda.kt | 6 ++ .../insertTypeWithLambda.kt.after | 6 ++ .../insertTypeWithTypeArguments.kt | 8 ++ .../insertTypeWithTypeArguments.kt.after | 8 ++ .../insertTypeWithVarargs.kt | 6 ++ .../insertTypeWithVarargs.kt.after | 6 ++ .../simpleInsertTypeClass.kt | 8 ++ .../simpleInsertTypeClass.kt.after | 8 ++ .../simpleInsertTypeFun.kt | 6 ++ .../simpleInsertTypeFun.kt.after | 6 ++ .../AbstractCodeTransformationTest.java | 4 + .../CodeTransformationTestGenerated.java | 91 ++++++++++++++++++- 38 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 idea/resources/intentionDescriptions/InsertExplicitTypeArguments/after.kt.template create mode 100644 idea/resources/intentionDescriptions/InsertExplicitTypeArguments/before.kt.template create mode 100644 idea/resources/intentionDescriptions/InsertExplicitTypeArguments/description.html create mode 100644 idea/src/org/jetbrains/jet/plugin/intentions/InsertExplicitTypeArguments.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/inapplicableAlreadyTyped.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/inapplicableNotGeneric.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/inapplicableTypeNotInferred.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertManyTypes.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertManyTypes.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertManyTypesInDifferentOrder.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertManyTypesInDifferentOrder.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertMultipleSomeWithClashingName.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertMultipleSomeWithClashingName.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTwoTypesFun.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTwoTypesFun.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeAny.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeAny.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsAFunction.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsAFunction.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsATypeArg.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsATypeArg.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithClashingName.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithClashingName.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithLambda.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithLambda.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithTypeArguments.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithTypeArguments.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithVarargs.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithVarargs.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeClass.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeClass.kt.after create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeFun.kt create mode 100644 idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeFun.kt.after diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index d942ef5a854..141d24b9652 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -390,6 +390,7 @@ fun main(args: Array) { model("intentions/replaceWithOperatorAssign", testMethod = "doTestReplaceWithOperatorAssign") model("intentions/replaceWithTraditionalAssignment", testMethod = "doTestReplaceWithTraditionalAssignment") model("intentions/simplifyBooleanWithConstants", testMethod = "doTestSimplifyBooleanWithConstants") + model("intentions/insertExplicitTypeArguments", testMethod = "doTestInsertExplicitTypeArguments") } testClass(javaClass()) { diff --git a/idea/resources/intentionDescriptions/InsertExplicitTypeArguments/after.kt.template b/idea/resources/intentionDescriptions/InsertExplicitTypeArguments/after.kt.template new file mode 100644 index 00000000000..8701c8a293f --- /dev/null +++ b/idea/resources/intentionDescriptions/InsertExplicitTypeArguments/after.kt.template @@ -0,0 +1,5 @@ +fun foo() { + bar("x") +} + +fun bar(t: T) : T = t \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/InsertExplicitTypeArguments/before.kt.template b/idea/resources/intentionDescriptions/InsertExplicitTypeArguments/before.kt.template new file mode 100644 index 00000000000..f869e201a8f --- /dev/null +++ b/idea/resources/intentionDescriptions/InsertExplicitTypeArguments/before.kt.template @@ -0,0 +1,5 @@ +fun foo() { + bar("x") +} + +fun bar(t: T) : T = t \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/InsertExplicitTypeArguments/description.html b/idea/resources/intentionDescriptions/InsertExplicitTypeArguments/description.html new file mode 100644 index 00000000000..099218484ca --- /dev/null +++ b/idea/resources/intentionDescriptions/InsertExplicitTypeArguments/description.html @@ -0,0 +1,5 @@ + + +This intention inserts explicit type arguments to function calls + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 4bacf5d97d7..ae90fef2ed3 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -568,6 +568,11 @@ Kotlin + + org.jetbrains.jet.plugin.intentions.InsertExplicitTypeArguments + Kotlin + + org.jetbrains.jet.plugin.intentions.MoveLambdaOutsideParenthesesIntention Kotlin diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 049362829dd..14b1c7008ee 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -293,6 +293,9 @@ replace.with.traditional.assignment.intention=Replace with Traditional Assignmen replace.with.traditional.assignment.intention.family=Replace with Traditional Assignment simplify.boolean.with.constants=Simplify boolean expression simplify.boolean.with.constants.family=Simplify boolean expression +insert.explicit.type.arguments=Add explicit type arguments +insert.explicit.type.arguments.family=Add explicit type arguments +>>>>>>> Intention for adding explicit type arguments at function calls property.is.implemented.too.many=Has implementations property.is.overridden.too.many=Is overridden in subclasses diff --git a/idea/src/org/jetbrains/jet/plugin/intentions/InsertExplicitTypeArguments.kt b/idea/src/org/jetbrains/jet/plugin/intentions/InsertExplicitTypeArguments.kt new file mode 100644 index 00000000000..fcaccc0c298 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/intentions/InsertExplicitTypeArguments.kt @@ -0,0 +1,67 @@ +/* + * 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.JetCallExpression +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache +import org.jetbrains.jet.lang.resolve.BindingContext +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall +import org.jetbrains.jet.lang.descriptors.CallableDescriptor +import org.jetbrains.jet.lang.psi.JetPsiFactory +import kotlin.properties.Delegates +import org.jetbrains.jet.lang.types.TypeUtils +import org.jetbrains.jet.lang.types.ErrorUtils +import org.jetbrains.jet.renderer.DescriptorRenderer +import org.jetbrains.jet.plugin.codeInsight.ShortenReferences + +public class InsertExplicitTypeArguments : JetSelfTargetingIntention( + "insert.explicit.type.arguments", javaClass()) { + + private var resolvedCall: ResolvedCall by Delegates.notNull() + + override fun isApplicableTo(element: JetCallExpression): Boolean { + if (!element.getTypeArguments().isEmpty()) return false + val context = AnalyzerFacadeWithCache.getContextForElement(element) + val nullableResolvedCall = context[BindingContext.RESOLVED_CALL, element.getCalleeExpression()] + if (nullableResolvedCall == null) return false + resolvedCall = nullableResolvedCall + val types = resolvedCall.getTypeArguments() + return !types.isEmpty() && types.values().none { ErrorUtils.containsErrorType(it) } + } + + override fun applyTo(element: JetCallExpression, editor: Editor) { + val args = resolvedCall.getTypeArguments() + val types = resolvedCall.getCandidateDescriptor()?.getTypeParameters() + if (types == null) return + + val typeArgs = types.map { + assert(args[it] != null, "there is a null in the type arguments to transform") + val typeToCompute = DescriptorRenderer.TEXT.renderType(args[it]!!); + val computedTypeRef = JetPsiFactory.createType(element.getProject(), typeToCompute) + ShortenReferences.process(computedTypeRef) + computedTypeRef.getText() + }.makeString(", ", "<", ">") + + val name = element.getCalleeExpression()?.getText() + val text = element.getText() + if (name == null || text == null) return + val valueAndFunctionArguments = text.substring(name.size) + val expr = JetPsiFactory.createExpression(element.getProject(), "$name$typeArgs${valueAndFunctionArguments}") + element.replace(expr) + } +} \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/inapplicableAlreadyTyped.kt b/idea/testData/intentions/insertExplicitTypeArguments/inapplicableAlreadyTyped.kt new file mode 100644 index 00000000000..26147a049d5 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/inapplicableAlreadyTyped.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: false +fun foo() { + val x = bar("x") +} + +fun bar(t: T): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/inapplicableNotGeneric.kt b/idea/testData/intentions/insertExplicitTypeArguments/inapplicableNotGeneric.kt new file mode 100644 index 00000000000..078337612bf --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/inapplicableNotGeneric.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: false +fun foo() { + val x = bar(1) +} + +fun bar(t: Int): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/inapplicableTypeNotInferred.kt b/idea/testData/intentions/insertExplicitTypeArguments/inapplicableTypeNotInferred.kt new file mode 100644 index 00000000000..9bc2762c86e --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/inapplicableTypeNotInferred.kt @@ -0,0 +1,7 @@ +// IS_APPLICABLE: false +// ERROR: Unresolved reference: s +fun foo() { + val x = bar(s) // s not definded, can't be inferred +} + +fun bar(t: T): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypes.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypes.kt new file mode 100644 index 00000000000..94c73859b6f --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypes.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + val z = bar("1", 1, 2, "x") +} + +fun bar(t: T, v: V, r: R, k: K): Int = 2 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypes.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypes.kt.after new file mode 100644 index 00000000000..029031a8c26 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypes.kt.after @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + val z = bar("1", 1, 2, "x") +} + +fun bar(t: T, v: V, r: R, k: K): Int = 2 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypesInDifferentOrder.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypesInDifferentOrder.kt new file mode 100644 index 00000000000..e907215349a --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypesInDifferentOrder.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + val z = bar("1", 1, 2, "x") +} + +fun bar(t: T, v: V, r: R, k: K): Int = 2 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypesInDifferentOrder.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypesInDifferentOrder.kt.after new file mode 100644 index 00000000000..5e7b8dfcf7f --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertManyTypesInDifferentOrder.kt.after @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + val z = bar("1", 1, 2, "x") +} + +fun bar(t: T, v: V, r: R, k: K): Int = 2 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertMultipleSomeWithClashingName.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertMultipleSomeWithClashingName.kt new file mode 100644 index 00000000000..4da6ef543de --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertMultipleSomeWithClashingName.kt @@ -0,0 +1,10 @@ +// IS_APPLICABLE: true +class Array + +fun test() { + bar(foo(""), 0, foo("")) +} + +fun foo(vararg x: String) = x + +fun bar(t: T, r: R, v: V) {} diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertMultipleSomeWithClashingName.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertMultipleSomeWithClashingName.kt.after new file mode 100644 index 00000000000..c7ba4e8d1af --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertMultipleSomeWithClashingName.kt.after @@ -0,0 +1,10 @@ +// IS_APPLICABLE: true +class Array + +fun test() { + bar, Int, kotlin.Array>(foo(""), 0, foo("")) +} + +fun foo(vararg x: String) = x + +fun bar(t: T, r: R, v: V) {} diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTwoTypesFun.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertTwoTypesFun.kt new file mode 100644 index 00000000000..96926081ab6 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTwoTypesFun.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + val x = bar("x", 0) +} + +fun bar(t: T, v: V): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTwoTypesFun.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertTwoTypesFun.kt.after new file mode 100644 index 00000000000..e2703a4cb29 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTwoTypesFun.kt.after @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + val x = bar("x", 0) +} + +fun bar(t: T, v: V): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeAny.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeAny.kt new file mode 100644 index 00000000000..825e54fa385 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeAny.kt @@ -0,0 +1,8 @@ +// IS_APPLICABLE: true +fun foo() { + val x = Box(Any()) +} + +class Box(t : T) { + var value = t +} \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeAny.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeAny.kt.after new file mode 100644 index 00000000000..4fcff5af2d9 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeAny.kt.after @@ -0,0 +1,8 @@ +// IS_APPLICABLE: true +fun foo() { + val x = Box(Any()) +} + +class Box(t : T) { + var value = t +} \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsAFunction.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsAFunction.kt new file mode 100644 index 00000000000..17fb24be071 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsAFunction.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + bar({ 2 * it }: (Int) -> Int) +} + +fun bar(t: T): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsAFunction.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsAFunction.kt.after new file mode 100644 index 00000000000..3fb1f459be2 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsAFunction.kt.after @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + bar<(Int) -> Int>({ 2 * it }: (Int) -> Int) +} + +fun bar(t: T): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsATypeArg.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsATypeArg.kt new file mode 100644 index 00000000000..a83d91a36bb --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsATypeArg.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo(t: T) { + bar(t) +} + +fun bar(t: T): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsATypeArg.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsATypeArg.kt.after new file mode 100644 index 00000000000..c1753292167 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsATypeArg.kt.after @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo(t: T) { + bar(t) +} + +fun bar(t: T): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithClashingName.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithClashingName.kt new file mode 100644 index 00000000000..73db0cc5bcb --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithClashingName.kt @@ -0,0 +1,10 @@ +// IS_APPLICABLE: true +class Array + +fun test() { + bar(foo("")) +} + +fun foo(vararg x: String) = x + +fun bar(vararg ts: T) {} \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithClashingName.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithClashingName.kt.after new file mode 100644 index 00000000000..76925c8001a --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithClashingName.kt.after @@ -0,0 +1,10 @@ +// IS_APPLICABLE: true +class Array + +fun test() { + bar>(foo("")) +} + +fun foo(vararg x: String) = x + +fun bar(vararg ts: T) {} \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithLambda.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithLambda.kt new file mode 100644 index 00000000000..de35ce1f390 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithLambda.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + val z = bar { it * 2 } +} + +fun bar(a: (Int)->T): T = a(1) \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithLambda.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithLambda.kt.after new file mode 100644 index 00000000000..0f2f823020e --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithLambda.kt.after @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + val z = bar { it * 2 } +} + +fun bar(a: (Int)->T): T = a(1) \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithTypeArguments.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithTypeArguments.kt new file mode 100644 index 00000000000..e7cb70fe2b2 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithTypeArguments.kt @@ -0,0 +1,8 @@ +// IS_APPLICABLE: true +fun foo() { + val x = Box(Box("x")) +} + +class Box(t : T) { + var value = t +} \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithTypeArguments.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithTypeArguments.kt.after new file mode 100644 index 00000000000..b336904d202 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithTypeArguments.kt.after @@ -0,0 +1,8 @@ +// IS_APPLICABLE: true +fun foo() { + val x = Box>(Box("x")) +} + +class Box(t : T) { + var value = t +} \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithVarargs.kt b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithVarargs.kt new file mode 100644 index 00000000000..0219fa09cda --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithVarargs.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + bar(1, 2, 3, 4) +} + +fun bar(vararg ts: T): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithVarargs.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithVarargs.kt.after new file mode 100644 index 00000000000..7edbe6123d6 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithVarargs.kt.after @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + bar(1, 2, 3, 4) +} + +fun bar(vararg ts: T): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeClass.kt b/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeClass.kt new file mode 100644 index 00000000000..003baa3ebb7 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeClass.kt @@ -0,0 +1,8 @@ +// IS_APPLICABLE: true +fun foo() { + val x = Box("x") +} + +class Box(t : T) { + var value = t +} \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeClass.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeClass.kt.after new file mode 100644 index 00000000000..f0072452412 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeClass.kt.after @@ -0,0 +1,8 @@ +// IS_APPLICABLE: true +fun foo() { + val x = Box("x") +} + +class Box(t : T) { + var value = t +} \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeFun.kt b/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeFun.kt new file mode 100644 index 00000000000..5f8b5de4fa4 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeFun.kt @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + bar("x") +} + +fun bar(t: T): Int = 1 \ No newline at end of file diff --git a/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeFun.kt.after b/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeFun.kt.after new file mode 100644 index 00000000000..d1686744c40 --- /dev/null +++ b/idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeFun.kt.after @@ -0,0 +1,6 @@ +// IS_APPLICABLE: true +fun foo() { + bar("x") +} + +fun bar(t: T): Int = 1 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java index 42ad6aae972..153cca5957f 100644 --- a/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java @@ -215,6 +215,10 @@ public abstract class AbstractCodeTransformationTest extends LightCodeInsightTes doTestIntention(path, new SimplifyNegatedBinaryExpressionIntention()); } + public void doTestInsertExplicitTypeArguments(@NotNull String path) throws Exception { + doTestIntention(path, new InsertExplicitTypeArguments()); + } + public void doTestSplitIf(@NotNull String path) throws Exception { doTestIntention(path, new SplitIfIntention()); } diff --git a/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationTestGenerated.java index 24f515c91b9..00ab17613f1 100644 --- a/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationTestGenerated.java @@ -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.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}) +@InnerTestClasses({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}) public class CodeTransformationTestGenerated extends AbstractCodeTransformationTest { @TestMetadata("idea/testData/intentions/branched/elvisToIfThen") public static class ElvisToIfThen extends AbstractCodeTransformationTest { @@ -3327,6 +3327,94 @@ public class CodeTransformationTestGenerated extends AbstractCodeTransformationT } + @TestMetadata("idea/testData/intentions/insertExplicitTypeArguments") + public static class InsertExplicitTypeArguments extends AbstractCodeTransformationTest { + public void testAllFilesPresentInInsertExplicitTypeArguments() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/intentions/insertExplicitTypeArguments"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("inapplicableAlreadyTyped.kt") + public void testInapplicableAlreadyTyped() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/inapplicableAlreadyTyped.kt"); + } + + @TestMetadata("inapplicableNotGeneric.kt") + public void testInapplicableNotGeneric() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/inapplicableNotGeneric.kt"); + } + + @TestMetadata("inapplicableTypeNotInferred.kt") + public void testInapplicableTypeNotInferred() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/inapplicableTypeNotInferred.kt"); + } + + @TestMetadata("insertManyTypes.kt") + public void testInsertManyTypes() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertManyTypes.kt"); + } + + @TestMetadata("insertManyTypesInDifferentOrder.kt") + public void testInsertManyTypesInDifferentOrder() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertManyTypesInDifferentOrder.kt"); + } + + @TestMetadata("insertMultipleSomeWithClashingName.kt") + public void testInsertMultipleSomeWithClashingName() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertMultipleSomeWithClashingName.kt"); + } + + @TestMetadata("insertTwoTypesFun.kt") + public void testInsertTwoTypesFun() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertTwoTypesFun.kt"); + } + + @TestMetadata("insertTypeAny.kt") + public void testInsertTypeAny() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertTypeAny.kt"); + } + + @TestMetadata("insertTypeThatIsAFunction.kt") + public void testInsertTypeThatIsAFunction() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsAFunction.kt"); + } + + @TestMetadata("insertTypeThatIsATypeArg.kt") + public void testInsertTypeThatIsATypeArg() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertTypeThatIsATypeArg.kt"); + } + + @TestMetadata("insertTypeWithClashingName.kt") + public void testInsertTypeWithClashingName() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithClashingName.kt"); + } + + @TestMetadata("insertTypeWithLambda.kt") + public void testInsertTypeWithLambda() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithLambda.kt"); + } + + @TestMetadata("insertTypeWithTypeArguments.kt") + public void testInsertTypeWithTypeArguments() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithTypeArguments.kt"); + } + + @TestMetadata("insertTypeWithVarargs.kt") + public void testInsertTypeWithVarargs() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/insertTypeWithVarargs.kt"); + } + + @TestMetadata("simpleInsertTypeClass.kt") + public void testSimpleInsertTypeClass() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeClass.kt"); + } + + @TestMetadata("simpleInsertTypeFun.kt") + public void testSimpleInsertTypeFun() throws Exception { + doTestInsertExplicitTypeArguments("idea/testData/intentions/insertExplicitTypeArguments/simpleInsertTypeFun.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("CodeTransformationTestGenerated"); suite.addTestSuite(ElvisToIfThen.class); @@ -3377,6 +3465,7 @@ public class CodeTransformationTestGenerated extends AbstractCodeTransformationT suite.addTestSuite(ReplaceWithOperatorAssign.class); suite.addTestSuite(ReplaceWithTraditionalAssignment.class); suite.addTestSuite(SimplifyBooleanWithConstants.class); + suite.addTestSuite(InsertExplicitTypeArguments.class); return suite; } }