<commit_before>/*
 * Copyright 2000-2007 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;

import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
 * @author max
 */
public class AnnotationUtil {
  /**
   * The full qualified name of the standard Nullable annotation.
   */
  public static final String NULLABLE = "org.jetbrains.annotations.Nullable";

  /**
   * The full qualified name of the standard NotNull annotation.
   */
  public static final String NOT_NULL = "org.jetbrains.annotations.NotNull";

  @NonNls public static final String NOT_NULL_SIMPLE_NAME = "NotNull";

  @NonNls public static final String NULLABLE_SIMPLE_NAME = "Nullable";

  /**
   * The full qualified name of the standard NonNls annotation.
   *
   * @since 5.0.1
   */
  public static final String NON_NLS = "org.jetbrains.annotations.NonNls";
  public static final String NLS = "org.jetbrains.annotations.Nls";
  public static final String PROPERTY_KEY = "org.jetbrains.annotations.PropertyKey";
  @NonNls public static final String PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER = "resourceBundle";

  @NonNls public static final String NON_NLS_SIMPLE_NAME = "NonNls";
  @NonNls public static final String PROPERTY_KEY_SIMPLE_NAME = "PropertyKey";

  public static final String TEST_ONLY = "org.jetbrains.annotations.TestOnly";
  @NonNls public static final String TEST_ONLY_SIMPLE_NAME = "TestOnly";

  public static final Set<String> ALL_ANNOTATIONS;

  static {
    ALL_ANNOTATIONS = new HashSet<String>(2);
    ALL_ANNOTATIONS.add(NULLABLE);
    ALL_ANNOTATIONS.add(NOT_NULL);
  }

  public static boolean isNullable(PsiModifierListOwner owner) {
    return !isNotNull(owner) && isAnnotated(owner, NULLABLE, true);
  }

  public static boolean isNotNull(PsiModifierListOwner owner) {
    return isAnnotated(owner, NOT_NULL, true);
  }

  @Nullable
  public static PsiAnnotation findAnnotation(PsiModifierListOwner listOwner, String... annotationNames) {
    return findAnnotation(listOwner, new HashSet<String>(Arrays.asList(annotationNames)));
  }

  @Nullable
  public static PsiAnnotation findAnnotation(@Nullable PsiModifierListOwner listOwner, Set<String> annotationNames) {
    return findAnnotation(listOwner, (Collection<String>)annotationNames);
  }

  @Nullable
  public static PsiAnnotation findAnnotation(@Nullable PsiModifierListOwner listOwner, Collection<String> annotationNames) {
    final PsiAnnotation[] allAnnotations;
    if (listOwner instanceof PsiParameter) {
      allAnnotations = ((PsiParameter)listOwner).getAnnotations();
    }
    else {
      if (listOwner == null) return null;
      final PsiModifierList list = listOwner.getModifierList();
      if (list == null) return null;
      allAnnotations = list.getAnnotations();
    }
    for (PsiAnnotation annotation : allAnnotations) {
      String qualifiedName = annotation.getQualifiedName();
      if (annotationNames.contains(qualifiedName)) {
        return annotation;
      }
    }
    final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(listOwner.getProject());
    for (String annotationName : annotationNames) {
      final PsiAnnotation annotation = annotationsManager.findExternalAnnotation(listOwner, annotationName);
      if (annotation != null) {
        return annotation;
      }
    }
    return null;
  }

  @NotNull
  public static PsiAnnotation[] findAnnotations(final PsiMember psiMember, Collection<String> annotationNames) {
    if (psiMember == null) return PsiAnnotation.EMPTY_ARRAY;
    final PsiModifierList modifierList = psiMember.getModifierList();
    if (modifierList == null) return PsiAnnotation.EMPTY_ARRAY;
    final PsiAnnotation[] annotations = modifierList.getAnnotations();
    final ArrayList<PsiAnnotation> result = new ArrayList<PsiAnnotation>();
    for (final PsiAnnotation psiAnnotation : annotations) {
      if (annotationNames.contains(psiAnnotation.getQualifiedName())) {
        result.add(psiAnnotation);
      }
    }
    return result.isEmpty() ? PsiAnnotation.EMPTY_ARRAY : result.toArray(new PsiAnnotation[result.size()]);
  }

  @Nullable
  public static PsiAnnotation findAnnotationInHierarchy(PsiModifierListOwner listOwner, Set<String> annotationNames) {
    PsiAnnotation directAnnotation = findAnnotation(listOwner, annotationNames);
    if (directAnnotation != null) return directAnnotation;

    if (!(listOwner instanceof PsiMethod)) {
      return null;
    }
    PsiMethod method = (PsiMethod)listOwner;
    PsiClass aClass = method.getContainingClass();
    if (aClass == null) return null;
    HierarchicalMethodSignature methodSignature = method.getHierarchicalMethodSignature();
    return findAnnotationInHierarchy(methodSignature, annotationNames, method);
  }

  private static PsiAnnotation findAnnotationInHierarchy(HierarchicalMethodSignature signature,
                                                         Set<String> annotationNames,
                                                         PsiElement place) {
    List<HierarchicalMethodSignature> superSignatures = signature.getSuperSignatures();
    PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(place.getProject()).getResolveHelper();
    for (HierarchicalMethodSignature superSignature : superSignatures) {
      PsiMethod superMethod = superSignature.getMethod();
      if (!resolveHelper.isAccessible(superMethod, place, null)) continue;
      PsiAnnotation direct = findAnnotation(superMethod, annotationNames);
      if (direct != null) return direct;
      PsiAnnotation superResult = findAnnotationInHierarchy(superSignature, annotationNames, place);
      if (superResult != null) return superResult;
    }

    return null;
  }

  public static boolean isAnnotated(PsiModifierListOwner listOwner, Collection<String> annotations) {
    for (String annotation : annotations) {
      if (isAnnotated(listOwner, annotation, false)) return true;
    }
    return false;
  }

  public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NonNls String annotationFQN, boolean checkHierarchy) {
    return isAnnotated(listOwner, annotationFQN, checkHierarchy, new HashSet<PsiMethod>());
  }

  private static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NonNls String annotationFQN, boolean checkHierarchy, Set<PsiMethod> processed) {
    if (!listOwner.isValid()) return false;
    if (listOwner instanceof PsiParameter) {
      // this is more efficient than getting the modifier list
      PsiAnnotation[] paramAnnotations = ((PsiParameter)listOwner).getAnnotations();
      for (PsiAnnotation annotation : paramAnnotations) {
        if (annotationFQN.equals(annotation.getQualifiedName())) {
          return true;
        }
      }
    } else {
      final PsiModifierList modifierList = listOwner.getModifierList();
      if (modifierList == null) {
        return false;
      }
      PsiAnnotation annotation = modifierList.findAnnotation(annotationFQN);
      if (annotation != null) return true;
    }
    if (ExternalAnnotationsManager.getInstance(listOwner.getProject()).findExternalAnnotation(listOwner, annotationFQN) != null) return true;
    if (checkHierarchy && listOwner instanceof PsiMethod) {
      PsiMethod method = (PsiMethod)listOwner;
      if (processed.contains(method)) return false;
      processed.add(method);
      final PsiMethod[] superMethods = method.findSuperMethods();
      for (PsiMethod superMethod : superMethods) {
        if (isAnnotated(superMethod, annotationFQN, checkHierarchy, processed)) return true;
      }
    }
    return false;
  }

  public static boolean isAnnotatingApplicable(PsiElement elt) {
    return PsiUtil.getLanguageLevel(elt).compareTo(LanguageLevel.JDK_1_5) >= 0 &&
           JavaPsiFacade.getInstance(elt.getProject()).findClass(NULLABLE, elt.getResolveScope()) != null;
  }

  public static boolean isJetbrainsAnnotation(@NonNls final String simpleName) {
    return NOT_NULL_SIMPLE_NAME.equals(simpleName) || NULLABLE_SIMPLE_NAME.equals(simpleName) ||
           NON_NLS_SIMPLE_NAME.equals(simpleName) || PROPERTY_KEY_SIMPLE_NAME.equals(simpleName) ||
           TEST_ONLY_SIMPLE_NAME.equals(simpleName);
  }
}<commit_msg>don't search for @Test in external annotations (IDEADEV-26651)<commit_after>/*
 * Copyright 2000-2007 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;

import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
 * @author max
 */
public class AnnotationUtil {
  /**
   * The full qualified name of the standard Nullable annotation.
   */
  public static final String NULLABLE = "org.jetbrains.annotations.Nullable";

  /**
   * The full qualified name of the standard NotNull annotation.
   */
  public static final String NOT_NULL = "org.jetbrains.annotations.NotNull";

  @NonNls public static final String NOT_NULL_SIMPLE_NAME = "NotNull";

  @NonNls public static final String NULLABLE_SIMPLE_NAME = "Nullable";

  /**
   * The full qualified name of the standard NonNls annotation.
   *
   * @since 5.0.1
   */
  public static final String NON_NLS = "org.jetbrains.annotations.NonNls";
  public static final String NLS = "org.jetbrains.annotations.Nls";
  public static final String PROPERTY_KEY = "org.jetbrains.annotations.PropertyKey";
  @NonNls public static final String PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER = "resourceBundle";

  @NonNls public static final String NON_NLS_SIMPLE_NAME = "NonNls";
  @NonNls public static final String PROPERTY_KEY_SIMPLE_NAME = "PropertyKey";

  public static final String TEST_ONLY = "org.jetbrains.annotations.TestOnly";
  @NonNls public static final String TEST_ONLY_SIMPLE_NAME = "TestOnly";

  public static final Set<String> ALL_ANNOTATIONS;

  static {
    ALL_ANNOTATIONS = new HashSet<String>(2);
    ALL_ANNOTATIONS.add(NULLABLE);
    ALL_ANNOTATIONS.add(NOT_NULL);
  }

  public static boolean isNullable(PsiModifierListOwner owner) {
    return !isNotNull(owner) && isAnnotated(owner, NULLABLE, true);
  }

  public static boolean isNotNull(PsiModifierListOwner owner) {
    return isAnnotated(owner, NOT_NULL, true);
  }

  @Nullable
  public static PsiAnnotation findAnnotation(PsiModifierListOwner listOwner, String... annotationNames) {
    return findAnnotation(listOwner, false, annotationNames);
  }

  @Nullable
  public static PsiAnnotation findAnnotation(PsiModifierListOwner listOwner, final boolean skipExternal, String... annotationNames) {
    return findAnnotation(listOwner, new HashSet<String>(Arrays.asList(annotationNames)), skipExternal);
  }

  @Nullable
  public static PsiAnnotation findAnnotation(@Nullable PsiModifierListOwner listOwner, Set<String> annotationNames) {
    return findAnnotation(listOwner, (Collection<String>)annotationNames);
  }

  @Nullable
  public static PsiAnnotation findAnnotation(@Nullable PsiModifierListOwner listOwner, Collection<String> annotationNames) {
    return findAnnotation(listOwner, annotationNames, false);
  }

  @Nullable
  public static PsiAnnotation findAnnotation(@Nullable PsiModifierListOwner listOwner, Collection<String> annotationNames,
                                             final boolean skipExternal) {
    final PsiAnnotation[] allAnnotations;
    if (listOwner instanceof PsiParameter) {
      allAnnotations = ((PsiParameter)listOwner).getAnnotations();
    }
    else {
      if (listOwner == null) return null;
      final PsiModifierList list = listOwner.getModifierList();
      if (list == null) return null;
      allAnnotations = list.getAnnotations();
    }
    for (PsiAnnotation annotation : allAnnotations) {
      String qualifiedName = annotation.getQualifiedName();
      if (annotationNames.contains(qualifiedName)) {
        return annotation;
      }
    }
    if (!skipExternal) {
      final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(listOwner.getProject());
      for (String annotationName : annotationNames) {
        final PsiAnnotation annotation = annotationsManager.findExternalAnnotation(listOwner, annotationName);
        if (annotation != null) {
          return annotation;
        }
      }
    }
    return null;
  }

  @NotNull
  public static PsiAnnotation[] findAnnotations(final PsiMember psiMember, Collection<String> annotationNames) {
    if (psiMember == null) return PsiAnnotation.EMPTY_ARRAY;
    final PsiModifierList modifierList = psiMember.getModifierList();
    if (modifierList == null) return PsiAnnotation.EMPTY_ARRAY;
    final PsiAnnotation[] annotations = modifierList.getAnnotations();
    final ArrayList<PsiAnnotation> result = new ArrayList<PsiAnnotation>();
    for (final PsiAnnotation psiAnnotation : annotations) {
      if (annotationNames.contains(psiAnnotation.getQualifiedName())) {
        result.add(psiAnnotation);
      }
    }
    return result.isEmpty() ? PsiAnnotation.EMPTY_ARRAY : result.toArray(new PsiAnnotation[result.size()]);
  }

  @Nullable
  public static PsiAnnotation findAnnotationInHierarchy(PsiModifierListOwner listOwner, Set<String> annotationNames) {
    PsiAnnotation directAnnotation = findAnnotation(listOwner, annotationNames);
    if (directAnnotation != null) return directAnnotation;

    if (!(listOwner instanceof PsiMethod)) {
      return null;
    }
    PsiMethod method = (PsiMethod)listOwner;
    PsiClass aClass = method.getContainingClass();
    if (aClass == null) return null;
    HierarchicalMethodSignature methodSignature = method.getHierarchicalMethodSignature();
    return findAnnotationInHierarchy(methodSignature, annotationNames, method);
  }

  private static PsiAnnotation findAnnotationInHierarchy(HierarchicalMethodSignature signature,
                                                         Set<String> annotationNames,
                                                         PsiElement place) {
    List<HierarchicalMethodSignature> superSignatures = signature.getSuperSignatures();
    PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(place.getProject()).getResolveHelper();
    for (HierarchicalMethodSignature superSignature : superSignatures) {
      PsiMethod superMethod = superSignature.getMethod();
      if (!resolveHelper.isAccessible(superMethod, place, null)) continue;
      PsiAnnotation direct = findAnnotation(superMethod, annotationNames);
      if (direct != null) return direct;
      PsiAnnotation superResult = findAnnotationInHierarchy(superSignature, annotationNames, place);
      if (superResult != null) return superResult;
    }

    return null;
  }

  public static boolean isAnnotated(PsiModifierListOwner listOwner, Collection<String> annotations) {
    for (String annotation : annotations) {
      if (isAnnotated(listOwner, annotation, false)) return true;
    }
    return false;
  }

  public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NonNls String annotationFQN, boolean checkHierarchy) {
    return isAnnotated(listOwner, annotationFQN, checkHierarchy, false, new HashSet<PsiMethod>());
  }

  public static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner, @NonNls String annotationFQN, boolean checkHierarchy,
                                    boolean skipExternal) {
    return isAnnotated(listOwner, annotationFQN, checkHierarchy, skipExternal, new HashSet<PsiMethod>());
  }

  private static boolean isAnnotated(@NotNull PsiModifierListOwner listOwner,
                                     @NonNls String annotationFQN,
                                     boolean checkHierarchy, final boolean skipExternal, Set<PsiMethod> processed) {
    if (!listOwner.isValid()) return false;
    if (listOwner instanceof PsiParameter) {
      // this is more efficient than getting the modifier list
      PsiAnnotation[] paramAnnotations = ((PsiParameter)listOwner).getAnnotations();
      for (PsiAnnotation annotation : paramAnnotations) {
        if (annotationFQN.equals(annotation.getQualifiedName())) {
          return true;
        }
      }
    } else {
      final PsiModifierList modifierList = listOwner.getModifierList();
      if (modifierList == null) {
        return false;
      }
      PsiAnnotation annotation = modifierList.findAnnotation(annotationFQN);
      if (annotation != null) return true;
    }
    if (!skipExternal && ExternalAnnotationsManager.getInstance(listOwner.getProject()).findExternalAnnotation(listOwner, annotationFQN) != null) {
      return true;
    }
    if (checkHierarchy && listOwner instanceof PsiMethod) {
      PsiMethod method = (PsiMethod)listOwner;
      if (processed.contains(method)) return false;
      processed.add(method);
      final PsiMethod[] superMethods = method.findSuperMethods();
      for (PsiMethod superMethod : superMethods) {
        if (isAnnotated(superMethod, annotationFQN, checkHierarchy, skipExternal, processed)) return true;
      }
    }
    return false;
  }

  public static boolean isAnnotatingApplicable(PsiElement elt) {
    return PsiUtil.getLanguageLevel(elt).compareTo(LanguageLevel.JDK_1_5) >= 0 &&
           JavaPsiFacade.getInstance(elt.getProject()).findClass(NULLABLE, elt.getResolveScope()) != null;
  }

  public static boolean isJetbrainsAnnotation(@NonNls final String simpleName) {
    return NOT_NULL_SIMPLE_NAME.equals(simpleName) || NULLABLE_SIMPLE_NAME.equals(simpleName) ||
           NON_NLS_SIMPLE_NAME.equals(simpleName) || PROPERTY_KEY_SIMPLE_NAME.equals(simpleName) ||
           TEST_ONLY_SIMPLE_NAME.equals(simpleName);
  }
}
{'fraction_non_alphanumeric': 0.08613777824665049, 'fraction_numerical': 0.0022681717480746914, 'mean_word_length': 4.065188351589634, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 13, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '417271', 'n_tokens_mistral': 5245, 'n_tokens_neox': 5047, 'n_words': 1307}