formal varargs not accessible check (jls)

This commit is contained in:
Anna Kozlova
2015-08-18 12:34:40 +02:00
parent d016c911ec
commit c97ce52826
3 changed files with 52 additions and 0 deletions
@@ -359,6 +359,10 @@ public class HighlightMethodUtil {
} else {
highlightInfo = GenericsHighlightUtil.checkInferredIntersections(substitutor, fixRange);
}
if (highlightInfo == null) {
highlightInfo = checkVarargParameterErasureToBeAccessible((MethodCandidateInfo)resolveResult, methodCall);
}
}
}
else {
@@ -1509,9 +1513,43 @@ public class HighlightMethodUtil {
}
}
}
if (result != null && !holder.hasErrorResults()) {
holder.add(checkVarargParameterErasureToBeAccessible(result, constructorCall));
}
}
}
/**
* If the compile-time declaration is applicable by variable arity invocation,
* then where the last formal parameter type of the invocation type of the method is Fn[],
* it is a compile-time error if the type which is the erasure of Fn is not accessible at the point of invocation.
*/
private static HighlightInfo checkVarargParameterErasureToBeAccessible(MethodCandidateInfo info, PsiCall place) {
final PsiMethod method = info.getElement();
if (info.isVarargs() || method.isVarArgs() && !PsiUtil.isLanguageLevel8OrHigher(place)) {
if (method.hasTypeParameters()) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
final PsiType componentType = ((PsiEllipsisType)parameters[parameters.length - 1].getType()).getComponentType();
final PsiClass classOfComponent = PsiUtil.resolveClassInClassTypeOnly(componentType);
if (classOfComponent instanceof PsiTypeParameter) {
final PsiType substitutedTypeErasure = TypeConversionUtil.erasure(info.getSubstitutor().substitute(componentType));
final PsiClass targetClass = PsiUtil.resolveClassInClassTypeOnly(substitutedTypeErasure);
if (targetClass != null && !PsiUtil.isAccessible(targetClass, place, null)) {
final PsiExpressionList argumentList = place.getArgumentList();
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.descriptionAndTooltip("Formal varargs element type " +
PsiFormatUtil.formatClass(targetClass, PsiFormatUtilBase.SHOW_FQ_NAME) +
" is inaccessible here")
.range(argumentList != null ? argumentList : place)
.create();
}
}
}
}
return null;
}
private static void registerFixesOnInvalidConstructorCall(PsiConstructorCall constructorCall,
PsiJavaCodeReferenceElement classReference,
PsiExpressionList list,
@@ -0,0 +1,13 @@
import java.util.Arrays;
class Test {
{
Arrays.asList<error descr="Formal varargs element type is inaccessible here">(new Outer.B(), new Outer.C())</error>;
}
}
class Outer {
private static class A {}
public static class B extends A {}
public static class C extends A {}
}
@@ -167,4 +167,5 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
public void testExternalizable() { doTest(true, false); }
public void testAccessToStaticMethodsFromInterfaces() { doTest(true, false); }
public void testUncheckedExtendedWarnings() { doTest(true, false); }
public void testInaccessibleInferredTypeForVarargsArgument() { doTest(false, false);}
}