@SafeVarargs for java 9 (IDEA-132278)

This commit is contained in:
Anna Kozlova
2014-11-18 18:36:28 +01:00
parent 803f5a7316
commit 2bd9c19a63
5 changed files with 82 additions and 6 deletions
@@ -941,7 +941,7 @@ public class GenericsHighlightUtil {
}
@Nullable
public static HighlightInfo checkSafeVarargsAnnotation(PsiMethod method) {
public static HighlightInfo checkSafeVarargsAnnotation(PsiMethod method, LanguageLevel languageLevel) {
PsiModifierList list = method.getModifierList();
final PsiAnnotation safeVarargsAnnotation = list.findAnnotation("java.lang.SafeVarargs");
if (safeVarargsAnnotation == null) {
@@ -952,7 +952,7 @@ public class GenericsHighlightUtil {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(safeVarargsAnnotation).descriptionAndTooltip(
"@SafeVarargs is not allowed on methods with fixed arity").create();
}
if (!method.hasModifierProperty(PsiModifier.STATIC) && !method.hasModifierProperty(PsiModifier.FINAL) && !method.isConstructor()) {
if (!isSafeVarargsNoOverridingCondition(method, languageLevel)) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(safeVarargsAnnotation).descriptionAndTooltip(
"@SafeVarargs is not allowed on non-final instance methods").create();
}
@@ -983,6 +983,13 @@ public class GenericsHighlightUtil {
}
}
public static boolean isSafeVarargsNoOverridingCondition(PsiMethod method, LanguageLevel languageLevel) {
return method.hasModifierProperty(PsiModifier.FINAL) ||
method.hasModifierProperty(PsiModifier.STATIC) ||
method.isConstructor() ||
method.hasModifierProperty(PsiModifier.PRIVATE) && languageLevel.isAtLeast(LanguageLevel.JDK_1_9);
}
static void checkEnumConstantForConstructorProblems(@NotNull PsiEnumConstant enumConstant,
@NotNull HighlightInfoHolder holder,
@NotNull JavaSdkVersion javaSdkVersion) {
@@ -739,7 +739,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorHandleSuperClassExceptions(method));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkRecursiveConstructorInvocation(method));
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkOverrideAnnotation(method, myLanguageLevel));
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSafeVarargsAnnotation(method));
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSafeVarargsAnnotation(method, myLanguageLevel));
PsiClass aClass = method.getContainingClass();
if (!myHolder.hasErrorResults() && method.isConstructor()) {
@@ -18,6 +18,7 @@ package com.intellij.codeInspection;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.openapi.diagnostic.Logger;
@@ -74,9 +75,7 @@ public class PossibleHeapPollutionVarargsInspection extends BaseJavaBatchLocalIn
@Override
protected void registerProblem(PsiMethod method, PsiIdentifier nameIdentifier) {
final LocalQuickFix quickFix;
if (method.hasModifierProperty(PsiModifier.FINAL) ||
method.hasModifierProperty(PsiModifier.STATIC) ||
method.isConstructor()) {
if (GenericsHighlightUtil.isSafeVarargsNoOverridingCondition(method, PsiUtil.getLanguageLevel(method))) {
quickFix = new AnnotateAsSafeVarargsQuickFix();
}
else {
@@ -0,0 +1,14 @@
import java.util.List;
final class Test {
@SafeVarargs
private <T> void testPrivate(T... <warning descr="Parameter 'i' is never used">i</warning>){}
<error descr="@SafeVarargs is not allowed on non-final instance methods">@SafeVarargs</error>
protected <T> void testProtected(T... <warning descr="Parameter 'i' is never used">i</warning>){} //but in final class
public static void main(String[] args) {
new Test().testPrivate();
new Test().testProtected();
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.compiler.JavacQuirksInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.redundantCast.RedundantCastInspection;
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.IdeaTestUtil;
import org.jetbrains.annotations.NotNull;
public class LightAdvHighlightingJdk9Test extends LightDaemonAnalyzerTestCase {
private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/advHighlighting9";
@Override
protected void setUp() throws Exception {
super.setUp();
enableInspectionTool(new UnusedDeclarationInspection());
}
private void doTest(boolean checkWarnings, boolean checkInfos, InspectionProfileEntry... classes) {
setLanguageLevel(LanguageLevel.JDK_1_9);
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_9, getModule(), myTestRootDisposable);
enableInspectionTools(classes);
doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos);
}
@NotNull
@Override
protected LocalInspectionTool[] configureLocalInspectionTools() {
return new LocalInspectionTool[]{
new UncheckedWarningLocalInspection(),
new JavacQuirksInspection(),
new RedundantCastInspection()
};
}
public void testSafeVarargsApplicability() { doTest(true, false); }
}