Change Signature: Support refactoring of primary/secondary constructor by delegation call reference

This commit is contained in:
Alexey Sedunov
2015-03-18 12:29:31 +03:00
parent 173a28a25e
commit 5c7debbf88
14 changed files with 247 additions and 14 deletions
@@ -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)
}
@@ -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();