Change Signature: Support refactoring of primary/secondary constructor by delegation call reference
This commit is contained in:
+13
-13
@@ -76,24 +76,24 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
return elementParent;
|
return elementParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
JetCallElement call = PsiTreeUtil.getParentOfType(element, JetCallExpression.class, JetDelegatorToSuperCall.class);
|
JetCallElement call = PsiTreeUtil.getParentOfType(element,
|
||||||
if (call == null) {
|
JetCallExpression.class,
|
||||||
return null;
|
JetDelegatorToSuperCall.class,
|
||||||
}
|
JetConstructorDelegationCall.class);
|
||||||
JetExpression receiverExpr = call instanceof JetCallExpression ? call.getCalleeExpression() :
|
if (call == null) return null;
|
||||||
((JetDelegatorToSuperCall) call).getCalleeExpression().getConstructorReferenceExpression();
|
|
||||||
|
|
||||||
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);
|
JetElement jetElement = PsiTreeUtil.getParentOfType(element, JetElement.class);
|
||||||
if (jetElement == null) return null;
|
if (jetElement == null) return null;
|
||||||
|
|
||||||
BindingContext bindingContext = ResolvePackage.analyze(jetElement);
|
BindingContext bindingContext = ResolvePackage.analyze(jetElement);
|
||||||
DeclarationDescriptor descriptor =
|
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) receiverExpr);
|
||||||
bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) receiverExpr);
|
|
||||||
|
|
||||||
if (descriptor instanceof ClassDescriptor || descriptor instanceof FunctionDescriptor) {
|
if (descriptor instanceof ClassDescriptor || descriptor instanceof FunctionDescriptor) return receiverExpr;
|
||||||
return receiverExpr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -211,7 +211,7 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return null;
|
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return null;
|
||||||
|
|
||||||
DeclarationDescriptor descriptor;
|
DeclarationDescriptor descriptor;
|
||||||
if (element instanceof JetSimpleNameExpression) {
|
if (element instanceof JetReferenceExpression) {
|
||||||
descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) element);
|
descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) element);
|
||||||
} else {
|
} else {
|
||||||
descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class J {
|
||||||
|
public J(int n, String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
open class K: J {
|
||||||
|
constructor(a: Int): super(a, "foo") {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
J(1, "foo")
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class J {
|
||||||
|
public J(int n) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
open class K: J {
|
||||||
|
constructor(a: Int): <caret>super(a) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
J(1)
|
||||||
|
}
|
||||||
@@ -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")
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
open class A() {
|
||||||
|
constructor(a: Int) : this() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B: A {
|
||||||
|
constructor(a: Int) : <caret>super() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class C: A {
|
||||||
|
constructor(a: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
A()
|
||||||
|
}
|
||||||
@@ -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")
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
open class A() {
|
||||||
|
constructor(a: Int) : <caret>this() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B: A {
|
||||||
|
constructor(a: Int) : super() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class C: A {
|
||||||
|
constructor(a: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
A()
|
||||||
|
}
|
||||||
@@ -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")
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
open class A {
|
||||||
|
constructor(a: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(): this(1) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B: A {
|
||||||
|
constructor(a: Int): <caret>super(a) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
A(1)
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
open class A {
|
||||||
|
constructor(a: Int, s: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(): <caret>this(1, "foo") {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B: A {
|
||||||
|
constructor(a: Int): super(a, "foo") {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
A(1, "foo")
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
open class A {
|
||||||
|
constructor(a: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(): <caret>this(1) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B: A {
|
||||||
|
constructor(a: Int): super(a) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
A(1)
|
||||||
|
}
|
||||||
+46
-1
@@ -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
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
protected String getTestDataPath() {
|
protected String getTestDataPath() {
|
||||||
@@ -847,7 +889,10 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase {
|
|||||||
private void doJavaTest(JavaRefactoringProvider provider) throws Exception {
|
private void doJavaTest(JavaRefactoringProvider provider) throws Exception {
|
||||||
configureFiles();
|
configureFiles();
|
||||||
|
|
||||||
PsiElement targetElement = TargetElementUtilBase.findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
|
PsiElement targetElement = TargetElementUtilBase.findTargetElement(
|
||||||
|
getEditor(),
|
||||||
|
TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED
|
||||||
|
);
|
||||||
assertTrue("<caret> is not on method name", targetElement instanceof PsiMethod);
|
assertTrue("<caret> is not on method name", targetElement instanceof PsiMethod);
|
||||||
|
|
||||||
provider.getProcessor((PsiMethod)targetElement).run();
|
provider.getProcessor((PsiMethod)targetElement).run();
|
||||||
|
|||||||
Reference in New Issue
Block a user