formal varargs not accessible check (jls)
authorAnna Kozlova <anna.kozlova@jetbrains.com>
Tue, 18 Aug 2015 10:24:49 +0000 (12:24 +0200)
committerAnna Kozlova <anna.kozlova@jetbrains.com>
Tue, 18 Aug 2015 10:34:40 +0000 (12:34 +0200)
java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/InaccessibleInferredTypeForVarargsArgument.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java

index 98c9b0e5e22548863ca5ae7e6f45fc96b71aba81..c8522b286307655b6c4312a661a633dcdf614243 100644 (file)
@@ -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,
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/InaccessibleInferredTypeForVarargsArgument.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/InaccessibleInferredTypeForVarargsArgument.java
new file mode 100644 (file)
index 0000000..5ed7852
--- /dev/null
@@ -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 {}
+}
\ No newline at end of file
index ab379eb0d3776b20263cbb1368165c83e7794302..3d23f49ef4ad055c33351ca442825cde760f4030 100644 (file)
@@ -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);}
 }