<commit_before>// Copyright 2000-2018 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.ide.scopeView;

import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.SelectInTarget;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.ProjectViewSettings;
import com.intellij.ide.projectView.impl.AbstractProjectViewPane;
import com.intellij.ide.projectView.impl.CompoundProjectViewNodeDecorator;
import com.intellij.ide.projectView.impl.CompoundTreeStructureProvider;
import com.intellij.ide.projectView.impl.ProjectViewTree;
import com.intellij.ide.projectView.impl.ShowModulesAction;
import com.intellij.ide.ui.customization.CustomizationUtil;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.ide.util.treeView.TreeState;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.openapi.vcs.changes.ChangeListAdapter;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packageDependencies.ChangeListScope;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.scope.packageSet.NamedScopeManager;
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
import com.intellij.ui.stripe.ErrorStripePainter;
import com.intellij.ui.stripe.TreeUpdater;
import com.intellij.ui.tree.AsyncTreeModel;
import com.intellij.ui.tree.TreeVisitor;
import com.intellij.util.EditSourceOnDoubleClickHandler;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.tree.TreePath;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

import static com.intellij.ui.ScrollPaneFactory.createScrollPane;
import static com.intellij.util.ArrayUtilRt.EMPTY_STRING_ARRAY;
import static com.intellij.util.concurrency.EdtExecutorService.getScheduledExecutorInstance;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

public final class ScopeViewPane extends AbstractProjectViewPane {
  @NonNls public static final String ID = "Scope";
  private static final Logger LOG = Logger.getInstance(ScopeViewPane.class);
  private final NamedScopesHolder myDependencyValidationManager;
  private final NamedScopesHolder myNamedScopeManager;
  private final NamedScopesHolder.ScopeListener myScopeListener = new NamedScopesHolder.ScopeListener() {
    private final AtomicLong counter = new AtomicLong();

    @Override
    public void scopesChanged() {
      if (myProject.isDisposed()) return;
      long count = counter.incrementAndGet();
      getScheduledExecutorInstance().schedule(() -> {
        // is this request still actual after 10 ms?
        if (count == counter.get()) {
          ProjectView view = myProject.isDisposed() ? null : ProjectView.getInstance(myProject);
          if (view == null) return;
          myFilters = map(myDependencyValidationManager, myNamedScopeManager);
          String currentId = view.getCurrentViewId();
          String currentSubId = getSubId();
          // update changes subIds if needed
          view.removeProjectPane(ScopeViewPane.this);
          view.addProjectPane(ScopeViewPane.this);
          if (currentId == null) return;
          if (currentId.equals(getId())) {
            // try to restore selected subId
            view.changeView(currentId, currentSubId);
          }
          else {
            view.changeView(currentId);
          }
        }
      }, 10, MILLISECONDS);
    }
  };
  private final ScopeViewTreeModel myTreeModel;
  private final AsyncTreeModel myAsyncTreeModel;
  private LinkedHashMap<String, NamedScopeFilter> myFilters;
  private JScrollPane myScrollPane;

  public ScopeViewPane(@NotNull Project project, @NotNull DependencyValidationManager dvm, @NotNull NamedScopeManager nsm) {
    super(project);
    myDependencyValidationManager = dvm;
    myNamedScopeManager = nsm;
    myFilters = map(myDependencyValidationManager, myNamedScopeManager);
    myTreeModel = new ScopeViewTreeModel(project, new ProjectViewSettings.Delegate(project, ID));
    myTreeModel.setStructureProvider(CompoundTreeStructureProvider.get(project));
    myTreeModel.setNodeDecorator(CompoundProjectViewNodeDecorator.get(project));
    myAsyncTreeModel = new AsyncTreeModel(myTreeModel, true, this);
    myDependencyValidationManager.addScopeListener(myScopeListener);
    myNamedScopeManager.addScopeListener(myScopeListener);
    ChangeListManager.getInstance(project).addChangeListListener(new ChangeListAdapter() {
      @Override
      public void changeListAdded(ChangeList list) {
        myDependencyValidationManager.fireScopeListeners();
      }

      @Override
      public void changeListRemoved(ChangeList list) {
        myDependencyValidationManager.fireScopeListeners();
      }

      @Override
      public void changeListRenamed(ChangeList list, String name) {
        myDependencyValidationManager.fireScopeListeners();
      }

      @Override
      public void changeListsChanged() {
        NamedScopeFilter filter = myTreeModel.getFilter();
        if (filter != null && filter.getScope() instanceof ChangeListScope) {
          myTreeModel.setFilter(filter);
        }
      }
    }, this);
    installComparator();
  }

  @Override
  public void dispose() {
    JTree tree = myTree;
    if (tree != null) tree.setModel(null);
    myDependencyValidationManager.removeScopeListener(myScopeListener);
    myNamedScopeManager.removeScopeListener(myScopeListener);
    super.dispose();
  }

  @NotNull
  @Override
  public String getId() {
    return ID;
  }

  @Override
  public int getWeight() {
    return 4;
  }

  @Override
  public String getTitle() {
    return IdeBundle.message("scope.view.title");
  }

  @Override
  public Icon getIcon() {
    return AllIcons.Ide.LocalScope;
  }

  @Override
  public JComponent createComponent() {
    onSubIdChange();
    if (myTree == null) {
      myTree = new ProjectViewTree(myAsyncTreeModel);
      myTree.setName("ScopeViewTree");
      myTree.setRootVisible(false);
      myTree.setShowsRootHandles(true);
      TreeUtil.installActions(myTree);
      ToolTipManager.sharedInstance().registerComponent(myTree);
      EditSourceOnDoubleClickHandler.install(myTree);
      CustomizationUtil.installPopupHandler(myTree, IdeActions.GROUP_SCOPE_VIEW_POPUP, ActionPlaces.SCOPE_VIEW_POPUP);
      enableDnD();
    }
    if (myScrollPane == null) {
      myScrollPane = createScrollPane(myTree, true);
      ErrorStripePainter painter = new ErrorStripePainter(true);
      Disposer.register(this, new TreeUpdater<ErrorStripePainter>(painter, myScrollPane, myTree) {
        @Override
        protected void update(ErrorStripePainter painter, int index, Object object) {
          super.update(painter, index, myTreeModel.getStripe(object, myTree.isExpanded(index)));
        }
      });<commit_msg>ScopeView: add speed search<commit_after>// Copyright 2000-2018 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.ide.scopeView;

import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.SelectInTarget;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.ProjectViewSettings;
import com.intellij.ide.projectView.impl.AbstractProjectViewPane;
import com.intellij.ide.projectView.impl.CompoundProjectViewNodeDecorator;
import com.intellij.ide.projectView.impl.CompoundTreeStructureProvider;
import com.intellij.ide.projectView.impl.ProjectViewTree;
import com.intellij.ide.projectView.impl.ShowModulesAction;
import com.intellij.ide.ui.customization.CustomizationUtil;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.ide.util.treeView.TreeState;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.openapi.vcs.changes.ChangeListAdapter;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packageDependencies.ChangeListScope;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.scope.packageSet.NamedScopeManager;
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.stripe.ErrorStripePainter;
import com.intellij.ui.stripe.TreeUpdater;
import com.intellij.ui.tree.AsyncTreeModel;
import com.intellij.ui.tree.TreeVisitor;
import com.intellij.util.EditSourceOnDoubleClickHandler;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.tree.TreePath;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

import static com.intellij.ui.ScrollPaneFactory.createScrollPane;
import static com.intellij.util.ArrayUtilRt.EMPTY_STRING_ARRAY;
import static com.intellij.util.concurrency.EdtExecutorService.getScheduledExecutorInstance;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

public final class ScopeViewPane extends AbstractProjectViewPane {
  @NonNls public static final String ID = "Scope";
  private static final Logger LOG = Logger.getInstance(ScopeViewPane.class);
  private final NamedScopesHolder myDependencyValidationManager;
  private final NamedScopesHolder myNamedScopeManager;
  private final NamedScopesHolder.ScopeListener myScopeListener = new NamedScopesHolder.ScopeListener() {
    private final AtomicLong counter = new AtomicLong();

    @Override
    public void scopesChanged() {
      if (myProject.isDisposed()) return;
      long count = counter.incrementAndGet();
      getScheduledExecutorInstance().schedule(() -> {
        // is this request still actual after 10 ms?
        if (count == counter.get()) {
          ProjectView view = myProject.isDisposed() ? null : ProjectView.getInstance(myProject);
          if (view == null) return;
          myFilters = map(myDependencyValidationManager, myNamedScopeManager);
          String currentId = view.getCurrentViewId();
          String currentSubId = getSubId();
          // update changes subIds if needed
          view.removeProjectPane(ScopeViewPane.this);
          view.addProjectPane(ScopeViewPane.this);
          if (currentId == null) return;
          if (currentId.equals(getId())) {
            // try to restore selected subId
            view.changeView(currentId, currentSubId);
          }
          else {
            view.changeView(currentId);
          }
        }
      }, 10, MILLISECONDS);
    }
  };
  private final ScopeViewTreeModel myTreeModel;
  private final AsyncTreeModel myAsyncTreeModel;
  private LinkedHashMap<String, NamedScopeFilter> myFilters;
  private JScrollPane myScrollPane;

  public ScopeViewPane(@NotNull Project project, @NotNull DependencyValidationManager dvm, @NotNull NamedScopeManager nsm) {
    super(project);
    myDependencyValidationManager = dvm;
    myNamedScopeManager = nsm;
    myFilters = map(myDependencyValidationManager, myNamedScopeManager);
    myTreeModel = new ScopeViewTreeModel(project, new ProjectViewSettings.Delegate(project, ID));
    myTreeModel.setStructureProvider(CompoundTreeStructureProvider.get(project));
    myTreeModel.setNodeDecorator(CompoundProjectViewNodeDecorator.get(project));
    myAsyncTreeModel = new AsyncTreeModel(myTreeModel, true, this);
    myDependencyValidationManager.addScopeListener(myScopeListener);
    myNamedScopeManager.addScopeListener(myScopeListener);
    ChangeListManager.getInstance(project).addChangeListListener(new ChangeListAdapter() {
      @Override
      public void changeListAdded(ChangeList list) {
        myDependencyValidationManager.fireScopeListeners();
      }

      @Override
      public void changeListRemoved(ChangeList list) {
        myDependencyValidationManager.fireScopeListeners();
      }

      @Override
      public void changeListRenamed(ChangeList list, String name) {
        myDependencyValidationManager.fireScopeListeners();
      }

      @Override
      public void changeListsChanged() {
        NamedScopeFilter filter = myTreeModel.getFilter();
        if (filter != null && filter.getScope() instanceof ChangeListScope) {
          myTreeModel.setFilter(filter);
        }
      }
    }, this);
    installComparator();
  }

  @Override
  public void dispose() {
    JTree tree = myTree;
    if (tree != null) tree.setModel(null);
    myDependencyValidationManager.removeScopeListener(myScopeListener);
    myNamedScopeManager.removeScopeListener(myScopeListener);
    super.dispose();
  }

  @NotNull
  @Override
  public String getId() {
    return ID;
  }

  @Override
  public int getWeight() {
    return 4;
  }

  @Override
  public String getTitle() {
    return IdeBundle.message("scope.view.title");
  }

  @Override
  public Icon getIcon() {
    return AllIcons.Ide.LocalScope;
  }

  @Override
  public JComponent createComponent() {
    onSubIdChange();
    if (myTree == null) {
      myTree = new ProjectViewTree(myAsyncTreeModel);
      myTree.setName("ScopeViewTree");
      myTree.setRootVisible(false);
      myTree.setShowsRootHandles(true);
      TreeUtil.installActions(myTree);
      ToolTipManager.sharedInstance().registerComponent(myTree);
      EditSourceOnDoubleClickHandler.install(myTree);
      CustomizationUtil.installPopupHandler(myTree, IdeActions.GROUP_SCOPE_VIEW_POPUP, ActionPlaces.SCOPE_VIEW_POPUP);
      new TreeSpeedSearch(myTree);
      enableDnD();
    }
    if (myScrollPane == null) {
      myScrollPane = createScrollPane(myTree, true);
      ErrorStripePainter painter = new ErrorStripePainter(true);
      Disposer.register(this, new TreeUpdater<ErrorStripePainter>(painter, myScrollPane, myTree) {
        @Override
        protected void update(ErrorStripePainter painter, int index, Object object) {
          super.update(painter, index, myTreeModel.getStripe(object, myTree.isExpanded(index)));
        }
      });
{'fraction_non_alphanumeric': 0.09120070444682056, 'fraction_numerical': 0.0018869111264859426, 'mean_word_length': 4.492227979274611, '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': '7060190', 'n_tokens_mistral': 4672, 'n_tokens_neox': 4609, 'n_words': 847}