in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Util/FcsTypeMappingUtil.cs [108:180]
public static IType MapType([NotNull] this FSharpType fcsType, [NotNull] IList<ITypeParameter> typeParams,
[NotNull] IPsiModule psiModule, bool isFromMethod = false, bool isFromReturn = false)
{
var type = GetStrippedType(fcsType);
if (type == null || type.IsUnresolved)
return TypeFactory.CreateUnknownType(psiModule);
// F# 4.0 specs 18.1.3
try
{
// todo: check type vs fcsType
if (isFromMethod && type.IsNativePointerType && !HasGenericTypeParams(fcsType))
{
var argType = GetSingleTypeArgument(fcsType, typeParams, psiModule, true);
return TypeFactory.CreatePointerType(argType);
}
}
catch (Exception e)
{
Logger.LogMessage(LoggingLevel.WARN, "Could not map pointer type: {0}", fcsType);
Logger.LogExceptionSilently(e);
}
if (isFromReturn && type.IsUnitType)
return psiModule.GetPredefinedType().Void;
if (type.IsGenericParameter)
return GetTypeParameterByName(type, typeParams, psiModule);
if (!type.HasTypeDefinition)
return TypeFactory.CreateUnknownType(psiModule);
var entity = type.TypeDefinition;
// F# 4.0 specs 5.1.4
if (entity.IsArrayType)
{
var argType = GetSingleTypeArgument(type, typeParams, psiModule, isFromMethod);
return TypeFactory.CreateArrayType(argType, type.TypeDefinition.ArrayRank, NullableAnnotation.Unknown);
}
// e.g. byref<int>, we need int
if (entity.IsByRef)
return MapType(type.GenericArguments[0], typeParams, psiModule, isFromMethod, isFromReturn);
if (entity.IsProvidedAndErased)
return entity.BaseType is { } baseType
? MapType(baseType.Value, typeParams, psiModule, isFromMethod, isFromReturn)
: TypeFactory.CreateUnknownType(psiModule);
// todo: prevent getting clr name
var clrName = entity.GetClrName();
if (clrName == null)
{
// bug Microsoft/visualfsharp#3532
// e.g. byref<int>, we need int
return entity.CompiledName == "byref`1" && entity.AccessPath == "Microsoft.FSharp.Core"
? MapType(type.GenericArguments[0], typeParams, psiModule, isFromMethod, isFromReturn)
: TypeFactory.CreateUnknownType(psiModule);
}
if (entity.IsProvidedAndGenerated &&
ProvidedTypesResolveUtil.TryGetProvidedType(psiModule, clrName, out var providedType))
return MapType(providedType, psiModule);
var typeElement = entity.GetTypeElement(psiModule);
if (typeElement == null)
return TypeFactory.CreateUnknownType(psiModule);
var genericArgs = type.GenericArguments;
return genericArgs.IsEmpty()
? TypeFactory.CreateType(typeElement)
: GetTypeWithSubstitution(typeElement, genericArgs, typeParams, psiModule, isFromMethod);
}