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();
}