/**
  * Get jet non-extension top-level function names. Method is allowed to give invalid names - all
  * result should be checked with getTopLevelFunctionDescriptorsByName().
  *
  * @return
  */
 @NotNull
 public Collection<String> getAllTopLevelFunctionNames() {
   Set<String> functionNames = new HashSet<String>();
   functionNames.addAll(JetShortFunctionNameIndex.getInstance().getAllKeys(project));
   functionNames.addAll(
       JetFromJavaDescriptorHelper.getPossiblePackageDeclarationsNames(
           project, GlobalSearchScope.allScope(project)));
   return functionNames;
 }
 @Override
 public void getAllMethodNames(@NotNull HashSet<String> set) {
   set.addAll(JetShortFunctionNameIndex.getInstance().getAllKeys(project));
 }
  @NotNull
  public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName(
      @NotNull String name,
      @NotNull JetSimpleNameExpression expression,
      @NotNull ResolveSession resolveSession,
      @NotNull GlobalSearchScope scope) {
    // name parameter can differ from expression.getReferenceName() when expression contains
    // completion suffix
    Name referenceName =
        expression.getIdentifier() == null
            ? JetPsiUtil.getConventionName(expression)
            : Name.identifier(name);
    if (referenceName == null || referenceName.toString().isEmpty()) {
      return Collections.emptyList();
    }

    BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression);
    JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);

    if (jetScope == null) {
      return Collections.emptyList();
    }

    Set<FunctionDescriptor> result = Sets.newHashSet();

    Collection<PsiMethod> topLevelFunctionPrototypes =
        JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName(
            referenceName.getName(), project, scope);
    for (PsiMethod method : topLevelFunctionPrototypes) {
      FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method);
      if (functionFQN != null) {
        JetImportDirective importDirective =
            JetPsiFactory.createImportDirective(project, new ImportPath(functionFQN, false));
        Collection<? extends DeclarationDescriptor> declarationDescriptors =
            new QualifiedExpressionResolver()
                .analyseImportReference(
                    importDirective,
                    jetScope,
                    new BindingTraceContext(),
                    resolveSession.getModuleConfiguration());
        for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
          if (declarationDescriptor instanceof FunctionDescriptor) {
            result.add((FunctionDescriptor) declarationDescriptor);
          }
        }
      }
    }

    Set<FqName> affectedPackages = Sets.newHashSet();
    Collection<JetNamedFunction> jetNamedFunctions =
        JetShortFunctionNameIndex.getInstance().get(referenceName.getName(), project, scope);
    for (JetNamedFunction jetNamedFunction : jetNamedFunctions) {
      PsiFile containingFile = jetNamedFunction.getContainingFile();
      if (containingFile instanceof JetFile) {
        JetFile jetFile = (JetFile) containingFile;
        String packageName = jetFile.getPackageName();
        if (packageName != null) {
          affectedPackages.add(new FqName(packageName));
        }
      }
    }

    for (FqName affectedPackage : affectedPackages) {
      NamespaceDescriptor packageDescriptor =
          resolveSession.getPackageDescriptorByFqName(affectedPackage);
      assert packageDescriptor != null
          : "There's a function in stub index with invalid package: " + affectedPackage;
      JetScope memberScope = packageDescriptor.getMemberScope();
      result.addAll(memberScope.getFunctions(referenceName));
    }

    return result;
  }