Create From Usage: Add support of star projections/incorrect type arguments

#EA-62661 Fixed
This commit is contained in:
Alexey Sedunov
2015-03-10 14:22:59 +03:00
parent ab5a691612
commit f0b0fd07c5
11 changed files with 67 additions and 10 deletions
@@ -231,3 +231,7 @@ private fun JetType.substitute(substitution: JetTypeSubstitution, variance: Vari
}
fun JetExpression.getExpressionForTypeGuess() = getAssignmentByLHS()?.getRight() ?: this
fun JetCallElement.getTypeInfoForTypeArguments(): List<TypeInfo> {
return getTypeArguments().map { it.getTypeReference()?.let { TypeInfo(it, Variance.INVARIANT) } }.filterNotNull()
}
@@ -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)
}
@@ -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,
@@ -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<IntentionAction> {
@@ -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)
}
@@ -0,0 +1,7 @@
// "Create class 'Foo'" "true"
fun test() = Foo<String>(2, "2")
class Foo<T>(i: Int, t: T) {
}
@@ -0,0 +1,3 @@
// "Create class 'Foo'" "true"
fun test() = <caret>Foo<String, *>(2, "2")
@@ -0,0 +1,8 @@
// "Create class 'A'" "true"
package p
fun foo(): A<*, String> = throw Throwable("")
class A<T, U> {
}
@@ -0,0 +1,4 @@
// "Create class 'A'" "true"
package p
fun foo(): <caret>A<*, String> = throw Throwable("")
@@ -0,0 +1,9 @@
// "Create function 'foo'" "true"
fun test(): Int {
return foo<String>(2, "2")
}
fun <T> foo(i: Int, t: T): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -0,0 +1,5 @@
// "Create function 'foo'" "true"
fun test(): Int {
return <caret>foo<String, *>(2, "2")
}
@@ -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");