private IteratorTypeInfo CreateIteratorTypeInfo(Type type) { TypeInfo typeInfo = type.GetTypeInfo(); var fi = new IteratorTypeInfo { Type = type, MethodName = NameUtility.ParseOriginalName(type.Name), Constructor = typeInfo.DeclaredConstructors.FirstOrDefault(c => !c.IsStatic) }; foreach (FieldInfo field in typeInfo.DeclaredFields) { char typeChar; string suffix; string original; if (NameUtility.TryParseGeneratedName(field.Name, out typeChar, out suffix, out original)) { if (typeChar == StateTypeChar) { // Must check suffix too since <>1__managedThreadId is also used if (suffix == StateSuffix) { fi.State = field; } } else if (typeChar == CurrentTypeChar) { fi.Current = field; } else if (typeChar == ThisTypeChar) { fi.This = field; } else if (typeChar == ArgumentTypeChar) { fi.Arguments.Add(original ?? suffix, field); } else if (typeChar == HoistedVariableTypeChar) { Debug.Assert(original != null); fi.Variables.Add(original, field); } } else { Debug.Assert(!field.IsPublic); fi.Variables.Add(field.Name, field); } } if (fi.Current == null || fi.State == null || fi.Constructor == null) { return(null); } return(fi); }
private Type GetIteratorTypeChecked(string declaringTypeName, string methodName) { Type declaringType = Type.GetType(declaringTypeName, true); Tuple <string, string> key = Tuple.Create(declaringType.AssemblyQualifiedName, methodName); Type iteratorType; if (_iteratorTypes.TryGetValue(key, out iteratorType)) { return(iteratorType); } TypeInfo declaringTypeInfo = declaringType.GetTypeInfo(); MethodInfo method = declaringTypeInfo.GetDeclaredMethod(methodName); if (method == null || !(s_enumeratorType.IsAssignableFrom(method.ReturnType.GetTypeInfo()) || s_enumerableType.IsAssignableFrom(method.ReturnType.GetTypeInfo()))) { throw new ArgumentException("invalid iterator method name: " + methodName, nameof(methodName)); } foreach (TypeInfo nt in declaringTypeInfo.DeclaredNestedTypes) { char typeChar; string suffix; string original; if (NameUtility.TryParseGeneratedName(nt.Name, out typeChar, out suffix, out original) && typeChar == StateMachineTypeChar && original == methodName) { iteratorType = nt.AsType(); break; } } if (iteratorType == null) { throw new ArgumentException($"no iterator state machine type found for method {methodName} and type {declaringType.AssemblyQualifiedName}"); } _iteratorTypes.Add(key, iteratorType); return(iteratorType); }