in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Util/FcsSymbolMappingUtil.cs [132:194]
public static IDeclaredElement GetDeclaredElement([CanBeNull] this FSharpSymbol symbol,
[NotNull] IPsiModule psiModule, [CanBeNull] IFSharpReferenceOwner referenceOwner = null)
{
if (symbol == null)
return null;
if (symbol is FSharpEntity entity)
{
if (entity.IsUnresolved)
return null;
if (entity.IsNamespace)
return GetDeclaredNamespace(entity, psiModule);
if (entity.IsFSharpExceptionDeclaration && referenceOwner != null)
return GetFSharpException(entity, psiModule, referenceOwner);
return GetTypeElement(entity, psiModule);
}
if (symbol is FSharpMemberOrFunctionOrValue mfv)
{
if (mfv.IsUnresolved) return null;
return mfv.IsModuleValueOrMember
? GetTypeMember(mfv, psiModule)
: GetLocalValueDeclaredElement(mfv, referenceOwner);
}
if (symbol is FSharpUnionCase unionCase)
return GetDeclaredElement(unionCase, psiModule);
if (symbol is FSharpField field)
{
if (field.IsAnonRecordField && referenceOwner != null)
return new FSharpAnonRecordFieldProperty(referenceOwner.Reference);
if (field.IsUnionCaseField && field.DeclaringUnionCase?.Value is { } fieldUnionCase)
{
var unionEntity = fieldUnionCase.ReturnType.TypeDefinition;
var fieldOwnerTypeElement =
unionEntity.UnionCases.Count > 1 && !unionEntity.IsValueType
? GetDeclaredElement(fieldUnionCase, psiModule, true) as ITypeElement
: GetTypeElement(unionEntity, psiModule);
return fieldOwnerTypeElement?.EnumerateOwnMembersWithName(field.Name, true).FirstOrDefault();
}
if (!field.IsUnresolved && field.DeclaringEntity?.Value is { } fieldEntity)
return GetTypeElement(fieldEntity, psiModule)?.EnumerateOwnMembersWithName(field.Name, true).FirstOrDefault();
}
if (symbol is FSharpActivePatternCase patternCase)
return GetActivePatternCaseElement(patternCase, psiModule, referenceOwner);
if (symbol is FSharpGenericParameter genericParameter)
return GetTypeParameter(genericParameter, referenceOwner);
if (symbol is FSharpParameter parameter && referenceOwner != null)
return parameter.GetOwner(referenceOwner.Reference); // todo: map to parameter
return null;
}