IDEA-106390 Fold anonymous classes with multiple candidate methods for overriding.

This commit is contained in:
peter
2013-05-07 18:17:04 +02:00
parent f3193142a7
commit 0e81d0efa3
2 changed files with 35 additions and 5 deletions
@@ -388,12 +388,12 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
protected abstract boolean shouldShowExplicitLambdaType(PsiAnonymousClass anonymousClass, PsiNewExpression expression);
private static boolean seemsLikeLambda(@Nullable final PsiClass baseClass) {
if (baseClass == null) return false;
return baseClass != null && PsiUtil.hasDefaultConstructor(baseClass, true);
}
private static boolean isImplementingLambdaMethod(PsiClass baseClass) {
if (!baseClass.hasModifierProperty(PsiModifier.ABSTRACT)) return false;
if (!PsiUtil.hasDefaultConstructor(baseClass, true)) return false;
for (final PsiMethod method : baseClass.getMethods()) {
if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
return true;
@@ -672,7 +672,8 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
final PsiExpressionList argumentList = expression.getArgumentList();
if (argumentList != null && argumentList.getExpressions().length == 0) {
final PsiMethod[] methods = anonymousClass.getMethods();
if (hasOnlyOneLambdaMethod(anonymousClass, !quick) && (quick || seemsLikeLambda(anonymousClass.getBaseClassType().resolve()))) {
PsiClass baseClass = anonymousClass.getBaseClassType().resolve();
if (hasOnlyOneLambdaMethod(anonymousClass, !quick) && seemsLikeLambda(baseClass)) {
final PsiMethod method = methods[0];
final PsiCodeBlock body = method.getBody();
if (body != null) {
@@ -704,6 +705,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
if (lastLineEnd < firstLineStart) return false;
String type = quick ? "" : getOptionalLambdaType(anonymousClass, expression);
String methodName = quick || !isImplementingLambdaMethod(baseClass) ? method.getName() : "";
final String params = StringUtil.join(method.getParameterList().getParameters(), new Function<PsiParameter, String>() {
@Override
@@ -711,7 +713,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
return psiParameter.getName();
}
}, ", ");
@NonNls final String lambdas = type + "(" + params + ") -> {";
@NonNls final String lambdas = type + methodName + "(" + params + ") -> {";
final int closureStart = expression.getTextRange().getStartOffset();
final int closureEnd = expression.getTextRange().getEndOffset();
@@ -266,6 +266,34 @@ class Test {
assert foldingModel.getCollapsedRegionAtOffset(text.indexOf("MyAction(")).placeholderText == '(MyAction) () -> { '
}
public void "test closure folding when overriding one method of many"() {
myFixture.addClass('abstract class Runnable { void run() {}; void run2() {} }')
myFixture.addClass('abstract class Runnable2 { void run() {}; void run2() {} }')
def text = """\
class Test {
void test() {
Runnable r = new Runnable() {
public void run() {
System.out.println();
}
};
foo(new Runnable2() {
public void run2() {
System.out.println();
}
});
}
void foo(Object o) {}
}
"""
configure text
def foldingModel = myFixture.editor.foldingModel as FoldingModelImpl
assert foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable("))?.placeholderText == 'run() -> { '
assert foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable2("))?.placeholderText == '(Runnable2) run2() -> { '
}
public void "test no closure folding when the method throws an unresolved exception"() {
def text = """\
class Test {