mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
lambda: void return type compatibility (initial); functional interfaces without method params error messages
This commit is contained in:
@@ -126,22 +126,29 @@ public class LambdaUtil {
|
||||
}
|
||||
LOG.assertTrue(psiClass != null);
|
||||
PsiType methodReturnType = getReturnType(psiClass, methodSignature);
|
||||
if (methodReturnType != null && methodReturnType != PsiType.VOID) {
|
||||
methodReturnType = resolveResult.getSubstitutor().substitute(methodSignature.getSubstitutor().substitute(methodReturnType));
|
||||
final PsiElement body = lambdaExpression.getBody();
|
||||
if (body instanceof PsiCodeBlock) {
|
||||
final PsiCodeBlock block = (PsiCodeBlock)body;
|
||||
for (PsiStatement statement : block.getStatements()) {
|
||||
if (statement instanceof PsiReturnStatement) {
|
||||
final PsiExpression returnValue = ((PsiReturnStatement)statement).getReturnValue();
|
||||
if (returnValue != null) {
|
||||
if (!checkReturnTypeAssignability(returnValue.getType(), parameterTypes, lambdaExpression, methodReturnType)) return false;
|
||||
if (methodReturnType != null) {
|
||||
if (methodReturnType != PsiType.VOID) {
|
||||
methodReturnType = resolveResult.getSubstitutor().substitute(methodSignature.getSubstitutor().substitute(methodReturnType));
|
||||
final PsiElement body = lambdaExpression.getBody();
|
||||
if (body instanceof PsiCodeBlock) {
|
||||
final PsiCodeBlock block = (PsiCodeBlock)body;
|
||||
for (PsiStatement statement : block.getStatements()) {
|
||||
if (statement instanceof PsiReturnStatement) {
|
||||
final PsiExpression returnValue = ((PsiReturnStatement)statement).getReturnValue();
|
||||
if (returnValue != null) {
|
||||
if (!checkReturnTypeAssignability(returnValue.getType(), parameterTypes, lambdaExpression, methodReturnType)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (body instanceof PsiExpression) {
|
||||
return checkReturnTypeAssignability(((PsiExpression)body).getType(), parameterTypes, lambdaExpression, methodReturnType);
|
||||
else if (body instanceof PsiExpression) {
|
||||
return checkReturnTypeAssignability(((PsiExpression)body).getType(), parameterTypes, lambdaExpression, methodReturnType);
|
||||
}
|
||||
} else {
|
||||
final List<PsiExpression> returnExpressions = lambdaExpression.getReturnExpressions();
|
||||
for (PsiExpression returnValue : returnExpressions) {
|
||||
if (returnValue.getType() != PsiType.VOID) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
+9
-2
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiLambdaExpressionImpl;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.scope.MethodProcessorSetupFailedException;
|
||||
@@ -876,8 +877,14 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
final PsiExpressionList argumentList = methodCall.getArgumentList();
|
||||
if (argumentList != null && PsiUtil.getLanguageLevel(argumentList).isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
for (PsiExpression expression : argumentList.getExpressions()) {
|
||||
if (expression instanceof PsiLambdaExpression){
|
||||
return getFailedInferenceConstraint(typeParameter);
|
||||
if (expression instanceof PsiLambdaExpression) {
|
||||
if (((PsiLambdaExpression)expression).getParameterList().getParametersCount() > 0){
|
||||
return getFailedInferenceConstraint(typeParameter);
|
||||
}
|
||||
final PsiType functionalInterfaceType = PsiLambdaExpressionImpl.getFunctionalInterfaceType(((PsiLambdaExpression)expression), false);
|
||||
if (functionalInterfaceType == null || PsiUtil.resolveClassInType(functionalInterfaceType) == typeParameter){
|
||||
return getFailedInferenceConstraint(typeParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ class ReturnTypeCompatibility {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
call(<error descr="Cyclic inference">i-> {return i;}</error>);
|
||||
<error descr="Cannot resolve method 'call(<lambda expression>)'">call</error>(i-> {return i;});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import java.util.*;
|
||||
class Test4 {
|
||||
interface I<K> {
|
||||
List<K> foo();
|
||||
}
|
||||
|
||||
static <T> void bar(I<T> i){}
|
||||
|
||||
{
|
||||
bar(() -> null);
|
||||
}
|
||||
}
|
||||
|
||||
class Test5 {
|
||||
interface I<K> {
|
||||
void foo(K k);
|
||||
}
|
||||
|
||||
static <T> void bar(I<T> i){}
|
||||
|
||||
{
|
||||
bar<error descr="'bar(Test5.I<T>)' in 'Test5' cannot be applied to '(<lambda expression>)'">(() -> null)</error>;
|
||||
}
|
||||
}
|
||||
class Test6 {
|
||||
interface I<K> {
|
||||
void foo();
|
||||
}
|
||||
|
||||
static <T> void bar(I<T> i){}
|
||||
|
||||
{
|
||||
bar<error descr="'bar(Test6.I<java.lang.Object>)' in 'Test6' cannot be applied to '(<lambda expression>)'">(() -> null)</error>;
|
||||
bar(() -> {});
|
||||
}
|
||||
}
|
||||
+4
@@ -49,6 +49,10 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testTypeArgsConsistencyWithoutParams() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testWildcardBounds() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user