diff --git a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java index 94f1df22deec..deedb344493c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java +++ b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java @@ -15,6 +15,8 @@ */ package com.intellij.codeInsight.folding.impl; +import com.intellij.codeInsight.ExpectedTypeInfo; +import com.intellij.codeInsight.ExpectedTypesProvider; import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil; import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; import com.intellij.codeInsight.folding.JavaCodeFoldingSettings; @@ -44,6 +46,7 @@ import com.intellij.psi.util.PropertyUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Function; +import com.intellij.util.ObjectUtils; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -646,13 +649,24 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar if (lastLineEnd > 0 && seq.charAt(lastLineEnd) == '\n') lastLineEnd--; if (lastLineEnd < firstLineStart) return false; + String type = ""; + if (!quick) { + ExpectedTypeInfo[] types = ExpectedTypesProvider.getExpectedTypes(expression, false); + if (types.length != 1 || !types[0].getType().equals(anonymousClass.getBaseClassType())) { + final String baseClassName = ObjectUtils.assertNotNull(anonymousClass.getBaseClassType().resolve()).getName(); + if (baseClassName != null) { + type = "(" + baseClassName + ") "; + } + } + } + final String params = StringUtil.join(method.getParameterList().getParameters(), new Function() { @Override public String fun(final PsiParameter psiParameter) { return psiParameter.getName(); } }, ", "); - @NonNls final String lambdas = "(" + params + ") -> {"; + @NonNls final String lambdas = type + "(" + params + ") -> {"; final int closureStart = expression.getTextRange().getStartOffset(); final int closureEnd = expression.getTextRange().getEndOffset(); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index f993262b32ac..30d4ff2fe02b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -217,6 +217,48 @@ class Test { assert closureStartFold } + public void "test closure folding placeholder texts"() { + myFixture.addClass('interface Runnable2 { void run(); }') + myFixture.addClass('interface Runnable3 { void run(); }') + myFixture.addClass('interface Runnable4 { void run(); }') + def text = """\ +class Test { + void test() { + Runnable r = new Runnable() { + public void run() { + System.out.println(); + } + }; + new Runnable2() { + public void run() { + System.out.println(); + } + }.run(); + foo(new Runnable3() { + public void run() { + System.out.println(); + } + }); + bar(new Runnable4() { + public void run() { + System.out.println(); + } + }); + } + + void foo(Object o) {} + void bar(Runnable4 o) {} +} +""" + configure text + def foldingModel = myFixture.editor.foldingModel as FoldingModelImpl + + assert foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable(")).placeholderText == '() -> { ' + assert foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable2(")).placeholderText == '(Runnable2) () -> { ' + assert foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable3(")).placeholderText == '(Runnable3) () -> { ' + assert foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable4(")).placeholderText == '() -> { ' + } + public void "test no closure folding when the method throws an unresolved exception"() { def text = """\ class Test {