Create From Usage: Add support of star projections/incorrect type arguments
#EA-62661 Fixed
This commit is contained in:
+4
@@ -231,3 +231,7 @@ private fun JetType.substitute(substitution: JetTypeSubstitution, variance: Vari
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun JetExpression.getExpressionForTypeGuess() = getAssignmentByLHS()?.getRight() ?: this
|
fun JetExpression.getExpressionForTypeGuess() = getAssignmentByLHS()?.getRight() ?: this
|
||||||
|
|
||||||
|
fun JetCallElement.getTypeInfoForTypeArguments(): List<TypeInfo> {
|
||||||
|
return getTypeArguments().map { it.getTypeReference()?.let { TypeInfo(it, Variance.INVARIANT) } }.filterNotNull()
|
||||||
|
}
|
||||||
+1
-1
@@ -96,7 +96,7 @@ object CreateFunctionOrPropertyFromCallActionFactory : JetIntentionActionsFactor
|
|||||||
it.getArgumentName()?.getReferenceExpression()?.getReferencedName()
|
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)
|
val returnType = TypeInfo(fullCallExpr, Variance.OUT_VARIANCE)
|
||||||
FunctionInfo(calleeExpr.getReferencedName(), receiverType, returnType, possibleContainers, parameters, typeParameters)
|
FunctionInfo(calleeExpr.getReferencedName(), receiverType, returnType, possibleContainers, parameters, typeParameters)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-8
@@ -24,15 +24,14 @@ import org.jetbrains.kotlin.psi.JetCallExpression
|
|||||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.psi.JetQualifiedExpression
|
import org.jetbrains.kotlin.psi.JetQualifiedExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
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.types.Variance
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
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.quickfix.JetSingleIntentionActionFactory
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
||||||
import org.jetbrains.kotlin.psi.JetFile
|
import org.jetbrains.kotlin.psi.JetFile
|
||||||
import org.jetbrains.kotlin.psi.JetAnnotationEntry
|
import org.jetbrains.kotlin.psi.JetAnnotationEntry
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
|
||||||
|
|
||||||
public object CreateClassFromConstructorCallActionFactory: JetSingleIntentionActionFactory() {
|
public object CreateClassFromConstructorCallActionFactory: JetSingleIntentionActionFactory() {
|
||||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
@@ -76,12 +75,7 @@ public object CreateClassFromConstructorCallActionFactory: JetSingleIntentionAct
|
|||||||
val (expectedTypeInfo, filter) = fullCallExpr.getInheritableTypeInfo(context, moduleDescriptor, targetParent)
|
val (expectedTypeInfo, filter) = fullCallExpr.getInheritableTypeInfo(context, moduleDescriptor, targetParent)
|
||||||
if (!filter(classKind)) return null
|
if (!filter(classKind)) return null
|
||||||
|
|
||||||
val typeArgumentInfos = if (inAnnotationEntry) {
|
val typeArgumentInfos = if (inAnnotationEntry) Collections.emptyList() else callExpr.getTypeInfoForTypeArguments()
|
||||||
Collections.emptyList()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callExpr.getTypeArguments().map { TypeInfo(it.getTypeReference(), Variance.INVARIANT) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val classInfo = ClassInfo(
|
val classInfo = ClassInfo(
|
||||||
kind = classKind,
|
kind = classKind,
|
||||||
|
|||||||
+6
-1
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.JetDelegatorToSuperClass
|
|||||||
import org.jetbrains.kotlin.psi.JetConstructorCalleeExpression
|
import org.jetbrains.kotlin.psi.JetConstructorCalleeExpression
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.builtins.*
|
||||||
|
|
||||||
public object CreateClassFromTypeReferenceActionFactory: JetIntentionActionsFactory() {
|
public object CreateClassFromTypeReferenceActionFactory: JetIntentionActionsFactory() {
|
||||||
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
|
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 createPackageAction = refExpr.getCreatePackageFixIfApplicable(targetParent)
|
||||||
val createClassActions = possibleKinds.map {
|
val createClassActions = possibleKinds.map {
|
||||||
val classInfo = ClassInfo(
|
val classInfo = ClassInfo(
|
||||||
@@ -75,7 +78,9 @@ public object CreateClassFromTypeReferenceActionFactory: JetIntentionActionsFact
|
|||||||
name = name,
|
name = name,
|
||||||
targetParent = targetParent,
|
targetParent = targetParent,
|
||||||
expectedTypeInfo = TypeInfo.Empty,
|
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)
|
CreateClassFromUsageFix(userType, classInfo)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
|
||||||
|
fun test() = Foo<String>(2, "2")
|
||||||
|
|
||||||
|
class Foo<T>(i: Int, t: T) {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
|
||||||
|
fun test() = <caret>Foo<String, *>(2, "2")
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// "Create class 'A'" "true"
|
||||||
|
package p
|
||||||
|
|
||||||
|
fun foo(): A<*, String> = throw Throwable("")
|
||||||
|
|
||||||
|
class A<T, U> {
|
||||||
|
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// "Create class 'A'" "true"
|
||||||
|
package p
|
||||||
|
|
||||||
|
fun foo(): <caret>A<*, String> = throw Throwable("")
|
||||||
+9
@@ -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.
|
||||||
|
}
|
||||||
+5
@@ -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);
|
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")
|
@TestMetadata("beforeClassMember.kt")
|
||||||
public void testClassMember() throws Exception {
|
public void testClassMember() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/beforeClassMember.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/callExpression/typeArguments/beforeClassMember.kt");
|
||||||
@@ -1385,6 +1391,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("beforeClassNotQualifierWithTypeArgs.kt")
|
||||||
public void testClassNotQualifierWithTypeArgs() throws Exception {
|
public void testClassNotQualifierWithTypeArgs() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createClass/typeReference/beforeClassNotQualifierWithTypeArgs.kt");
|
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);
|
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")
|
@TestMetadata("beforeClassMember.kt")
|
||||||
public void testClassMember() throws Exception {
|
public void testClassMember() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeClassMember.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeClassMember.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user