meth ref -> lambda: work on array refs (IDEA-102374)

This commit is contained in:
anna
2013-03-04 16:03:07 +01:00
parent d7c5ecacdd
commit 62c5b58a76
8 changed files with 126 additions and 35 deletions
@@ -82,15 +82,19 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention {
buf.append("{");
}
final PsiElement qualifier = referenceExpression.getQualifier();
boolean isReceiver = false;
PsiClass containingClass = null;
if (resolveElement instanceof PsiMethod) {
final PsiClass containingClass = ((PsiMember)resolveElement).getContainingClass();
containingClass = ((PsiMember)resolveElement).getContainingClass();
LOG.assertTrue(containingClass != null);
isReceiver = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, (PsiMethod)resolveElement);
} else if (resolveElement instanceof PsiClass) {
isReceiver = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, (PsiClass)resolveElement, (PsiMethod)null);
containingClass = (PsiClass)resolveElement;
}
final boolean onArrayRef =
JavaPsiFacade.getElementFactory(element.getProject()).getArrayClass(PsiUtil.getLanguageLevel(element)) == containingClass;
boolean isReceiver = onArrayRef && resolveElement instanceof PsiMethod ||
PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, resolveElement instanceof PsiMethod ? (PsiMethod)resolveElement : null);
final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement();
if (isReceiver){
buf.append(parameters[0].getName()).append(".");
@@ -113,43 +117,52 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention {
if (referenceNameElement instanceof PsiKeyword) {
//class name
buf.append(" ");
buf.append(((PsiMember)resolveElement).getName());
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
PsiClass containingClass;
if (resolveElement instanceof PsiClass) {
containingClass = (PsiClass)resolveElement;
} else {
containingClass = ((PsiMember)resolveElement).getContainingClass();
}
LOG.assertTrue(containingClass != null);
if (containingClass.hasTypeParameters() && !PsiUtil.isRawSubstitutor(containingClass, substitutor)) {
buf.append("<").append(StringUtil.join(containingClass.getTypeParameters(), new Function<PsiTypeParameter, String>() {
@Override
public String fun(PsiTypeParameter parameter) {
final PsiType psiType = substitutor.substitute(parameter);
LOG.assertTrue(psiType != null);
return psiType.getCanonicalText();
if (onArrayRef) {
if (qualifier instanceof PsiTypeElement) {
final PsiType type = ((PsiTypeElement)qualifier).getType();
int dim = type.getArrayDimensions();
buf.append(type.getDeepComponentType().getCanonicalText());
buf.append("[");
buf.append(parameters[0].getName());
buf.append("]");
while (--dim > 0) {
buf.append("[]");
}
}, ", ")).append(">");
}
} else {
buf.append(((PsiMember)resolveElement).getName());
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
LOG.assertTrue(containingClass != null);
if (containingClass.hasTypeParameters() && !PsiUtil.isRawSubstitutor(containingClass, substitutor)) {
buf.append("<").append(StringUtil.join(containingClass.getTypeParameters(), new Function<PsiTypeParameter, String>() {
@Override
public String fun(PsiTypeParameter parameter) {
final PsiType psiType = substitutor.substitute(parameter);
LOG.assertTrue(psiType != null);
return psiType.getCanonicalText();
}
}, ", ")).append(">");
}
}
}
//param list
buf.append("(");
boolean first = true;
for (int i = isReceiver ? 1 : 0; i < parameters.length; i++) {
PsiParameter parameter = parameters[i];
if (!first) {
buf.append(", ");
} else {
first = false;
if (!onArrayRef || isReceiver) {
//param list
buf.append("(");
boolean first = true;
for (int i = isReceiver ? 1 : 0; i < parameters.length; i++) {
PsiParameter parameter = parameters[i];
if (!first) {
buf.append(", ");
} else {
first = false;
}
buf.append(map.get(parameter));
}
buf.append(map.get(parameter));
buf.append(")");
}
buf.append(")");
if (needBraces) {
buf.append(";}");
@@ -0,0 +1,12 @@
public class Foo {
static void foo() {
Ar<String> a = Stri<caret>ng[]::new;
}
interface Ar<T> {
T[] jjj(int p);
}
}
@@ -0,0 +1,12 @@
public class Foo {
static void foo() {
Ar<String> a = Str<caret>ing[][]::new;
}
interface Ar<T> {
T[][] jjj(int p);
}
}
@@ -0,0 +1,12 @@
public class Foo {
static void foo() {
Ar<String> a = (p) -> new String[p][];
}
interface Ar<T> {
T[][] jjj(int p);
}
}
@@ -0,0 +1,12 @@
public class Foo {
static void foo() {
Ar<String> a = (p) -> new String[p];
}
interface Ar<T> {
T[] jjj(int p);
}
}
@@ -0,0 +1,9 @@
public class Foo {
static void foo() {
Cln j = i<caret>nt[]::clone;
}
interface Cln {
Object _(int[] p);
}
}
@@ -0,0 +1,9 @@
public class Foo {
static void foo() {
Cln j = (p) -> p.clone();
}
interface Cln {
Object _(int[] p);
}
}
@@ -89,4 +89,16 @@ public class ReplaceMethodReferenceWithLambdaIntentionTest extends IPPTestCase {
public void testNewDefaultConstructor() throws Exception {
doTest();
}
public void testArrayConstructorRef() throws Exception {
doTest();
}
public void testArrayConstructorRef2Dim() throws Exception {
doTest();
}
public void testArrayMethodRef() throws Exception {
doTest();
}
}