// 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.jetbrains.python.findUsages;

import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usages.UsageTarget;
import com.intellij.usages.impl.rules.UsageType;
import com.intellij.usages.impl.rules.UsageTypeProviderEx;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyPsiUtils;
import com.jetbrains.python.psi.types.PyStructuralType;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;

/**
 * @author yole
 */
public class PyUsageTypeProvider implements UsageTypeProviderEx {
  private static final UsageType IN_IMPORT = new UsageType(PyBundle.message("python.find.usages.usage.in.import.statement"));
  private static final UsageType UNTYPED = new UsageType(PyBundle.message("python.find.usages.untyped.probable.usage"));
  private static final UsageType USAGE_IN_ISINSTANCE = new UsageType(PyBundle.message("python.find.usages.usage.in.isinstance"));
  private static final UsageType USAGE_IN_SUPERCLASS = new UsageType(PyBundle.message("python.find.usages.usage.in.superclass.list"));

  @Override
  public UsageType getUsageType(PsiElement element) {
    return getUsageType(element, UsageTarget.EMPTY_ARRAY);
  }

  @Override
  public UsageType getUsageType(PsiElement element, UsageTarget @NotNull [] targets) {
    if (element instanceof PyElement) {
      if (PsiTreeUtil.getParentOfType(element, PyImportStatementBase.class) != null) {
        return IN_IMPORT;
      }
      if (element instanceof PyQualifiedExpression) {
        final PyExpression qualifier = ((PyQualifiedExpression)element).getQualifier();
        if (qualifier != null) {
          final TypeEvalContext context = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile());
          final PyType type = context.getType(qualifier);
          if (type == null || type instanceof PyStructuralType) {
            return UNTYPED;
          }
        }
      }
      if (element instanceof PyReferenceExpression) {
        final PyCallExpression call = PsiTreeUtil.getParentOfType(element, PyCallExpression.class);
        if (call != null && call.isCalleeText(PyNames.ISINSTANCE)) {
          final PyExpression[] args = call.getArguments();
          if (args.length == 2) {
            PyExpression typeExpression = args[1];
            if (element == typeExpression) {
              return USAGE_IN_ISINSTANCE;
            }
            typeExpression = PyPsiUtils.flattenParens(typeExpression);
            if (typeExpression instanceof PySequenceExpression && element.getParent() == typeExpression) {
              return USAGE_IN_ISINSTANCE;
            }
          }
        }
        final PyClass pyClass = PsiTreeUtil.getParentOfType(element, PyClass.class);
        if (pyClass != null && PsiTreeUtil.isAncestor(pyClass.getSuperClassExpressionList(), element, true)) {
          return USAGE_IN_SUPERCLASS;
        }
      }
    }
    return null;
  }
}

@@ -432,22 +432,21 @@
 ython.Py
-Bundle
+Names
 ;%0Aimport
@@ -461,37 +461,41 @@
 brains.python.Py
-Names
+PsiBundle
 ;%0Aimport com.jet
@@ -907,32 +907,35 @@
 new UsageType(Py
+Psi
 Bundle.message(%22
@@ -1034,32 +1034,35 @@
 new UsageType(Py
+Psi
 Bundle.message(%22
@@ -1170,32 +1170,35 @@
 new UsageType(Py
+Psi
 Bundle.message(%22
@@ -1311,16 +1311,19 @@
 eType(Py
+Psi
 Bundle.m

Fix bundle access