From 4b3e26fb2f6791a8f820a5faabeab9e9cb248179 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 27 Oct 2017 14:21:05 +0200 Subject: [PATCH] [java] deprecates outdated AnnotationUtil API (IDEA-181206) --- .../InferredAnnotationsManagerImpl.java | 24 ++--- .../impl/AddNullableNotNullAnnotationFix.java | 21 +--- .../dataFlow/rangeSet/LongRangeSet.java | 20 +--- .../nullable/NullableStuffInspectionBase.java | 4 +- .../OverrideImplementsAnnotationsHandler.java | 25 ++--- .../extractMethod/ExtractMethodProcessor.java | 25 ++--- .../intellij/codeInsight/AnnotationUtil.java | 95 +++++++++++-------- .../codeInsight/NullableNotNullManager.java | 58 ++++++----- .../codeInsight/psi/AnnotatedTypeTest.groovy | 26 ++--- 9 files changed, 121 insertions(+), 177 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java index 32c1dd4bc93c..41cb7c1f5238 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight; import com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalysis; @@ -29,6 +15,9 @@ import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Set; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_EXTERNAL; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_INFERRED; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_TYPE; import static com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT; public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager { @@ -59,7 +48,7 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager { if (ignoreInference(listOwner, annotationFQN)) { return null; } - + PsiAnnotation fromBytecode = ProjectBytecodeAnalysis.getInstance(myProject).findInferredAnnotation(listOwner, annotationFQN); if (fromBytecode != null) { return fromBytecode; @@ -98,7 +87,8 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager { return true; } if (AnnotationUtil.NOT_NULL.equals(annotationFQN) && owner instanceof PsiParameter && owner.getParent() != null) { - if (AnnotationUtil.isAnnotated(owner, NullableNotNullManager.getInstance(owner.getProject()).getNullables(), false, false)) { + List annotations = NullableNotNullManager.getInstance(owner.getProject()).getNullables(); + if (AnnotationUtil.isAnnotated(owner, annotations, CHECK_EXTERNAL | CHECK_INFERRED | CHECK_TYPE)) { return true; } if (HardcodedContracts.hasHardcodedContracts(owner)) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java index 4151e2f22b2b..584b676c4149 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2009 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. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.intention.impl; @@ -22,6 +8,9 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_EXTERNAL; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_TYPE; + public class AddNullableNotNullAnnotationFix extends AddAnnotationPsiFix { public AddNullableNotNullAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner owner, @NotNull String... annotationToRemove) { super(fqn, owner, PsiNameValuePair.EMPTY_ARRAY, annotationToRemove); @@ -36,7 +25,7 @@ public class AddNullableNotNullAnnotationFix extends AddAnnotationPsiFix { return false; } PsiModifierListOwner owner = getContainer(file, startElement.getTextRange().getStartOffset()); - if (owner == null || AnnotationUtil.isAnnotated(owner, getAnnotationsToRemove()[0], false, false)) { + if (owner == null || AnnotationUtil.isAnnotated(owner, getAnnotationsToRemove()[0], CHECK_EXTERNAL | CHECK_TYPE)) { return false; } return canAnnotate(owner); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/rangeSet/LongRangeSet.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/rangeSet/LongRangeSet.java index f48dad7b80a8..00347af69fd2 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/rangeSet/LongRangeSet.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/rangeSet/LongRangeSet.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInspection.dataFlow.rangeSet; import com.intellij.codeInsight.AnnotationUtil; @@ -30,6 +16,8 @@ import java.util.NoSuchElementException; import java.util.stream.IntStream; import java.util.stream.LongStream; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_TYPE; + /** * An immutable set of long values optimized for small number of ranges. * @@ -406,7 +394,7 @@ public abstract class LongRangeSet { @NotNull public static LongRangeSet fromAnnotation(PsiModifierListOwner owner) { if (owner == null) return all(); - if (AnnotationUtil.isAnnotated(owner, "javax.annotation.Nonnegative", false)) { + if (AnnotationUtil.isAnnotated(owner, "javax.annotation.Nonnegative", CHECK_TYPE)) { return range(0, Long.MAX_VALUE); } return all(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java index 162a35a4f35f..6febb6eab9f1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java @@ -35,6 +35,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.*; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_HIERARCHY; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_TYPE; import static com.intellij.patterns.PsiJavaPatterns.psiElement; import static com.intellij.patterns.PsiJavaPatterns.psiMethod; @@ -648,7 +650,7 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection } private static boolean hasInheritableNotNull(PsiModifierListOwner owner) { - return AnnotationUtil.isAnnotated(owner, "javax.annotation.constraints.NotNull", true); + return AnnotationUtil.isAnnotated(owner, "javax.annotation.constraints.NotNull", CHECK_HIERARCHY | CHECK_TYPE); } private void checkParameters(PsiMethod method, diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementsAnnotationsHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementsAnnotationsHandler.java index e79fe2227540..85cd098371b9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementsAnnotationsHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementsAnnotationsHandler.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.generation; import com.intellij.codeInsight.AnnotationUtil; @@ -28,6 +14,10 @@ import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_EXTERNAL; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_INFERRED; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_TYPE; + /** * @author anna * @since 19-Aug-2008 @@ -57,8 +47,9 @@ public interface OverrideImplementsAnnotationsHandler { for (String annotation : each.getAnnotations(project)) { if (moduleScope != null && facade.findClass(annotation, moduleScope) == null) continue; - if (AnnotationUtil.isAnnotated(source, annotation, false, false) && - !AnnotationUtil.isAnnotated(target, annotation, false, false)) { + int flags = CHECK_EXTERNAL | CHECK_INFERRED | CHECK_TYPE; + if (AnnotationUtil.isAnnotated(source, annotation, flags) && + !AnnotationUtil.isAnnotated(target, annotation, flags)) { PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotation(source, annotation); if (psiAnnotation != null && AnnotationUtil.isInferredAnnotation(psiAnnotation)) { continue; diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index 0f07a0995503..e21ab096ebfd 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.refactoring.extractMethod; import com.intellij.codeInsight.*; @@ -83,6 +69,8 @@ import org.jetbrains.annotations.TestOnly; import java.util.*; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_TYPE; + public class ExtractMethodProcessor implements MatchProvider { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractMethod.ExtractMethodProcessor"); @@ -1513,17 +1501,16 @@ public class ExtractMethodProcessor implements MatchProvider { final List notNullAnnotations = nullabilityManager.getNotNulls(); final List nullableAnnotations = nullabilityManager.getNullables(); - if (AnnotationUtil.isAnnotated(variable, nullableAnnotations) || - AnnotationUtil.isAnnotated(variable, notNullAnnotations) || + if (AnnotationUtil.isAnnotated(variable, nullableAnnotations, CHECK_TYPE) || + AnnotationUtil.isAnnotated(variable, notNullAnnotations, CHECK_TYPE) || PropertiesComponent.getInstance(myProject).getBoolean(ExtractMethodDialog.EXTRACT_METHOD_GENERATE_ANNOTATIONS, false)) { - final Boolean isNotNull = isNotNullAt(variable, myElements[0]); if (isNotNull != null) { final List toKeep = isNotNull ? notNullAnnotations : nullableAnnotations; final String[] toRemove = (!isNotNull ? notNullAnnotations : nullableAnnotations).toArray(ArrayUtil.EMPTY_STRING_ARRAY); AddAnnotationPsiFix.removePhysicalAnnotations(parm, toRemove); - if (!AnnotationUtil.isAnnotated(parm, toKeep)) { + if (!AnnotationUtil.isAnnotated(parm, toKeep, CHECK_TYPE)) { final String toAdd = isNotNull ? nullabilityManager.getDefaultNotNull() : nullabilityManager.getDefaultNullable(); final PsiAnnotation added = AddAnnotationPsiFix.addPhysicalAnnotation(toAdd, PsiNameValuePair.EMPTY_ARRAY, parm.getModifierList()); diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java index fa8a73052e8d..10dda6a77eb2 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java @@ -16,6 +16,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; import java.lang.reflect.Proxy; import java.util.*; @@ -224,56 +226,17 @@ public class AnnotationUtil { } } - public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NotNull Collection annotations) { - return isAnnotated(listOwner, annotations, false); - } - - public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, - @NotNull Collection annotations, - boolean checkHierarchy) { - return isAnnotated(listOwner, annotations, checkHierarchy, true); - } - - public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, - @NotNull Collection annotations, - boolean checkHierarchy, - boolean skipExternal) { - return annotations.stream().anyMatch(annotation -> isAnnotated(listOwner, annotation, checkHierarchy, skipExternal)); - } - - public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN, boolean checkHierarchy) { - return isAnnotated(listOwner, annotationFQN, checkHierarchy, true, true); - } - - public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, - @NotNull String annotationFQN, - boolean checkHierarchy, - boolean skipExternal) { - return isAnnotated(listOwner, annotationFQN, checkHierarchy, skipExternal, skipExternal); - } - - public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, - @NotNull String annotationFQN, - boolean checkHierarchy, - boolean skipExternal, - boolean skipInferred) { - int flags = CHECK_TYPE; - if (checkHierarchy) flags |= CHECK_HIERARCHY; - if (!skipExternal) flags |= CHECK_EXTERNAL; - if (!skipInferred) flags |= CHECK_INFERRED; - return isAnnotated(listOwner, annotationFQN, flags, null); - } - public static final int CHECK_HIERARCHY = 0x01; public static final int CHECK_EXTERNAL = 0x02; public static final int CHECK_INFERRED = 0x04; public static final int CHECK_TYPE = 0x08; @MagicConstant(flags = {CHECK_HIERARCHY, CHECK_EXTERNAL, CHECK_INFERRED, CHECK_TYPE}) + @Target(ElementType.TYPE_USE) public @interface Flags { } public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NotNull Collection annotations, @Flags int flags) { - return annotations.stream().anyMatch(annotation -> isAnnotated(listOwner, annotation, flags)); + return annotations.stream().anyMatch(annotation -> isAnnotated(listOwner, annotation, flags, null)); } public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFqn, @Flags int flags) { @@ -659,5 +622,55 @@ public class AnnotationUtil { public static boolean isJetbrainsAnnotation(@NotNull String simpleName) { return ArrayUtil.find(SIMPLE_NAMES, simpleName) != -1; } + + /** @deprecated use {@link #isAnnotated(PsiModifierListOwner, Collection, int)} (to be removed in IDEA 2019) */ + public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NotNull Collection annotations) { + return isAnnotated(listOwner, annotations, CHECK_TYPE); + } + + /** @deprecated use {@link #isAnnotated(PsiModifierListOwner, Collection, int)} (to be removed in IDEA 2019) */ + public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, + @NotNull Collection annotations, + boolean checkHierarchy) { + return isAnnotated(listOwner, annotations, flags(checkHierarchy, true, true)); + } + + /** @deprecated use {@link #isAnnotated(PsiModifierListOwner, Collection, int)} (to be removed in IDEA 2019) */ + public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, + @NotNull Collection annotations, + boolean checkHierarchy, + boolean skipExternal) { + return isAnnotated(listOwner, annotations, flags(checkHierarchy, skipExternal, skipExternal)); + } + + /** @deprecated use {@link #isAnnotated(PsiModifierListOwner, String, int)} (to be removed in IDEA 2019) */ + public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN, boolean checkHierarchy) { + return isAnnotated(listOwner, annotationFQN, flags(checkHierarchy, true, true)); + } + + /** @deprecated use {@link #isAnnotated(PsiModifierListOwner, String, int)} (to be removed in IDEA 2019) */ + public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, + @NotNull String annotationFQN, + boolean checkHierarchy, + boolean skipExternal) { + return isAnnotated(listOwner, annotationFQN, flags(checkHierarchy, skipExternal, skipExternal)); + } + + /** @deprecated use {@link #isAnnotated(PsiModifierListOwner, String, int)} (to be removed in IDEA 2019) */ + public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, + @NotNull String annotationFQN, + boolean checkHierarchy, + boolean skipExternal, + boolean skipInferred) { + return isAnnotated(listOwner, annotationFQN, flags(checkHierarchy, skipExternal, skipInferred)); + } + + private static @Flags int flags(boolean checkHierarchy, boolean skipExternal, boolean skipInferred) { + int flags = CHECK_TYPE; + if (checkHierarchy) flags |= CHECK_HIERARCHY; + if (!skipExternal) flags |= CHECK_EXTERNAL; + if (!skipInferred) flags |= CHECK_INFERRED; + return flags; + } // } \ No newline at end of file diff --git a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java index 48d7d3c76d4c..65445306f7c5 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2015 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. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight; import com.intellij.openapi.components.ServiceManager; @@ -28,6 +14,11 @@ import org.jetbrains.annotations.Nullable; import java.util.*; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_HIERARCHY; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_EXTERNAL; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_INFERRED; +import static com.intellij.codeInsight.AnnotationUtil.CHECK_TYPE; + /** * @author anna * @since 25.01.2011 @@ -38,15 +29,18 @@ public abstract class NullableNotNullManager { public String myDefaultNullable = AnnotationUtil.NULLABLE; public String myDefaultNotNull = AnnotationUtil.NOT_NULL; - public final JDOMExternalizableStringList myNullables = new JDOMExternalizableStringList(); - public final JDOMExternalizableStringList myNotNulls = new JDOMExternalizableStringList(); + @SuppressWarnings("deprecation") public final JDOMExternalizableStringList myNullables = new JDOMExternalizableStringList(); + @SuppressWarnings("deprecation") public final JDOMExternalizableStringList myNotNulls = new JDOMExternalizableStringList(); private static final String JAVAX_ANNOTATION_NULLABLE = "javax.annotation.Nullable"; protected static final String JAVAX_ANNOTATION_NONNULL = "javax.annotation.Nonnull"; - static final String[] DEFAULT_NULLABLES = {AnnotationUtil.NULLABLE, - JAVAX_ANNOTATION_NULLABLE, "javax.annotation.CheckForNull", - "edu.umd.cs.findbugs.annotations.Nullable", "android.support.annotation.Nullable" + static final String[] DEFAULT_NULLABLES = { + AnnotationUtil.NULLABLE, + JAVAX_ANNOTATION_NULLABLE, + "javax.annotation.CheckForNull", + "edu.umd.cs.findbugs.annotations.Nullable", + "android.support.annotation.Nullable" }; public NullableNotNullManager(Project project) { @@ -102,11 +96,11 @@ public abstract class NullableNotNullManager { return annotation == null ? null : annotation.getQualifiedName(); } - private String checkContainer(PsiAnnotation annotation, boolean acceptContainer) { + private String checkContainer(PsiAnnotation annotation) { if (annotation == null) { return null; } - if (!acceptContainer && isContainerAnnotation(annotation)) { + if (isContainerAnnotation(annotation)) { return null; } return annotation.getQualifiedName(); @@ -121,7 +115,7 @@ public abstract class NullableNotNullManager { PsiAnnotation.TargetType[] acceptAnyTarget = PsiAnnotation.TargetType.values(); return isNullabilityDefault(anno, true, acceptAnyTarget) || isNullabilityDefault(anno, false, acceptAnyTarget); } - + public void setDefaultNullable(@NotNull String defaultNullable) { LOG.assertTrue(getNullables().contains(defaultNullable)); myDefaultNullable = defaultNullable; @@ -131,7 +125,7 @@ public abstract class NullableNotNullManager { public String getDefaultNotNull() { return myDefaultNotNull; } - + @Nullable public PsiAnnotation getNotNullAnnotation(@NotNull PsiModifierListOwner owner, boolean checkBases) { return findNullabilityAnnotationWithDefault(owner, checkBases, false); @@ -158,7 +152,7 @@ public abstract class NullableNotNullManager { private PsiAnnotation copyAnnotation(PsiAnnotation annotation, PsiModifierListOwner target) { // type annotations are part of target's type and should not to be copied explicitly to avoid duplication if (annotation != null && !AnnotationTargetUtil.isTypeAnnotation(annotation)) { - String qualifiedName = checkContainer(annotation, false); + String qualifiedName = checkContainer(annotation); if (qualifiedName != null) { PsiModifierList modifierList = target.getModifierList(); if (modifierList != null && modifierList.findAnnotation(qualifiedName) == null) { @@ -181,7 +175,7 @@ public abstract class NullableNotNullManager { } private PsiAnnotation copyAnnotation(PsiModifierListOwner owner, PsiAnnotation annotation) { - String notNull = checkContainer(annotation, false); + String notNull = checkContainer(annotation); return notNull != null ? JavaPsiFacade.getElementFactory(owner.getProject()).createAnnotationFromText("@" + notNull, owner) : null; } @@ -196,7 +190,7 @@ public abstract class NullableNotNullManager { myDefaultNotNull = defaultNotNull; } - @Nullable + @Nullable private PsiAnnotation findNullabilityAnnotationWithDefault(@NotNull PsiModifierListOwner owner, boolean checkBases, boolean nullable) { PsiAnnotation annotation = findPlainNullabilityAnnotation(owner, checkBases); if (annotation != null) { @@ -213,7 +207,9 @@ public abstract class NullableNotNullManager { if (type == null || TypeConversionUtil.isPrimitiveAndNotNull(type)) return null; // even if javax.annotation.Nullable is not configured, it should still take precedence over ByDefault annotations - if (AnnotationUtil.isAnnotated(owner, nullable ? getPredefinedNotNulls() : Arrays.asList(DEFAULT_NULLABLES), checkBases, false)) { + List annotations = nullable ? getPredefinedNotNulls() : Arrays.asList(DEFAULT_NULLABLES); + int flags = (checkBases ? CHECK_HIERARCHY : 0) | CHECK_EXTERNAL | CHECK_INFERRED | CHECK_TYPE; + if (AnnotationUtil.isAnnotated(owner, annotations, flags)) { return null; } @@ -250,7 +246,7 @@ public abstract class NullableNotNullManager { PsiType type = getOwnerType(owner); if (memberAnno != null) { return preferTypeAnnotation(memberAnno, type); - } + } if (type != null) { return ContainerUtil.find(type.getAnnotations(), a -> qNames.contains(a.getQualifiedName())); } @@ -302,7 +298,7 @@ public abstract class NullableNotNullManager { return findNullabilityAnnotationWithDefault(owner, checkBases, false) != null; } - @Nullable + @Nullable static PsiAnnotation findNullabilityDefaultInHierarchy(PsiModifierListOwner owner, boolean nullable) { PsiAnnotation.TargetType[] placeTargetTypes = AnnotationTargetUtil.getTargetsForLocation(owner.getModifierList()); @@ -343,7 +339,7 @@ public abstract class NullableNotNullManager { if (!(declaration instanceof PsiClass)) return false; String fqn = nullable ? JAVAX_ANNOTATION_NULLABLE : JAVAX_ANNOTATION_NONNULL; - if (!AnnotationUtil.isAnnotated((PsiClass)declaration, fqn, false, true)) return false; + if (!AnnotationUtil.isAnnotated((PsiClass)declaration, fqn, CHECK_TYPE)) return false; PsiAnnotation tqDefault = AnnotationUtil.findAnnotation((PsiClass)declaration, true, "javax.annotation.meta.TypeQualifierDefault"); if (tqDefault == null) return false; diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/psi/AnnotatedTypeTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/psi/AnnotatedTypeTest.groovy index 430ced1f9b23..19a1d2ad27cb 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/psi/AnnotatedTypeTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/psi/AnnotatedTypeTest.groovy @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.java.codeInsight.psi import com.intellij.codeInsight.AnnotationUtil @@ -21,6 +7,8 @@ import com.intellij.psi.* import com.intellij.psi.impl.source.PsiImmediateClassType import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import static com.intellij.codeInsight.AnnotationUtil.CHECK_TYPE + class AnnotatedTypeTest extends LightCodeInsightFixtureTestCase { private PsiElementFactory factory private PsiElement context @@ -115,12 +103,12 @@ class AnnotatedTypeTest extends LightCodeInsightFixtureTestCase { void testIsAnnotated() { def unqualified = factory.createParameterFromText("@A @TA(1) String p", context) - assert AnnotationUtil.isAnnotated(unqualified, "pkg.A", false) - assert AnnotationUtil.isAnnotated(unqualified, "pkg.TA", false) + assert AnnotationUtil.isAnnotated(unqualified, "pkg.A", CHECK_TYPE) + assert AnnotationUtil.isAnnotated(unqualified, "pkg.TA", CHECK_TYPE) def qualified = factory.createParameterFromText("@A java.lang.@TA(1) String p", context) - assert AnnotationUtil.isAnnotated(qualified, "pkg.A", false) - assert AnnotationUtil.isAnnotated(qualified, "pkg.TA", false) + assert AnnotationUtil.isAnnotated(qualified, "pkg.A", CHECK_TYPE) + assert AnnotationUtil.isAnnotated(qualified, "pkg.TA", CHECK_TYPE) } private void doTest(String text, String annotated, String canonical) {