public TypeInfo GetTypeInformation(TypeReference type) { if (type == null) { throw new ArgumentNullException("type"); } TypeInfo result; var typedef = TypeUtil.GetTypeDefinition(type); if (typedef == null) { return(null); } var identifier = new TypeIdentifier(typedef); if (TypeInformation.TryGet(identifier, out result)) { return(result); } var args = new MakeTypeInfoArgs(); EnqueueType(args.TypesToInitialize, type); // We must construct type information in two passes, so that method group construction // behaves correctly and ignores all the right methods. // The first pass walks all the way through the type graph (starting with the current type), // ensuring we have type information for all the types in the graph. We do this iteratively // to avoid overflowing the stack. // After we have type information for all the types in the graph, we then walk over all // the types again, and construct their method groups, since we have the necessary // information to determine which methods are ignored. while (args.TypesToInitialize.Count > 0) { var kvp = args.TypesToInitialize.First; args.TypesToInitialize.Remove(kvp.Key); args.Definition = kvp.Value; TypeInformation.TryCreate( kvp.Key, args, MakeTypeInfo ); } foreach (var ti in args.SecondPass.Values) { ti.Initialize(); ti.ConstructMethodGroups(); } if (!TypeInformation.TryGet(identifier, out result)) { return(null); } else { return(result); } }
private TypeInfo _MakeTypeInfo(TypeIdentifier identifier, MakeTypeInfoArgs args) { var constructed = ConstructTypeInformation(identifier, args.Definition, args.MoreTypes); args.SecondPass.Add(identifier, constructed); foreach (var typedef in args.MoreTypes.Values) { EnqueueType(args.TypesToInitialize, typedef); } args.MoreTypes.Clear(); return(constructed); }