mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Resolve to packages obscured by inaccessible class
This commit is contained in:
+14
-20
@@ -31,6 +31,7 @@ import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.impl.source.resolve.ClassResolverProcessor;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
|
||||
import com.intellij.psi.impl.source.resolve.ResolveCache;
|
||||
import com.intellij.psi.impl.source.resolve.VariableResolverProcessor;
|
||||
import com.intellij.psi.impl.source.tree.*;
|
||||
@@ -345,16 +346,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
}
|
||||
}
|
||||
|
||||
if (result.length > 0 && result[0].getElement() instanceof PsiClass) {
|
||||
PsiType[] parameters = ((PsiJavaCodeReferenceElement)ref).getTypeParameters();
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
CandidateInfo resolveResult = (CandidateInfo)result[i];
|
||||
PsiElement resultElement = resolveResult.getElement();
|
||||
if (resultElement instanceof PsiClass && ((PsiClass)resultElement).hasTypeParameters()) {
|
||||
result[i] = new CandidateInfo(resolveResult, resolveResult.getSubstitutor().putAll((PsiClass)resultElement, parameters));
|
||||
}
|
||||
}
|
||||
}
|
||||
JavaResolveUtil.substituteResults((PsiJavaCodeReferenceElement)ref, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -449,7 +441,6 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
final PsiElement classNameElement = getReferenceNameElement();
|
||||
if (!(classNameElement instanceof PsiIdentifier)) return JavaResolveResult.EMPTY_ARRAY;
|
||||
final String className = classNameElement.getText();
|
||||
|
||||
final ClassResolverProcessor processor = new ClassResolverProcessor(className, this);
|
||||
PsiScopesUtil.resolveAndWalk(processor, this, null);
|
||||
return processor.getResult();
|
||||
@@ -464,18 +455,21 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
}
|
||||
return new JavaResolveResult[]{new CandidateInfo(aPackage, PsiSubstitutor.EMPTY)};
|
||||
}
|
||||
case CLASS_FQ_OR_PACKAGE_NAME_KIND: {
|
||||
JavaResolveResult[] result = resolve(CLASS_FQ_NAME_KIND);
|
||||
if (result.length == 0) {
|
||||
result = resolve(PACKAGE_NAME_KIND);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case CLASS_FQ_OR_PACKAGE_NAME_KIND:
|
||||
case CLASS_OR_PACKAGE_NAME_KIND: {
|
||||
JavaResolveResult[] result = resolve(CLASS_NAME_KIND);
|
||||
if (result.length == 0) {
|
||||
int classKind = kind == CLASS_OR_PACKAGE_NAME_KIND ? CLASS_NAME_KIND : CLASS_FQ_NAME_KIND;
|
||||
JavaResolveResult[] result = resolve(classKind);
|
||||
|
||||
if (result.length == 1 && !result[0].isAccessible()) {
|
||||
JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND);
|
||||
if (packageResult.length != 0) {
|
||||
result = packageResult;
|
||||
}
|
||||
}
|
||||
else if (result.length == 0) {
|
||||
result = resolve(PACKAGE_NAME_KIND);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
@@ -216,4 +217,17 @@ public class JavaResolveUtil {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void substituteResults(@NotNull PsiJavaCodeReferenceElement ref, @NotNull JavaResolveResult[] result) {
|
||||
if (result.length > 0 && result[0].getElement() instanceof PsiClass) {
|
||||
PsiType[] parameters = ref.getTypeParameters();
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
CandidateInfo resolveResult = (CandidateInfo)result[i];
|
||||
PsiElement resultElement = resolveResult.getElement();
|
||||
if (resultElement instanceof PsiClass && ((PsiClass)resultElement).hasTypeParameters()) {
|
||||
result[i] = new CandidateInfo(resolveResult, resolveResult.getSubstitutor().putAll((PsiClass)resultElement, parameters));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
-55
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,10 +34,7 @@ import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.impl.source.SourceJavaCodeReference;
|
||||
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.psi.impl.source.resolve.ClassResolverProcessor;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveCache;
|
||||
import com.intellij.psi.impl.source.resolve.ResolveCache;
|
||||
import com.intellij.psi.impl.source.resolve.VariableResolverProcessor;
|
||||
import com.intellij.psi.impl.source.resolve.*;
|
||||
import com.intellij.psi.impl.source.tree.*;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.scope.ElementClassFilter;
|
||||
@@ -187,59 +184,46 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
private static final class OurGenericsResolver implements ResolveCache.PolyVariantResolver<PsiJavaReference> {
|
||||
private static final OurGenericsResolver INSTANCE = new OurGenericsResolver();
|
||||
|
||||
@NotNull
|
||||
private static JavaResolveResult[] _resolve(boolean incompleteCode, PsiReferenceExpressionImpl expression) {
|
||||
CompositeElement treeParent = expression.getTreeParent();
|
||||
IElementType parentType = treeParent == null ? null : treeParent.getElementType();
|
||||
expression.resolveAllQualifiers();
|
||||
final JavaResolveResult[] result = expression.resolve(parentType);
|
||||
|
||||
if (incompleteCode && parentType != JavaElementType.REFERENCE_EXPRESSION && result.length == 0) {
|
||||
return expression.resolve(JavaElementType.REFERENCE_EXPRESSION);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JavaResolveResult[] resolve(@NotNull PsiJavaReference ref, boolean incompleteCode) {
|
||||
final JavaResolveResult[] result = _resolve(incompleteCode, (PsiReferenceExpressionImpl)ref);
|
||||
if (result.length > 0 && result[0].getElement() instanceof PsiClass) {
|
||||
final PsiType[] parameters = ((PsiJavaCodeReferenceElement)ref).getTypeParameters();
|
||||
final JavaResolveResult[] newResult = new JavaResolveResult[result.length];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
final CandidateInfo resolveResult = (CandidateInfo)result[i];
|
||||
newResult[i] = new CandidateInfo(resolveResult, resolveResult.getSubstitutor().putAll(
|
||||
(PsiClass)resolveResult.getElement(), parameters));
|
||||
}
|
||||
return newResult;
|
||||
PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)ref;
|
||||
CompositeElement treeParent = expression.getTreeParent();
|
||||
IElementType parentType = treeParent == null ? null : treeParent.getElementType();
|
||||
resolveAllQualifiers(expression);
|
||||
JavaResolveResult[] result = expression.resolve(parentType);
|
||||
|
||||
if (result.length == 0 && incompleteCode && parentType != JavaElementType.REFERENCE_EXPRESSION) {
|
||||
result = expression.resolve(JavaElementType.REFERENCE_EXPRESSION);
|
||||
}
|
||||
|
||||
JavaResolveUtil.substituteResults(expression, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveAllQualifiers() {
|
||||
// to avoid SOE, resolve all qualifiers starting from the innermost
|
||||
PsiElement qualifier = getQualifier();
|
||||
if (qualifier == null) return;
|
||||
final ResolveCache resolveCache = ResolveCache.getInstance(getProject());
|
||||
qualifier.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
if (!(expression instanceof PsiReferenceExpressionImpl) || resolveCache.isCached(expression, true, false, true)) {
|
||||
return;
|
||||
private static void resolveAllQualifiers(PsiReferenceExpressionImpl expression) {
|
||||
// to avoid SOE, resolve all qualifiers starting from the innermost
|
||||
PsiElement qualifier = expression.getQualifier();
|
||||
if (qualifier == null) return;
|
||||
final ResolveCache resolveCache = ResolveCache.getInstance(expression.getProject());
|
||||
qualifier.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
if (!(expression instanceof PsiReferenceExpressionImpl) || resolveCache.isCached(expression, true, false, true)) {
|
||||
return;
|
||||
}
|
||||
visitElement(expression);
|
||||
}
|
||||
visitElement(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void elementFinished(PsiElement element) {
|
||||
if (!(element instanceof PsiReferenceExpressionImpl)) return;
|
||||
PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)element;
|
||||
resolveCache.resolveWithCaching(expression, OurGenericsResolver.INSTANCE, false, false);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
protected void elementFinished(PsiElement element) {
|
||||
if (!(element instanceof PsiReferenceExpressionImpl)) return;
|
||||
PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)element;
|
||||
resolveCache.resolveWithCaching(expression, INSTANCE, false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -250,21 +234,33 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
return result;
|
||||
}
|
||||
|
||||
final PsiElement classNameElement = getReferenceNameElement();
|
||||
if (!(classNameElement instanceof PsiIdentifier)) return JavaResolveResult.EMPTY_ARRAY;
|
||||
result = resolveToClass(classNameElement);
|
||||
if (result.length > 0) {
|
||||
return result;
|
||||
PsiElement classNameElement = getReferenceNameElement();
|
||||
if (!(classNameElement instanceof PsiIdentifier)) {
|
||||
return JavaResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
return resolveToPackage();
|
||||
result = resolveToClass(classNameElement);
|
||||
if (result.length == 1 && !result[0].isAccessible()) {
|
||||
JavaResolveResult[] packageResult = resolveToPackage();
|
||||
if (packageResult.length != 0) {
|
||||
result = packageResult;
|
||||
}
|
||||
}
|
||||
else if (result.length == 0) {
|
||||
result = resolveToPackage();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (parentType == JavaElementType.METHOD_CALL_EXPRESSION) {
|
||||
return resolveToMethod();
|
||||
}
|
||||
|
||||
if (parentType == JavaElementType.METHOD_REF_EXPRESSION) {
|
||||
return resolve(JavaElementType.REFERENCE_EXPRESSION);
|
||||
}
|
||||
|
||||
return resolveToVariable();
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package main;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
pkg.sub.Test obj = new pkg.sub.Test();
|
||||
obj.m1();
|
||||
obj.<error descr="Cannot resolve method 'm2()'">m2</error>();
|
||||
|
||||
pkg.sub.Test.s1();
|
||||
pkg.sub.Test.<error descr="Cannot resolve method 's2()'">s2</error>();
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package pkg;
|
||||
|
||||
class sub {
|
||||
public static class Test {
|
||||
public void m2() { }
|
||||
|
||||
public static void s2() { }
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package pkg.sub;
|
||||
|
||||
public class Test {
|
||||
public void m1() { }
|
||||
|
||||
public static void s1() { }
|
||||
}
|
||||
@@ -297,4 +297,8 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase {
|
||||
public void testPackageAndClassConflict3() throws Exception {
|
||||
doTest(BASE_PATH + "/packageClassClash/java/lang.java", false, false);
|
||||
}
|
||||
|
||||
public void testPackageObscuring() throws Exception {
|
||||
doTest(BASE_PATH + "/packageObscuring/main/Main.java", BASE_PATH + "/packageObscuring", false, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user