<commit_before>package com.intellij.refactoring.move.moveClassesOrPackages;

import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.move.MoveCallback;
import com.intellij.refactoring.move.MoveClassesOrPackagesCallback;
import com.intellij.refactoring.util.*;
import com.intellij.refactoring.util.classRefs.ClassInstanceScanner;
import com.intellij.refactoring.util.classRefs.ClassReferenceScanner;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;

import java.util.*;

/**
 * @author Jeka,dsl
 */
public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor {
  private static final Logger LOG = Logger.getInstance(
    "#com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor");

  private PsiElement[] myElementsToMove;
  private boolean mySearchInComments;
  private boolean mySearchInNonJavaFiles;
  private PackageWrapper myTargetPackage;
  private MoveCallback myMoveCallback;
  private final MoveDestination myMoveDestination;
  private NonCodeUsageInfo[] myNonCodeUsages;

  public MoveClassesOrPackagesProcessor(
    Project project,
    PsiElement[] elements,
    final MoveDestination moveDestination,
    boolean searchInComments,
    boolean searchInNonJavaFiles,
    MoveCallback moveCallback) {
    super(project);
    myElementsToMove = elements;
    myMoveDestination = moveDestination;
    myTargetPackage = myMoveDestination.getTargetPackage();
    mySearchInComments = searchInComments;
    mySearchInNonJavaFiles = searchInNonJavaFiles;
    myMoveCallback = moveCallback;
  }

  protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
    PsiElement[] elements = new PsiElement[myElementsToMove.length];
    System.arraycopy(myElementsToMove, 0, elements, 0, myElementsToMove.length);
    return new MoveClassesOrPackagesViewDescriptor(elements, mySearchInComments, mySearchInNonJavaFiles, myTargetPackage
    );
  }

  public boolean isSearchInComments() {
    return mySearchInComments;
  }

  public boolean isSearchInNonJavaFiles() {
    return mySearchInNonJavaFiles;
  }

  public void setSearchInComments(boolean searchInComments) {
    mySearchInComments = searchInComments;
  }

  public void setSearchInNonJavaFiles(boolean searchInNonJavaFiles) {
    mySearchInNonJavaFiles = searchInNonJavaFiles;
  }


  @NotNull
  protected UsageInfo[] findUsages() {
    List<UsageInfo> allUsages = new ArrayList<UsageInfo>();
    ArrayList<String> conflicts = new ArrayList<String>();
    for (PsiElement element : myElementsToMove) {
      String newName = getNewQName(element);
      final UsageInfo[] usages = MoveClassesOrPackagesUtil.findUsages(element, mySearchInComments,
                                                                      mySearchInNonJavaFiles, newName);
      ArrayList<UsageInfo> usageInfos = new ArrayList<UsageInfo>(Arrays.asList(usages));
      allUsages.addAll(usageInfos);
    }
    myMoveDestination.analyzeModuleConflicts(Arrays.asList(myElementsToMove), conflicts,
                                             allUsages.toArray(new UsageInfo[allUsages.size()]));
    final UsageInfo[] usageInfos = allUsages.toArray(new UsageInfo[allUsages.size()]);
    detectPackageLocalsMoved(usageInfos, conflicts);
    detectPackageLocalsUsed(conflicts);
    if (conflicts.size() > 0) {
      allUsages.add(new ConflictsUsageInfo(myElementsToMove[0], conflicts));
    }

    return UsageViewUtil.removeDuplicatedUsages(allUsages.toArray(new UsageInfo[allUsages.size()]));
  }

  public List<PsiElement> getElements() {
    return Collections.unmodifiableList(Arrays.asList(myElementsToMove));
  }

  public PackageWrapper getTargetPackage() {
    return myMoveDestination.getTargetPackage();
  }

  private static class ConflictsUsageInfo extends UsageInfo {
    private final ArrayList<String> myConflicts;

    public ConflictsUsageInfo(PsiElement pseudoElement, ArrayList<String> conflicts) {
      super(pseudoElement);
      myConflicts = conflicts;
    }

    public ArrayList<String> getConflicts() {
      return myConflicts;
    }
  }



  protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
    final UsageInfo[] usages = refUsages.get();
    final ArrayList<String> conflicts = new ArrayList<String>();
    ArrayList<UsageInfo> filteredUsages = new ArrayList<UsageInfo>();
    for (UsageInfo usage : usages) {
      if (usage instanceof ConflictsUsageInfo) {
        conflicts.addAll(((ConflictsUsageInfo)usage).getConflicts());
      }
      else {
        filteredUsages.add(usage);
      }
    }

    refUsages.set(filteredUsages.toArray(new UsageInfo[filteredUsages.size()]));
    return showConflicts(conflicts);
  }

  private boolean isInsideMoved(PsiElement place) {
    for (PsiElement element : myElementsToMove) {
      if (element instanceof PsiClass) {
        if (PsiTreeUtil.isAncestor(element, place, false)) return true;
      }
    }
    return false;
  }

  private class PackageLocalsVisitor extends PsiRecursiveElementVisitor {
    private HashMap<PsiElement,HashSet<PsiElement>> myReported = new HashMap<PsiElement, HashSet<PsiElement>>();
    private final ArrayList<String> myConflicts;

    public PackageLocalsVisitor(ArrayList<String> conflicts) {
      myConflicts = conflicts;
    }

    public void visitReferenceExpression(PsiReferenceExpression expression) {
      visitReferenceElement(expression);
    }

    public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
      PsiElement resolved = reference.resolve();
      visitResolvedReference(resolved, reference);
    }


    private void visitResolvedReference(PsiElement resolved, PsiJavaCodeReferenceElement reference) {
      if (resolved instanceof PsiModifierListOwner) {<commit_msg>IDEADEV-13089<commit_after>package com.intellij.refactoring.move.moveClassesOrPackages;

import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.move.MoveCallback;
import com.intellij.refactoring.move.MoveClassesOrPackagesCallback;
import com.intellij.refactoring.util.*;
import com.intellij.refactoring.util.classRefs.ClassInstanceScanner;
import com.intellij.refactoring.util.classRefs.ClassReferenceScanner;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;

import java.util.*;

/**
 * @author Jeka,dsl
 */
public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor {
  private static final Logger LOG = Logger.getInstance(
    "#com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor");

  private PsiElement[] myElementsToMove;
  private boolean mySearchInComments;
  private boolean mySearchInNonJavaFiles;
  private PackageWrapper myTargetPackage;
  private MoveCallback myMoveCallback;
  private final MoveDestination myMoveDestination;
  private NonCodeUsageInfo[] myNonCodeUsages;

  public MoveClassesOrPackagesProcessor(
    Project project,
    PsiElement[] elements,
    final MoveDestination moveDestination,
    boolean searchInComments,
    boolean searchInNonJavaFiles,
    MoveCallback moveCallback) {
    super(project);
    myElementsToMove = elements;
    myMoveDestination = moveDestination;
    myTargetPackage = myMoveDestination.getTargetPackage();
    mySearchInComments = searchInComments;
    mySearchInNonJavaFiles = searchInNonJavaFiles;
    myMoveCallback = moveCallback;
  }

  protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
    PsiElement[] elements = new PsiElement[myElementsToMove.length];
    System.arraycopy(myElementsToMove, 0, elements, 0, myElementsToMove.length);
    return new MoveClassesOrPackagesViewDescriptor(elements, mySearchInComments, mySearchInNonJavaFiles, myTargetPackage
    );
  }

  public boolean isSearchInComments() {
    return mySearchInComments;
  }

  public boolean isSearchInNonJavaFiles() {
    return mySearchInNonJavaFiles;
  }

  public void setSearchInComments(boolean searchInComments) {
    mySearchInComments = searchInComments;
  }

  public void setSearchInNonJavaFiles(boolean searchInNonJavaFiles) {
    mySearchInNonJavaFiles = searchInNonJavaFiles;
  }


  @NotNull
  protected UsageInfo[] findUsages() {
    List<UsageInfo> allUsages = new ArrayList<UsageInfo>();
    ArrayList<String> conflicts = new ArrayList<String>();
    for (PsiElement element : myElementsToMove) {
      String newName = getNewQName(element);
      final UsageInfo[] usages = MoveClassesOrPackagesUtil.findUsages(element, mySearchInComments,
                                                                      mySearchInNonJavaFiles, newName);
      allUsages.addAll(new ArrayList<UsageInfo>(Arrays.asList(usages)));
    }
    myMoveDestination.analyzeModuleConflicts(Arrays.asList(myElementsToMove), conflicts,
                                             allUsages.toArray(new UsageInfo[allUsages.size()]));
    final UsageInfo[] usageInfos = allUsages.toArray(new UsageInfo[allUsages.size()]);
    detectPackageLocalsMoved(usageInfos, conflicts);
    detectPackageLocalsUsed(conflicts);
    if (conflicts.size() > 0) {
      allUsages.add(new ConflictsUsageInfo(myElementsToMove[0], conflicts));
    }

    return UsageViewUtil.removeDuplicatedUsages(allUsages.toArray(new UsageInfo[allUsages.size()]));
  }

  public List<PsiElement> getElements() {
    return Collections.unmodifiableList(Arrays.asList(myElementsToMove));
  }

  public PackageWrapper getTargetPackage() {
    return myMoveDestination.getTargetPackage();
  }

  private static class ConflictsUsageInfo extends UsageInfo {
    private final ArrayList<String> myConflicts;

    public ConflictsUsageInfo(PsiElement pseudoElement, ArrayList<String> conflicts) {
      super(pseudoElement);
      myConflicts = conflicts;
    }

    public ArrayList<String> getConflicts() {
      return myConflicts;
    }
  }



  protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
    final UsageInfo[] usages = refUsages.get();
    final ArrayList<String> conflicts = new ArrayList<String>();
    ArrayList<UsageInfo> filteredUsages = new ArrayList<UsageInfo>();
    for (UsageInfo usage : usages) {
      if (usage instanceof ConflictsUsageInfo) {
        conflicts.addAll(((ConflictsUsageInfo)usage).getConflicts());
      }
      else {
        filteredUsages.add(usage);
      }
    }

    refUsages.set(filteredUsages.toArray(new UsageInfo[filteredUsages.size()]));
    return showConflicts(conflicts);
  }

  private boolean isInsideMoved(PsiElement place) {
    for (PsiElement element : myElementsToMove) {
      if (element instanceof PsiClass) {
        if (PsiTreeUtil.isAncestor(element, place, false)) return true;
      }
    }
    return false;
  }

  private class PackageLocalsVisitor extends PsiRecursiveElementVisitor {
    private HashMap<PsiElement,HashSet<PsiElement>> myReported = new HashMap<PsiElement, HashSet<PsiElement>>();
    private final ArrayList<String> myConflicts;

    public PackageLocalsVisitor(ArrayList<String> conflicts) {
      myConflicts = conflicts;
    }

    public void visitReferenceExpression(PsiReferenceExpression expression) {
      super.visitReferenceExpression(expression);
      visitReferenceElement(expression);
    }

    public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
      super.visitReferenceElement(reference);
      PsiElement resolved = reference.resolve();
      visitResolvedReference(resolved, reference);
    }


    private void visitResolvedReference(PsiElement resolved, PsiJavaCodeReferenceElement reference) {
      if (resolved instanceof PsiModifierListOwner) {
{'fraction_non_alphanumeric': 0.08487221155266657, 'fraction_numerical': 0.0009602600088639386, 'mean_word_length': 4.7958047945205475, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '539861', 'n_tokens_mistral': 3918, 'n_tokens_neox': 3794, 'n_words': 691}