Package com.jetbrains.lang.dart.ide.marker

Source Code of com.jetbrains.lang.dart.ide.marker.DartImplementationsMarkerProvider

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

import com.intellij.codeHighlighting.Pass;
import com.intellij.codeInsight.daemon.DaemonBundle;
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.PsiElement;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.lang.dart.ide.index.DartInheritanceIndex;
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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class DartImplementationsMarkerProvider implements LineMarkerProvider {

  @Override
  public LineMarkerInfo getLineMarkerInfo(@NotNull final PsiElement element) {
    return null;
  }

  @Override
  public void collectSlowLineMarkers(@NotNull final List<PsiElement> elements, @NotNull final Collection<LineMarkerInfo> result) {
    for (PsiElement element : elements) {
      ProgressManager.checkCanceled();
      if (element instanceof DartClass) {
        collectMarkers(result, (DartClass)element);
      }
    }
  }

  private static void collectMarkers(@NotNull final Collection<LineMarkerInfo> result, @NotNull final DartClass dartClass) {
    final List<DartClass> subClasses = DartInheritanceIndex.getItemsByName(dartClass);
    if (!subClasses.isEmpty() && !DartResolveUtil.OBJECT.equals(dartClass.getName())) {
      result.add(createImplementationMarker(dartClass, subClasses));
    }

    final List<DartComponent> subItems = new ArrayList<DartComponent>();
    for (DartClass subClass : subClasses) {
      subItems.addAll(DartResolveUtil.getNamedSubComponents(subClass));
    }

    for (DartComponent dartComponent : DartResolveUtil.getNamedSubComponents(dartClass)) {
      final LineMarkerInfo markerInfo = tryCreateImplementationMarker(dartComponent, subItems, dartComponent.isAbstract());
      if (markerInfo != null) {
        result.add(markerInfo);
      }
    }
  }

  @NotNull
  private static LineMarkerInfo createImplementationMarker(@NotNull final DartClass dartClass, @NotNull final List<DartClass> subClasses) {
    final DartComponentName componentName = dartClass.getComponentName();
    assert componentName != null : dartClass.getText(); // unnamed class can't have subclasses

    return new LineMarkerInfo<PsiElement>(
      componentName,
      componentName.getTextRange(),
      AllIcons.Gutter.OverridenMethod,
      Pass.UPDATE_OVERRIDEN_MARKERS,
      new Function<PsiElement, String>() {
        @Override
        public String fun(PsiElement element) {
          return DaemonBundle.message("method.is.implemented.too.many");
        }
      },
      new GutterIconNavigationHandler<PsiElement>() {
        @Override
        public void navigate(MouseEvent e, PsiElement elt) {
          PsiElementListNavigator.openTargets(
            e, DartResolveUtil.getComponentNames(subClasses).toArray(new NavigatablePsiElement[subClasses.size()]),
            DaemonBundle.message("navigation.title.subclass", dartClass.getName(), subClasses.size()),
            "Superclasses of " + dartClass.getName(),
            new DefaultPsiElementCellRenderer()
          );
        }
      },
      GutterIconRenderer.Alignment.RIGHT
    );
  }

  @Nullable
  private static LineMarkerInfo tryCreateImplementationMarker(@NotNull final DartComponent componentWithDeclarationList,
                                                              @NotNull final List<DartComponent> subItems,
                                                              final boolean isInterface) {
    final PsiElement componentName = componentWithDeclarationList.getComponentName();
    final String methodName = componentWithDeclarationList.getName();
    if (methodName == null || !componentWithDeclarationList.isPublic()) {
      return null;
    }
    final List<DartComponent> filteredSubItems = ContainerUtil.filter(subItems, new Condition<DartComponent>() {
      @Override
      public boolean value(DartComponent component) {
        return methodName.equals(component.getName());
      }
    });
    if (filteredSubItems.isEmpty() || componentName == null) {
      return null;
    }
    return new LineMarkerInfo<PsiElement>(
      componentName,
      componentName.getTextRange(),
      isInterface ? AllIcons.Gutter.ImplementedMethod : AllIcons.Gutter.OverridenMethod,
      Pass.UPDATE_OVERRIDEN_MARKERS,
      new Function<PsiElement, String>() {
        @Override
        public String fun(PsiElement element) {
          return isInterface
                 ? DaemonBundle.message("method.is.implemented.too.many")
                 : DaemonBundle.message("method.is.overridden.too.many");
        }
      },
      new GutterIconNavigationHandler<PsiElement>() {
        @Override
        public void navigate(MouseEvent e, PsiElement elt) {
          PsiElementListNavigator.openTargets(
            e, DartResolveUtil.getComponentNames(filteredSubItems).toArray(new NavigatablePsiElement[filteredSubItems.size()]),
            isInterface ?
            DaemonBundle.message("navigation.title.implementation.method", componentWithDeclarationList.getName(), filteredSubItems.size())
                        :
            DaemonBundle.message("navigation.title.overrider.method", componentWithDeclarationList.getName(), filteredSubItems.size()),
            "Implementations of " + componentWithDeclarationList.getName(),
            new DefaultPsiElementCellRenderer()
          );
        }
      },
      GutterIconRenderer.Alignment.RIGHT
    );
  }
}
TOP

Related Classes of com.jetbrains.lang.dart.ide.marker.DartImplementationsMarkerProvider

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.