mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
new overload resolution: integrate isPotentiallyCompatible in isApplicable checks
This commit is contained in:
@@ -18,6 +18,7 @@ package com.intellij.psi;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.*;
|
||||
@@ -493,6 +494,31 @@ public class LambdaUtil {
|
||||
return expression;
|
||||
}
|
||||
|
||||
// http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1
|
||||
// A lambda expression or a method reference expression is potentially compatible with a type variable
|
||||
// if the type variable is a type parameter of the candidate method.
|
||||
public static boolean isPotentiallyCompatibleWithTypeParameter(PsiFunctionalExpression expression,
|
||||
PsiExpressionList argsList,
|
||||
PsiMethod method) {
|
||||
if (!Registry.is("JDK8042508.bug.fixed", false)) {
|
||||
final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(argsList, PsiCallExpression.class);
|
||||
if (callExpression == null || callExpression.getTypeArguments().length > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final int lambdaIdx = getLambdaIdx(argsList, expression);
|
||||
if (lambdaIdx >= 0) {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
final PsiParameter lambdaParameter = parameters[Math.min(lambdaIdx, parameters.length - 1)];
|
||||
final PsiClass paramClass = PsiUtil.resolveClassInType(lambdaParameter.getType());
|
||||
if (paramClass instanceof PsiTypeParameter && ((PsiTypeParameter)paramClass).getOwner() == method) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
|
||||
private PsiMethod myMethod;
|
||||
private final PsiClass myClass;
|
||||
|
||||
@@ -46,6 +46,4 @@ public interface PsiLambdaExpression extends PsiFunctionalExpression {
|
||||
* @return true when lambda declares parameter types explicitly
|
||||
*/
|
||||
boolean hasFormalParameterTypes();
|
||||
|
||||
boolean isAcceptable(PsiType leftType, boolean checkReturnType);
|
||||
}
|
||||
|
||||
@@ -731,7 +731,7 @@ public class TypeConversionUtil {
|
||||
final PsiType lType = lLambdaExpression.getFunctionalInterfaceType();
|
||||
return Comparing.equal(rType, lType);
|
||||
}
|
||||
return !(left instanceof PsiArrayType) && rLambdaExpression.isAcceptable(left, false);
|
||||
return !(left instanceof PsiArrayType) && rLambdaExpression.isAcceptable(left);
|
||||
}
|
||||
|
||||
if (left instanceof PsiIntersectionType) {
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.controlFlow.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
|
||||
@@ -34,6 +33,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements PsiLambdaExpression {
|
||||
|
||||
@@ -168,35 +169,35 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptable(PsiType left) {
|
||||
return isAcceptable(left, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAcceptable(PsiType leftType, boolean checkReturnType) {
|
||||
public boolean isAcceptable(PsiType leftType) {
|
||||
if (leftType instanceof PsiIntersectionType) {
|
||||
for (PsiType conjunctType : ((PsiIntersectionType)leftType).getConjuncts()) {
|
||||
if (isAcceptable(conjunctType, checkReturnType)) return true;
|
||||
if (isAcceptable(conjunctType)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final PsiElement argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
|
||||
if (!hasFormalParameterTypes()) {
|
||||
return true;
|
||||
}
|
||||
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList);
|
||||
if (candidateProperties != null && !InferenceSession.isPertinentToApplicability(this, candidateProperties.getMethod())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
|
||||
|
||||
leftType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(leftType, this);
|
||||
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(leftType);
|
||||
final PsiClass psiClass = resolveResult.getElement();
|
||||
if (psiClass instanceof PsiAnonymousClass) {
|
||||
return isAcceptable(((PsiAnonymousClass)psiClass).getBaseClassType(), checkReturnType);
|
||||
return isAcceptable(((PsiAnonymousClass)psiClass).getBaseClassType());
|
||||
}
|
||||
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
|
||||
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList);
|
||||
if (candidateProperties != null) {
|
||||
final PsiMethod method = candidateProperties.getMethod();
|
||||
if (!InferenceSession.isPertinentToApplicability(this, method) && hasFormalParameterTypes()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
|
||||
@@ -206,56 +207,77 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
|
||||
final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
|
||||
|
||||
assert leftType != null;
|
||||
final PsiParameter[] lambdaParameters = getParameterList().getParameters();
|
||||
final PsiType[] parameterTypes = interfaceMethod.getSignature(substitutor).getParameterTypes();
|
||||
if (lambdaParameters.length != parameterTypes.length) return false;
|
||||
if (!isPotentiallyCompatible(leftType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int lambdaParamIdx = 0, length = lambdaParameters.length; lambdaParamIdx < length; lambdaParamIdx++) {
|
||||
PsiParameter parameter = lambdaParameters[lambdaParamIdx];
|
||||
final PsiTypeElement typeElement = parameter.getTypeElement();
|
||||
if (typeElement != null) {
|
||||
final PsiType lambdaFormalType = toArray(typeElement.getType());
|
||||
final PsiType methodParameterType = toArray(parameterTypes[lambdaParamIdx]);
|
||||
if (!lambdaFormalType.equals(methodParameterType)) {
|
||||
return false;
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList) && !hasFormalParameterTypes()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (hasFormalParameterTypes()) {
|
||||
final PsiParameter[] lambdaParameters = getParameterList().getParameters();
|
||||
final PsiType[] parameterTypes = interfaceMethod.getSignature(substitutor).getParameterTypes();
|
||||
for (int lambdaParamIdx = 0, length = lambdaParameters.length; lambdaParamIdx < length; lambdaParamIdx++) {
|
||||
PsiParameter parameter = lambdaParameters[lambdaParamIdx];
|
||||
final PsiTypeElement typeElement = parameter.getTypeElement();
|
||||
if (typeElement != null) {
|
||||
final PsiType lambdaFormalType = toArray(typeElement.getType());
|
||||
final PsiType methodParameterType = toArray(parameterTypes[lambdaParamIdx]);
|
||||
if (!lambdaFormalType.equals(methodParameterType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//A lambda expression (§15.27) is potentially compatible with a functional interface type (§9.8) if all of the following are true:
|
||||
// The arity of the target type's function type is the same as the arity of the lambda expression.
|
||||
// If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2).
|
||||
// If the target type's function type has a (non-void) return type, then the lambda body is either an expression or a value-compatible block (§15.27.2).
|
||||
PsiType methodReturnType = interfaceMethod.getReturnType();
|
||||
if (checkReturnType) {
|
||||
final String uniqueVarName = JavaCodeStyleManager.getInstance(getProject()).suggestUniqueVariableName("l", this, true);
|
||||
final String canonicalText = toArray(leftType).getCanonicalText();
|
||||
final PsiStatement assignmentFromText = JavaPsiFacade.getElementFactory(getProject())
|
||||
.createStatementFromText(canonicalText + " " + uniqueVarName + " = " + getText(), this);
|
||||
final PsiLocalVariable localVariable = (PsiLocalVariable)((PsiDeclarationStatement)assignmentFromText).getDeclaredElements()[0];
|
||||
if (methodReturnType != null) {
|
||||
return LambdaHighlightingUtil.checkReturnTypeCompatible((PsiLambdaExpression)localVariable.getInitializer(),
|
||||
substitutor.substitute(methodReturnType)) == null;
|
||||
if (methodReturnType != null) {
|
||||
Map<PsiElement, PsiType> map = LambdaUtil.ourFunctionTypes.get();
|
||||
if (map == null) {
|
||||
map = new HashMap<PsiElement, PsiType>();
|
||||
LambdaUtil.ourFunctionTypes.set(map);
|
||||
}
|
||||
} else {
|
||||
final PsiElement body = getBody();
|
||||
if (methodReturnType == PsiType.VOID) {
|
||||
if (body instanceof PsiCodeBlock) {
|
||||
return isVoidCompatible();
|
||||
} else {
|
||||
return LambdaUtil.isExpressionStatementExpression(body);
|
||||
try {
|
||||
if (map.put(this, leftType) != null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (body instanceof PsiCodeBlock) {
|
||||
return isValueCompatible();
|
||||
}
|
||||
return body instanceof PsiExpression;
|
||||
return LambdaHighlightingUtil.checkReturnTypeCompatible(this, substitutor.substitute(methodReturnType)) == null;
|
||||
}
|
||||
finally {
|
||||
map.remove(this);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//A lambda expression (§15.27) is potentially compatible with a functional interface type (§9.8) if all of the following are true:
|
||||
// The arity of the target type's function type is the same as the arity of the lambda expression.
|
||||
// If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2).
|
||||
// If the target type's function type has a (non-void) return type, then the lambda body is either an expression or a value-compatible block (§15.27.2).
|
||||
private boolean isPotentiallyCompatible(PsiType left) {
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(left);
|
||||
if (interfaceMethod == null) return false;
|
||||
|
||||
if (getParameterList().getParametersCount() != interfaceMethod.getParameterList().getParametersCount()) {
|
||||
return false;
|
||||
}
|
||||
final PsiType methodReturnType = interfaceMethod.getReturnType();
|
||||
final PsiElement body = getBody();
|
||||
if (methodReturnType == PsiType.VOID) {
|
||||
if (body instanceof PsiCodeBlock) {
|
||||
return isVoidCompatible();
|
||||
} else {
|
||||
return LambdaUtil.isExpressionStatementExpression(body);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return body instanceof PsiCodeBlock && isValueCompatible() || body instanceof PsiExpression;
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiType toArray(PsiType paramType) {
|
||||
if (paramType instanceof PsiEllipsisType) {
|
||||
return ((PsiEllipsisType)paramType).toArrayType();
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
|
||||
@@ -373,12 +374,19 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiElement argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
|
||||
final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
|
||||
final boolean isExact = isExact();
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList) && isExact) {
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
|
||||
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList);
|
||||
if (candidateProperties != null && !InferenceSession.isPertinentToApplicability(this, candidateProperties.getMethod())) {
|
||||
return true;
|
||||
if (candidateProperties != null) {
|
||||
final PsiMethod method = candidateProperties.getMethod();
|
||||
if (isExact && !InferenceSession.isPertinentToApplicability(this, method)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.intellij.util.containers.HashSet;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -91,9 +92,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
// then noone can be more specific
|
||||
if (!atLeastOneMatch) return null;
|
||||
|
||||
checkLambdaApplicable(conflicts, myLanguageLevel);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkSpecifics(conflicts, applicabilityLevel, myLanguageLevel);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
@@ -108,63 +106,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, @NotNull LanguageLevel languageLevel) {
|
||||
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return;
|
||||
for (int i = 0; i < getActualParametersLength(); i++) {
|
||||
|
||||
PsiExpression expression;
|
||||
if (myArgumentsList instanceof PsiExpressionList) {
|
||||
expression = ((PsiExpressionList)myArgumentsList).getExpressions()[i];
|
||||
}
|
||||
else {
|
||||
final PsiType argType = getActualParameterTypes()[i];
|
||||
expression = argType instanceof PsiLambdaExpressionType ? ((PsiLambdaExpressionType)argType).getExpression() : null;
|
||||
}
|
||||
|
||||
final PsiLambdaExpression lambdaExpression = findNestedLambdaExpression(expression);
|
||||
if (lambdaExpression != null) {
|
||||
checkLambdaApplicable(conflicts, i, lambdaExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiLambdaExpression findNestedLambdaExpression(PsiExpression expression) {
|
||||
if (expression instanceof PsiLambdaExpression) {
|
||||
return (PsiLambdaExpression)expression;
|
||||
}
|
||||
else if (expression instanceof PsiParenthesizedExpression) {
|
||||
return findNestedLambdaExpression(((PsiParenthesizedExpression)expression).getExpression());
|
||||
}
|
||||
else if (expression instanceof PsiConditionalExpression) {
|
||||
PsiLambdaExpression lambdaExpression = findNestedLambdaExpression(((PsiConditionalExpression)expression).getThenExpression());
|
||||
if (lambdaExpression != null) {
|
||||
return lambdaExpression;
|
||||
}
|
||||
return findNestedLambdaExpression(((PsiConditionalExpression)expression).getElseExpression());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, int i, @NotNull PsiLambdaExpression lambdaExpression) {
|
||||
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
|
||||
ProgressManager.checkCanceled();
|
||||
final CandidateInfo conflict = iterator.next();
|
||||
final PsiMethod method = (PsiMethod)conflict.getElement();
|
||||
final PsiParameter[] methodParameters = method.getParameterList().getParameters();
|
||||
if (methodParameters.length == 0) continue;
|
||||
final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
|
||||
final PsiType paramType = param.getType();
|
||||
// http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1
|
||||
// A lambda expression or a method reference expression is potentially compatible with a type variable if the type variable is a type parameter of the candidate method.
|
||||
final PsiClass paramClass = PsiUtil.resolveClassInType(paramType);
|
||||
if (paramClass instanceof PsiTypeParameter && ((PsiTypeParameter)paramClass).getOwner() == method) continue;
|
||||
if (!lambdaExpression.isAcceptable(((MethodCandidateInfo)conflict).getSubstitutor(false).substitute(paramType),
|
||||
InferenceSession.isPertinentToApplicability(lambdaExpression, method))) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkSpecifics(@NotNull List<CandidateInfo> conflicts,
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
|
||||
@@ -20,7 +20,7 @@ public class Test<A, B extends Number> {
|
||||
public static void main(String[] args) {
|
||||
Inner<Number, Double> inn = new Inner<>();
|
||||
inn.m8<error descr="Ambiguous method call: both 'Inner.m8(IO<? extends Number>)' and 'Inner.m8(IN<? extends Double>)' match">(p -> 1.0)</error>;
|
||||
new Test<Number, Integer>().foo<error descr="Ambiguous method call: both 'Test.foo(IO<? extends Number>)' and 'Test.foo(IN<? extends Integer>)' match">(p -> 1.0)</error>;
|
||||
new Test<Number, Integer>().foo<error descr="Cannot resolve method 'foo(<lambda expression>)'">(p -> 1.0)</error>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Demo {
|
||||
|
||||
public void f1() {
|
||||
f2(2, <error descr="Target type of a lambda conversion must be an interface">input -> input</error>);
|
||||
f2<error descr="Cannot resolve method 'f2(int, <lambda expression>)'">(2, input -> input)</error>;
|
||||
}
|
||||
|
||||
public void f2() {
|
||||
|
||||
@@ -25,7 +25,7 @@ class ReturnTypeIncompatibility {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
call<error descr="Ambiguous method call: both 'ReturnTypeIncompatibility.call(I1<Integer>)' and 'ReturnTypeIncompatibility.call(I2<P>)' match">(i-> {return i;})</error>;
|
||||
call<error descr="Cannot resolve method 'call(<lambda expression>)'">(i-> {return i;})</error>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ class ReturnTypeCompatibility {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
call<error descr="Ambiguous method call: both 'ReturnTypeCompatibility.call(I1<Number>)' and 'ReturnTypeCompatibility.call(I2<String>)' match">(i-> {return i;})</error>;
|
||||
call<error descr="Cannot resolve method 'call(<lambda expression>)'">(i-> {return i;})</error>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ class Test {
|
||||
}
|
||||
|
||||
void foo(Foo<String> as, final Foo<Character> ac) {
|
||||
boolean b1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> false)</error>);
|
||||
String s1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>);
|
||||
boolean b2 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>);
|
||||
boolean b1 = as.forAll(s -> ac.forAll<error descr="Cannot resolve method 'forAll(<lambda expression>)'">(c -> false)</error>);
|
||||
String s1 = as.forAll(s -> ac.forAll<error descr="Cannot resolve method 'forAll(<lambda expression>)'">(c -> "")</error>);
|
||||
boolean b2 = as.forAll(s -> ac.forAll<error descr="Cannot resolve method 'forAll(<lambda expression>)'">(c -> "")</error>);
|
||||
String s2 = as.forAll2(s -> ac.forAll2(<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
|
||||
boolean b3 = as.forAll((I<String, Boolean>)s -> ac.forAll((I<Character, Boolean>)<error descr="Incompatible return type String in lambda expression">c -> ""</error>));
|
||||
String s3 = as.forAll((II<String, String>)s -> ac.forAll((II<Character, String>)<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
|
||||
|
||||
@@ -14,7 +14,7 @@ class Test {
|
||||
}
|
||||
|
||||
void fooBar(IntStream1 instr){
|
||||
Supplier<Stream<Integer>> si = () -> instr.map ((i) -> (( <error descr="Operator '%' cannot be applied to '<lambda parameter>', 'int'">i % 2</error>) == 0) ? i : <error descr="Incompatible types. Found: '<lambda parameter>', required: '<lambda parameter>'">-i</error>).boxed();
|
||||
Supplier<Stream<Integer>> si = () -> instr.map ((i) -> (( <error descr="Operator '%' cannot be applied to '<lambda parameter>', 'int'">i % 2</error>) == 0) ? i : -i).boxed();
|
||||
System.out.println(si);
|
||||
Supplier<Stream<Integer>> si1 = () -> instr.map <error descr="Ambiguous method call: both 'IntStream1.map(IntFunction<Integer>)' and 'IntStream1.map(IntUnaryOperator)' match">(null)</error>.boxed();
|
||||
System.out.println(si1);
|
||||
|
||||
@@ -12,6 +12,6 @@ abstract class PertinentToApplicabilityOfExplicitlyTypedLambdaTest {
|
||||
abstract void foo(B b);
|
||||
|
||||
{
|
||||
foo<error descr="Ambiguous method call: both 'PertinentToApplicabilityOfExplicitlyTypedLambdaTest.foo(A)' and 'PertinentToApplicabilityOfExplicitlyTypedLambdaTest.foo(B)' match">(x -> y -> 42)</error>;
|
||||
foo<error descr="Cannot resolve method 'foo(<lambda expression>)'">(x -> y -> 42)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,10 @@ abstract class Test {
|
||||
foo(x -> {
|
||||
return x += 1;
|
||||
});
|
||||
foo(x -> <error descr="Incompatible types. Found: 'int', required: '<lambda parameter>'">x += 1</error>);
|
||||
foo<error descr="Ambiguous method call: both 'Test.foo(A)' and 'Test.foo(B)' match">(x -> x += 1)</error>;
|
||||
foo(x -> 1);
|
||||
foo(x -> <error descr="Operator '!' cannot be applied to 'int'">!x</error>);
|
||||
foo(x -> <error descr="Operator '++' cannot be applied to '<lambda parameter>'">++x</error>);
|
||||
foo<error descr="Ambiguous method call: both 'Test.foo(A)' and 'Test.foo(B)' match">(x -> ++x)</error>;
|
||||
foo(x -> o instanceof String ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ class Foo {
|
||||
System.out.println(s);
|
||||
});
|
||||
|
||||
<error descr="Cannot resolve method 'foo(<lambda expression>)'">foo</error>((String p, String k) -> {
|
||||
foo<error descr="Cannot resolve method 'foo(<lambda expression>)'">((String p, String k) -> {
|
||||
System.out.println(p);
|
||||
});
|
||||
})</error>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ class WithTypeParams {
|
||||
System.out.println(p);
|
||||
});
|
||||
|
||||
<error descr="Cannot resolve method 'foo(<lambda expression>)'">foo</error>((int k) -> {System.out.println(k);});
|
||||
foo<error descr="Cannot resolve method 'foo(<lambda expression>)'">((int k) -> {System.out.println(k);})</error>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
@@ -100,7 +101,9 @@ public class MostSpecificResolutionTest extends LightDaemonAnalyzerTestCase {
|
||||
}
|
||||
|
||||
public void testJDK8042508() throws Exception {
|
||||
doTest(false);
|
||||
if (Registry.is("JDK8042508.bug.fixed", false)) {
|
||||
doTest(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void testIDEA125855() throws Exception {
|
||||
|
||||
@@ -495,4 +495,7 @@ editor.xcode.like.scrollbar=false
|
||||
editor.xcode.like.scrollbar.description=Enables auto-hideable Xcode-like editor stripes
|
||||
|
||||
editor.config.stop.at.project.root=true
|
||||
editor.config.stop.at.project.root.description=Stops searching for .editorconfig at project root (requires project reopening)
|
||||
editor.config.stop.at.project.root.description=Stops searching for .editorconfig at project root (requires project reopening)
|
||||
|
||||
JDK8042508.bug.fixed=false
|
||||
JDK8042508.bug.fixed.description=Disable check for type variable until javac bug is fixed
|
||||
|
||||
Reference in New Issue
Block a user