diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
index bfd2f6e5cf79..1e5416cdc798 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
@@ -48,11 +48,11 @@ public class HighlightControlFlowUtil {
private HighlightControlFlowUtil() { }
@Nullable
- public static HighlightInfo checkMissingReturnStatement(PsiMethod method) {
- PsiCodeBlock body = method.getBody();
+ public static HighlightInfo checkMissingReturnStatement(PsiCodeBlock body, PsiType returnType) {
+
if (body == null
- || method.getReturnType() == null
- || PsiType.VOID.equals(method.getReturnType())) {
+ || returnType == null
+ || PsiType.VOID.equals(returnType)) {
return null;
}
// do not compute constant expressions for if() statement condition
@@ -68,9 +68,13 @@ public class HighlightControlFlowUtil {
HighlightInfoType.ERROR,
context,
JavaErrorMessages.message("missing.return.statement"));
- QuickFixAction.registerQuickFixAction(highlightInfo, new AddReturnFix(method));
- IntentionAction fix = QUICK_FIX_FACTORY.createMethodReturnFix(method, PsiType.VOID, true);
- QuickFixAction.registerQuickFixAction(highlightInfo, fix);
+ final PsiElement parent = body.getParent();
+ if (parent instanceof PsiMethod) {
+ final PsiMethod method = (PsiMethod)parent;
+ QuickFixAction.registerQuickFixAction(highlightInfo, new AddReturnFix(method));
+ IntentionAction fix = QUICK_FIX_FACTORY.createMethodReturnFix(method, PsiType.VOID, true);
+ QuickFixAction.registerQuickFixAction(highlightInfo, fix);
+ }
return highlightInfo;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index a11968f67cbd..3dc1cb631d88 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -282,6 +282,12 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
} else {
myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, "Lambda expression not expected here"));
}
+ if (!myHolder.hasErrorResults()) {
+ final PsiElement body = expression.getBody();
+ if (body instanceof PsiCodeBlock) {
+ myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement((PsiCodeBlock)body));
+ }
+ }
}
}
@@ -333,10 +339,24 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
super.visitJavaToken(token);
if (!myHolder.hasErrorResults()
&& token.getTokenType() == JavaTokenType.RBRACE
- && token.getParent() instanceof PsiCodeBlock
- && token.getParent().getParent() instanceof PsiMethod) {
- PsiMethod method = (PsiMethod)token.getParent().getParent();
- myHolder.add(HighlightControlFlowUtil.checkMissingReturnStatement(method));
+ && token.getParent() instanceof PsiCodeBlock) {
+
+ final PsiElement gParent = token.getParent().getParent();
+ final PsiCodeBlock codeBlock;
+ final PsiType returnType;
+ if (gParent instanceof PsiMethod) {
+ PsiMethod method = (PsiMethod)gParent;
+ codeBlock = method.getBody();
+ returnType = method.getReturnType();
+ } else if (gParent instanceof PsiLambdaExpression) {
+ final PsiElement body = ((PsiLambdaExpression)gParent).getBody();
+ if (!(body instanceof PsiCodeBlock)) return;
+ codeBlock = (PsiCodeBlock)body;
+ returnType = LambdaUtil.getFunctionalInterfaceReturnType((PsiLambdaExpression)gParent);
+ } else {
+ return;
+ }
+ myHolder.add(HighlightControlFlowUtil.checkMissingReturnStatement(codeBlock, returnType));
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
index e190687f430e..04d6533f8ea4 100644
--- a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
@@ -97,7 +97,12 @@ public class RedundantLambdaCodeBlockInspection extends BaseJavaLocalInspectionT
return returnStatement.getReturnValue();
}
else {
- return ((PsiExpressionStatement)statements[0]).getExpression();
+ final PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression();
+ final PsiType psiType = expression.getType();
+ if (psiType != PsiType.VOID) {
+ return null;
+ }
+ return expression;
}
}
}
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
index 20f87a9b2841..64d5b1246585 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -92,12 +92,25 @@ public class LambdaUtil {
public static boolean isLambdaFullyInferred(PsiLambdaExpression expression, PsiType functionalInterfaceType) {
if (expression.getParameterList().getParametersCount() > 0 ||
getFunctionalInterfaceReturnType(functionalInterfaceType) != PsiType.VOID) { //todo check that void lambdas without params check
- if (functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()) return false;
+ if (!checkRawAcceptable(expression, functionalInterfaceType)) {
+ return false;
+ }
return !dependsOnTypeParams(functionalInterfaceType, functionalInterfaceType, expression, null);
}
return true;
}
+ private static boolean checkRawAcceptable(PsiLambdaExpression expression, PsiType functionalInterfaceType) {
+ PsiElement parent = expression.getParent();
+ while (parent instanceof PsiParenthesizedExpression) {
+ parent = parent.getParent();
+ }
+ if (parent instanceof PsiExpressionList && functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()){
+ return false;
+ }
+ return true;
+ }
+
@Nullable
public static String checkInterfaceFunctional(PsiType functionalInterfaceType) {
final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(functionalInterfaceType);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
index ac9a3ed686eb..21b208db2aac 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
@@ -850,9 +850,17 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
}
}
else if (parent instanceof PsiReturnStatement) {
- PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
- if (method != null) {
- expectedType = method.getReturnType();
+ final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
+ if (lambdaExpression != null) {
+ expectedType = LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression.getFunctionalInterfaceType());
+ if (expectedType == null) {
+ return getFailedInferenceConstraint(typeParameter);
+ }
+ } else {
+ PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
+ if (method != null) {
+ expectedType = method.getReturnType();
+ }
}
}
else if (parent instanceof PsiExpressionList) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConditionalExpr.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConditionalExpr.java
index a083d9ec1b6f..e44f0de64815 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConditionalExpr.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConditionalExpr.java
@@ -25,7 +25,7 @@ class Test {
{
boolean flag = true;
I i = flag ? (() -> 123) : (() -> 222);
- I i1 = flag ? (() -> {}) : (() -> 222);
+ I i1 = flag ? (() -> {}) : (() -> 222);
Object i2 = flag ? (() -> 42) : (() -> 222);
I i3 = flag ? ((x) -> 42) : (() -> 222);
I i4 = flag ? (() -> 42) : new I() {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleReturnTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleReturnTypes.java
index 61b13e5c0e04..7c16a8b75723 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleReturnTypes.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleReturnTypes.java
@@ -18,7 +18,7 @@ class Test2 {
}
{
IntReturnType aI = () -> System.out.println();
- IntReturnType aI1 = () -> {System.out.println();};
+ IntReturnType aI1 = () -> {System.out.println();};
IntReturnType aI2 = () -> {return 1;};
IntReturnType aI3 = () -> 1;
}
@@ -32,10 +32,10 @@ class Test3 {
}
{
XReturnType