diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/typeUtils.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/typeUtils.kt index 52fe9664130..bd118395895 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/typeUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/typeUtils.kt @@ -231,3 +231,7 @@ private fun JetType.substitute(substitution: JetTypeSubstitution, variance: Vari } fun JetExpression.getExpressionForTypeGuess() = getAssignmentByLHS()?.getRight() ?: this + +fun JetCallElement.getTypeInfoForTypeArguments(): List { + return getTypeArguments().map { it.getTypeReference()?.let { TypeInfo(it, Variance.INVARIANT) } }.filterNotNull() +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateFunctionOrPropertyFromCallActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateFunctionOrPropertyFromCallActionFactory.kt index cd548f62aef..8dfe8a8f37b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateFunctionOrPropertyFromCallActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateFunctionOrPropertyFromCallActionFactory.kt @@ -96,7 +96,7 @@ object CreateFunctionOrPropertyFromCallActionFactory : JetIntentionActionsFactor it.getArgumentName()?.getReferenceExpression()?.getReferencedName() ) } - val typeParameters = callExpr.getTypeArguments().map { TypeInfo(it.getTypeReference(), Variance.INVARIANT) } + val typeParameters = callExpr.getTypeInfoForTypeArguments() val returnType = TypeInfo(fullCallExpr, Variance.OUT_VARIANCE) FunctionInfo(calleeExpr.getReferencedName(), receiverType, returnType, possibleContainers, parameters, typeParameters) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromConstructorCallActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromConstructorCallActionFactory.kt index 58614ce2661..a5b85dd3269 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromConstructorCallActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromConstructorCallActionFactory.kt @@ -24,15 +24,14 @@ import org.jetbrains.kotlin.psi.JetCallExpression import org.jetbrains.kotlin.psi.JetSimpleNameExpression import org.jetbrains.kotlin.psi.JetQualifiedExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getCall -import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo import org.jetbrains.kotlin.idea.quickfix.JetSingleIntentionActionFactory import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetAnnotationEntry import java.util.Collections +import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.* public object CreateClassFromConstructorCallActionFactory: JetSingleIntentionActionFactory() { override fun createAction(diagnostic: Diagnostic): IntentionAction? { @@ -76,12 +75,7 @@ public object CreateClassFromConstructorCallActionFactory: JetSingleIntentionAct val (expectedTypeInfo, filter) = fullCallExpr.getInheritableTypeInfo(context, moduleDescriptor, targetParent) if (!filter(classKind)) return null - val typeArgumentInfos = if (inAnnotationEntry) { - Collections.emptyList() - } - else { - callExpr.getTypeArguments().map { TypeInfo(it.getTypeReference(), Variance.INVARIANT) } - } + val typeArgumentInfos = if (inAnnotationEntry) Collections.emptyList() else callExpr.getTypeInfoForTypeArguments() val classInfo = ClassInfo( kind = classKind, diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt index b988eae22e7..39c33f03dab 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createClass/CreateClassFromTypeReferenceActionFactory.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.JetDelegatorToSuperClass import org.jetbrains.kotlin.psi.JetConstructorCalleeExpression import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.builtins.* public object CreateClassFromTypeReferenceActionFactory: JetIntentionActionsFactory() { override fun doCreateActions(diagnostic: Diagnostic): List { @@ -68,6 +69,8 @@ public object CreateClassFromTypeReferenceActionFactory: JetIntentionActionsFact } } + val anyType = KotlinBuiltIns.getInstance().getAnyType() + val createPackageAction = refExpr.getCreatePackageFixIfApplicable(targetParent) val createClassActions = possibleKinds.map { val classInfo = ClassInfo( @@ -75,7 +78,9 @@ public object CreateClassFromTypeReferenceActionFactory: JetIntentionActionsFact name = name, targetParent = targetParent, expectedTypeInfo = TypeInfo.Empty, - typeArguments = typeArguments.map { TypeInfo(it, Variance.INVARIANT) } + typeArguments = typeArguments.map { + if (it != null) TypeInfo(it, Variance.INVARIANT) else TypeInfo(anyType, Variance.INVARIANT) + } ) CreateClassFromUsageFix(userType, classInfo) } diff --git a/idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/afterCallWithStarProjection.kt b/idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/afterCallWithStarProjection.kt new file mode 100644 index 00000000000..8ab0df063a1 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/afterCallWithStarProjection.kt @@ -0,0 +1,7 @@ +// "Create class 'Foo'" "true" + +fun test() = Foo(2, "2") + +class Foo(i: Int, t: T) { + +} diff --git a/idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/beforeCallWithStarProjection.kt b/idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/beforeCallWithStarProjection.kt new file mode 100644 index 00000000000..04c06cd2e1b --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/beforeCallWithStarProjection.kt @@ -0,0 +1,3 @@ +// "Create class 'Foo'" "true" + +fun test() = Foo(2, "2") \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/afterClassNotQualifierWithStarProjection.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/afterClassNotQualifierWithStarProjection.kt new file mode 100644 index 00000000000..6c5ce8cd597 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/afterClassNotQualifierWithStarProjection.kt @@ -0,0 +1,8 @@ +// "Create class 'A'" "true" +package p + +fun foo(): A<*, String> = throw Throwable("") + +class A { + +} diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/beforeClassNotQualifierWithStarProjection.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/beforeClassNotQualifierWithStarProjection.kt new file mode 100644 index 00000000000..7b2d622dd39 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/beforeClassNotQualifierWithStarProjection.kt @@ -0,0 +1,4 @@ +// "Create class 'A'" "true" +package p + +fun foo(): A<*, String> = throw Throwable("") \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/afterCallWithStarProjection.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/afterCallWithStarProjection.kt new file mode 100644 index 00000000000..a2166043dd5 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/afterCallWithStarProjection.kt @@ -0,0 +1,9 @@ +// "Create function 'foo'" "true" + +fun test(): Int { + return foo(2, "2") +} + +fun foo(i: Int, t: T): Int { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. +} diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeCallWithStarProjection.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeCallWithStarProjection.kt new file mode 100644 index 00000000000..05776d20a92 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeCallWithStarProjection.kt @@ -0,0 +1,5 @@ +// "Create function 'foo'" "true" + +fun test(): Int { + return foo(2, "2") +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 33a87c36192..a4413c7beee 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -958,6 +958,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments"), Pattern.compile("^before(\\w+)\\.kt$"), true); } + @TestMetadata("beforeCallWithStarProjection.kt") + public void testCallWithStarProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/beforeCallWithStarProjection.kt"); + doTest(fileName); + } + @TestMetadata("beforeClassMember.kt") public void testClassMember() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/beforeClassMember.kt"); @@ -1385,6 +1391,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("beforeClassNotQualifierWithStarProjection.kt") + public void testClassNotQualifierWithStarProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/beforeClassNotQualifierWithStarProjection.kt"); + doTest(fileName); + } + @TestMetadata("beforeClassNotQualifierWithTypeArgs.kt") public void testClassNotQualifierWithTypeArgs() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/beforeClassNotQualifierWithTypeArgs.kt"); @@ -1844,6 +1856,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments"), Pattern.compile("^before(\\w+)\\.kt$"), true); } + @TestMetadata("beforeCallWithStarProjection.kt") + public void testCallWithStarProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeCallWithStarProjection.kt"); + doTest(fileName); + } + @TestMetadata("beforeClassMember.kt") public void testClassMember() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeClassMember.kt");