Package com.squareup.ideaplugin.otto

Source Code of com.squareup.ideaplugin.otto.OttoLineMarkerProvider

package com.squareup.ideaplugin.otto;

import com.intellij.codeHighlighting.Pass;
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.PsiNewExpression;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiParameterList;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeElement;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.usages.Usage;
import com.intellij.usages.UsageInfo2UsageAdapter;

import javax.swing.Icon;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class OttoLineMarkerProvider implements LineMarkerProvider {
  public static final Icon ICON = IconLoader.getIcon("/icons/otto.png");

  public static final Decider INSTANTIATIONS = new Decider() {
    @Override public boolean shouldShow(Usage usage) {
      PsiElement element = ((UsageInfo2UsageAdapter) usage).getElement();
      if (element.getParent() instanceof PsiNewExpression) {
        PsiMethod method = PsiConsultantImpl.findMethod(element);
        return !SubscriberMetadata.isAnnotatedWithProducer(method);
      }
      return false;
    }
  };

  public static final Decider PRODUCERS = new Decider() {
    @Override public boolean shouldShow(Usage usage) {
      PsiElement element = ((UsageInfo2UsageAdapter) usage).getElement().getContext();
      if (element != null) {
        PsiElement parent = element.getParent();
        if (parent != null && parent instanceof PsiMethod) {
          return SubscriberMetadata.isAnnotatedWithProducer((PsiMethod) parent);
        }
      }
      return false;
    }
  };

  public static final Decider SUBSCRIBERS = new Decider() {
    @Override public boolean shouldShow(Usage usage) {
      PsiElement element = ((UsageInfo2UsageAdapter) usage).getElement();
      if (element instanceof PsiJavaCodeReferenceElement) {
        if ((element = element.getContext()) instanceof PsiTypeElement) {
          if ((element = element.getContext()) instanceof PsiParameter) {
            if ((element = element.getContext()) instanceof PsiParameterList) {
              if ((element = element.getContext()) instanceof PsiMethod) {
                return SubscriberMetadata.isAnnotatedWithSubscriber((PsiMethod) element);
              }
            }
          }
        }
      }
      return false;
    }
  };
  public static final Decider ALL = new Decider() {
    @Override public boolean shouldShow(Usage usage) {
      return INSTANTIATIONS.shouldShow(usage)
          || SUBSCRIBERS.shouldShow(usage)
          || PRODUCERS.shouldShow(usage);
    }
  };

  public static final int MAX_USAGES = 100;

  public static final GutterIconNavigationHandler<PsiElement> SHOW_SUBSCRIBERS =
      new GutterIconNavigationHandler<PsiElement>() {
        @Override public void navigate(MouseEvent e, PsiElement psiElement) {
          if (psiElement instanceof PsiClass) {
            PsiClass eventClass = (PsiClass) psiElement;
            new ShowUsagesAction(SUBSCRIBERS).startFindUsages(eventClass, new RelativePoint(e),
                PsiUtilBase.findEditor(eventClass), MAX_USAGES);
          } else if (psiElement instanceof PsiMethodCallExpression) {
            PsiMethodCallExpression expression = (PsiMethodCallExpression) psiElement;
            PsiType[] expressionTypes = expression.getArgumentList().getExpressionTypes();
            if (expressionTypes.length > 0) {
              PsiClass eventClass = PsiConsultantImpl.getClass(expressionTypes[0]);
              if (eventClass != null) {
                new ShowUsagesAction(SUBSCRIBERS).startFindUsages(eventClass, new RelativePoint(e),
                    PsiUtilBase.findEditor(eventClass), MAX_USAGES);
              }
            }
          }
        }
      };

  public static final GutterIconNavigationHandler<PsiClass> SHOW_ALL =
      new GutterIconNavigationHandler<PsiClass>() {
        @Override public void navigate(MouseEvent e, PsiClass psiClass) {
          new ShowUsagesAction(ALL).startFindUsages(psiClass,
              new RelativePoint(e), PsiUtilBase.findEditor(psiClass), MAX_USAGES);
        }
      };

  public static final GutterIconNavigationHandler<PsiElement> SHOW_INSTANTIATIONS_AND_PRODUCERS =
      new GutterIconNavigationHandler<PsiElement>() {
        @Override public void navigate(final MouseEvent mouseEvent, final PsiElement psiElement) {
          PsiMethod subscribeMethod = (PsiMethod) psiElement;
          final PsiTypeElement parameterTypeElement = getMethodParameter(subscribeMethod);
          final SubscriberMetadata subscriberMetadata = SubscriberMetadata.getSubscriberMetadata(subscribeMethod);
          if ((parameterTypeElement.getType() instanceof PsiClassType) && (subscriberMetadata != null)) {
            final PsiClass eventClass = ((PsiClassType) parameterTypeElement.getType()).resolve();
            PickAction.startPicker(subscriberMetadata.displayedTypesOnSubscriberMethods(),
                new RelativePoint(mouseEvent), new PickAction.Callback() {

              @Override public void onTypeChose(PickAction.Type type) {
                if (type.equals(PickAction.Type.PRODUCER)) {
                  new ShowUsagesAction(PRODUCERS).startFindUsages(eventClass,
                      new RelativePoint(mouseEvent), PsiUtilBase.findEditor(psiElement),
                      MAX_USAGES);
                } else if (type.equals(PickAction.Type.EVENT_POST)) {
                  PsiMethod ottoBusMethod = subscriberMetadata.getBusPostMethod(psiElement.getProject());
                  new ShowUsagesAction(new BusPostDecider(eventClass)).startFindUsages(
                      ottoBusMethod, new RelativePoint(mouseEvent),
                      PsiUtilBase.findEditor(psiElement), MAX_USAGES);
                }
              }
            });
          }
        }
      };

  private static final GutterIconNavigationHandler<PsiElement> SHOW_SUBSCRIBERS_FROM_PRODUCERS =
      new GutterIconNavigationHandler<PsiElement>() {
        @Override public void navigate(MouseEvent mouseEvent, PsiElement psiElement) {
          if (psiElement instanceof PsiMethod) {
            PsiMethod psiMethod = (PsiMethod) psiElement;
            PsiTypeElement returnTypeElement = psiMethod.getReturnTypeElement();
            PsiClass eventClass = ((PsiClassType) returnTypeElement.getType()).resolve();

            new ShowUsagesAction(SUBSCRIBERS).startFindUsages(eventClass,
                new RelativePoint(mouseEvent), PsiUtilBase.findEditor(returnTypeElement),
                MAX_USAGES);
          }
        }
      };

  @Nullable @Override public LineMarkerInfo getLineMarkerInfo(@NotNull final PsiElement element) {
    if (element instanceof PsiMethod) {
      PsiMethod psiMethod = (PsiMethod) element;
      SubscriberMetadata subscriberMetadata = SubscriberMetadata.getSubscriberMetadata(psiMethod);
      if (subscriberMetadata != null) {
        PsiTypeElement methodParameter = getMethodParameter(psiMethod);
        if (methodParameter != null) {
          return new LineMarkerInfo<PsiElement>(psiMethod, methodParameter.getTextRange(), ICON,
              Pass.UPDATE_ALL, null, SHOW_INSTANTIATIONS_AND_PRODUCERS,
              GutterIconRenderer.Alignment.LEFT);
        }
      }

      if (SubscriberMetadata.isAnnotatedWithProducer(psiMethod)) {
        return new LineMarkerInfo<PsiElement>(psiMethod, psiMethod.getTextRange(), ICON,
            Pass.UPDATE_ALL, null, SHOW_SUBSCRIBERS_FROM_PRODUCERS,
            GutterIconRenderer.Alignment.LEFT);
      }
    } else if (element instanceof PsiClass) {
      PsiClass psiClass = (PsiClass) element;
      String qualifiedName = psiClass.getQualifiedName();
      if (qualifiedName != null) {
        OttoProjectHandler ottoProjectHandler = OttoProjectHandler.get(element.getProject());
        if (ottoProjectHandler.isEventClass(qualifiedName)) {
          PsiIdentifier nameIdentifier = psiClass.getNameIdentifier();
          if (nameIdentifier != null) {
            return new LineMarkerInfo<PsiClass>(psiClass, nameIdentifier.getTextRange(), ICON,
                Pass.UPDATE_ALL, null, SHOW_ALL, GutterIconRenderer.Alignment.LEFT);
          }
        }
      }
    } else if (element instanceof PsiMethodCallExpression) {
      PsiMethodCallExpression expression = (PsiMethodCallExpression) element;
      PsiMethod psiMethod = expression.resolveMethod();
      if (psiMethod != null) {
        if (SubscriberMetadata.isBusPostMethod(psiMethod, element.getProject())) {
          PsiType[] expressionTypes = expression.getArgumentList().getExpressionTypes();
          if (expressionTypes.length > 0) {
            PsiClass eventClass = PsiConsultantImpl.getClass(expressionTypes[0]);
            if (eventClass != null) {
              return new LineMarkerInfo<PsiElement>(element, element.getTextRange(), ICON,
                  Pass.UPDATE_ALL, null, SHOW_SUBSCRIBERS, GutterIconRenderer.Alignment.LEFT);
            }
          }

        }
      }
    }

    return null;
  }

  public static @Nullable PsiTypeElement getMethodParameter(PsiMethod subscribeMethod) {
    PsiParameterList parameterList = subscribeMethod.getParameterList();
    if (parameterList.getParametersCount() != 1) {
      return null;
    } else {
      PsiParameter subscribeMethodParam = parameterList.getParameters()[0];
      return subscribeMethodParam.getTypeElement();
    }
  }

  @Override public void collectSlowLineMarkers(@NotNull List<PsiElement> psiElements,
      @NotNull Collection<LineMarkerInfo> lineMarkerInfos) {
  }
}
TOP

Related Classes of com.squareup.ideaplugin.otto.OttoLineMarkerProvider

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.