public sealed class FSharpSearchFilter()

in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Searching/FSharpSearchFilter.cs [14:76]


  public sealed class FSharpSearchFilter(IFcsProjectProvider fsProjectProvider) : ISearchFilter
  {
    private record FSharpSearchFilterKey(
      bool IsTypePrivateMember,
      IPsiModule PsiModule,
      HybridCollection<IPsiSourceFile> SourceFiles,
      int FileIndex);

    public SearchFilterKind Kind => SearchFilterKind.Cache;

    public bool IsAvailable(SearchPattern pattern) => true;

    public static bool CanContainReference(IDeclaredElement declaredElement, IPsiSourceFile sourceFile, IFcsProjectProvider fsProjectProvider)
    {
      if (!sourceFile.LanguageType.Is<FSharpProjectFileType>()) return true;

      var key = TryGetKey(declaredElement, fsProjectProvider);

      if (key.SourceFiles.Contains(sourceFile)) return true;
      if (key.IsTypePrivateMember) return false;
      if (!sourceFile.PsiModule.Equals(key.PsiModule)) return true;

      var sourceFileIndex = fsProjectProvider.GetFileIndex(sourceFile);
      return sourceFileIndex >= key.FileIndex;
    }

    private static FSharpSearchFilterKey TryGetKey(IDeclaredElement declaredElement, IFcsProjectProvider fsProjectProvider)
    {
      if (declaredElement is not IFSharpDeclaredElement fsDeclaredElement) return null;

      var typeElement = fsDeclaredElement as ITypeElement
                        ?? fsDeclaredElement.GetContainingType();

      if (typeElement is null) return null;

      var sourceFiles = typeElement.GetSourceFiles();
      if (sourceFiles.IsEmpty) return null;

      if (declaredElement is ITypePrivateMember)
        return new FSharpSearchFilterKey(IsTypePrivateMember: true, fsDeclaredElement.Module, sourceFiles, FileIndex: -1);

      var fileIndex = sourceFiles.Select(fsProjectProvider.GetFileIndex).Min();

      return new FSharpSearchFilterKey(IsTypePrivateMember: false, fsDeclaredElement.Module, sourceFiles, fileIndex);
    }

    public object TryGetKey(IDeclaredElement declaredElement) =>
      TryGetKey(declaredElement, fsProjectProvider);

    public bool CanContainReferences(IPsiSourceFile sourceFile, object key)
    {
      if (!sourceFile.LanguageType.Is<FSharpProjectFileType>()) return true;

      var fsSearchFilterKey = (FSharpSearchFilterKey)key;

      if (fsSearchFilterKey.SourceFiles.Contains(sourceFile)) return true;
      if (fsSearchFilterKey.IsTypePrivateMember) return false;
      if (!sourceFile.PsiModule.Equals(fsSearchFilterKey.PsiModule)) return true;

      var sourceFileIndex = fsProjectProvider.GetFileIndex(sourceFile);
      return sourceFileIndex >= fsSearchFilterKey.FileIndex;
    }
  }