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