public static IDeclaredElement GetDeclaredElement()

in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Util/FcsSymbolMappingUtil.cs [221:265]


    public static IDeclaredElement GetDeclaredElement([CanBeNull] this FSharpSymbol symbol,
      [NotNull] FSharpSymbolReference reference) =>
      symbol != null && reference.GetElement() is var referenceOwner
        ? symbol.GetDeclaredElement(referenceOwner.GetPsiModule(), referenceOwner)
        : null;

    private static IDeclaredElement GetDeclaredElement(FSharpUnionCase unionCase, IPsiModule psiModule,
      bool preferType = false)
    {
      if (unionCase.IsUnresolved) return null;

      var unionTypeElement = GetTypeElement(unionCase.ReturnType.TypeDefinition, psiModule);
      if (unionTypeElement == null) return null;

      // todo: remove preferType param, get the field through the union case
      if (!preferType && unionTypeElement is IFSharpSourceTypeElement sourceTypeElement && sourceTypeElement.IsUnion())
      {
        var sourceUnionCase = sourceTypeElement.GetSourceUnionCases()
          .FirstOrDefault(sourceUnionCase => sourceUnionCase.ShortName == unionCase.Name);

        return (IDeclaredElement)sourceUnionCase?.GetConstructor() ?? sourceUnionCase;
      }

      var caseCompiledName = unionCase.CompiledName;
      var caseMember = unionTypeElement.GetMembers().FirstOrDefault(m =>
      {
        if (preferType)
        {
          if (!(m is FSharpUnionCaseClass))
            return false;
        }
        else if (m is IFSharpGeneratedFromUnionCase)
          return false;

        var shortName = m.ShortName;
        return shortName == caseCompiledName || shortName == "New" + caseCompiledName;
      });

      if (caseMember != null)
        return caseMember;

      var unionClrName = unionTypeElement.GetClrName();
      var caseDeclaredType = TypeFactory.CreateTypeByCLRName(unionClrName + "+" + caseCompiledName, psiModule, true);
      return caseDeclaredType.GetTypeElement();
    }