check class accessible from another module: don't check parameters but check if method return type/param types are accessible

This commit is contained in:
Anna Kozlova
2016-02-18 16:31:20 +01:00
parent 4475c9c72a
commit e85ff6f47f
4 changed files with 67 additions and 12 deletions
@@ -1414,19 +1414,63 @@ public class GenericsHighlightUtil {
}
static HighlightInfo areSupersAccessible(@NotNull PsiClass aClass) {
return areSupersAccessible(aClass, aClass.getResolveScope(), HighlightNamesUtil.getClassDeclarationTextRange(aClass));
return areSupersAccessible(aClass, aClass.getResolveScope(), HighlightNamesUtil.getClassDeclarationTextRange(aClass), true);
}
static HighlightInfo areSupersAccessible(@NotNull PsiClass aClass, PsiElement ref) {
return areSupersAccessible(aClass, ref.getResolveScope(), ref.getTextRange());
static HighlightInfo areSupersAccessible(@NotNull PsiClass aClass, PsiReferenceExpression ref) {
final GlobalSearchScope resolveScope = ref.getResolveScope();
final HighlightInfo info = areSupersAccessible(aClass, resolveScope, ref.getTextRange(), false);
if (info != null) {
return info;
}
String message = null;
final PsiElement parent = ref.getParent();
if (parent instanceof PsiMethodCallExpression) {
final JavaResolveResult resolveResult = ((PsiMethodCallExpression)parent).resolveMethodGenerics();
final PsiMethod method = (PsiMethod)resolveResult.getElement();
if (method != null) {
final HashSet<PsiClass> classes = new HashSet<>();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(aClass.getProject());
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
message = isSuperTypeAccessible(substitutor.substitute(method.getReturnType()), classes, false, resolveScope, facade);
if (message == null) {
for (PsiType type : method.getSignature(substitutor).getParameterTypes()) {
message = isSuperTypeAccessible(type, classes, false, resolveScope, facade);
if (message != null) {
break;
}
}
}
}
}
else {
final PsiElement resolve = ref.resolve();
if (resolve instanceof PsiField) {
message = isSuperTypeAccessible(((PsiField)resolve).getType(), new HashSet<>(), false, resolveScope, JavaPsiFacade.getInstance(aClass.getProject()));
}
}
if (message != null) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.descriptionAndTooltip(message)
.range(ref.getTextRange())
.create();
}
return null;
}
private static HighlightInfo areSupersAccessible(@NotNull PsiClass aClass,
GlobalSearchScope resolveScope,
TextRange range) {
TextRange range,
boolean checkParameters) {
final JavaPsiFacade factory = JavaPsiFacade.getInstance(aClass.getProject());
for (PsiClassType superType : aClass.getSuperTypes()) {
final String notAccessibleErrorMessage = isSuperTypeAccessible(superType, new HashSet<PsiClass>(), resolveScope, factory);
final String notAccessibleErrorMessage = isSuperTypeAccessible(superType, new HashSet<PsiClass>(), checkParameters, resolveScope, factory);
if (notAccessibleErrorMessage != null) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.descriptionAndTooltip(notAccessibleErrorMessage)
@@ -1440,6 +1484,7 @@ public class GenericsHighlightUtil {
@Nullable
private static String isSuperTypeAccessible(PsiType superType,
HashSet<PsiClass> classes,
boolean checkParameters,
GlobalSearchScope resolveScope,
JavaPsiFacade factory) {
final PsiClass aClass = PsiUtil.resolveClassInType(superType);
@@ -1449,9 +1494,9 @@ public class GenericsHighlightUtil {
return "Cannot access " + HighlightUtil.formatClass(aClass);
}
if (superType instanceof PsiClassType) {
if (checkParameters && superType instanceof PsiClassType) {
for (PsiType psiType : ((PsiClassType)superType).getParameters()) {
final String notAccessibleMessage = isSuperTypeAccessible(psiType, classes, resolveScope, factory);
final String notAccessibleMessage = isSuperTypeAccessible(psiType, classes, checkParameters, resolveScope, factory);
if (notAccessibleMessage != null) {
return notAccessibleMessage;
}
@@ -1459,7 +1504,7 @@ public class GenericsHighlightUtil {
}
for (PsiClassType type : aClass.getSuperTypes()) {
final String notAccessibleMessage = isSuperTypeAccessible(type, classes, resolveScope, factory);
final String notAccessibleMessage = isSuperTypeAccessible(type, classes, checkParameters, resolveScope, factory);
if (notAccessibleMessage != null) {
return notAccessibleMessage;
}
@@ -1246,7 +1246,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
if (psiClass != null) {
myHolder.add(GenericsHighlightUtil.areSupersAccessible(psiClass, qualifierExpression));
myHolder.add(GenericsHighlightUtil.areSupersAccessible(psiClass, expression));
}
}
}
@@ -1,10 +1,16 @@
package p;
abstract class B {
void f(A a) {
<error descr="Cannot access java.util.stream.Stream">a</error>.foo();
<error descr="Cannot access java.util.stream.Stream">a.foo</error>();
Object o = a;
a.bar();
<error descr="Cannot access java.util.stream.Stream">a.myField</error>;
}
void f(java.util.List<? extends A> a) {
<error descr="Cannot access java.util.stream.Stream">a.get(0)</error>.foo();
<error descr="Cannot access java.util.stream.Stream">a.get(0).foo</error>();
}
}
@@ -3,5 +3,9 @@ import java.util.stream.Stream;
import java.util.List;
public abstract class A implements List<Stream<String>> {
public void foo() {}
public Stream<String> foo() {}
public void bar() {}
public Stream<String> myField;
}