Create from Usage: Suggest "Create secondary constructor" on NONE_APPLICABLE error
#KT-11866 Fixed
This commit is contained in:
@@ -21,6 +21,7 @@ Issues fixed:
|
|||||||
- [KT-11155](https://youtrack.jetbrains.com/issue/KT-11155) Allow running multiple Kotlin classes as well as running mixtures of Kotlin and Java classes
|
- [KT-11155](https://youtrack.jetbrains.com/issue/KT-11155) Allow running multiple Kotlin classes as well as running mixtures of Kotlin and Java classes
|
||||||
- [KT-11495](https://youtrack.jetbrains.com/issue/KT-11495) Show recursion line markers for extension function calls with different receiver
|
- [KT-11495](https://youtrack.jetbrains.com/issue/KT-11495) Show recursion line markers for extension function calls with different receiver
|
||||||
- [KT-11659](https://youtrack.jetbrains.com/issue/KT-11659) Generate abstract overrides for Any members inside of Kotlin interfaces
|
- [KT-11659](https://youtrack.jetbrains.com/issue/KT-11659) Generate abstract overrides for Any members inside of Kotlin interfaces
|
||||||
|
- [KT-11866](https://youtrack.jetbrains.com/issue/KT-11866) Suggest "Create secondary constructor" when constructors exist but are not applicable
|
||||||
|
|
||||||
#### Debugger
|
#### Debugger
|
||||||
|
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
NO_VALUE_FOR_PARAMETER.registerFactory(*CreateCallableFromCallActionFactory.INSTANCES)
|
NO_VALUE_FOR_PARAMETER.registerFactory(*CreateCallableFromCallActionFactory.INSTANCES)
|
||||||
TOO_MANY_ARGUMENTS.registerFactory(*CreateCallableFromCallActionFactory.INSTANCES)
|
TOO_MANY_ARGUMENTS.registerFactory(*CreateCallableFromCallActionFactory.INSTANCES)
|
||||||
EXPRESSION_EXPECTED_PACKAGE_FOUND.registerFactory(*CreateCallableFromCallActionFactory.INSTANCES)
|
EXPRESSION_EXPECTED_PACKAGE_FOUND.registerFactory(*CreateCallableFromCallActionFactory.INSTANCES)
|
||||||
|
NONE_APPLICABLE.registerFactory(*CreateCallableFromCallActionFactory.INSTANCES)
|
||||||
|
|
||||||
NO_VALUE_FOR_PARAMETER.registerFactory(CreateConstructorFromDelegationCallActionFactory)
|
NO_VALUE_FOR_PARAMETER.registerFactory(CreateConstructorFromDelegationCallActionFactory)
|
||||||
TOO_MANY_ARGUMENTS.registerFactory(CreateConstructorFromDelegationCallActionFactory)
|
TOO_MANY_ARGUMENTS.registerFactory(CreateConstructorFromDelegationCallActionFactory)
|
||||||
|
|||||||
+9
-4
@@ -36,8 +36,8 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||||
@@ -71,7 +71,8 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Errors.NO_VALUE_FOR_PARAMETER,
|
Errors.NO_VALUE_FOR_PARAMETER,
|
||||||
Errors.TOO_MANY_ARGUMENTS -> diagElement.getNonStrictParentOfType<KtCallExpression>()
|
Errors.TOO_MANY_ARGUMENTS,
|
||||||
|
Errors.NONE_APPLICABLE -> diagElement.getNonStrictParentOfType<KtCallExpression>()
|
||||||
|
|
||||||
else -> throw AssertionError("Unexpected diagnostic: ${diagnostic.factory}")
|
else -> throw AssertionError("Unexpected diagnostic: ${diagnostic.factory}")
|
||||||
} as? KtExpression
|
} as? KtExpression
|
||||||
@@ -182,8 +183,12 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
|
|||||||
): CallableInfo? {
|
): CallableInfo? {
|
||||||
if (expression.typeArguments.isNotEmpty()) return null
|
if (expression.typeArguments.isNotEmpty()) return null
|
||||||
|
|
||||||
val constructorDescriptor = expression.getResolvedCall(context)?.resultingDescriptor as? ConstructorDescriptor
|
val classDescriptor = expression
|
||||||
val classDescriptor = constructorDescriptor?.containingDeclaration as? ClassDescriptor
|
.calleeExpression
|
||||||
|
?.getReferenceTargets(context)
|
||||||
|
?.mapNotNull { (it as? ConstructorDescriptor)?.containingDeclaration }
|
||||||
|
?.distinct()
|
||||||
|
?.singleOrNull() as? ClassDescriptor
|
||||||
val klass = classDescriptor?.source?.getPsi()
|
val klass = classDescriptor?.source?.getPsi()
|
||||||
if ((klass !is KtClass && klass !is PsiClass) || !klass.canRefactor()) return null
|
if ((klass !is KtClass && klass !is PsiClass) || !klass.canRefactor()) return null
|
||||||
|
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Create secondary constructor" "true"
|
||||||
|
// ERROR: Primary constructor call expected
|
||||||
|
|
||||||
|
class CtorSecondary() {
|
||||||
|
constructor(p: Int) : this()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun construct() {
|
||||||
|
// todo: add this()
|
||||||
|
val vA = <caret>CtorSecondary(2, 3)
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// "Create secondary constructor" "true"
|
||||||
|
// ERROR: Primary constructor call expected
|
||||||
|
|
||||||
|
class CtorSecondary() {
|
||||||
|
constructor(p: Int) : this()
|
||||||
|
|
||||||
|
constructor<caret>(i: Int, i1: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun construct() {
|
||||||
|
// todo: add this()
|
||||||
|
val vA = CtorSecondary(2, 3)
|
||||||
|
}
|
||||||
@@ -2701,6 +2701,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("noneApplicable.kt")
|
||||||
|
public void testNoneApplicable() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createSecondaryConstructor/noneApplicable.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("superCall.kt")
|
@TestMetadata("superCall.kt")
|
||||||
public void testSuperCall() throws Exception {
|
public void testSuperCall() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createSecondaryConstructor/superCall.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createSecondaryConstructor/superCall.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user