private Collection<JSQualifiedNamedElement> getCandidates(Editor editor, PsiFile file) {
    final Collection<JSQualifiedNamedElement> candidates;

    if (myReference instanceof JSReferenceExpression
        && ((JSReferenceExpression) myReference).getQualifier() == null) {
      Collection<JSQualifiedNamedElement> c =
          getCandidates(editor, file, myReference.getCanonicalText());
      filterCandidates(c);
      candidates = new THashSet<>(c, JSPsiImplUtils.QUALIFIED_NAME_HASHING_STRATEGY);
    } else {
      JSQualifiedNamedElement invalidResult = null;

      for (ResolveResult r : myReference.multiResolve(false)) {
        PsiElement element = r.getElement();
        if (element instanceof JSQualifiedNamedElement) {
          invalidResult = (JSQualifiedNamedElement) element;
        }
      }
      if (invalidResult != null) {
        if (myReference.getElement().getParent() instanceof JSNewExpression
            && invalidResult instanceof JSFunction
            && ((JSFunction) invalidResult).isConstructor()) {
          invalidResult = (JSClass) invalidResult.getParent();
        }
        candidates = new SmartList<>();
        candidates.add(invalidResult);
      } else {
        candidates = Collections.emptyList();
      }
    }
    return candidates;
  }
  @Nullable
  static HighlightInfo checkModuleReference(@Nullable PsiJavaModuleReferenceElement refElement) {
    if (refElement != null) {
      PsiPolyVariantReference ref = refElement.getReference();
      assert ref != null : refElement.getParent();
      if (ref.multiResolve(false).length == 0) {
        String message =
            JavaErrorMessages.message("module.ref.unknown", refElement.getReferenceText());
        return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF)
            .range(refElement)
            .description(message)
            .create();
      }
    }

    return null;
  }
  public boolean isAvailable(
      @NotNull final Project project, final Editor editor, final PsiFile file) {
    if (!myReference.getElement().isValid()) return false;
    final long modL =
        myReference.getElement().getManager().getModificationTracker().getModificationCount();

    if (!isAvailableCalculated || modL != modificationCount) {
      final ResolveResult[] results = myReference.multiResolve(false);
      boolean hasValidResult = false;

      for (ResolveResult r : results) {
        if (r.isValidResult()) {
          hasValidResult = true;
          break;
        }
      }

      if (!hasValidResult) {
        final Collection<JSQualifiedNamedElement> candidates = getCandidates(editor, file);

        isAvailableCalculated = true;
        isAvailable = candidates.size() > 0;
        String text;

        if (isAvailable) {
          final JSQualifiedNamedElement element = candidates.iterator().next();
          text = element.getQualifiedName() + "?";
          if (candidates.size() > 1) text += " (multiple choices...)";
          if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
            text += " Alt+Enter";
          }
        } else {
          text = "";
        }
        myText = text;
      } else {
        isAvailableCalculated = true;
        isAvailable = false;
        myText = "";
      }

      modificationCount = modL;
    }

    return isAvailable;
  }
 public boolean showHint(@NotNull final Editor editor) {
   myEditor = editor;
   final PsiElement element = myReference.getElement();
   TextRange range =
       InjectedLanguageManager.getInstance(element.getProject())
           .injectedToHost(element, element.getTextRange());
   HintManager.getInstance()
       .showQuestionHint(editor, getText(), range.getStartOffset(), range.getEndOffset(), this);
   return true;
 }
  private void doTest() throws Exception {
    PsiPolyVariantReference reference =
        (PsiPolyVariantReference) configureByFile(getTestName(true) + ".kt");
    PsiElement resolved = reference.resolve();
    assertNotNull(resolved);
    assertEquals(1, reference.multiResolve(false).length);

    List<PsiComment> comments = PsiTreeUtil.getChildrenOfTypeAsList(getFile(), PsiComment.class);
    String[] expectedTarget = comments.get(comments.size() - 1).getText().substring(2).split(":");
    assertEquals(2, expectedTarget.length);
    String expectedFile = expectedTarget[0];
    String expectedName = expectedTarget[1];

    PsiFile targetFile = resolved.getContainingFile();
    PsiDirectory targetDir = targetFile.getParent();
    assertNotNull(targetDir);
    assertEquals(expectedFile, targetDir.getName() + "/" + targetFile.getName());
    assertInstanceOf(resolved, PsiNamedElement.class);
    assertEquals(expectedName, ((PsiNamedElement) resolved).getName());
  }
 private void doImport(final String qName) {
   ApplicationManager.getApplication()
       .runWriteAction(
           () -> {
             final PsiElement element = myReference.getElement();
             SmartPsiElementPointer<PsiElement> pointer =
                 SmartPointerManager.getInstance(element.getProject())
                     .createSmartPsiElementPointer(element);
             ImportUtils.doImport(element, qName, true);
             PsiElement newElement = pointer.getElement();
             if (newElement != null) {
               ImportUtils.insertUseNamespaceIfNeeded(qName, newElement);
             }
           });
 }
 @Override
 public void visitPyReferenceExpression(final PyReferenceExpression node) {
   if (node.getContainingFile() instanceof PyExpressionCodeFragment) {
     return;
   }
   // Ignore global statements arguments
   if (PyGlobalStatementNavigator.getByArgument(node) != null) {
     return;
   }
   // Ignore qualifier inspections
   if (node.getQualifier() != null) {
     return;
   }
   // Ignore import subelements
   if (PsiTreeUtil.getParentOfType(node, PyImportStatementBase.class) != null) {
     return;
   }
   final String name = node.getReferencedName();
   if (name == null) {
     return;
   }
   final ScopeOwner owner = ScopeUtil.getDeclarationScopeOwner(node, name);
   final Set<ScopeOwner> largeFunctions = getSession().getUserData(LARGE_FUNCTIONS_KEY);
   assert largeFunctions != null;
   if (owner == null || largeFunctions.contains(owner)) {
     return;
   }
   // Ignore references declared in outer scopes
   if (owner != ScopeUtil.getScopeOwner(node)) {
     return;
   }
   final Scope scope = ControlFlowCache.getScope(owner);
   // Ignore globals and if scope even doesn't contain such a declaration
   if (scope.isGlobal(name) || (!scope.containsDeclaration(name))) {
     return;
   }
   // Start DFA from the assignment statement in case of augmented assignments
   final PsiElement anchor;
   final PyAugAssignmentStatement augAssignment =
       PsiTreeUtil.getParentOfType(node, PyAugAssignmentStatement.class);
   if (augAssignment != null && name.equals(augAssignment.getTarget().getName())) {
     anchor = augAssignment;
   } else {
     anchor = node;
   }
   final ScopeVariable variable;
   try {
     variable = scope.getDeclaredVariable(anchor, name);
   } catch (DFALimitExceededException e) {
     largeFunctions.add(owner);
     registerLargeFunction(owner);
     return;
   }
   if (variable == null) {
     if (!isFirstUnboundRead(node, owner)) {
       return;
     }
     final PsiPolyVariantReference ref = node.getReference(resolveWithoutImplicits());
     if (ref == null) {
       return;
     }
     final PsiElement resolved = ref.resolve();
     final boolean isBuiltin = PyBuiltinCache.getInstance(node).hasInBuiltins(resolved);
     if (owner instanceof PyClass) {
       if (isBuiltin || ScopeUtil.getDeclarationScopeOwner(owner, name) != null) {
         return;
       }
     }
     if (PyUnreachableCodeInspection.hasAnyInterruptedControlFlowPaths(node)) {
       return;
     }
     if (owner instanceof PyFile) {
       if (isBuiltin) {
         return;
       }
       if (resolved != null && !PyUtil.inSameFile(node, resolved)) {
         return;
       }
       registerProblem(node, PyBundle.message("INSP.unbound.name.not.defined", name));
     } else {
       registerProblem(
           node,
           PyBundle.message("INSP.unbound.local.variable", node.getName()),
           ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
           null,
           new AddGlobalQuickFix());
     }
   }
 }
  public boolean execute() {
    final PsiFile containingFile = myReference.getElement().getContainingFile();
    invoke(containingFile.getProject(), myEditor, containingFile);

    return true;
  }