diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureHandler.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureHandler.java index 1071ad0d7ec..35ac390ba5f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureHandler.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureHandler.java @@ -76,24 +76,24 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler { return elementParent; } - JetCallElement call = PsiTreeUtil.getParentOfType(element, JetCallExpression.class, JetDelegatorToSuperCall.class); - if (call == null) { - return null; - } - JetExpression receiverExpr = call instanceof JetCallExpression ? call.getCalleeExpression() : - ((JetDelegatorToSuperCall) call).getCalleeExpression().getConstructorReferenceExpression(); + JetCallElement call = PsiTreeUtil.getParentOfType(element, + JetCallExpression.class, + JetDelegatorToSuperCall.class, + JetConstructorDelegationCall.class); + if (call == null) return null; - if (receiverExpr instanceof JetSimpleNameExpression) { + JetExpression receiverExpr = call.getCalleeExpression(); + if (receiverExpr instanceof JetConstructorCalleeExpression) { + receiverExpr = ((JetConstructorCalleeExpression) receiverExpr).getConstructorReferenceExpression(); + } + if (receiverExpr instanceof JetSimpleNameExpression || receiverExpr instanceof JetConstructorDelegationReferenceExpression) { JetElement jetElement = PsiTreeUtil.getParentOfType(element, JetElement.class); if (jetElement == null) return null; BindingContext bindingContext = ResolvePackage.analyze(jetElement); - DeclarationDescriptor descriptor = - bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) receiverExpr); + DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) receiverExpr); - if (descriptor instanceof ClassDescriptor || descriptor instanceof FunctionDescriptor) { - return receiverExpr; - } + if (descriptor instanceof ClassDescriptor || descriptor instanceof FunctionDescriptor) return receiverExpr; } return null; @@ -211,7 +211,7 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler { if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return null; DeclarationDescriptor descriptor; - if (element instanceof JetSimpleNameExpression) { + if (element instanceof JetReferenceExpression) { descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) element); } else { descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element); diff --git a/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefAfter.1.java b/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefAfter.1.java new file mode 100644 index 00000000000..a072e761da8 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefAfter.1.java @@ -0,0 +1,5 @@ +class J { + public J(int n, String s) { + + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefAfter.kt b/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefAfter.kt new file mode 100644 index 00000000000..35ec30e6e82 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefAfter.kt @@ -0,0 +1,9 @@ +open class K: J { + constructor(a: Int): super(a, "foo") { + + } +} + +fun test() { + J(1, "foo") +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefBefore.1.java b/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefBefore.1.java new file mode 100644 index 00000000000..92f5828fe9e --- /dev/null +++ b/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefBefore.1.java @@ -0,0 +1,5 @@ +class J { + public J(int n) { + + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefBefore.kt b/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefBefore.kt new file mode 100644 index 00000000000..3c1fe774cc4 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/JavaConstructorBySuperRefBefore.kt @@ -0,0 +1,9 @@ +open class K: J { + constructor(a: Int): super(a) { + + } +} + +fun test() { + J(1) +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/PrimaryConstructorBySuperRefAfter.kt b/idea/testData/refactoring/changeSignature/PrimaryConstructorBySuperRefAfter.kt new file mode 100644 index 00000000000..a8e14d9a965 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/PrimaryConstructorBySuperRefAfter.kt @@ -0,0 +1,21 @@ +open class A(s: String) { + constructor(a: Int) : this("foo") { + + } +} + +open class B: A { + constructor(a: Int) : super("foo") { + + } +} + +open class C: A { + constructor(a: Int) : super("foo") { + + } +} + +fun test() { + A("foo") +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/PrimaryConstructorBySuperRefBefore.kt b/idea/testData/refactoring/changeSignature/PrimaryConstructorBySuperRefBefore.kt new file mode 100644 index 00000000000..922c0d76095 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/PrimaryConstructorBySuperRefBefore.kt @@ -0,0 +1,21 @@ +open class A() { + constructor(a: Int) : this() { + + } +} + +open class B: A { + constructor(a: Int) : super() { + + } +} + +open class C: A { + constructor(a: Int) { + + } +} + +fun test() { + A() +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/PrimaryConstructorByThisRefAfter.kt b/idea/testData/refactoring/changeSignature/PrimaryConstructorByThisRefAfter.kt new file mode 100644 index 00000000000..a8e14d9a965 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/PrimaryConstructorByThisRefAfter.kt @@ -0,0 +1,21 @@ +open class A(s: String) { + constructor(a: Int) : this("foo") { + + } +} + +open class B: A { + constructor(a: Int) : super("foo") { + + } +} + +open class C: A { + constructor(a: Int) : super("foo") { + + } +} + +fun test() { + A("foo") +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/PrimaryConstructorByThisRefBefore.kt b/idea/testData/refactoring/changeSignature/PrimaryConstructorByThisRefBefore.kt new file mode 100644 index 00000000000..52ac6b6c399 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/PrimaryConstructorByThisRefBefore.kt @@ -0,0 +1,21 @@ +open class A() { + constructor(a: Int) : this() { + + } +} + +open class B: A { + constructor(a: Int) : super() { + + } +} + +open class C: A { + constructor(a: Int) { + + } +} + +fun test() { + A() +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/SecondaryConstructorBySuperRefAfter.kt b/idea/testData/refactoring/changeSignature/SecondaryConstructorBySuperRefAfter.kt new file mode 100644 index 00000000000..6d9c187ead0 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/SecondaryConstructorBySuperRefAfter.kt @@ -0,0 +1,19 @@ +open class A { + constructor(a: Int, s: String) { + + } + + constructor(): this(1, "foo") { + + } +} + +open class B: A { + constructor(a: Int): super(a, "foo") { + + } +} + +fun test() { + A(1, "foo") +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/SecondaryConstructorBySuperRefBefore.kt b/idea/testData/refactoring/changeSignature/SecondaryConstructorBySuperRefBefore.kt new file mode 100644 index 00000000000..7bac4f157e1 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/SecondaryConstructorBySuperRefBefore.kt @@ -0,0 +1,19 @@ +open class A { + constructor(a: Int) { + + } + + constructor(): this(1) { + + } +} + +open class B: A { + constructor(a: Int): super(a) { + + } +} + +fun test() { + A(1) +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/SecondaryConstructorByThisRefAfter.kt b/idea/testData/refactoring/changeSignature/SecondaryConstructorByThisRefAfter.kt new file mode 100644 index 00000000000..b15bf736fe6 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/SecondaryConstructorByThisRefAfter.kt @@ -0,0 +1,19 @@ +open class A { + constructor(a: Int, s: String) { + + } + + constructor(): this(1, "foo") { + + } +} + +open class B: A { + constructor(a: Int): super(a, "foo") { + + } +} + +fun test() { + A(1, "foo") +} \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/SecondaryConstructorByThisRefBefore.kt b/idea/testData/refactoring/changeSignature/SecondaryConstructorByThisRefBefore.kt new file mode 100644 index 00000000000..bad0b64e485 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/SecondaryConstructorByThisRefBefore.kt @@ -0,0 +1,19 @@ +open class A { + constructor(a: Int) { + + } + + constructor(): this(1) { + + } +} + +open class B: A { + constructor(a: Int): super(a) { + + } +} + +fun test() { + A(1) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.java index bbf60f72405..add06b32db7 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureTest.java @@ -752,6 +752,48 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase { ); } + public void testPrimaryConstructorByThisRef() throws Exception { + JetChangeInfo changeInfo = getChangeInfo(); + changeInfo.addParameter(new JetParameterInfo(-1, "s", KotlinBuiltIns.getInstance().getStringType(), null, "\"foo\"", null, null)); + doTest(changeInfo); + } + + public void testPrimaryConstructorBySuperRef() throws Exception { + JetChangeInfo changeInfo = getChangeInfo(); + changeInfo.addParameter(new JetParameterInfo(-1, "s", KotlinBuiltIns.getInstance().getStringType(), null, "\"foo\"", null, null)); + doTest(changeInfo); + } + + public void testSecondaryConstructorByThisRef() throws Exception { + JetChangeInfo changeInfo = getChangeInfo(); + changeInfo.addParameter(new JetParameterInfo(-1, "s", KotlinBuiltIns.getInstance().getStringType(), null, "\"foo\"", null, null)); + doTest(changeInfo); + } + + public void testSecondaryConstructorBySuperRef() throws Exception { + JetChangeInfo changeInfo = getChangeInfo(); + changeInfo.addParameter(new JetParameterInfo(-1, "s", KotlinBuiltIns.getInstance().getStringType(), null, "\"foo\"", null, null)); + doTest(changeInfo); + } + + public void testJavaConstructorBySuperRef() throws Exception { + doJavaTest( + new JavaRefactoringProvider() { + @NotNull + @Override + ParameterInfoImpl[] getNewParameters(@NotNull PsiMethod method) { + ParameterInfoImpl[] newParameters = super.getNewParameters(method); + newParameters = Arrays.copyOf(newParameters, newParameters.length + 1); + + PsiType paramType = PsiType.getJavaLangString(getPsiManager(), GlobalSearchScope.allScope(getProject())); + newParameters[newParameters.length - 1] = new ParameterInfoImpl(-1, "s", paramType, "\"foo\""); + + return newParameters; + } + } + ); + } + @NotNull @Override protected String getTestDataPath() { @@ -847,7 +889,10 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase { private void doJavaTest(JavaRefactoringProvider provider) throws Exception { configureFiles(); - PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED); + PsiElement targetElement = TargetElementUtilBase.findTargetElement( + getEditor(), + TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED + ); assertTrue(" is not on method name", targetElement instanceof PsiMethod); provider.getProcessor((PsiMethod)targetElement).run();