in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Util/FcsSymbolMappingUtil.cs [36:98]
public static ITypeElement GetTypeElement([NotNull] this FSharpEntity entity, [NotNull] IPsiModule psiModule)
{
if (((FSharpSymbol) entity).DeclarationLocation == null || entity.IsByRef || entity.IsProvidedAndErased)
return null;
if (!entity.IsFSharpAbbreviation)
{
var clrTypeName = entity.GetClrName();
if (clrTypeName == null)
return null;
var context = CompilationContextCookie.GetContext();
var scopePsiModule = context.GetPsiModule() ?? psiModule;
var scope = scopePsiModule.GetCachedCaseSensitiveSymbolScopeWithReferences();
var typeElements = scope.GetTypeElementsByCLRName(clrTypeName);
if (typeElements.IsEmpty())
{
if (entity.IsProvidedAndGenerated &&
ProvidedTypesResolveUtil.TryGetProvidedType(psiModule, clrTypeName, out var providedType) &&
providedType.DeclaringType != null)
return providedType.MapType(psiModule).GetTypeElement();
return null;
}
if (typeElements.Length == 1)
return typeElements[0];
// If there are multiple entities with a given FQN, try to choose one based on the assembly name or entity kind.
var fcsAssemblySimpleName = entity.Assembly.SimpleName;
var isModule = entity.IsFSharpModule;
return typeElements.FirstOrDefault(typeElement =>
{
if (GetModuleName(typeElement.Module) != fcsAssemblySimpleName)
return false;
// Happens when there are an exception and a module with the same name.
// It's now allowed, but we want to keep resolve working where possible.
if (typeElement is IFSharpDeclaredElement)
return isModule == typeElement is IFSharpModule;
return true;
});
}
var symbolScope = psiModule.GetSymbolScope(false);
while (entity.IsFSharpAbbreviation)
{
// FCS returns Clr names for non-abbreviated types only, using the fullname
var typeElement = TryFindByNames(GetPossibleNames(entity), symbolScope);
if (typeElement != null)
return typeElement;
var abbreviatedType = entity.AbbreviatedType;
if (!abbreviatedType.HasTypeDefinition)
return null;
entity = entity.AbbreviatedType.TypeDefinition;
}
return entity.GetTypeElement(psiModule);
}