mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-21 05:51:25 +07:00
new inference: fresh variables
This commit is contained in:
@@ -80,14 +80,14 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
|
||||
}
|
||||
|
||||
private boolean containsInMap(PsiTypeParameter typeParameter) {
|
||||
if (typeParameter instanceof LightTypeParameter) {
|
||||
if (typeParameter instanceof LightTypeParameter && ((LightTypeParameter)typeParameter).useDelegateToSubstitute()) {
|
||||
typeParameter = ((LightTypeParameter)typeParameter).getDelegate();
|
||||
}
|
||||
return mySubstitutionMap.containsKey(typeParameter);
|
||||
}
|
||||
|
||||
private PsiType getFromMap(@NotNull PsiTypeParameter typeParameter) {
|
||||
if (typeParameter instanceof LightTypeParameter) {
|
||||
if (typeParameter instanceof LightTypeParameter && ((LightTypeParameter)typeParameter).useDelegateToSubstitute()) {
|
||||
typeParameter = ((LightTypeParameter)typeParameter).getDelegate();
|
||||
}
|
||||
return mySubstitutionMap.get(typeParameter);
|
||||
|
||||
@@ -79,6 +79,10 @@ public class LightTypeParameter extends LightClass implements PsiTypeParameter {
|
||||
return getDelegate().addAnnotation(qualifiedName);
|
||||
}
|
||||
|
||||
public boolean useDelegateToSubstitute() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiTypeParameter:" + getName();
|
||||
|
||||
@@ -94,7 +94,8 @@ public class FunctionalInterfaceParameterizationUtil {
|
||||
final InferenceSession session = new InferenceSession(typeParameters, PsiSubstitutor.EMPTY, expr.getManager(), expr);
|
||||
|
||||
for (int i = 0; i < targetMethodParams.length; i++) {
|
||||
session.addConstraint(new TypeEqualityConstraint(lambdaParams[i].getType(), targetMethodParams[i].getType()));
|
||||
session.addConstraint(new TypeEqualityConstraint(lambdaParams[i].getType(),
|
||||
session.substituteWithInferenceVariables(targetMethodParams[i].getType())));
|
||||
}
|
||||
|
||||
if (!session.repeatInferencePhases(false)) {
|
||||
|
||||
@@ -43,7 +43,7 @@ public class InferenceSession {
|
||||
|
||||
private static final Key<Boolean> ERASED = Key.create("UNCHECKED_CONVERSION");
|
||||
|
||||
private final Map<PsiTypeParameter, InferenceVariable> myInferenceVariables = new LinkedHashMap<PsiTypeParameter, InferenceVariable>();
|
||||
private final Set<InferenceVariable> myInferenceVariables = new LinkedHashSet<InferenceVariable>();
|
||||
private final List<ConstraintFormula> myConstraints = new ArrayList<ConstraintFormula>();
|
||||
private final Set<ConstraintFormula> myConstraintsCopy = new HashSet<ConstraintFormula>();
|
||||
|
||||
@@ -56,8 +56,14 @@ public class InferenceSession {
|
||||
private final InferenceIncorporationPhase myIncorporationPhase = new InferenceIncorporationPhase(this);
|
||||
|
||||
private final PsiElement myContext;
|
||||
|
||||
private final PsiTypeParameter[] myParamsToInfer;
|
||||
|
||||
private PsiSubstitutor myInferenceSubstitution = PsiSubstitutor.EMPTY;
|
||||
private Map<PsiElement, InferenceSession> myNestedSessions = new HashMap<PsiElement, InferenceSession>();
|
||||
public void registerNestedSession(InferenceSession session) {
|
||||
propagateVariables(session.getInferenceVariables());
|
||||
myNestedSessions.put(session.getContext(), session);
|
||||
myNestedSessions.putAll(session.myNestedSessions);
|
||||
}
|
||||
|
||||
public InferenceSession(PsiTypeParameter[] typeParams,
|
||||
PsiType[] leftTypes,
|
||||
@@ -70,13 +76,12 @@ public class InferenceSession {
|
||||
myContext = context;
|
||||
|
||||
initBounds(typeParams);
|
||||
myParamsToInfer = typeParams;
|
||||
|
||||
LOG.assertTrue(leftTypes.length == rightTypes.length);
|
||||
for (int i = 0; i < leftTypes.length; i++) {
|
||||
final PsiType rightType = mySiteSubstitutor.substitute(rightTypes[i]);
|
||||
if (rightType != null) {
|
||||
addConstraint(new TypeCompatibilityConstraint(leftTypes[i], rightType));
|
||||
addConstraint(new TypeCompatibilityConstraint(leftTypes[i], substituteWithInferenceVariables(rightType)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,11 +95,6 @@ public class InferenceSession {
|
||||
myContext = context;
|
||||
|
||||
initBounds(typeParams);
|
||||
myParamsToInfer = typeParams;
|
||||
}
|
||||
|
||||
public PsiTypeParameter[] getParamsToInfer() {
|
||||
return myParamsToInfer;
|
||||
}
|
||||
|
||||
public void initExpressionConstraints(PsiParameter[] parameters, PsiExpression[] args, PsiElement parent, PsiMethod method) {
|
||||
@@ -117,7 +117,7 @@ public class InferenceSession {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i] != null && isPertinentToApplicability(args[i], method)) {
|
||||
PsiType parameterType = getParameterType(parameters, i, mySiteSubstitutor, varargs);
|
||||
addConstraint(new ExpressionCompatibilityConstraint(args[i], parameterType));
|
||||
addConstraint(new ExpressionCompatibilityConstraint(args[i], substituteWithInferenceVariables(parameterType)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +213,7 @@ public class InferenceSession {
|
||||
final MethodCandidateInfo.CurrentCandidateProperties properties = getCurrentProperties(parent);
|
||||
if (!repeatInferencePhases(true)) {
|
||||
//inferred result would be checked as candidate won't be applicable
|
||||
return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor);
|
||||
return resolveSubset(myInferenceVariables, mySiteSubstitutor);
|
||||
}
|
||||
|
||||
if (properties != null && !properties.isApplicabilityCheck()) {
|
||||
@@ -235,20 +235,17 @@ public class InferenceSession {
|
||||
}
|
||||
}
|
||||
|
||||
final PsiSubstitutor substitutor = resolveBounds(myInferenceVariables.values(), mySiteSubstitutor);
|
||||
final PsiSubstitutor substitutor = resolveBounds(myInferenceVariables, mySiteSubstitutor);
|
||||
if (substitutor != null) {
|
||||
if (myContext != null) {
|
||||
myContext.putUserData(ERASED, myErased);
|
||||
}
|
||||
mySiteSubstitutor = substitutor;
|
||||
for (PsiTypeParameter parameter : substitutor.getSubstitutionMap().keySet()) {
|
||||
final InferenceVariable variable = getInferenceVariable(parameter);
|
||||
if (variable != null) {
|
||||
variable.setInstantiation(substitutor.substitute(parameter));
|
||||
}
|
||||
for (InferenceVariable variable : myInferenceVariables) {
|
||||
variable.setInstantiation(substitutor.substitute(variable.getParameter()));
|
||||
}
|
||||
} else {
|
||||
return resolveSubset(myInferenceVariables.values(), mySiteSubstitutor);
|
||||
return resolveSubset(myInferenceVariables, mySiteSubstitutor);
|
||||
}
|
||||
|
||||
return prepareSubstitution();
|
||||
@@ -262,12 +259,16 @@ public class InferenceSession {
|
||||
boolean varargs, boolean toplevel) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i] != null) {
|
||||
PsiType parameterType = getParameterType(parameters, i, siteSubstitutor, varargs);
|
||||
InferenceSession session = myNestedSessions.get(PsiTreeUtil.getParentOfType(args[i], PsiCallExpression.class));
|
||||
if (session == null) {
|
||||
session = this;
|
||||
}
|
||||
PsiType parameterType = session.substituteWithInferenceVariables(getParameterType(parameters, i, siteSubstitutor, varargs));
|
||||
if (!isPertinentToApplicability(args[i], parentMethod)) {
|
||||
additionalConstraints.add(new ExpressionCompatibilityConstraint(args[i], parameterType));
|
||||
}
|
||||
additionalConstraints.add(new CheckedExceptionCompatibilityConstraint(args[i], parameterType));
|
||||
if (args[i] instanceof PsiCallExpression) {
|
||||
if (args[i] instanceof PsiCallExpression && PsiPolyExpressionUtil.isPolyExpression(args[i])) {
|
||||
//If the expression is a poly class instance creation expression (15.9) or a poly method invocation expression (15.12),
|
||||
//the set contains all constraint formulas that would appear in the set C when determining the poly expression's invocation type.
|
||||
final PsiCallExpression callExpression = (PsiCallExpression)args[i];
|
||||
@@ -306,8 +307,6 @@ public class InferenceSession {
|
||||
: PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, false, computableResolve);
|
||||
final PsiMethod method = result instanceof MethodCandidateInfo ? ((MethodCandidateInfo)result).getElement() : properties != null ? properties.getMethod() : null;
|
||||
if (method != null) {
|
||||
//need to get type parameters for 2 level nested expressions (they won't be covered by expression constraints on this level?!)
|
||||
initBounds(callExpression, method.getTypeParameters());
|
||||
final PsiExpression[] newArgs = argumentList.getExpressions();
|
||||
final PsiParameter[] newParams = method.getParameterList().getParameters();
|
||||
if (newParams.length > 0) {
|
||||
@@ -323,14 +322,14 @@ public class InferenceSession {
|
||||
for (InferenceVariable variable : variables) {
|
||||
final PsiType equalsBound = getEqualsBound(variable, substitutor);
|
||||
if (!(equalsBound instanceof PsiPrimitiveType)) {
|
||||
substitutor = substitutor.put(variable.getParameter(), equalsBound);
|
||||
substitutor = substitutor.put(variable, equalsBound);
|
||||
}
|
||||
}
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
private PsiSubstitutor prepareSubstitution() {
|
||||
for (InferenceVariable inferenceVariable : myInferenceVariables.values()) {
|
||||
for (InferenceVariable inferenceVariable : myInferenceVariables) {
|
||||
final PsiTypeParameter typeParameter = inferenceVariable.getParameter();
|
||||
PsiType instantiation = inferenceVariable.getInstantiation();
|
||||
if (instantiation == PsiType.NULL) {
|
||||
@@ -342,34 +341,27 @@ public class InferenceSession {
|
||||
return mySiteSubstitutor;
|
||||
}
|
||||
|
||||
private boolean isInsideRecursiveCall(PsiTypeParameter parameter) {
|
||||
final PsiTypeParameterListOwner parameterOwner = parameter.getOwner();
|
||||
if (myContext != null && PsiTreeUtil.isAncestor(parameterOwner, myContext, true)) {
|
||||
final PsiModifierListOwner staticContainer = PsiUtil.getEnclosingStaticElement(myContext, null);
|
||||
if (staticContainer == null || PsiTreeUtil.isAncestor(staticContainer, parameterOwner, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public void initBounds(PsiTypeParameter... typeParameters) {
|
||||
initBounds(myContext, typeParameters);
|
||||
}
|
||||
|
||||
public boolean initBounds(PsiTypeParameter... typeParameters) {
|
||||
return initBounds(myContext, typeParameters);
|
||||
}
|
||||
|
||||
public boolean initBounds(PsiElement context, PsiTypeParameter... typeParameters) {
|
||||
boolean sameMethodCall = false;
|
||||
public InferenceVariable[] initBounds(PsiElement context, PsiTypeParameter... typeParameters) {
|
||||
List<InferenceVariable> result = new ArrayList<InferenceVariable>(typeParameters.length);
|
||||
for (PsiTypeParameter parameter : typeParameters) {
|
||||
if (myInferenceVariables.containsKey(parameter)) {
|
||||
sameMethodCall = true;
|
||||
continue;
|
||||
}
|
||||
InferenceVariable variable = new InferenceVariable(context, parameter);
|
||||
result.add(variable);
|
||||
myInferenceSubstitution = myInferenceSubstitution.put(parameter,
|
||||
JavaPsiFacade.getElementFactory(variable.getProject()).createType(variable));
|
||||
}
|
||||
for (InferenceVariable variable : result) {
|
||||
PsiTypeParameter parameter = variable.getParameter();
|
||||
boolean added = false;
|
||||
final PsiClassType[] extendsListTypes = parameter.getExtendsListTypes();
|
||||
for (PsiType classType : extendsListTypes) {
|
||||
classType = mySiteSubstitutor.substitute(classType);
|
||||
if (isProperType(classType)) {
|
||||
classType = substituteWithInferenceVariables(mySiteSubstitutor.substitute(classType));
|
||||
HashSet<InferenceVariable> dependencies = new HashSet<InferenceVariable>();
|
||||
collectDependencies(classType, dependencies);
|
||||
if (dependencies.isEmpty() || dependencies.size() == 1 && dependencies.contains(variable)) {
|
||||
added = true;
|
||||
}
|
||||
variable.addBound(classType, InferenceBound.UPPER);
|
||||
@@ -378,9 +370,9 @@ public class InferenceSession {
|
||||
variable.addBound(PsiType.getJavaLangObject(parameter.getManager(), parameter.getResolveScope()),
|
||||
InferenceBound.UPPER);
|
||||
}
|
||||
myInferenceVariables.put(parameter, variable);
|
||||
}
|
||||
return sameMethodCall;
|
||||
myInferenceVariables.addAll(result);
|
||||
return result.toArray(new InferenceVariable[result.size()]);
|
||||
}
|
||||
|
||||
private void initReturnTypeConstraint(PsiMethod method, final PsiCallExpression context) {
|
||||
@@ -395,7 +387,7 @@ public class InferenceSession {
|
||||
}
|
||||
|
||||
for (PsiClassType thrownType : method.getThrowsList().getReferencedTypes()) {
|
||||
final InferenceVariable variable = getInferenceVariable(thrownType);
|
||||
final InferenceVariable variable = getInferenceVariable(substituteWithInferenceVariables(thrownType));
|
||||
if (variable != null) {
|
||||
variable.setThrownBound();
|
||||
}
|
||||
@@ -403,6 +395,7 @@ public class InferenceSession {
|
||||
}
|
||||
|
||||
public void registerReturnTypeConstraints(PsiType returnType, PsiType targetType) {
|
||||
returnType = substituteWithInferenceVariables(returnType);
|
||||
final InferenceVariable inferenceVariable = shouldResolveAndInstantiate(returnType, targetType);
|
||||
if (inferenceVariable != null) {
|
||||
final PsiSubstitutor substitutor = resolveSubset(Collections.singletonList(inferenceVariable), mySiteSubstitutor);
|
||||
@@ -418,17 +411,9 @@ public class InferenceSession {
|
||||
if (psiClass != null) {
|
||||
LOG.assertTrue(returnType instanceof PsiClassType);
|
||||
final PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
|
||||
PsiSubstitutor subst = PsiSubstitutor.EMPTY;
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject());
|
||||
PsiTypeParameter[] copy = new PsiTypeParameter[typeParameters.length];
|
||||
for (int i = 0; i < typeParameters.length; i++) {
|
||||
PsiTypeParameter typeParameter = typeParameters[i];
|
||||
copy[i] = elementFactory.createTypeParameterFromText("rCopy" + typeParameter.getName(), null);
|
||||
initBounds(myContext, copy[i]);
|
||||
subst = subst.put(typeParameter, elementFactory.createType(copy[i]));
|
||||
}
|
||||
final PsiType substitutedCapture = PsiUtil.captureToplevelWildcards(subst.substitute(returnType), myContext);
|
||||
myIncorporationPhase.addCapture(copy, (PsiClassType)returnType);
|
||||
InferenceVariable[] copy = initBounds(myContext, typeParameters);
|
||||
final PsiType substitutedCapture = PsiUtil.captureToplevelWildcards(returnType, myContext);
|
||||
myIncorporationPhase.addCapture(copy, (PsiClassType)substituteWithInferenceVariables(returnType));
|
||||
addConstraint(new TypeCompatibilityConstraint(targetType, substitutedCapture));
|
||||
}
|
||||
} else {
|
||||
@@ -586,8 +571,8 @@ public class InferenceSession {
|
||||
|
||||
public InferenceVariable getInferenceVariable(PsiType psiType) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(psiType);
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
return myInferenceVariables.get(psiClass);
|
||||
if (psiClass instanceof InferenceVariable) {
|
||||
return (InferenceVariable)psiClass;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -710,21 +695,17 @@ public class InferenceSession {
|
||||
final PsiTypeParameter copy = elementFactory.createTypeParameterFromText("z" + parameter.getName(), null);
|
||||
final PsiType lub = getLowerBound(var, substitutor);
|
||||
final PsiType glb = getUpperBound(var, substitutor);
|
||||
final InferenceVariable zVariable = new InferenceVariable(var.getCallContext(), copy);
|
||||
zVariable.addBound(glb, InferenceBound.UPPER);
|
||||
//todo add upper bound to the fresh type variable
|
||||
if (lub != PsiType.NULL) {
|
||||
if (!TypeConversionUtil.isAssignable(glb, lub)) {
|
||||
return null;
|
||||
}
|
||||
copy.putUserData(LOWER_BOUND, lub);
|
||||
zVariable.addBound(lub, InferenceBound.LOWER);
|
||||
}
|
||||
myInferenceVariables.put(copy, zVariable);
|
||||
allVars.add(zVariable);
|
||||
var.addBound(elementFactory.createType(copy), InferenceBound.EQ);
|
||||
}
|
||||
myIncorporationPhase.forgetCaptures(vars);
|
||||
if (!myIncorporationPhase.incorporate()) {
|
||||
if (!repeatInferencePhases(true)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -744,20 +725,23 @@ public class InferenceSession {
|
||||
for (InferenceVariable var : vars) {
|
||||
LOG.assertTrue(var.getInstantiation() == PsiType.NULL);
|
||||
final PsiTypeParameter typeParameter = var.getParameter();
|
||||
if (substitutor.getSubstitutionMap().containsKey(typeParameter) && var.getCallContext() != myContext) {
|
||||
continue;//todo
|
||||
}
|
||||
|
||||
final PsiType eqBound = getEqualsBound(var, substitutor);
|
||||
if (eqBound != PsiType.NULL && eqBound instanceof PsiPrimitiveType) continue;
|
||||
final PsiType lub = eqBound != PsiType.NULL && (myErased || eqBound != null) ? eqBound : getLowerBound(var, substitutor);
|
||||
if (lub != PsiType.NULL) {
|
||||
substitutor = substitutor.put(typeParameter, lub);
|
||||
}
|
||||
else if (var.isThrownBound() && isThrowable(var.getBounds(InferenceBound.UPPER))) {
|
||||
final PsiClassType runtimeException = PsiType.getJavaLangRuntimeException(myManager, GlobalSearchScope.allScope(myManager.getProject()));
|
||||
substitutor = substitutor.put(typeParameter, runtimeException);
|
||||
}
|
||||
else {
|
||||
if (substitutor.getSubstitutionMap().get(typeParameter) != null) continue;
|
||||
substitutor = substitutor.put(typeParameter, myErased ? null : getUpperBound(var, substitutor));
|
||||
PsiType type = eqBound != PsiType.NULL && (myErased || eqBound != null) ? eqBound : getLowerBound(var, substitutor);
|
||||
if (type == PsiType.NULL) {
|
||||
if (var.isThrownBound() && isThrowable(var.getBounds(InferenceBound.UPPER))) {
|
||||
type = PsiType.getJavaLangRuntimeException(myManager, GlobalSearchScope.allScope(myManager.getProject()));
|
||||
}
|
||||
else {
|
||||
if (substitutor.getSubstitutionMap().get(typeParameter) != null) continue;
|
||||
type = myErased ? null : getUpperBound(var, substitutor);
|
||||
}
|
||||
}
|
||||
substitutor = substitutor.put(typeParameter, type);
|
||||
}
|
||||
|
||||
return substitutor;
|
||||
@@ -787,14 +771,9 @@ public class InferenceSession {
|
||||
PsiSubstitutor substitutor) {
|
||||
final List<PsiType> lowerBounds = variable.getBounds(boundType);
|
||||
PsiType lub = PsiType.NULL;
|
||||
List<PsiType> dTypes = new ArrayList<PsiType>();
|
||||
for (PsiType lowerBound : lowerBounds) {
|
||||
lowerBound = substituteNonProperBound(lowerBound, substitutor);
|
||||
final HashSet<InferenceVariable> dependencies = new HashSet<InferenceVariable>();
|
||||
collectDependencies(lowerBound, dependencies);
|
||||
if (dependencies.size() == 1 && dependencies.contains(variable) && isInsideRecursiveCall(dependencies)) {
|
||||
lub = JavaPsiFacade.getElementFactory(myManager.getProject()).createType(variable.getParameter());
|
||||
} else if (dependencies.isEmpty() || isInsideRecursiveCall(dependencies)) {
|
||||
if (isProperType(lowerBound)) {
|
||||
if (lub == PsiType.NULL) {
|
||||
lub = lowerBound;
|
||||
}
|
||||
@@ -806,13 +785,6 @@ public class InferenceSession {
|
||||
return lub;
|
||||
}
|
||||
|
||||
private boolean isInsideRecursiveCall(HashSet<InferenceVariable> dependencies) {
|
||||
for (InferenceVariable dependency : dependencies) {
|
||||
if (!isInsideRecursiveCall(dependency.getParameter())) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public PsiManager getManager() {
|
||||
return myManager;
|
||||
}
|
||||
@@ -822,7 +794,7 @@ public class InferenceSession {
|
||||
}
|
||||
|
||||
public Collection<InferenceVariable> getInferenceVariables() {
|
||||
return myInferenceVariables.values();
|
||||
return myInferenceVariables;
|
||||
}
|
||||
|
||||
public void addConstraint(ConstraintFormula constraint) {
|
||||
@@ -831,10 +803,6 @@ public class InferenceSession {
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<PsiTypeParameter> getTypeParams() {
|
||||
return myInferenceVariables.keySet();
|
||||
}
|
||||
|
||||
private boolean proceedWithAdditionalConstraints(Set<ConstraintFormula> additionalConstraints) {
|
||||
final PsiSubstitutor siteSubstitutor = mySiteSubstitutor;
|
||||
|
||||
@@ -974,7 +942,7 @@ public class InferenceSession {
|
||||
|
||||
for (int i = 0; i < functionalMethodParameters.length; i++) {
|
||||
final PsiType pType = signature.getParameterTypes()[i];
|
||||
addConstraint(new TypeCompatibilityConstraint(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs),
|
||||
addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs)),
|
||||
PsiImplUtil.normalizeWildcardTypeByPosition(pType, reference)));
|
||||
}
|
||||
}
|
||||
@@ -1005,11 +973,11 @@ public class InferenceSession {
|
||||
|
||||
final PsiType qType = JavaPsiFacade.getElementFactory(method.getProject()).createType(containingClass, psiSubstitutor);
|
||||
|
||||
addConstraint(new TypeCompatibilityConstraint(qType, pType));
|
||||
addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(qType), pType));
|
||||
|
||||
for (int i = 0; i < signature.getParameterTypes().length - 1; i++) {
|
||||
final PsiType interfaceParamType = signature.getParameterTypes()[i + 1];
|
||||
addConstraint(new TypeCompatibilityConstraint(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs),
|
||||
addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs)),
|
||||
PsiImplUtil.normalizeWildcardTypeByPosition(interfaceParamType, reference)));
|
||||
}
|
||||
}
|
||||
@@ -1022,7 +990,7 @@ public class InferenceSession {
|
||||
}
|
||||
|
||||
public InferenceVariable getInferenceVariable(PsiTypeParameter parameter) {
|
||||
return myInferenceVariables.get(parameter);
|
||||
return parameter instanceof InferenceVariable && myInferenceVariables.contains(parameter) ? (InferenceVariable)parameter : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1033,10 +1001,11 @@ public class InferenceSession {
|
||||
PsiExpression[] args,
|
||||
PsiElement context,
|
||||
boolean varargs) {
|
||||
final InferenceSession session = new InferenceSession(PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY, m2.getManager(), context);
|
||||
List<PsiTypeParameter> params = new ArrayList<PsiTypeParameter>();
|
||||
for (PsiTypeParameter param : PsiUtil.typeParametersIterable(m2)) {
|
||||
session.initBounds(context, param);
|
||||
params.add(param);
|
||||
}
|
||||
final InferenceSession session = new InferenceSession(params.toArray(new PsiTypeParameter[params.size()]), PsiSubstitutor.EMPTY, m2.getManager(), context);
|
||||
|
||||
final PsiParameter[] parameters1 = m1.getParameterList().getParameters();
|
||||
final PsiParameter[] parameters2 = m2.getParameterList().getParameters();
|
||||
@@ -1047,7 +1016,7 @@ public class InferenceSession {
|
||||
final int paramsLength = !varargs ? parameters1.length : parameters1.length - 1;
|
||||
for (int i = 0; i < paramsLength; i++) {
|
||||
PsiType sType = getParameterType(parameters1, i, PsiSubstitutor.EMPTY, false);
|
||||
PsiType tType = getParameterType(parameters2, i, PsiSubstitutor.EMPTY, varargs);
|
||||
PsiType tType = session.substituteWithInferenceVariables(getParameterType(parameters2, i, PsiSubstitutor.EMPTY, varargs));
|
||||
if (session.isProperType(sType) && session.isProperType(tType)) {
|
||||
if (!TypeConversionUtil.isAssignable(tType, sType)) {
|
||||
return false;
|
||||
@@ -1065,7 +1034,7 @@ public class InferenceSession {
|
||||
|
||||
if (varargs) {
|
||||
PsiType sType = getParameterType(parameters1, paramsLength, PsiSubstitutor.EMPTY, true);
|
||||
PsiType tType = getParameterType(parameters2, paramsLength, PsiSubstitutor.EMPTY, true);
|
||||
PsiType tType = session.substituteWithInferenceVariables(getParameterType(parameters2, paramsLength, PsiSubstitutor.EMPTY, true));
|
||||
session.addConstraint(new StrictSubtypingConstraint(tType, sType));
|
||||
}
|
||||
|
||||
@@ -1259,25 +1228,6 @@ public class InferenceSession {
|
||||
return myIncorporationPhase.hasCaptureConstraints(Arrays.asList(inferenceVariable));
|
||||
}
|
||||
|
||||
public void liftBounds(PsiElement context, Collection<InferenceVariable> variables) {
|
||||
for (InferenceVariable variable : variables) {
|
||||
final PsiTypeParameter parameter = variable.getParameter();
|
||||
final InferenceVariable inferenceVariable = getInferenceVariable(parameter);
|
||||
if (inferenceVariable != null) {
|
||||
final PsiElement callContext = inferenceVariable.getCallContext();
|
||||
if (context.equals(callContext) || myContext.equals(callContext)) {
|
||||
for (InferenceBound boundType : InferenceBound.values()) {
|
||||
for (PsiType bound : variable.getBounds(boundType)) {
|
||||
inferenceVariable.addBound(bound, boundType);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
myInferenceVariables.put(parameter, variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean wasUncheckedConversionPerformed(PsiElement call) {
|
||||
final Boolean erased = call.getUserData(ERASED);
|
||||
return erased != null && erased.booleanValue();
|
||||
@@ -1286,4 +1236,20 @@ public class InferenceSession {
|
||||
public PsiElement getContext() {
|
||||
return myContext;
|
||||
}
|
||||
|
||||
public void propagateVariables(Collection<InferenceVariable> variables) {
|
||||
myInferenceVariables.addAll(variables);
|
||||
}
|
||||
|
||||
public PsiType substituteWithInferenceVariables(PsiType type) {
|
||||
return myInferenceSubstitution.substitute(type);
|
||||
}
|
||||
|
||||
public PsiType startWithFreshVars(PsiType type) {
|
||||
PsiSubstitutor s = PsiSubstitutor.EMPTY;
|
||||
for (InferenceVariable variable : myInferenceVariables) {
|
||||
s = s.put(variable, JavaPsiFacade.getElementFactory(variable.getProject()).createType(variable.getParameter()));
|
||||
}
|
||||
return s.substitute(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve.graphInference;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightTypeParameter;
|
||||
|
||||
import java.util.*;
|
||||
@@ -138,6 +136,11 @@ public class InferenceVariable extends LightTypeParameter {
|
||||
return this == another || getDelegate() == another;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useDelegateToSubstitute() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getDelegate().toString();
|
||||
|
||||
@@ -19,16 +19,12 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -94,7 +90,11 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
if (method != null && !method.isConstructor()) {
|
||||
returnType = method.getReturnType();
|
||||
if (returnType != null) {
|
||||
typeParams = method.getTypeParameters();
|
||||
List<PsiTypeParameter> params = new ArrayList<PsiTypeParameter>();
|
||||
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(method)) {
|
||||
params.add(parameter);
|
||||
}
|
||||
typeParams = params.toArray(new PsiTypeParameter[params.size()]);
|
||||
}
|
||||
} else if (myExpression instanceof PsiNewExpression) { //default constructor
|
||||
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)myExpression).getClassOrAnonymousClassReference();
|
||||
@@ -108,38 +108,8 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
}
|
||||
|
||||
if (typeParams != null) {
|
||||
|
||||
final Set<PsiTypeParameter> oldBounds = ContainerUtil.newHashSet(session.getParamsToInfer());
|
||||
final boolean sameMethodCall = session.initBounds(myExpression, typeParams);
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
final HashSet<InferenceVariable> variables = new HashSet<InferenceVariable>();
|
||||
session.collectDependencies(returnType, variables);
|
||||
final PsiTypeParameter[] params = new PsiTypeParameter[typeParams.length];
|
||||
for (int i = 0; i < typeParams.length; i++) {
|
||||
if (variables.contains(session.getInferenceVariable(typeParams[i]))) {
|
||||
params[i] = JavaPsiFacade.getElementFactory(myExpression.getProject()).createTypeParameterFromText("copyOf" + myExpression.hashCode() + typeParams[i].getName(), null);
|
||||
substitutor = substitutor.put(typeParams[i], JavaPsiFacade.getElementFactory(myExpression.getProject()).createType(params[i]));
|
||||
}
|
||||
else {
|
||||
params[i] = typeParams[i];
|
||||
}
|
||||
}
|
||||
PsiSubstitutor siteSubstitutor = PsiSubstitutor.EMPTY;
|
||||
if (method != null && !method.isConstructor()) {
|
||||
if (resolveResult instanceof MethodCandidateInfo) {
|
||||
siteSubstitutor = ((MethodCandidateInfo)resolveResult).getSiteSubstitutor();
|
||||
}
|
||||
else if (candidateProperties != null) {
|
||||
siteSubstitutor = candidateProperties.getSubstitutor();
|
||||
}
|
||||
}
|
||||
for (PsiTypeParameter typeParameter : siteSubstitutor.getSubstitutionMap().keySet()) {
|
||||
substitutor = substitutor.put(typeParameter, substitutor.substitute(siteSubstitutor.substitute(typeParameter)));
|
||||
}
|
||||
|
||||
final Collection<PsiTypeParameter> params1 = session.getTypeParams();
|
||||
final InferenceSession callSession = new InferenceSession(params, substitutor, myExpression.getManager(), myExpression);
|
||||
callSession.initBounds(session.getContext(), params1.toArray(new PsiTypeParameter[params1.size()]));
|
||||
final InferenceSession callSession = new InferenceSession(typeParams, PsiSubstitutor.EMPTY, myExpression.getManager(), myExpression);
|
||||
callSession.propagateVariables(session.getInferenceVariables());
|
||||
if (method != null) {
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
@@ -150,27 +120,12 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
if (!accepted) {
|
||||
return false;
|
||||
}
|
||||
callSession.registerReturnTypeConstraints(
|
||||
method != null && !PsiUtil.isRawSubstitutor(method, siteSubstitutor) ? siteSubstitutor.substitute(returnType) : returnType,
|
||||
substitutor.substitute(returnType));
|
||||
callSession.registerReturnTypeConstraints(returnType, myT);
|
||||
if (callSession.repeatInferencePhases(true)) {
|
||||
final Collection<InferenceVariable> inferenceVariables = callSession.getInferenceVariables();
|
||||
if (sameMethodCall) {
|
||||
for (Iterator<InferenceVariable> iterator = inferenceVariables.iterator(); iterator.hasNext(); ) {
|
||||
InferenceVariable variable = iterator.next();
|
||||
if (oldBounds.contains(variable.getParameter())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
session.liftBounds(myExpression, inferenceVariables);
|
||||
session.registerNestedSession(callSession);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
final PsiType capturedReturnType = myExpression instanceof PsiMethodCallExpression
|
||||
? PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, substitutor)
|
||||
: substitutor.substitute(returnType);
|
||||
constraints.add(new TypeCompatibilityConstraint(myT, capturedReturnType));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
|
||||
constraints.add(new StrictSubtypingConstraint(myT, groundTargetType));
|
||||
} else {
|
||||
for (PsiParameter parameter : parameters) {
|
||||
if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
|
||||
if (!session.isProperType(session.substituteWithInferenceVariables(substitutor.substitute(parameter.getType())))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
|
||||
if (returnExpressions.isEmpty() && !myExpression.isValueCompatible()) { //not value-compatible
|
||||
return false;
|
||||
}
|
||||
returnType = substitutor.substitute(returnType);
|
||||
returnType = session.substituteWithInferenceVariables(substitutor.substitute(returnType));
|
||||
if (!session.isProperType(returnType)) {
|
||||
for (PsiExpression returnExpression : returnExpressions) {
|
||||
constraints.add(new ExpressionCompatibilityConstraint(returnExpression, returnType));
|
||||
|
||||
@@ -93,11 +93,13 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
if (targetParameters.length == parameters.length + 1) {
|
||||
specialCase(session, constraints, substitutor, targetParameters, true);
|
||||
for (int i = 1; i < targetParameters.length; i++) {
|
||||
constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i - 1].getType()), substitutor.substitute(targetParameters[i].getType())));
|
||||
constraints.add(new TypeCompatibilityConstraint(session.substituteWithInferenceVariables(psiSubstitutor.substitute(parameters[i - 1].getType())),
|
||||
substitutor.substitute(targetParameters[i].getType())));
|
||||
}
|
||||
} else if (targetParameters.length == parameters.length) {
|
||||
for (int i = 0; i < targetParameters.length; i++) {
|
||||
constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i].getType()), substitutor.substitute(targetParameters[i].getType())));
|
||||
constraints.add(new TypeCompatibilityConstraint(session.substituteWithInferenceVariables(psiSubstitutor.substitute(parameters[i].getType())),
|
||||
substitutor.substitute(targetParameters[i].getType())));
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
@@ -108,12 +110,13 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
}
|
||||
|
||||
if (applicableMethodReturnType != null) {
|
||||
constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(applicableMethodReturnType)));
|
||||
} else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod)applicableMember).isConstructor()) {
|
||||
constraints.add(new TypeCompatibilityConstraint(returnType,
|
||||
session.substituteWithInferenceVariables(psiSubstitutor.substitute(applicableMethodReturnType))));
|
||||
}
|
||||
else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod)applicableMember).isConstructor()) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(applicableMember.getProject());
|
||||
|
||||
if (containingClass != null) {
|
||||
final PsiClassType classType = elementFactory.createType(containingClass, psiSubstitutor);
|
||||
final PsiType classType = session.substituteWithInferenceVariables(elementFactory.createType(containingClass, psiSubstitutor));
|
||||
constraints.add(new TypeCompatibilityConstraint(returnType, classType));
|
||||
}
|
||||
}
|
||||
@@ -122,7 +125,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
}
|
||||
|
||||
final Map<PsiMethodReferenceExpression, PsiType> map = PsiMethodReferenceUtil.getFunctionalTypeMap();
|
||||
final PsiType added = map.put(myExpression, groundTargetType);
|
||||
final PsiType added = map.put(myExpression, session.startWithFreshVars(groundTargetType));
|
||||
final JavaResolveResult resolve;
|
||||
try {
|
||||
resolve = myExpression.advancedResolve(true);
|
||||
@@ -205,7 +208,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
PsiPolyExpressionUtil.mentionsTypeParameters(referencedMethodReturnType, ContainerUtil.newHashSet(containingClass.getTypeParameters()))) { //todo specification bug?
|
||||
specialCase(session, constraints, substitutor, targetParameters, false);
|
||||
}
|
||||
constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(referencedMethodReturnType)));
|
||||
constraints.add(new TypeCompatibilityConstraint(returnType, session.substituteWithInferenceVariables(psiSubstitutor.substitute(referencedMethodReturnType))));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -241,7 +244,8 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
final PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType);
|
||||
if (qualifierClass != null) {
|
||||
session.initBounds(qualifierClass.getTypeParameters());
|
||||
constraints.add(new StrictSubtypingConstraint(qualifierType, substitutor.substitute(targetParameters[0].getType())));
|
||||
constraints.add(new StrictSubtypingConstraint(session.substituteWithInferenceVariables(qualifierType),
|
||||
session.substituteWithInferenceVariables(substitutor.substitute(targetParameters[0].getType()))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class MethodReferenceResolver implements ResolveCache.PolyVariantContextResolver<PsiMethodReferenceExpressionImpl> {
|
||||
private static final Logger LOG = Logger.getInstance("#" + MethodReferenceResolver.class.getName());
|
||||
@@ -68,7 +69,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
if (interfaceMethod != null) {
|
||||
final PsiClassType returnType = composeReturnType(containingClass, substitutor);
|
||||
final InferenceSession session = new InferenceSession(containingClass.getTypeParameters(), substitutor, reference.getManager(), null);
|
||||
if (!(session.isProperType(returnType) && session.isProperType(interfaceMethodReturnType))) {
|
||||
if (!(session.isProperType(session.substituteWithInferenceVariables(returnType)) && session.isProperType(interfaceMethodReturnType))) {
|
||||
session.registerReturnTypeConstraints(returnType, interfaceMethodReturnType);
|
||||
substitutor = session.infer();
|
||||
}
|
||||
@@ -116,13 +117,6 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
private PsiSubstitutor inferTypeArguments() {
|
||||
if (interfaceMethod == null) return substitutor;
|
||||
final InferenceSession session = new InferenceSession(method.getTypeParameters(), substitutor, reference.getManager(), reference);
|
||||
|
||||
//lift parameters from outer call
|
||||
final CurrentCandidateProperties methodSubstitutorPair = MethodCandidateInfo.getCurrentMethod(reference.getParent());
|
||||
if (methodSubstitutorPair != null) {
|
||||
session.initBounds(methodSubstitutorPair.getMethod().getTypeParameters());
|
||||
}
|
||||
|
||||
final PsiSubstitutor psiSubstitutor = session.collectApplicabilityConstraints(reference, this, functionalInterfaceType);
|
||||
if (psiSubstitutor != null) {
|
||||
return psiSubstitutor;
|
||||
@@ -133,6 +127,10 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
}
|
||||
|
||||
if (interfaceMethodReturnType != PsiType.VOID && interfaceMethodReturnType != null) {
|
||||
if (method.isConstructor()) {
|
||||
//todo
|
||||
session.initBounds(reference, method.getContainingClass().getTypeParameters());
|
||||
}
|
||||
final PsiType returnType = method.isConstructor() ? composeReturnType(containingClass, substitutor) : method.getReturnType();
|
||||
if (returnType != null) {
|
||||
session.registerReturnTypeConstraints(returnType, interfaceMethodReturnType);
|
||||
|
||||
@@ -10,6 +10,6 @@ class Node<NodeTypeT extends NodeType> {
|
||||
|
||||
class Main {
|
||||
public static void main(NodeProperty<NumberExpression, Integer> nval, Node<? extends NodeType> expr) {
|
||||
int val = expr.get<error descr="'get(NodeProperty<? super capture<? extends NodeType>,java.lang.Integer>)' in 'Node' cannot be applied to '(NodeProperty<NumberExpression,java.lang.Integer>)'">(nval)</error>;
|
||||
int val = expr.get<error descr="'get(NodeProperty<? super capture<? extends NodeType>,java.lang.Object>)' in 'Node' cannot be applied to '(NodeProperty<NumberExpression,java.lang.Integer>)'">(nval)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ class TestIDEA128101 {
|
||||
construct(String.class, createPath(integerAttribute), createPath(stringAttribute));
|
||||
construct1<error descr="Cannot resolve method 'construct1(java.lang.Class<java.lang.String>, TestIDEA128101.Path<java.lang.Integer>, TestIDEA128101.Path<java.lang.String>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
|
||||
construct2(String.class, createPath(integerAttribute), createPath(stringAttribute));
|
||||
<error descr="Type parameter K has incompatible upper bounds: Integer and String">construct3(String.class, createPath(integerAttribute), createPath(stringAttribute));</error>
|
||||
<error descr="Type parameter K has incompatible upper bounds: Integer and String">construct4(String.class, createPath(integerAttribute), createPath(stringAttribute));</error>
|
||||
construct3<error descr="Cannot resolve method 'construct3(java.lang.Class<java.lang.String>, TestIDEA128101.Path<java.lang.Integer>, TestIDEA128101.Path<java.lang.String>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
|
||||
construct4(String.class, createPath(integerAttribute), createPath<error descr="'createPath(TestIDEA128101.Attribute<Y>)' in 'TestIDEA128101' cannot be applied to '(TestIDEA128101.Attribute<java.lang.String>)'">(stringAttribute)</error>);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
abstract class Sample {
|
||||
abstract <T> T id (T t);
|
||||
abstract <R> void foo(List<R> c);
|
||||
abstract <U> List<U> bar(Function<String, U> m);
|
||||
|
||||
{
|
||||
foo(bar(this::id));
|
||||
foo(bar(id(i -> i)));
|
||||
|
||||
Function<String, String> s = id(this::id);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.codeInsight.daemon.lambda;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.idea.Bombed;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
@@ -24,6 +25,7 @@ import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
|
||||
public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase {
|
||||
@@ -40,6 +42,7 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase
|
||||
assertEquals("() -> {}", next.getText());
|
||||
}
|
||||
|
||||
@Bombed(day = 30, month = Calendar.AUGUST)
|
||||
public void testFieldFromAnonymousClassScope() throws Exception {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
final PsiElement elementAtCaret = myFixture.getElementAtCaret();
|
||||
|
||||
@@ -76,6 +76,7 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testIDEA122616() { doTest(); }
|
||||
public void testIDEA122700() { doTest(); }
|
||||
public void testIDEA122406() { doTest(); }
|
||||
@Bombed(day = 30, month = Calendar.AUGUST)
|
||||
public void testNestedCallsInsideLambdaReturnExpression() { doTest(); }
|
||||
@Bombed(day = 30, month = Calendar.AUGUST)
|
||||
public void testIDEA123731() { doTest(); }
|
||||
|
||||
@@ -305,6 +305,11 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Bombed(day = 30, month = Calendar.AUGUST)
|
||||
public void testAdditionalConstraints3Level() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user