delete old inference strategy for java 8

This commit is contained in:
Anna Kozlova
2014-02-21 18:55:56 +01:00
parent 96af56c572
commit cf00d70317
17 changed files with 138 additions and 751 deletions
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -57,7 +58,7 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti
if (parameter.getTypeElement() == null) return false;
}
if (parameters.length == 0) return false;
final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(expression, false);
final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(expression, true);
if (functionalInterfaceType != null) {
final PsiElement lambdaParent = expression.getParent();
if (lambdaParent instanceof PsiExpressionList) {
@@ -84,11 +85,12 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti
for (PsiTypeParameter parameter : typeParameters) {
final PsiType psiType = substitutor.substitute(parameter);
if (psiType == null || LambdaUtil.dependsOnTypeParams(psiType, expression, parameter)) return false;
if (psiType == null || dependsOnTypeParams(psiType, expression, parameter)) return false;
}
return functionalInterfaceType.isAssignableFrom(substitutor.substitute(method.getParameterList().getParameters()[idx].getType()));
}
}
else if (!LambdaUtil.isLambdaFullyInferred(expression, functionalInterfaceType)) {
if (!LambdaUtil.isLambdaFullyInferred(expression, functionalInterfaceType)) {
return false;
}
return true;
@@ -122,4 +124,11 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti
lambdaExpression.getParameterList().replace(expression.getParameterList());
}
}
private static boolean dependsOnTypeParams(PsiType type,
PsiLambdaExpression expr,
PsiTypeParameter param2Check) {
return LambdaUtil.depends(type, new LambdaUtil.TypeParamsChecker(expr, PsiUtil
.resolveGenericsClassInType(LambdaUtil.getFunctionalInterfaceType(expr, false)).getElement()), param2Check);
}
}
@@ -239,12 +239,6 @@ public class LambdaUtil {
return -1;
}
public static boolean dependsOnTypeParams(PsiType type,
PsiLambdaExpression expr,
PsiTypeParameter param2Check) {
return depends(type, new TypeParamsChecker(expr), param2Check);
}
public static boolean dependsOnTypeParams(PsiType type,
PsiType functionalInterfaceType,
PsiElement lambdaExpression,
@@ -253,13 +247,7 @@ public class LambdaUtil {
PsiUtil.resolveClassInType(functionalInterfaceType)), param2Check);
}
public static boolean dependsOnTypeParams(PsiType type,
PsiClass aClass,
PsiMethod aMethod) {
return depends(type, new TypeParamsChecker(aMethod, aClass));
}
static boolean depends(PsiType type, TypeParamsChecker visitor, PsiTypeParameter... param2Check) {
public static boolean depends(PsiType type, TypeParamsChecker visitor, PsiTypeParameter... param2Check) {
if (!visitor.startedInference()) return false;
final Boolean accept = type.accept(visitor);
if (param2Check.length > 0) {
@@ -268,79 +256,8 @@ public class LambdaUtil {
return accept != null && accept.booleanValue();
}
public static boolean isFreeFromTypeInferenceArgs(final PsiParameter[] methodParameters,
final PsiLambdaExpression lambdaExpression,
final PsiExpression expression,
final PsiSubstitutor subst,
final PsiType functionalInterfaceType,
final PsiTypeParameter typeParam) {
if (expression instanceof PsiCallExpression && ((PsiCallExpression)expression).getTypeArguments().length > 0) return true;
if (expression instanceof PsiNewExpression) {
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)expression).getClassOrAnonymousClassReference();
if (classReference != null) {
final PsiReferenceParameterList parameterList = classReference.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] typeParameterElements = parameterList.getTypeParameterElements();
if (typeParameterElements.length > 0) {
if (!(typeParameterElements[0].getType() instanceof PsiDiamondType)) {
return true;
}
}
}
}
}
final PsiParameter[] lambdaParams = lambdaExpression.getParameterList().getParameters();
if (lambdaParams.length != methodParameters.length) return false;
final boolean[] independent = {true};
final PsiMethod interfaceMethod = getFunctionalInterfaceMethod(functionalInterfaceType);
if (interfaceMethod == null) return false;
final TypeParamsChecker paramsChecker = new TypeParamsChecker(lambdaExpression);
for (PsiParameter parameter : interfaceMethod.getParameterList().getParameters()) {
subst.substitute(parameter.getType()).accept(paramsChecker);
}
paramsChecker.myUsedTypeParams.add(typeParam);
expression.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitConditionalExpression(PsiConditionalExpression expression) {
final PsiExpression thenExpression = expression.getThenExpression();
if (thenExpression != null) {
thenExpression.accept(this);
}
final PsiExpression elseExpression = expression.getElseExpression();
if (elseExpression != null) {
elseExpression.accept(this);
}
}
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
super.visitReferenceExpression(expression);
int usedParamIdx = -1;
for (int i = 0; i < lambdaParams.length; i++) {
PsiParameter param = lambdaParams[i];
if (expression.isReferenceTo(param)) {
usedParamIdx = i;
break;
}
}
if (usedParamIdx > -1 && dependsOnTypeParams(subst.substitute(methodParameters[usedParamIdx].getType()), functionalInterfaceType,
lambdaExpression, paramsChecker.myUsedTypeParams.toArray(new PsiTypeParameter[paramsChecker.myUsedTypeParams.size()]))) {
independent[0] = false;
}
}
});
return independent[0];
}
@Nullable
public static PsiType getFunctionalInterfaceType(PsiElement expression, final boolean tryToSubstitute) {
return getFunctionalInterfaceType(expression, tryToSubstitute, -1);
}
@Nullable
public static PsiType getFunctionalInterfaceType(PsiElement expression, final boolean tryToSubstitute, int paramIdx) {
PsiElement parent = expression.getParent();
PsiElement element = expression;
while (parent instanceof PsiParenthesizedExpression || parent instanceof PsiConditionalExpression) {
@@ -443,53 +360,6 @@ public class LambdaUtil {
return type;
}
public static PsiType getLambdaParameterType(PsiParameter param) {
final PsiElement paramParent = param.getParent();
if (paramParent instanceof PsiParameterList) {
final int parameterIndex = ((PsiParameterList)paramParent).getParameterIndex(param);
if (parameterIndex > -1) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(param, PsiLambdaExpression.class);
if (lambdaExpression != null) {
PsiType type = getFunctionalInterfaceType(lambdaExpression, true, parameterIndex);
if (type == null) {
type = getFunctionalInterfaceType(lambdaExpression, false);
}
if (type instanceof PsiIntersectionType) {
final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts();
for (PsiType conjunct : conjuncts) {
final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, conjunct);
if (lambdaParameterFromType != null) return lambdaParameterFromType;
}
} else {
final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, type);
if (lambdaParameterFromType != null) {
return lambdaParameterFromType;
}
}
}
}
}
return new PsiLambdaParameterType(param);
}
private static PsiType getLambdaParameterFromType(int parameterIndex, PsiLambdaExpression lambdaExpression, PsiType conjunct) {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(conjunct);
if (resolveResult != null) {
final PsiMethod method = getFunctionalInterfaceMethod(conjunct);
if (method != null) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameterIndex < parameters.length) {
final PsiType psiType = getSubstitutor(method, resolveResult).substitute(parameters[parameterIndex].getType());
if (!dependsOnTypeParams(psiType, conjunct, lambdaExpression)) {
return GenericsUtil.eliminateWildcards(psiType);
}
}
}
}
return null;
}
public static boolean notInferredType(PsiType typeByExpression) {
return typeByExpression instanceof PsiMethodReferenceType || typeByExpression instanceof PsiLambdaExpressionType || typeByExpression instanceof PsiLambdaParameterType;
}
@@ -560,19 +430,10 @@ public class LambdaUtil {
return true;
}
static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
public static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
private PsiMethod myMethod;
private final PsiClass myClass;
private final Set<PsiTypeParameter> myUsedTypeParams = new HashSet<PsiTypeParameter>();
private TypeParamsChecker(PsiMethod method, PsiClass aClass) {
myMethod = method;
myClass = aClass;
}
public TypeParamsChecker(PsiElement expression) {
this(expression, PsiUtil.resolveGenericsClassInType(getFunctionalInterfaceType(expression, false)).getElement());
}
public final Set<PsiTypeParameter> myUsedTypeParams = new HashSet<PsiTypeParameter>();
public TypeParamsChecker(PsiElement expression, PsiClass aClass) {
myClass = aClass;
@@ -1065,11 +1065,11 @@ public final class PsiUtil extends PsiUtilCore {
return className + "." + member.getName();
}
static boolean checkSameExpression(PsiExpression templateExpr, final PsiExpression expression) {
static boolean checkSameExpression(PsiElement templateExpr, final PsiExpression expression) {
return templateExpr.equals(skipParenthesizedExprDown(expression));
}
public static boolean isCondition(PsiExpression expr, PsiElement parent) {
public static boolean isCondition(PsiElement expr, PsiElement parent) {
if (parent instanceof PsiIfStatement) {
if (checkSameExpression(expr, ((PsiIfStatement)parent).getCondition())) {
return true;
@@ -32,6 +32,7 @@ import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.reference.SoftReference;
import com.intellij.ui.RowIcon;
import com.intellij.util.IncorrectOperationException;
@@ -59,6 +60,53 @@ public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> imple
super(node);
}
public static PsiType getLambdaParameterType(PsiParameter param) {
final PsiElement paramParent = param.getParent();
if (paramParent instanceof PsiParameterList) {
final int parameterIndex = ((PsiParameterList)paramParent).getParameterIndex(param);
if (parameterIndex > -1) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(param, PsiLambdaExpression.class);
if (lambdaExpression != null) {
PsiType type = LambdaUtil.getFunctionalInterfaceType(lambdaExpression, true);
if (type == null) {
type = LambdaUtil.getFunctionalInterfaceType(lambdaExpression, false);
}
if (type instanceof PsiIntersectionType) {
final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts();
for (PsiType conjunct : conjuncts) {
final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, conjunct);
if (lambdaParameterFromType != null) return lambdaParameterFromType;
}
} else {
final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, type);
if (lambdaParameterFromType != null) {
return lambdaParameterFromType;
}
}
}
}
}
return new PsiLambdaParameterType(param);
}
private static PsiType getLambdaParameterFromType(int parameterIndex, PsiLambdaExpression lambdaExpression, PsiType conjunct) {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(conjunct);
if (resolveResult != null) {
final PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(conjunct);
if (method != null) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameterIndex < parameters.length) {
final PsiType psiType = LambdaUtil.getSubstitutor(method, resolveResult).substitute(parameters[parameterIndex].getType());
if (!LambdaUtil.dependsOnTypeParams(psiType, conjunct, lambdaExpression)) {
return GenericsUtil.eliminateWildcards(psiType);
}
}
}
}
return null;
}
@Override
public void subtreeChanged() {
super.subtreeChanged();
@@ -138,7 +186,7 @@ public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> imple
PsiTypeElement typeElement = getTypeElement();
if (typeElement == null) {
assert isLambdaParameter() : this;
return LambdaUtil.getLambdaParameterType(this);
return getLambdaParameterType(this);
}
else {
return JavaSharedImplUtil.getType(typeElement, getParameterIdentifier());
@@ -1,114 +0,0 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.source.resolve;
import com.intellij.psi.*;
import com.intellij.psi.scope.MethodProcessorSetupFailedException;
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import java.util.*;
/**
* User: anna
* Date: 2/14/13
*/
public class GraphInferencePolicy extends ProcessCandidateParameterTypeInferencePolicy {
private static final ThreadLocal<Map<PsiExpression, Map<JavaResolveResult, PsiSubstitutor>>> ourResults = new ThreadLocal<Map<PsiExpression, Map<JavaResolveResult, PsiSubstitutor>>>() {
@Override
protected Map<PsiExpression, Map<JavaResolveResult, PsiSubstitutor>> initialValue() {
return new WeakHashMap<PsiExpression, Map<JavaResolveResult, PsiSubstitutor>>();
}
};
@Override
protected List<PsiExpression> getExpressions(PsiExpression[] expressions, int i) {
final List<PsiExpression> list = Arrays.asList(expressions);
list.set(i, null);
return list;
}
@Override
protected PsiSubstitutor getSubstitutor(PsiCallExpression contextCall, PsiExpression[] expressions, int i, JavaResolveResult result) {
Map<JavaResolveResult, PsiSubstitutor> map = ourResults.get().get(contextCall);
if (map != null) {
final PsiSubstitutor substitutor = map.get(result);
if (substitutor != PsiSubstitutor.UNKNOWN && substitutor != null && substitutor.isValid()) return substitutor;
}
final PsiSubstitutor substitutor = super.getSubstitutor(contextCall, expressions, i, result);
if (map != null) {
map.put(result, substitutor);
}
return substitutor;
}
@NotNull
@Override
protected JavaResolveResult[] getResults(@NotNull PsiCallExpression contextCall, final int exprIdx)
throws MethodProcessorSetupFailedException {
Map<JavaResolveResult, PsiSubstitutor> map = ourResults.get().get(contextCall);
if (map != null) {
final Set<JavaResolveResult> results = map.keySet();
return results.toArray(new JavaResolveResult[results.size()]);
}
PsiFile containingFile = contextCall.getContainingFile();
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall, containingFile) {
@Override
protected PsiType[] getExpressionTypes(PsiExpressionList argumentList) {
if (argumentList != null) {
final PsiExpression[] expressions = argumentList.getExpressions();
final PsiType[] types = PsiType.createArray(expressions.length);
for (int i = 0; i < expressions.length; i++) {
if (i != exprIdx) {
types[i] = expressions[i].getType();
}
else {
types[i] = PsiType.NULL;
}
}
return types;
}
else {
return null;
}
}
};
PsiScopesUtil.setupAndRunProcessor(processor, contextCall, false);
final JavaResolveResult[] results = processor.getResult();
map = new WeakHashMap<JavaResolveResult, PsiSubstitutor>();
ourResults.get().put(contextCall, map);
for (JavaResolveResult result : results) {
map.put(result, PsiSubstitutor.UNKNOWN);
}
return results;
}
public static void forget(PsiElement parent) {
if (parent instanceof PsiExpression) {
PsiElement gParent = PsiUtil.skipParenthesizedExprUp(parent.getParent());
if (gParent instanceof PsiExpressionList) {
final PsiElement ggParent = gParent.getParent();
if (ggParent instanceof PsiCallExpression) {
ourResults.get().remove(ggParent);
}
}
}
}
}
@@ -15,29 +15,22 @@
*/
package com.intellij.psi.impl.source.resolve;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
/**
* User: anna
*/
@@ -50,7 +43,7 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
myManager = manager;
}
private Pair<PsiType, ConstraintType> inferTypeForMethodTypeParameterInner(@NotNull PsiTypeParameter typeParameter,
private Pair<PsiType, ConstraintType> inferTypeForMethodTypeParameterInner(@NotNull PsiTypeParameter typeParameter,
@NotNull PsiParameter[] parameters,
@NotNull PsiExpression[] arguments,
@NotNull PsiSubstitutor partialSubstitutor,
@@ -98,10 +91,6 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
PsiType lowerBound = PsiType.NULL;
PsiType upperBound = PsiType.NULL;
if (paramTypes.length > 0) {
sortLambdaExpressionsLast(paramTypes, argTypes);
boolean rawType = false;
boolean nullPassed = false;
boolean lambdaRaw = false;
for (int j = 0; j < argTypes.length; j++) {
PsiType argumentType = argTypes[j];
if (argumentType == null) continue;
@@ -109,8 +98,6 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
PsiType parameterType = paramTypes[j];
if (parameterType == null) break;
rawType |= parameterType instanceof PsiClassType && ((PsiClassType)parameterType).isRaw();
nullPassed |= argumentType == PsiType.NULL;
if (parameterType instanceof PsiEllipsisType) {
parameterType = ((PsiEllipsisType)parameterType).getComponentType();
@@ -119,26 +106,8 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
}
}
final Pair<PsiType,ConstraintType> currentSubstitution;
if (argumentType instanceof PsiLambdaExpressionType) {
currentSubstitution = inferSubstitutionFromLambda(typeParameter, (PsiLambdaExpressionType)argumentType, lowerBound, partialSubstitutor);
if (rawType) {
if (currentSubstitution == FAILED_INFERENCE || currentSubstitution == null && lowerBound == PsiType.NULL) return RAW_INFERENCE;
}
if (nullPassed && currentSubstitution == null) return RAW_INFERENCE;
if (currentSubstitution != null && currentSubstitution.first == null) {
lambdaRaw = true;
}
if (currentSubstitution == null && lambdaRaw) {
return new Pair<PsiType, ConstraintType>(PsiType.getJavaLangObject(myManager, typeParameter.getResolveScope()), ConstraintType.EQUALS);
}
} else if (argumentType instanceof PsiMethodReferenceType) {
final PsiMethodReferenceExpression referenceExpression = ((PsiMethodReferenceType)argumentType).getExpression();
currentSubstitution = inferConstraintFromFunctionalInterfaceMethod(typeParameter, referenceExpression, partialSubstitutor.substitute(parameterType), partialSubstitutor, policy);
}
else {
currentSubstitution = getSubstitutionForTypeParameterConstraint(typeParameter, parameterType,
argumentType, true, PsiUtil.getLanguageLevel(typeParameter));
}
currentSubstitution = getSubstitutionForTypeParameterConstraint(typeParameter, parameterType,
argumentType, true, PsiUtil.getLanguageLevel(typeParameter));
if (currentSubstitution == null) continue;
if (currentSubstitution == FAILED_INFERENCE) {
return getFailedInferenceConstraint(typeParameter);
@@ -210,23 +179,6 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
return null;
}
private static void sortLambdaExpressionsLast(@NotNull PsiType[] paramTypes, @NotNull PsiType[] argTypes) {
for (int i = 0; i < argTypes.length; i++) {
PsiType argType = argTypes[i];
if ((argType instanceof PsiLambdaExpressionType || argType instanceof PsiMethodReferenceType) && i < argTypes.length - 1) {
int k = i + 1;
while((argTypes[k] instanceof PsiLambdaExpressionType || argTypes[k] instanceof PsiMethodReferenceType) && k < argTypes.length - 1) {
k++;
}
if (!(argTypes[k] instanceof PsiLambdaExpressionType || argTypes[k] instanceof PsiMethodReferenceType)) {
ArrayUtil.swap(paramTypes, i, k);
ArrayUtil.swap(argTypes, i, k);
i = k;
}
}
}
}
private static Pair<PsiType, ConstraintType> getFailedInferenceConstraint(@NotNull PsiTypeParameter typeParameter) {
return new Pair<PsiType, ConstraintType>(JavaPsiFacade.getInstance(typeParameter.getProject()).getElementFactory().createType(typeParameter), ConstraintType.EQUALS);
}
@@ -321,41 +273,36 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
}
}
try {
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter typeParameter = typeParameters[i];
PsiType substitution = substitutions[i];
if (substitution != null) continue;
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter typeParameter = typeParameters[i];
PsiType substitution = substitutions[i];
if (substitution != null) continue;
Pair<PsiType, ConstraintType> constraint = constraints[i];
if (constraint == null) {
constraint = inferMethodTypeParameterFromParent(typeParameter, partialSubstitutor, parent, policy);
}
else if (constraint.getSecond() == ConstraintType.SUBTYPE) {
Pair<PsiType, ConstraintType> otherConstraint =
inferMethodTypeParameterFromParent(typeParameter, partialSubstitutor, parent, policy);
if (otherConstraint != null) {
if (otherConstraint.getSecond() == ConstraintType.EQUALS || otherConstraint.getSecond() == ConstraintType.SUPERTYPE) {
constraint = otherConstraint;
}
Pair<PsiType, ConstraintType> constraint = constraints[i];
if (constraint == null) {
constraint = inferMethodTypeParameterFromParent(typeParameter, partialSubstitutor, parent, policy);
}
else if (constraint.getSecond() == ConstraintType.SUBTYPE) {
Pair<PsiType, ConstraintType> otherConstraint =
inferMethodTypeParameterFromParent(typeParameter, partialSubstitutor, parent, policy);
if (otherConstraint != null) {
if (otherConstraint.getSecond() == ConstraintType.EQUALS || otherConstraint.getSecond() == ConstraintType.SUPERTYPE) {
constraint = otherConstraint;
}
}
if (constraint != null) {
substitution = constraint.getFirst();
}
if (substitution == null) {
PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
return factory.createRawSubstitutor(partialSubstitutor, typeParameters);
}
if (substitution != PsiType.NULL) {
partialSubstitutor = partialSubstitutor.put(typeParameter, substitution);
}
}
}
finally {
GraphInferencePolicy.forget(parent);
if (constraint != null) {
substitution = constraint.getFirst();
}
if (substitution == null) {
PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
return factory.createRawSubstitutor(partialSubstitutor, typeParameters);
}
if (substitution != PsiType.NULL) {
partialSubstitutor = partialSubstitutor.put(typeParameter, substitution);
}
}
return partialSubstitutor;
}
@@ -544,222 +491,6 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
return getSubstitutionForTypeParameterInner(param, arg, patternType, ConstraintType.SUPERTYPE, 0);
}
@Nullable
private Pair<PsiType, ConstraintType> inferSubstitutionFromLambda(PsiTypeParameter typeParam,
PsiLambdaExpressionType arg,
PsiType lowerBound,
PsiSubstitutor partialSubstitutor) {
final PsiLambdaExpression lambdaExpression = arg.getExpression();
if (PsiUtil.getLanguageLevel(lambdaExpression).isAtLeast(LanguageLevel.JDK_1_8)) {
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(lambdaExpression.getParent());
if (parent instanceof PsiExpressionList) {
final PsiExpressionList expressionList = (PsiExpressionList)parent;
final Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>> methodMap = MethodCandidateInfo.CURRENT_CANDIDATE.get();
final Pair<PsiMethod, PsiSubstitutor> pair = methodMap != null ? methodMap.get(expressionList) : null;
if (pair != null) {
final int i = LambdaUtil.getLambdaIdx(expressionList, lambdaExpression);
if (i < 0) return null;
final PsiParameter[] parameters = pair.first.getParameterList().getParameters();
if (parameters.length <= i) return null;
final PsiSubstitutor combinedSubst = pair.second.putAll(partialSubstitutor);
methodMap.put(expressionList, Pair.create(pair.first, combinedSubst));
return inferConstraintFromFunctionalInterfaceMethod(typeParam, lambdaExpression, combinedSubst.substitute(parameters[i].getType()), lowerBound);
}
}
else {
return inferConstraintFromFunctionalInterfaceMethod(typeParam, lambdaExpression,
partialSubstitutor.substitute(lambdaExpression.getFunctionalInterfaceType()), lowerBound);
}
}
return null;
}
@Nullable
private Pair<PsiType, ConstraintType> inferConstraintFromFunctionalInterfaceMethod(final PsiTypeParameter typeParam,
final PsiMethodReferenceExpression methodReferenceExpression,
final PsiType functionalInterfaceType,
final PsiSubstitutor partialSubstitutor,
final ParameterTypeInferencePolicy policy) {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
final PsiMethod functionalInterfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
if (functionalInterfaceMethod != null) {
final PsiSubstitutor subst = LambdaUtil.getSubstitutor(functionalInterfaceMethod, resolveResult);
final PsiParameter[] methodParameters = functionalInterfaceMethod.getParameterList().getParameters();
PsiType[] methodParamTypes = PsiType.createArray(methodParameters.length);
for (int i = 0; i < methodParameters.length; i++) {
methodParamTypes[i] = GenericsUtil.eliminateWildcards(subst.substitute(methodParameters[i].getType()));
}
if (methodParamsDependOn(typeParam, methodReferenceExpression, functionalInterfaceType, methodParameters, subst)) {
return null;
}
final PsiType[] args = PsiType.createArray(methodParameters.length);
Map<PsiMethodReferenceExpression,PsiType> map = PsiMethodReferenceUtil.ourRefs.get();
if (map == null) {
map = new HashMap<PsiMethodReferenceExpression, PsiType>();
PsiMethodReferenceUtil.ourRefs.set(map);
}
final PsiType added = map.put(methodReferenceExpression, functionalInterfaceType);
final JavaResolveResult methReferenceResolveResult;
try {
methReferenceResolveResult = methodReferenceExpression.advancedResolve(false);
}
finally {
if (added == null) {
map.remove(methodReferenceExpression);
}
}
final PsiElement resolved = methReferenceResolveResult.getElement();
if (resolved instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)resolved;
final PsiParameter[] parameters = method.getParameterList().getParameters();
boolean hasReceiver = false;
if (methodParamTypes.length == parameters.length + 1) {
if (!PsiMethodReferenceUtil
.isReceiverType(methodParamTypes[0], method.getContainingClass(), methReferenceResolveResult.getSubstitutor())) return null;
hasReceiver = true;
} else if (parameters.length != methodParameters.length) {
return null;
}
for (int i = 0; i < parameters.length; i++) {
args[i] = methReferenceResolveResult.getSubstitutor().substitute(subst.substitute(parameters[i].getType()));
}
final PsiType[] typesToInfer = hasReceiver ? ArrayUtil.remove(methodParamTypes, 0) : methodParamTypes;
final Pair<PsiType, ConstraintType> constraint = inferTypeForMethodTypeParameterInner(typeParam, typesToInfer, args, subst, null, DefaultParameterTypeInferencePolicy.INSTANCE);
if (constraint != null){
return constraint;
}
PsiType functionalInterfaceReturnType = functionalInterfaceMethod.getReturnType();
if (functionalInterfaceReturnType != null && functionalInterfaceReturnType != PsiType.VOID) {
functionalInterfaceReturnType = GenericsUtil.eliminateWildcards(subst.substitute(functionalInterfaceReturnType));
final PsiType argType;
if (method.isConstructor()) {
argType = JavaPsiFacade.getElementFactory(functionalInterfaceMethod.getProject()).createType(method.getContainingClass(), methReferenceResolveResult.getSubstitutor());
} else {
argType = methReferenceResolveResult.getSubstitutor().substitute(subst.substitute(method.getReturnType()));
}
final Pair<PsiType, ConstraintType> typeParameterConstraint =
getSubstitutionForTypeParameterConstraint(typeParam, functionalInterfaceReturnType, argType, true, PsiUtil.getLanguageLevel(functionalInterfaceMethod));
if (typeParameterConstraint != null && typeParameterConstraint.getSecond() != ConstraintType.EQUALS && method.isConstructor()) {
final Pair<PsiType, ConstraintType> constraintFromParent =
inferMethodTypeParameterFromParent(typeParam, partialSubstitutor, methodReferenceExpression.getParent().getParent(), policy);
if (constraintFromParent != null && constraintFromParent.getSecond() == ConstraintType.EQUALS) return constraintFromParent;
}
return typeParameterConstraint;
}
}
}
return null;
}
@Nullable
private Pair<PsiType, ConstraintType> inferConstraintFromFunctionalInterfaceMethod(PsiTypeParameter typeParam,
final PsiLambdaExpression lambdaExpression,
final PsiType functionalInterfaceType,
PsiType lowerBound) {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
final PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
if (method != null) {
final PsiSubstitutor subst = LambdaUtil.getSubstitutor(method, resolveResult);
final Pair<PsiType, ConstraintType> constraintFromFormalParams = inferConstraintFromLambdaFormalParams(typeParam, subst, method, lambdaExpression);
if (constraintFromFormalParams != null) return constraintFromFormalParams;
final PsiParameter[] methodParameters = method.getParameterList().getParameters();
if (methodParamsDependOn(typeParam, lambdaExpression, functionalInterfaceType, methodParameters, subst)) {
return null;
}
final PsiType returnType = subst.substitute(method.getReturnType());
if (returnType != null && returnType != PsiType.VOID) {
Pair<PsiType, ConstraintType> constraint = null;
final List<PsiExpression> expressions = LambdaUtil.getReturnExpressions(lambdaExpression);
for (final PsiExpression expression : expressions) {
final boolean independent = lambdaExpression.hasFormalParameterTypes() || LambdaUtil.isFreeFromTypeInferenceArgs(methodParameters, lambdaExpression, expression, subst, functionalInterfaceType, typeParam);
if (!independent) {
if (lowerBound != PsiType.NULL) {
return null;
}
continue;
}
if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() == null) continue;
PsiType exprType = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return expression.getType();
}
});
if (exprType instanceof PsiLambdaParameterType) {
final PsiParameter parameter = ((PsiLambdaParameterType)exprType).getParameter();
final int parameterIndex = lambdaExpression.getParameterList().getParameterIndex(parameter);
if (parameterIndex > -1) {
exprType = subst.substitute(methodParameters[parameterIndex].getType());
}
} else if (exprType instanceof PsiLambdaExpressionType) {
return inferConstraintFromFunctionalInterfaceMethod(typeParam, ((PsiLambdaExpressionType)exprType).getExpression(), returnType,
lowerBound);
} else if (exprType == null && independent) {
return null;
}
if (exprType == null){
return FAILED_INFERENCE;
}
final Pair<PsiType, ConstraintType> returnExprConstraint =
getSubstitutionForTypeParameterConstraint(typeParam, GenericsUtil.eliminateWildcards(returnType), exprType, true, PsiUtil.getLanguageLevel(method));
if (returnExprConstraint != null) {
if (returnExprConstraint == FAILED_INFERENCE) return returnExprConstraint;
if (constraint != null) {
final PsiType leastUpperBound = GenericsUtil.getLeastUpperBound(constraint.getFirst(), returnExprConstraint.getFirst(), myManager);
constraint = new Pair<PsiType, ConstraintType>(leastUpperBound, ConstraintType.SUPERTYPE);
} else {
constraint = returnExprConstraint;
}
}
}
if (constraint != null) return constraint;
}
}
return null;
}
private static boolean methodParamsDependOn(PsiTypeParameter typeParam, PsiElement psiElement,
PsiType functionalInterfaceType,
PsiParameter[] methodParameters,
PsiSubstitutor subst) {
for (PsiParameter parameter : methodParameters) {
if (LambdaUtil.dependsOnTypeParams(subst.substitute(parameter.getType()), functionalInterfaceType, psiElement, typeParam)) {
return true;
}
}
return false;
}
@Nullable
private Pair<PsiType, ConstraintType> inferConstraintFromLambdaFormalParams(PsiTypeParameter typeParam,
PsiSubstitutor subst,
PsiMethod method, PsiLambdaExpression lambdaExpression) {
final PsiParameter[] parameters = lambdaExpression.getParameterList().getParameters();
if (parameters.length == 0) return null;
final PsiType[] lambdaArgs = PsiType.createArray(parameters.length);
for (int i = 0; i < parameters.length; i++) {
PsiParameter parameter = parameters[i];
if (parameter.getTypeElement() == null) {
return null;
}
lambdaArgs[i] = parameter.getType();
}
final PsiParameter[] methodParameters = method.getParameterList().getParameters();
PsiType[] methodParamTypes = PsiType.createArray(methodParameters.length);
for (int i = 0; i < methodParameters.length; i++) {
methodParamTypes[i] = GenericsUtil.eliminateWildcards(subst.substitute(methodParameters[i].getType()));
}
return inferTypeForMethodTypeParameterInner(typeParam, methodParamTypes, lambdaArgs, subst, null, DefaultParameterTypeInferencePolicy.INSTANCE);
}
private static PsiType intersectAllExtends(PsiTypeParameter typeParam, PsiType arg) {
if (arg == null) return null;
PsiClassType[] superTypes = typeParam.getSuperTypes();
@@ -979,48 +710,10 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
PsiType expectedType = PsiTypesUtil.getExpectedTypeByParent(methodCall);
if (expectedType == null) {
if (parent instanceof PsiReturnStatement) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class);
if (lambdaExpression != null) {
return getFailedInferenceConstraint(typeParameter);
}
}
else if (parent instanceof PsiExpressionList) {
if (parent instanceof PsiExpressionList) {
final PsiElement pParent = parent.getParent();
if (pParent instanceof PsiCallExpression && parent.equals(((PsiCallExpression)pParent).getArgumentList())) {
constraint = policy.inferTypeConstraintFromCallContext(methodCall, (PsiExpressionList)parent, (PsiCallExpression)pParent, typeParameter);
if (constraint == null && PsiUtil.isLanguageLevel8OrHigher(methodCall)) {
constraint = graphInferenceFromCallContext(methodCall, typeParameter, (PsiCallExpression)pParent);
if (constraint != null) {
final PsiType constraintFirst = constraint.getFirst();
if (constraintFirst == null || constraintFirst.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
constraint = null;
}
}
}
}
} else if (parent instanceof PsiLambdaExpression) {
expectedType = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(methodCall, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression)parent).getFunctionalInterfaceType());
}
});
if (expectedType == null) {
return null;
}
expectedType = GenericsUtil.eliminateWildcards(expectedType);
} else if (parent instanceof PsiConditionalExpression) {
if (PsiUtil.isLanguageLevel8OrHigher(parent)) {
try {
final Pair<PsiType, ConstraintType> pair = inferFromConditionalExpression(parent, methodCall, typeParameter, substitutor, policy);
if (pair != null) {
return pair;
}
}
finally {
GraphInferencePolicy.forget(parent);
}
}
}
}
@@ -1054,33 +747,6 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
if (constraint == null) {
if (methodCall instanceof PsiCallExpression) {
final PsiExpressionList argumentList = ((PsiCallExpression)methodCall).getArgumentList();
if (argumentList != null && PsiUtil.getLanguageLevel(argumentList).isAtLeast(LanguageLevel.JDK_1_8)) {
for (PsiExpression expression : argumentList.getExpressions()) {
if (expression instanceof PsiLambdaExpression || expression instanceof PsiMethodReferenceExpression) {
final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(expression, false);
if (functionalInterfaceType == null || PsiUtil.resolveClassInType(functionalInterfaceType) == typeParameter){
return getFailedInferenceConstraint(typeParameter);
}
final PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType);
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
if (method == null || methodParamsDependOn(typeParameter, expression,
functionalInterfaceType, method.getParameterList().getParameters(),
LambdaUtil.getSubstitutor(method, resolveResult))) {
if (expression instanceof PsiMethodReferenceExpression) {
return getFailedInferenceConstraint(typeParameter);
}
return null;
}
final Pair<PsiType, ConstraintType> inferredExceptionTypeConstraint = inferExceptionConstrains(typeParameter, expression, method, resolveResult.getSubstitutor());
if (inferredExceptionTypeConstraint != null) {
return inferredExceptionTypeConstraint;
}
}
}
}
PsiType[] superTypes = typeParameter.getSuperTypes();
if (superTypes.length == 0) return null;
final PsiType[] types = PsiType.createArray(superTypes.length);
@@ -1090,7 +756,6 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
superType = TypeConversionUtil.erasure(superType);
}
if (superType == null) superType = PsiType.getJavaLangObject(myManager, scope);
if (superType == null) return null;
types[i] = superType;
}
return policy.getInferredTypeWithNoConstraint(myManager, PsiIntersectionType.createIntersection(types));
@@ -1120,113 +785,4 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
return new Pair<PsiType, ConstraintType>(guess, constraint.getSecond());
}
private static boolean checkSameExpression(PsiExpression templateExpr, final PsiExpression expression) {
return templateExpr.equals(PsiUtil.skipParenthesizedExprDown(expression));
}
private static Pair<PsiType, ConstraintType> inferExceptionConstrains(PsiTypeParameter typeParameter,
PsiExpression expression,
PsiMethod method,
PsiSubstitutor substitutor) {
final PsiClassType[] declaredExceptions = method.getThrowsList().getReferencedTypes();
for (PsiClassType exception : declaredExceptions) {
final PsiType substitute = substitutor.substitute(exception);
if (PsiUtil.resolveClassInType(substitute) == typeParameter) {
if (expression instanceof PsiLambdaExpression) {
final PsiElement body = ((PsiLambdaExpression)expression).getBody();
if (body != null) {
final List<PsiClassType> unhandledExceptions = ExceptionUtil.getUnhandledExceptions(body);
if (unhandledExceptions.isEmpty()) {
return inferUncheckedException(typeParameter, exception, method);
}
}
}
else if (expression instanceof PsiMethodReferenceExpression) {
final PsiElement resolve = ((PsiMethodReferenceExpression)expression).resolve();
if (resolve instanceof PsiMethod) {
final PsiClassType[] declaredThrowsList = ((PsiMethod)resolve).getThrowsList().getReferencedTypes();
for (PsiClassType psiClassType : declaredThrowsList) {
if (!ExceptionUtil.isUncheckedException(psiClassType)) return null;
}
return inferUncheckedException(typeParameter, exception, method);
}
}
break;
}
}
return null;
}
private static Pair<PsiType, ConstraintType> inferUncheckedException(PsiTypeParameter typeParameter,
PsiClassType exception,
PsiMethod method) {
final Project project = typeParameter.getProject();
final PsiClass runtimeException = JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, method.getResolveScope());
if (runtimeException != null) {
for (PsiType superType : exception.getSuperTypes()) {
if (!InheritanceUtil.isInheritorOrSelf(runtimeException, PsiUtil.resolveClassInType(superType), true)) {
return getFailedInferenceConstraint(typeParameter);
}
}
return Pair.<PsiType, ConstraintType>create(JavaPsiFacade.getElementFactory(project).createType(runtimeException, PsiSubstitutor.EMPTY), ConstraintType.EQUALS);
}
return null;
}
private Pair<PsiType, ConstraintType> inferFromConditionalExpression(@NotNull PsiElement parent,
@NotNull PsiExpression methodCall,
@NotNull PsiTypeParameter typeParameter,
@NotNull PsiSubstitutor substitutor,
@NotNull ParameterTypeInferencePolicy policy) {
Pair<PsiType, ConstraintType> pair =
inferMethodTypeParameterFromParent(PsiUtil.skipParenthesizedExprUp(parent.getParent()), (PsiExpression)parent, typeParameter, substitutor, policy);
if (pair == null) {
final PsiExpression thenExpression = ((PsiConditionalExpression)parent).getThenExpression();
final PsiExpression elseExpression = ((PsiConditionalExpression)parent).getElseExpression();
final PsiType[] paramTypes = {((PsiMethod)typeParameter.getOwner()).getReturnType()};
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(elseExpression)) && thenExpression != null) {
final PsiType thenType = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(parent, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return thenExpression.getType();
}
});
if (thenType != null) {
pair = inferTypeForMethodTypeParameterInner(typeParameter, paramTypes, new PsiType[] {thenType}, substitutor, null, policy);
}
} else if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(thenExpression)) && elseExpression != null) {
final PsiType elseType = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(parent, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return elseExpression.getType();
}
});
if (elseType != null) {
pair = inferTypeForMethodTypeParameterInner(typeParameter, paramTypes, new PsiType[] {elseType}, substitutor, null, policy);
}
}
}
return pair;
}
private static final ProcessCandidateParameterTypeInferencePolicy GRAPH_INFERENCE_POLICY = new GraphInferencePolicy();
private static Pair<PsiType, ConstraintType> graphInferenceFromCallContext(@NotNull final PsiExpression methodCall,
@NotNull final PsiTypeParameter typeParameter,
@NotNull final PsiCallExpression parentCall) {
if (Registry.is("disable.graph.inference", false)) return null;
final PsiExpressionList argumentList = parentCall.getArgumentList();
if (PsiDiamondType.ourDiamondGuard.currentStack().contains(parentCall)) {
PsiDiamondType.ourDiamondGuard.prohibitResultCaching(parentCall);
return FAILED_INFERENCE;
}
return PsiResolveHelper.ourGraphGuard.doPreventingRecursion(methodCall, true, new Computable<Pair<PsiType, ConstraintType>>() {
@Override
public Pair<PsiType, ConstraintType> compute() {
return GRAPH_INFERENCE_POLICY.inferTypeConstraintFromCallContext(methodCall, argumentList, parentCall, typeParameter);
}
});
}
}
@@ -17,7 +17,6 @@ package com.intellij.psi.impl.source.resolve;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.PsiGraphInferenceHelper;
@@ -26,7 +25,8 @@ import com.intellij.psi.scope.MethodProcessorSetupFailedException;
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
import com.intellij.psi.scope.processor.MethodResolverProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -204,10 +204,10 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
}
public PsiInferenceHelper getInferenceHelper(LanguageLevel languageLevel) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
return myTestHelper != null ? myTestHelper : new PsiOldInferenceHelper(myManager);
if (ApplicationManager.getApplication().isUnitTestMode() && myTestHelper != null) {
return myTestHelper;
}
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && Registry.is("enable.graph.inference", true)) {
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
return new PsiGraphInferenceHelper(myManager);
}
return new PsiOldInferenceHelper(myManager);
@@ -1,6 +1,6 @@
class Test {
void foo() {
final Foo<Number> a = new Foo<Number>(1);
final Foo<Number> a = new Foo<>(1);
}
}
@@ -4,7 +4,7 @@ interface SAM<X> {
class Foo {
void test() {
SAM<String> c = (i, j) -> "" + i + j;
SAM<X> c = (i, j) -> "" + i + j;
SAM<Integer> s3 = m(c);
}
<X> SAM<X> m(SAM<X> s) { return null; }
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.compiler.JavacQuirksInspection;
import com.intellij.codeInspection.redundantCast.RedundantCastInspection;
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -52,4 +53,9 @@ public class AmbiguousMethodCallTest extends LightDaemonAnalyzerTestCase {
public void testMultipleInheritance() throws Exception {
doTest(false, false);
}
@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_1_7;
}
}
@@ -1,5 +1,7 @@
package com.intellij.codeInsight.daemon.quickFix;
import com.intellij.pom.java.LanguageLevel;
public class RemoveRedundantArgumentTest extends LightQuickFixParameterizedTestCase {
public void test() throws Exception { doAllTests(); }
@@ -9,4 +11,8 @@ public class RemoveRedundantArgumentTest extends LightQuickFixParameterizedTestC
return "/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantArgument";
}
@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_1_7;
}
}
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon.quickFix;
import com.intellij.codeInspection.ExplicitTypeCanBeDiamondInspection;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
@@ -37,4 +38,8 @@ public class Simplify2DiamondInspectionsTest extends LightQuickFixParameterizedT
return "/codeInsight/daemonCodeAnalyzer/quickFix/explicit2diamond";
}
@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_1_7;
}
}
@@ -16,6 +16,8 @@
package com.intellij.codeInsight.daemon.quickFix;
import com.intellij.pom.java.LanguageLevel;
public class VariableTypeFromCallTest extends LightQuickFixParameterizedTestCase {
public void test() throws Exception { doAllTests(); }
@@ -25,5 +27,9 @@ public class VariableTypeFromCallTest extends LightQuickFixParameterizedTestCase
return "/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall";
}
@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_1_7;
}
}
@@ -463,4 +463,9 @@ public class IntroduceParameterTest extends LightRefactoringTestCase {
IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE,
declareFinal, false, null, parametersToRemove).run();
}
@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_1_7;
}
}
@@ -428,6 +428,7 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
}
public void testLambdaExpr() throws Exception {
doTest(new MockIntroduceVariableHandler("c", false, false, false, "SAM<java.lang.Integer>"));
}
@@ -436,7 +437,7 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
}
public void testLambdaExprNotAccepted() throws Exception {
doTest(new MockIntroduceVariableHandler("c", false, false, false, "SAM<java.lang.String>"));
doTest(new MockIntroduceVariableHandler("c", false, false, false, "SAM<X>"));
}
public void testOneLineLambdaVoidCompatible() throws Exception {
@@ -318,8 +318,6 @@ diagrams.rendering.no.cache=true
wolf.the.problem.solver=true
ui.no.bangs.and.whistles=false
disable.graph.inference=false
enable.graph.inference=true
comment.by.line.bulk.lines.trigger=100
@@ -8,9 +8,9 @@ class Test2 {
static <T> I<T> bar(I<T> i){return i;}
{
bar(new I() {
bar(new I<Object>() {
@Override
public Object foo(Y x) {
public Object foo(Y<Object> x) {
<selection>return x;</selection>
}
});