avoid recursive super class reference resolve

This commit is contained in:
peter
2016-05-02 22:03:38 +02:00
parent be3e871a3b
commit e981c18b88
4 changed files with 41 additions and 5 deletions
@@ -28,15 +28,20 @@ import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class JavaResolveUtil {
public static PsiClass getContextClass(PsiElement element) {
public static PsiClass getContextClass(@NotNull PsiElement element) {
PsiElement prev = element;
PsiElement scope = element.getContext();
while (scope != null) {
if (scope instanceof PsiClass) return (PsiClass)scope;
if (scope instanceof PsiClass && (prev instanceof PsiMember || prev instanceof PsiDocComment)) {
return (PsiClass)scope;
}
prev = scope;
scope = scope.getContext();
}
return null;
@@ -110,15 +115,19 @@ public class JavaResolveUtil {
if (memberClass == null) {
return false;
}
for (PsiElement placeParent = place; placeParent != null; placeParent = placeParent.getContext()) {
if (placeParent instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)placeParent, memberClass, true)) {
PsiClass contextClass = member instanceof PsiClass ? getContextClass(place)
: PsiTreeUtil.getContextOfType(place, PsiClass.class, false);
while (contextClass != null) {
if (InheritanceUtil.isInheritorOrSelf(contextClass, memberClass, true)) {
if (member instanceof PsiClass ||
modifierList.hasModifierProperty(PsiModifier.STATIC) ||
accessObjectClass == null ||
InheritanceUtil.isInheritorOrSelf(accessObjectClass, (PsiClass)placeParent, true)) {
InheritanceUtil.isInheritorOrSelf(accessObjectClass, contextClass, true)) {
return true;
}
}
contextClass = getContextClass(contextClass);
}
return false;
}
@@ -0,0 +1,8 @@
import foo.Outer;
class Foo {
{
new Outer.<ref>Inner() { };
}
}
@@ -16,11 +16,13 @@
package com.intellij.psi.resolve;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packageDependencies.DependenciesBuilder;
@@ -226,6 +228,18 @@ public class ResolveClassTest extends ResolveTestCase {
PlatformTestUtil.assertTiming("exponent?", 20000, System.currentTimeMillis() - start);
}
public void testQualifiedAnonymousClass() throws Exception {
RecursionManager.assertOnRecursionPrevention(myTestRootDisposable);
PsiReference ref = configure();
VirtualFile file = ref.getElement().getContainingFile().getVirtualFile();
assertNotNull(file);
VirtualFile pkg = WriteAction.compute(() -> file.getParent().createChildDirectory(this, "foo"));
createFile(myModule, pkg, "Outer.java", "package foo; public class Outer { protected static class Inner { protected Inner() {} } }");
assertEquals("Inner", assertInstanceOf(ref.resolve(), PsiClass.class).getName());
}
@SuppressWarnings({"ConstantConditions"})
private void configureDependency() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@@ -1,6 +1,7 @@
package com.intellij.psi.resolve;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.PsiTreeUtil;
@@ -242,6 +243,8 @@ public class ResolveMethod15Test extends Resolve15TestCase {
assertTrue(!((PsiMethod) element).isVarArgs());
}
public void testFilterFixedVsVarargs9() throws Exception {
RecursionManager.assertOnRecursionPrevention(myTestRootDisposable);
final PsiReference ref = configureByFile();
assertThat(ref, instanceOf(PsiReferenceExpression.class));
final PsiReferenceExpression refExpr = (PsiReferenceExpression)ref;
@@ -485,6 +488,8 @@ public class ResolveMethod15Test extends Resolve15TestCase {
}
public void testInheritance4() throws Exception{
RecursionManager.assertOnRecursionPrevention(myTestRootDisposable);
PsiReference ref = configureByFile();
PsiElement target = ref.resolve();
assertThat(target, instanceOf(PsiMethod.class));