private static IDeclaredElement GetFSharpSourceTypeMember()

in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Util/FcsSymbolMappingUtil.cs [286:342]


    private static IDeclaredElement GetFSharpSourceTypeMember([NotNull] FSharpMemberOrFunctionOrValue mfv,
      [NotNull] IFSharpSourceTypeElement fsTypeElement)
    {
      var name = mfv.GetMfvCompiledName(fsTypeElement);

      var symbolTableCache = fsTypeElement.GetPsiServices().Caches.GetPsiCache<SymbolTableCache>();
      var symbolTable = symbolTableCache.TryGetCachedSymbolTable(fsTypeElement, SymbolTableMode.FULL);
      if (symbolTable != null)
      {
        var members = symbolTable.GetSymbolInfos(name).SelectNotNull(info =>
          info.GetDeclaredElement() is ITypeMember member && member.ShortName == name ? member : null);
        return ChooseTypeMember(mfv, members.AsList());
      }

      var fcsRange = mfv.DeclarationLocation;
      var path = VirtualFileSystemPath.TryParse(fcsRange.FileName, InteractionContext.SolutionContext);
      if (path.IsEmpty)
        return GetTypeMember(mfv, fsTypeElement);

      var declarations = new List<FSharpProperTypeMemberDeclarationBase>();
      var typeElement = (TypeElement) fsTypeElement;
      foreach (var typePart in typeElement.EnumerateParts())
      {
        var typeDeclaration = typePart.GetDeclaration() as FSharpTypeElementDeclarationBase;
        var sourceFile = typeDeclaration?.GetSourceFile();
        if (sourceFile == null || sourceFile.GetLocation() != path)
          continue;

        foreach (var declaration in typeDeclaration.MemberDeclarations)
        {
          if (declaration is FSharpProperTypeMemberDeclarationBase fsDeclaration && fsDeclaration.CompiledName == name)
            declarations.Add(fsDeclaration);
        }
      }

      if (declarations.Count == 0)
        return GetTypeMember(mfv, typeElement);

      var singleDeclaration =
        declarations.Count == 1
          ? declarations[0]
          : declarations.SingleItem(decl =>
          {
            var range = decl.GetSourceFile().NotNull().Document.GetTreeTextRange(fcsRange);
            var nameIdentifierRange = decl.GetNameIdentifierRange();
            return range.Contains(nameIdentifierRange);
          });

      var singleSourceElement = singleDeclaration?.GetOrCreateDeclaredElement(mfv);
      if (singleSourceElement != null)
        return singleSourceElement;

      if (mfv.IsPropertyGetterMethod || mfv.IsPropertySetterMethod && !mfv.IsImplicitAccessor())
        return GetTypeMember(mfv, typeElement);

      return null;
    }