change signature: expand expr lambda to block lambda when exception should be caught; don't expand method ref to lambda when only unchecked exceptions were added (IDEA-152386)

This commit is contained in:
Anna.Kozlova
2016-04-27 17:21:44 +02:00
parent bb09d3c6f3
commit bebf4975e6
8 changed files with 124 additions and 4 deletions

View File

@@ -317,7 +317,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
//methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions
newExceptions = filterCheckedExceptions(newExceptions);
PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class);
PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class, PsiLambdaExpression.class);
if (context instanceof PsiTryStatement) {
PsiTryStatement tryStatement = (PsiTryStatement)context;
PsiCodeBlock tryBlock = tryStatement.getTryBlock();
@@ -346,7 +346,16 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
//Add new try statement
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject());
PsiTryStatement tryStatement = (PsiTryStatement)elementFactory.createStatementFromText("try {} catch (Exception e) {}", null);
PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class);
PsiStatement anchor;
PsiElement lambdaBody = context instanceof PsiLambdaExpression ? ((PsiLambdaExpression)context).getBody() : null;
if (lambdaBody instanceof PsiExpression) {
PsiCodeBlock codeBlock = (PsiCodeBlock)((PsiLambdaExpression)RefactoringUtil.expandExpressionLambdaToCodeBlock(lambdaBody)).getBody();
LOG.assertTrue(codeBlock != null);
anchor = codeBlock.getStatements()[0];
}
else {
anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class);
}
LOG.assertTrue(anchor != null);
tryStatement.getTryBlock().add(anchor);
tryStatement = (PsiTryStatement)anchor.getParent().addAfter(tryStatement, anchor);
@@ -358,6 +367,10 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
}
}
public static boolean hasNewCheckedExceptions(JavaChangeInfo changeInfo) {
return filterCheckedExceptions(getPrimaryChangedExceptionInfo(changeInfo)).length > 0;
}
private static PsiClassType[] filterCheckedExceptions(PsiClassType[] exceptions) {
List<PsiClassType> result = new ArrayList<PsiClassType>();
for (PsiClassType exceptionType : exceptions) {

View File

@@ -47,7 +47,16 @@ class MethodReferenceUsageInfo extends UsageInfo {
}
public static boolean needToExpand(JavaChangeInfo changeInfo) {
return !changeInfo.isGenerateDelegate() && (changeInfo.isParameterSetOrOrderChanged() || changeInfo.isExceptionSetOrOrderChanged());
if (!changeInfo.isGenerateDelegate()) {
if (changeInfo.isParameterSetOrOrderChanged()) {
return true;
}
else if (changeInfo.isExceptionSetOrOrderChanged()) {
return JavaChangeSignatureUsageProcessor.hasNewCheckedExceptions(changeInfo);
}
}
return false;
}
@Nullable

View File

@@ -330,7 +330,7 @@ public class RefactoringUtil {
}
public static PsiMethod getEnclosingMethod(PsiElement element) {
final PsiElement container = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClass.class);
final PsiElement container = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClass.class, PsiLambdaExpression.class);
return container instanceof PsiMethod ? (PsiMethod)container : null;
}

View File

@@ -0,0 +1,19 @@
import java.util.function.Consumer;
class Action {
public void ac<caret>ting(String s) {
System.out.println(s);
}
}
class Client {
public static void consumer(String val, Consumer<String> func) {
func.accept(val);
}
public static void main(String[] args) {
Action a = new Action();
consumer("hello", (s) -> a.acting(s));
}
}

View File

@@ -0,0 +1,26 @@
import java.io.IOException;
import java.util.function.Consumer;
class Action {
public void acting(String s) throws IOException {
System.out.println(s);
}
}
class Client {
public static void consumer(String val, Consumer<String> func) {
func.accept(val);
}
public static void main(String[] args) {
Action a = new Action();
consumer("hello", (s) -> {
try {
a.acting(s);
} catch (IOException e) {
e.printStackTrace();
}
});
}
}

View File

@@ -0,0 +1,19 @@
import java.util.function.Consumer;
class Action {
public void ac<caret>ting(String s) {
System.out.println(s);
}
}
class Client {
public static void consumer(String val, Consumer<String> func) {
func.accept(val);
}
public static void main(String[] args) {
Action a = new Action();
consumer("hello", a::acting);
}
}

View File

@@ -0,0 +1,19 @@
import java.util.function.Consumer;
class Action {
public void acting(String s) throws NullPointerException {
System.out.println(s);
}
}
class Client {
public static void consumer(String val, Consumer<String> func) {
func.accept(val);
}
public static void main(String[] args) {
Action a = new Action();
consumer("hello", a::acting);
}
}

View File

@@ -15,10 +15,12 @@
*/
package com.intellij.codeInsight.daemon.lambda;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.psi.PsiType;
import com.intellij.refactoring.ChangeSignatureBaseTest;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
import com.intellij.refactoring.changeSignature.ThrownExceptionInfo;
import com.intellij.testFramework.IdeaTestUtil;
public class ChangeSignatureTouchLambdaTest extends ChangeSignatureBaseTest {
@@ -38,8 +40,21 @@ public class ChangeSignatureTouchLambdaTest extends ChangeSignatureBaseTest {
doTest(null, null, null, new ParameterInfoImpl[] {new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN, "false")}, new ThrownExceptionInfo[0], true);
}
public void testAddExceptionToCatchInOneLineLambda() throws Exception {
doTest(null, null, new String[] {"java.io.IOException"}, false);
}
public void testAddUncheckedExceptionInMethodRef() throws Exception {
doTest(null, null, new String[] {"java.lang.NullPointerException"}, false);
}
@Override
protected String getRelativePath() {
return "/codeInsight/daemonCodeAnalyzer/lambda/changeSignature/";
}
@Override
protected Sdk getProjectJDK() {
return IdeaTestUtil.getMockJdk18();
}
}