Package com.jetbrains.lang.dart.ide.index

Source Code of com.jetbrains.lang.dart.ide.index.DartInheritanceIndex$MyDataIndexer

package com.jetbrains.lang.dart.ide.index;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.DefinitionsScopedSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
import com.intellij.util.indexing.*;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.KeyDescriptor;
import com.jetbrains.lang.dart.DartComponentType;
import com.jetbrains.lang.dart.psi.DartClass;
import com.jetbrains.lang.dart.psi.DartComponent;
import com.jetbrains.lang.dart.psi.DartComponentName;
import com.jetbrains.lang.dart.util.DartResolveUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;

import java.util.*;

/**
* @author: Fedor.Korotkov
*/
public class DartInheritanceIndex extends FileBasedIndexExtension<String, List<DartComponentInfo>> {
  public static final ID<String, List<DartComponentInfo>> DART_INHERITANCE_INDEX = ID.create("DartInheritanceIndex");
  private static final int INDEX_VERSION = 2;
  private final DataIndexer<String, List<DartComponentInfo>, FileContent> myIndexer = new MyDataIndexer();
  private final DataExternalizer<List<DartComponentInfo>> myExternalizer = new DartComponentInfoListExternalizer();

  @NotNull
  @Override
  public ID<String, List<DartComponentInfo>> getName() {
    return DART_INHERITANCE_INDEX;
  }

  @Override
  public int getVersion() {
    return DartIndexUtil.BASE_VERSION + INDEX_VERSION;
  }

  @Override
  public boolean dependsOnFileContent() {
    return true;
  }

  @NotNull
  @Override
  public KeyDescriptor<String> getKeyDescriptor() {
    return new EnumeratorStringDescriptor();
  }

  @NotNull
  @Override
  public DataExternalizer<List<DartComponentInfo>> getValueExternalizer() {
    return myExternalizer;
  }

  @NotNull
  @Override
  public FileBasedIndex.InputFilter getInputFilter() {
    return DartInputFilter.INSTANCE;
  }

  @NotNull
  @Override
  public DataIndexer<String, List<DartComponentInfo>, FileContent> getIndexer() {
    return myIndexer;
  }

  private static class MyDataIndexer implements DataIndexer<String, List<DartComponentInfo>, FileContent> {
    @Override
    @NotNull
    public Map<String, List<DartComponentInfo>> map(@NotNull final FileContent inputData) {
      return DartIndexUtil.indexFile(inputData).getInheritorsMap();
    }
  }

  public static List<DartClass> getItemsByName(final DartClass dartClass) {
    final List<DartClass> result = new ArrayList<DartClass>();
    DefinitionsScopedSearch.search(dartClass).forEach(new Processor<PsiElement>() {
      @Override
      public boolean process(PsiElement element) {
        if (element instanceof DartClass) {
          result.add((DartClass)element);
        }
        return true;
      }
    });
    return result;
  }

  public static class DefinitionsSearchExecutor implements QueryExecutor<PsiElement, PsiElement> {
    @Override
    public boolean execute(@NotNull final PsiElement queryParameters, @NotNull final Processor<PsiElement> consumer) {
      return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
        public Boolean compute() {
          final PsiElement queryParametersParent = queryParameters.getParent();
          DartComponent dartComponent;
          if (queryParameters instanceof DartClass) {
            dartComponent = (DartClass)queryParameters;
          }
          else if (queryParametersParent instanceof DartComponent && queryParameters instanceof DartComponentName) {
            dartComponent = (DartComponent)queryParametersParent;
          }
          else {
            return true;
          }
          if (dartComponent instanceof DartClass) {
            processInheritors((DartClass)dartComponent, queryParameters, consumer);
          }
          else if (DartComponentType.typeOf(dartComponent) == DartComponentType.METHOD) {
            final String nameToFind = dartComponent.getName();
            if (nameToFind == null) return true;

            DartClass dartClass = PsiTreeUtil.getParentOfType(dartComponent, DartClass.class);
            assert dartClass != null;

            processInheritors(dartClass, queryParameters, new Processor<PsiElement>() {
              @Override
              public boolean process(PsiElement element) {
                for (DartComponent subDartNamedComponent : DartResolveUtil.getNamedSubComponents((DartClass)element)) {
                  if (nameToFind.equals(subDartNamedComponent.getName())) {
                    consumer.process(subDartNamedComponent);
                  }
                }
                return true;
              }
            });
          }
          return true;
        }
      });
    }

    private static boolean processInheritors(final DartClass dartClass, final PsiElement context, final Processor<PsiElement> consumer) {
      final Set<DartClass> classSet = new THashSet<DartClass>();
      final LinkedList<DartClass> namesQueue = new LinkedList<DartClass>();
      namesQueue.add(dartClass);
      while (!namesQueue.isEmpty()) {
        final DartClass currentClass = namesQueue.pollFirst();
        final String currentClassName = currentClass.getName();
        if (currentClassName == null || !classSet.add(currentClass)) {
          continue;
        }
        final Collection<VirtualFile> files =
          FileBasedIndex.getInstance()
            .getContainingFiles(DART_INHERITANCE_INDEX, currentClassName, GlobalSearchScope.allScope(context.getProject()));
        for (VirtualFile virtualFile : files) {
          PsiFile psiFile = dartClass.getManager().findFile(virtualFile);
          for (PsiElement root : DartResolveUtil.findDartRoots(psiFile)) {
            for (DartClass subClass : DartResolveUtil.findClassesByParent(currentClass, root)) {
              if (!consumer.process(subClass)) {
                return true;
              }
              namesQueue.add(subClass);
            }
          }
        }
      }
      return true;
    }
  }
}
TOP

Related Classes of com.jetbrains.lang.dart.ide.index.DartInheritanceIndex$MyDataIndexer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.