Create from Usage: Add delegation call to secondary constructor declaration

This commit is contained in:
Alexey Sedunov
2016-02-05 16:27:11 +03:00
parent 6696d2b70a
commit eabe675dbf
9 changed files with 75 additions and 7 deletions
@@ -66,6 +66,7 @@ import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
@@ -593,6 +594,16 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
if (it > 0) parent.addAfter(psiFactory.createNewLine(it), declarationInPlace)
}
if (declarationInPlace is KtSecondaryConstructor) {
val containingClass = declarationInPlace.containingClassOrObject!!
if (containingClass.getPrimaryConstructorParameters().isNotEmpty()) {
declarationInPlace.replaceImplicitDelegationCallWithExplicit(true)
}
else if ((receiverClassDescriptor as ClassDescriptor).getSuperClassOrAny().constructors.all { it.valueParameters.isNotEmpty() }) {
declarationInPlace.replaceImplicitDelegationCallWithExplicit(false)
}
}
return declarationInPlace
}
}
@@ -926,6 +937,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
containingFileEditor.caretModel.moveToOffset(range.endOffset)
return
}
if (declaration is KtSecondaryConstructor && !declaration.hasImplicitDelegationCall()) {
containingFileEditor.caretModel.moveToOffset(declaration.getDelegationCall().valueArgumentList!!.startOffset + 1)
return
}
setupEditorSelection(containingFileEditor, declaration)
}
@@ -0,0 +1,7 @@
// "Create secondary constructor" "true"
open class Base()
class Creation {
constructor(f: Int)
}
val v = Creation(<caret>)
@@ -1,7 +1,9 @@
// "Create secondary constructor" "true"
// ERROR: Primary constructor call expected
class Creation(val f: Int) {
open class Base()
class Creation {
constructor(f: Int)
constructor()
}
val v = Creation()
@@ -0,0 +1,9 @@
// "Create secondary constructor" "true"
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
// ERROR: No value passed for parameter f
open class Base(val f: Int)
class Creation: Base {
constructor(f: Int): super(f)
}
val v = Creation(<caret>)
@@ -0,0 +1,11 @@
// "Create secondary constructor" "true"
// SHOULD_BE_AVAILABLE_AFTER_EXECUTION
// ERROR: No value passed for parameter f
open class Base(val f: Int)
class Creation: Base {
constructor(f: Int): super(f)
constructor() : super(<caret>)
}
val v = Creation()
@@ -1,4 +1,4 @@
// "Create secondary constructor" "true"
// ERROR: Primary constructor call expected
// ERROR: There's a cycle in the delegation calls chain
class Creation(val f: Int)
val v = Creation(<caret>)
@@ -0,0 +1,7 @@
// "Create secondary constructor" "true"
// ERROR: There's a cycle in the delegation calls chain
class Creation(val f: Int) {
constructor() : this(<caret>)
}
val v = Creation()
@@ -92,6 +92,11 @@ public abstract class AbstractQuickFixTest extends KotlinLightQuickFixTestCase {
private static QuickFixTestCase myWrapper;
@Override
protected boolean shouldBeAvailableAfterExecution() {
return InTextDirectivesUtils.isDirectiveDefined(myWrapper.getFile().getText(), "// SHOULD_BE_AVAILABLE_AFTER_EXECUTION");
}
@NotNull
@Override
protected LocalInspectionTool[] configureLocalInspectionTools() {
@@ -2601,9 +2601,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("noParameters.kt")
public void testNoParameters() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createSecondaryConstructor/noParameters.kt");
@TestMetadata("noParametersImplicitSuperCall.kt")
public void testNoParametersImplicitSuperCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createSecondaryConstructor/noParametersImplicitSuperCall.kt");
doTest(fileName);
}
@TestMetadata("noParametersSuperCall.kt")
public void testNoParametersSuperCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createSecondaryConstructor/noParametersSuperCall.kt");
doTest(fileName);
}
@TestMetadata("noParametersThisCall.kt")
public void testNoParametersThisCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createSecondaryConstructor/noParametersThisCall.kt");
doTest(fileName);
}