mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
new inference: check bounds problems for all variables acceptable in current context (IDEA-138407); reject complicated dependencies (see JDK-8039299)
This commit is contained in:
+13
-7
@@ -787,22 +787,28 @@ public class InferenceSession {
|
||||
return substitutor.substitute(bound);
|
||||
}
|
||||
|
||||
private static boolean hasBoundProblems(final List<InferenceVariable> typeParams,
|
||||
final PsiSubstitutor substitutor,
|
||||
final PsiElement context) {
|
||||
private boolean hasBoundProblems(final List<InferenceVariable> typeParams,
|
||||
final PsiSubstitutor psiSubstitutor,
|
||||
final PsiSubstitutor substitutor) {
|
||||
for (InferenceVariable typeParameter : typeParams) {
|
||||
if (typeParameter.getCallContext() != context) {
|
||||
if (isForeignVariable(psiSubstitutor, typeParameter)) {
|
||||
continue;
|
||||
}
|
||||
final List<PsiType> extendsTypes = typeParameter.getBounds(InferenceBound.UPPER);
|
||||
final PsiType[] bounds = extendsTypes.toArray(new PsiType[extendsTypes.size()]);
|
||||
if (GenericsUtil.findTypeParameterBoundError(typeParameter, bounds, substitutor, context, true) != null) {
|
||||
if (GenericsUtil.findTypeParameterBoundError(typeParameter, bounds, substitutor, myContext, true) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isForeignVariable(PsiSubstitutor fullSubstitutor,
|
||||
InferenceVariable typeParameter) {
|
||||
return fullSubstitutor.putAll(mySiteSubstitutor).getSubstitutionMap().containsKey(typeParameter.getParameter()) &&
|
||||
typeParameter.getCallContext() != myContext;
|
||||
}
|
||||
|
||||
private PsiSubstitutor resolveBounds(final Collection<InferenceVariable> inferenceVariables,
|
||||
PsiSubstitutor substitutor) {
|
||||
final Collection<InferenceVariable> allVars = new ArrayList<InferenceVariable>(inferenceVariables);
|
||||
@@ -812,7 +818,7 @@ public class InferenceSession {
|
||||
if (!myIncorporationPhase.hasCaptureConstraints(vars)) {
|
||||
PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor, foreignMap);
|
||||
if (firstSubstitutor != null) {
|
||||
if (hasBoundProblems(vars, firstSubstitutor, myContext)) {
|
||||
if (hasBoundProblems(vars, substitutor, firstSubstitutor)) {
|
||||
firstSubstitutor = null;
|
||||
}
|
||||
}
|
||||
@@ -912,7 +918,7 @@ public class InferenceSession {
|
||||
foreignMap.put(var, type);
|
||||
}
|
||||
|
||||
if (substitutor.putAll(mySiteSubstitutor).getSubstitutionMap().containsKey(typeParameter) && var.getCallContext() != myContext) {
|
||||
if (isForeignVariable(substitutor, var)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
-17
@@ -102,23 +102,6 @@ public class InferenceVariable extends LightTypeParameter {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
next:
|
||||
for (InferenceVariable variable : session.getInferenceVariables()) {
|
||||
if (!dependencies.contains(variable) && variable != this) {
|
||||
for (List<PsiType> bounds : variable.myBounds.values()) { //todo
|
||||
if (bounds != null) {
|
||||
for (PsiType bound : bounds) {
|
||||
final InferenceVariable inferenceVariable = session.getInferenceVariable(bound);
|
||||
if (inferenceVariable == this) {
|
||||
dependencies.add(variable);
|
||||
continue next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!session.hasCapture(this)) {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
class Foo {
|
||||
{
|
||||
Bar<Baz> b = method(new Bar<>());
|
||||
}
|
||||
|
||||
static <T> T method(Class<T> t) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static <T> T method(T t) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
class Bar<T extends Enum<T>> {
|
||||
|
||||
}
|
||||
|
||||
enum Baz {}
|
||||
+4
@@ -39,6 +39,10 @@ public class Diamond8HighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testOverloadOuterCall() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user