DmdType?CreateCore(TypeMirror type) { if (type is null) { throw new ArgumentNullException(nameof(type)); } if (recursionCounter++ > 100) { throw new InvalidOperationException(); } List <DmdType>?types; DmdType? result; if (!typeCache.TryGetType(type, out result)) { bool canAddType = true; if (type.IsByRef) { result = CreateCore(type.GetElementType())?.MakeByRefType(); } else if (type.IsArray) { if (type.GetArrayRank() == 1) { if (type.FullName.EndsWith("[*]", StringComparison.Ordinal)) { result = CreateCore(type.GetElementType())?.MakeArrayType(1); } else { result = CreateCore(type.GetElementType())?.MakeArrayType(); } } else { result = CreateCore(type.GetElementType())?.MakeArrayType(type.GetArrayRank()); } } else if (type.IsPointer) { result = CreateCore(type.GetElementType())?.MakePointerType(); } else { var module = engine.TryGetModule(type.Module)?.GetReflectionModule() ?? throw new InvalidOperationException(); var reflectionType = module.ResolveType(type.MetadataToken, DmdResolveOptions.None); if (!(reflectionType is null) && reflectionType.GetGenericArguments().Count != 0) { DmdType? parsedType = null; TypeMirror[] genericArgs; if (type.VirtualMachine.Version.AtLeast(2, 15)) { genericArgs = type.GetGenericArguments(); } else { parsedType = reflectionType.Assembly.GetType(type.FullName); if (!(parsedType is null) && parsedType.MetadataToken != type.MetadataToken) { parsedType = null; } genericArgs = Array.Empty <TypeMirror>(); canAddType = !(parsedType is null); } if (!(parsedType is null)) { reflectionType = parsedType; } else { types = GetTypesList(); foreach (var t in genericArgs) { var newType = CreateCore(t); if (newType is null) { reflectionType = null; break; } types.Add(newType); } if (!(reflectionType is null)) { Debug.Assert(types.Count == 0 || reflectionType.GetGenericArguments().Count == types.Count); if (types.Count != 0) { reflectionType = reflectionType.MakeGenericType(types.ToArray()); } } FreeTypesList(ref types); } }