@NotNull private static PsiSubstitutor replaceVariables(Collection<InferenceVariable> inferenceVariables) { final List<InferenceVariable> targetVars = new ArrayList<InferenceVariable>(); PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; final InferenceVariable[] oldVars = inferenceVariables.toArray(new InferenceVariable[inferenceVariables.size()]); for (InferenceVariable variable : oldVars) { final InferenceVariable newVariable = new InferenceVariable( variable.getCallContext(), variable.getParameter(), variable.getName()); substitutor = substitutor.put( variable, JavaPsiFacade.getElementFactory(variable.getProject()).createType(newVariable)); targetVars.add(newVariable); if (variable.isThrownBound()) { newVariable.setThrownBound(); } } for (int i = 0; i < targetVars.size(); i++) { InferenceVariable var = targetVars.get(i); for (InferenceBound boundType : InferenceBound.values()) { for (PsiType bound : oldVars[i].getBounds(boundType)) { var.addBound(substitutor.substitute(bound), boundType, null); } } } return substitutor; }
/** a = b imply every bound of a matches a bound of b and vice versa */ private boolean eqCrossVariables(InferenceVariable inferenceVariable, List<PsiType> eqBounds) { boolean needFurtherIncorporation = false; for (PsiType eqBound : eqBounds) { final InferenceVariable inferenceVar = mySession.getInferenceVariable(eqBound); if (inferenceVar != null) { for (InferenceBound inferenceBound : InferenceBound.values()) { for (PsiType bound : inferenceVariable.getBounds(inferenceBound)) { if (mySession.getInferenceVariable(bound) != inferenceVar) { needFurtherIncorporation |= inferenceVar.addBound(bound, inferenceBound); } } for (PsiType bound : inferenceVar.getBounds(inferenceBound)) { if (mySession.getInferenceVariable(bound) != inferenceVariable) { needFurtherIncorporation |= inferenceVariable.addBound(bound, inferenceBound); } } } } } return needFurtherIncorporation; }