SOE with recursive type parameter dependencies

This commit is contained in:
Anna Kozlova
2016-03-15 13:31:13 +01:00
parent 67de6a752d
commit 65ebda0fff
3 changed files with 20 additions and 1 deletions
@@ -16,6 +16,9 @@
package com.intellij.psi.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightTypeParameter;
import com.intellij.psi.util.PsiUtil;
@@ -136,11 +139,17 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
return mySubstitutionMap != null ? mySubstitutionMap.hashCode() : 0;
}
private static RecursionGuard ourGuard = RecursionManager.createGuard("substituteGuard");
private PsiType rawTypeForTypeParameter(final PsiTypeParameter typeParameter) {
final PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes();
if (extendsTypes.length > 0) {
// First bound
return substitute(extendsTypes[0]);
return ourGuard.doPreventingRecursion(extendsTypes[0], true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return substitute(extendsTypes[0]);
}
});
}
// Object
return PsiType.getJavaLangObject(typeParameter.getManager(), typeParameter.getResolveScope());
@@ -0,0 +1,6 @@
class Test {
private <<error descr="Cyclic inheritance involving 'S'"></error>S extends K, K extends S> S b(S s) {
if (true) return b <error descr="'b(S)' in 'Test' cannot be applied to '()'">()</error>;
<error descr="Missing return statement">}</error>
}
@@ -571,6 +571,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, true);
}
public void testRecursiveBoundsDependencies() throws Exception {
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
}
public void testLeastUpperBoundWithRecursiveTypes() throws Exception {
final PsiManager manager = getPsiManager();
final GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());