<commit_before>package com.intellij.structuralsearch.impl.matcher;

import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.structuralsearch.MatchOptions;
import com.intellij.structuralsearch.MatchResult;
import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
import com.intellij.structuralsearch.impl.matcher.iterators.DocValuesIterator;
import com.intellij.structuralsearch.impl.matcher.iterators.HierarchyNodeIterator;
import com.intellij.dupLocator.iterators.NodeIterator;
import com.intellij.structuralsearch.impl.matcher.predicates.ExprTypePredicate;
import com.intellij.structuralsearch.impl.matcher.predicates.NotPredicate;
import com.intellij.structuralsearch.impl.matcher.predicates.RegExpPredicate;
import com.intellij.util.containers.ContainerUtil;

import java.util.*;

/**
 * @author Eugene.Kudelevsky
 */
public class JavaMatchingVisitor extends JavaElementVisitor {
  public static final String[] MODIFIERS = {
    PsiModifier.PUBLIC, PsiModifier.PROTECTED, PsiModifier.PRIVATE, PsiModifier.STATIC, PsiModifier.ABSTRACT, PsiModifier.FINAL,
    PsiModifier.NATIVE, PsiModifier.SYNCHRONIZED, PsiModifier.STRICTFP, PsiModifier.TRANSIENT, PsiModifier.VOLATILE
  };
  private final GlobalMatchingVisitor myMatchingVisitor;
  private PsiClass myClazz;

  static {
    Arrays.sort(MODIFIERS);
  }

  public JavaMatchingVisitor(GlobalMatchingVisitor matchingVisitor) {
    this.myMatchingVisitor = matchingVisitor;
  }

  @Override
  public void visitComment(PsiComment comment) {
    PsiElement comment2 = null;

    if (!(myMatchingVisitor.getElement() instanceof PsiComment)) {
      if (myMatchingVisitor.getElement() instanceof PsiMember) {
        final PsiElement[] children = myMatchingVisitor.getElement().getChildren();
        if (children[0] instanceof PsiComment) {
          comment2 = children[0];
        }
      }
    }
    else {
      comment2 = myMatchingVisitor.getElement();
    }

    if (comment2 == null) {
      myMatchingVisitor.setResult(false);
      return;
    }

    final Object userData = comment.getUserData(CompiledPattern.HANDLER_KEY);

    if (userData instanceof String) {
      String str = (String)userData;
      int end = comment2.getTextLength();

      if (((PsiComment)comment2).getTokenType() == JavaTokenType.C_STYLE_COMMENT) {
        end -= 2;
      }
      myMatchingVisitor.setResult(((SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(str)).handle(
        comment2,
        2,
        end,
        myMatchingVisitor.getMatchContext()
      ));
    }
    else if (userData instanceof MatchingHandler) {
      myMatchingVisitor.setResult(((MatchingHandler)userData).match(comment, comment2, myMatchingVisitor.getMatchContext()));
    }
    else {
      myMatchingVisitor.setResult(comment.getText().equals(comment2.getText()));
    }
  }

  @Override
  public void visitDocTagValue(final PsiDocTagValue value) {
    final PsiDocTagValue value2 = (PsiDocTagValue)myMatchingVisitor.getElement();
    final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(value);

    if (isTypedVar) {
      myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(value, value2));
    }
    else {
      myMatchingVisitor.setResult(value.textMatches(value2));
    }
  }

  private static boolean isNotInstanceModifier(final PsiModifierList list2) {
    return list2.hasModifierProperty("static") ||
           list2.hasModifierProperty("abstract");
  }

  @Override
  public final void visitModifierList(final PsiModifierList list) {
    final PsiModifierList list2 = (PsiModifierList)myMatchingVisitor.getElement();

    for (@Modifier String aMODIFIERS : MODIFIERS) {
      if (list.hasModifierProperty(aMODIFIERS) && !list2.hasModifierProperty(aMODIFIERS)) {
        myMatchingVisitor.setResult(false);
        return;
      }
    }

    final PsiAnnotation[] annotations = list.getAnnotations();
    if (annotations.length > 0) {
      HashSet<PsiAnnotation> set = new HashSet<PsiAnnotation>(Arrays.asList(annotations));

      for (PsiAnnotation annotation : annotations) {
        final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();

        if (nameReferenceElement != null && MatchOptions.MODIFIER_ANNOTATION_NAME.equals(nameReferenceElement.getText())) {
          final PsiAnnotationParameterList parameterList = annotation.getParameterList();
          final PsiNameValuePair[] attributes = parameterList.getAttributes();

          for (PsiNameValuePair pair : attributes) {
            final PsiAnnotationMemberValue value = pair.getValue();
            if (value == null) continue;

            if (value instanceof PsiArrayInitializerMemberValue) {
              boolean matchedOne = false;

              for (PsiAnnotationMemberValue v : ((PsiArrayInitializerMemberValue)value).getInitializers()) {
                final String name = StringUtil.stripQuotesAroundValue(v.getText());
                if (MatchOptions.INSTANCE_MODIFIER_NAME.equals(name)) {
                  if (isNotInstanceModifier(list2)) {
                    myMatchingVisitor.setResult(false);
                    return;
                  }
                  else {
                    matchedOne = true;
                  }
                }
                else if (list2.hasModifierProperty(name)) {
                  matchedOne = true;
                  break;
                }
              }

              if (!matchedOne) {
                myMatchingVisitor.setResult(false);
                return;
              }
            }
            else {
              final String name = StringUtil.stripQuotesAroundValue(value.getText());
              if (MatchOptions.INSTANCE_MODIFIER_NAME.equals(name)) {
                if (isNotInstanceModifier(list2)) {
                  myMatchingVisitor.setResult(false);
                  return;
                }
              }
              else if (!list2.hasModifierProperty(name)) {
                myMatchingVisitor.setResult(false);
                return;
              }
            }
          }

          set.remove(annotation);
        }
      }

      myMatchingVisitor.setResult(set.size() == 0 || myMatchingVisitor
        .matchInAnyOrder(set.toArray(new PsiAnnotation[set.size()]), list2.getAnnotations()));
    }
    else {
      myMatchingVisitor.setResult(true);<commit_msg>some methods annotated by MagicConstant annotations<commit_after>package com.intellij.structuralsearch.impl.matcher;

import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.structuralsearch.MatchOptions;
import com.intellij.structuralsearch.MatchResult;
import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
import com.intellij.structuralsearch.impl.matcher.iterators.DocValuesIterator;
import com.intellij.structuralsearch.impl.matcher.iterators.HierarchyNodeIterator;
import com.intellij.dupLocator.iterators.NodeIterator;
import com.intellij.structuralsearch.impl.matcher.predicates.ExprTypePredicate;
import com.intellij.structuralsearch.impl.matcher.predicates.NotPredicate;
import com.intellij.structuralsearch.impl.matcher.predicates.RegExpPredicate;
import com.intellij.util.containers.ContainerUtil;

import java.util.*;

/**
 * @author Eugene.Kudelevsky
 */
public class JavaMatchingVisitor extends JavaElementVisitor {
  public static final String[] MODIFIERS = {
    PsiModifier.PUBLIC, PsiModifier.PROTECTED, PsiModifier.PRIVATE, PsiModifier.STATIC, PsiModifier.ABSTRACT, PsiModifier.FINAL,
    PsiModifier.NATIVE, PsiModifier.SYNCHRONIZED, PsiModifier.STRICTFP, PsiModifier.TRANSIENT, PsiModifier.VOLATILE
  };
  private final GlobalMatchingVisitor myMatchingVisitor;
  private PsiClass myClazz;

  static {
    Arrays.sort(MODIFIERS);
  }

  public JavaMatchingVisitor(GlobalMatchingVisitor matchingVisitor) {
    this.myMatchingVisitor = matchingVisitor;
  }

  @Override
  public void visitComment(PsiComment comment) {
    PsiElement comment2 = null;

    if (!(myMatchingVisitor.getElement() instanceof PsiComment)) {
      if (myMatchingVisitor.getElement() instanceof PsiMember) {
        final PsiElement[] children = myMatchingVisitor.getElement().getChildren();
        if (children[0] instanceof PsiComment) {
          comment2 = children[0];
        }
      }
    }
    else {
      comment2 = myMatchingVisitor.getElement();
    }

    if (comment2 == null) {
      myMatchingVisitor.setResult(false);
      return;
    }

    final Object userData = comment.getUserData(CompiledPattern.HANDLER_KEY);

    if (userData instanceof String) {
      String str = (String)userData;
      int end = comment2.getTextLength();

      if (((PsiComment)comment2).getTokenType() == JavaTokenType.C_STYLE_COMMENT) {
        end -= 2;
      }
      myMatchingVisitor.setResult(((SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(str)).handle(
        comment2,
        2,
        end,
        myMatchingVisitor.getMatchContext()
      ));
    }
    else if (userData instanceof MatchingHandler) {
      myMatchingVisitor.setResult(((MatchingHandler)userData).match(comment, comment2, myMatchingVisitor.getMatchContext()));
    }
    else {
      myMatchingVisitor.setResult(comment.getText().equals(comment2.getText()));
    }
  }

  @Override
  public void visitDocTagValue(final PsiDocTagValue value) {
    final PsiDocTagValue value2 = (PsiDocTagValue)myMatchingVisitor.getElement();
    final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(value);

    if (isTypedVar) {
      myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(value, value2));
    }
    else {
      myMatchingVisitor.setResult(value.textMatches(value2));
    }
  }

  private static boolean isNotInstanceModifier(final PsiModifierList list2) {
    return list2.hasModifierProperty(PsiModifier.STATIC) ||
           list2.hasModifierProperty(PsiModifier.ABSTRACT);
  }

  @Override
  public final void visitModifierList(final PsiModifierList list) {
    final PsiModifierList list2 = (PsiModifierList)myMatchingVisitor.getElement();

    for (@PsiModifier.ModifierConstant String aMODIFIERS : MODIFIERS) {
      if (list.hasModifierProperty(aMODIFIERS) && !list2.hasModifierProperty(aMODIFIERS)) {
        myMatchingVisitor.setResult(false);
        return;
      }
    }

    final PsiAnnotation[] annotations = list.getAnnotations();
    if (annotations.length > 0) {
      HashSet<PsiAnnotation> set = new HashSet<PsiAnnotation>(Arrays.asList(annotations));

      for (PsiAnnotation annotation : annotations) {
        final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();

        if (nameReferenceElement != null && MatchOptions.MODIFIER_ANNOTATION_NAME.equals(nameReferenceElement.getText())) {
          final PsiAnnotationParameterList parameterList = annotation.getParameterList();
          final PsiNameValuePair[] attributes = parameterList.getAttributes();

          for (PsiNameValuePair pair : attributes) {
            final PsiAnnotationMemberValue value = pair.getValue();
            if (value == null) continue;

            if (value instanceof PsiArrayInitializerMemberValue) {
              boolean matchedOne = false;

              for (PsiAnnotationMemberValue v : ((PsiArrayInitializerMemberValue)value).getInitializers()) {
                @PsiModifier.ModifierConstant String name = StringUtil.stripQuotesAroundValue(v.getText());
                if (MatchOptions.INSTANCE_MODIFIER_NAME.equals(name)) {
                  if (isNotInstanceModifier(list2)) {
                    myMatchingVisitor.setResult(false);
                    return;
                  }
                  else {
                    matchedOne = true;
                  }
                }
                else if (list2.hasModifierProperty(name)) {
                  matchedOne = true;
                  break;
                }
              }

              if (!matchedOne) {
                myMatchingVisitor.setResult(false);
                return;
              }
            }
            else {
              @PsiModifier.ModifierConstant String name = StringUtil.stripQuotesAroundValue(value.getText());
              if (MatchOptions.INSTANCE_MODIFIER_NAME.equals(name)) {
                if (isNotInstanceModifier(list2)) {
                  myMatchingVisitor.setResult(false);
                  return;
                }
              }
              else if (!list2.hasModifierProperty(name)) {
                myMatchingVisitor.setResult(false);
                return;
              }
            }
          }

          set.remove(annotation);
        }
      }

      myMatchingVisitor.setResult(set.size() == 0 || myMatchingVisitor
        .matchInAnyOrder(set.toArray(new PsiAnnotation[set.size()]), list2.getAnnotations()));
    }
    else {
      myMatchingVisitor.setResult(true);
{'fraction_non_alphanumeric': 0.09427394146064223, 'fraction_numerical': 0.003978402955385053, 'mean_word_length': 3.11007299270073, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3026381', 'n_tokens_mistral': 4035, 'n_tokens_neox': 3927, 'n_words': 610}