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;
}
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);
@@ -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
@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("<caret> is not on method name", targetElement instanceof PsiMethod);
provider.getProcessor((PsiMethod)targetElement).run();