private static IEnumerable <IType> GetAllRequiredTypesForMethod( IMethod method, ReadingTypesContext readingTypesContext) { DicoverGenericSpecializedTypesAndAdditionalTypes( method.ReturnType, readingTypesContext); foreach (var param in method.GetParameters()) { DicoverGenericSpecializedTypesAndAdditionalTypes( param.ParameterType, readingTypesContext); } if (method.DeclaringType.IsInterface) { yield break; } var methodWithCustomBodyOrDefault = MethodBodyBank.GetMethodWithCustomBodyOrDefault(method, _codeWriter); var methodBody = methodWithCustomBodyOrDefault.GetMethodBody(MetadataGenericContext.DiscoverFrom(method)); if (methodBody != null) { foreach (var localVar in methodBody.LocalVariables) { DicoverGenericSpecializedTypesAndAdditionalTypes( localVar.LocalType, readingTypesContext); if (localVar.LocalType.IsStructureType() && !localVar.LocalType.IsPointer && !localVar.LocalType.IsByRef) { yield return(localVar.LocalType); } } var usedStructTypes = new NamespaceContainer <IType>(); methodWithCustomBodyOrDefault.DiscoverRequiredTypesAndMethodsInMethodBody( readingTypesContext.GenericTypeSpecializations, readingTypesContext.GenericMethodSpecializations, usedStructTypes, readingTypesContext.AdditionalTypesToProcess, new Queue <IMethod>()); foreach (var usedStructType in usedStructTypes) { yield return(usedStructType); } } }
/// <summary> /// </summary> /// <param name="method"> /// </param> /// <param name="allCalledMethods"> /// </param> /// <param name="allReadStaticFields"> /// </param> private void WalkMethod(IMethod method, ISet <IMethod> allCalledMethods, ISet <IField> allReadStaticFields) { var calledMethods = new NamespaceContainer <IMethod>(); method.DiscoverMethod(null, calledMethods, allReadStaticFields); foreach (var nextMethod in calledMethods) { if (allCalledMethods.Contains(nextMethod)) { continue; } allCalledMethods.Add(nextMethod); this.WalkMethod(nextMethod, allCalledMethods, allReadStaticFields); } }
/// <summary> /// </summary> /// <returns> /// </returns> public ISet <IType> DiscoverAllStaticFieldsDependencies() { var calledMethods = new NamespaceContainer <IMethod>(); var readStaticFields = new NamespaceContainer <IField>(); this.WalkMethod(this.startMethod, calledMethods, readStaticFields); var typesWithStaticFields = new NamespaceContainer <IType>(); foreach (var staticField in readStaticFields) { if (staticField.DeclaringType.TypeEquals(this.startMethod.DeclaringType)) { continue; } typesWithStaticFields.Add(staticField.DeclaringType); } return(typesWithStaticFields); }
/// <summary> /// </summary> /// <param name="types"> /// </param> /// <param name="genericTypeSpecializations"> /// </param> /// <param name="genericMethodSpecializations"> /// </param> /// <returns> /// </returns> private static IList <IType> FindUsedTypes(IEnumerable <IType> types, IList <IType> allTypes, ReadingTypesContext readingTypesContext) { var usedTypes = new NamespaceContainer <IType>(); if (concurrent) { Parallel.ForEach(types, type => AppendTypeWithRequiredTypePair(type, usedTypes, readingTypesContext)); } else { foreach (var type in types) { AppendTypeWithRequiredTypePair(type, usedTypes, readingTypesContext); } } ProcessGenericTypesAndAdditionalTypesToFindRequiredTypes(usedTypes, readingTypesContext, true); DiscoverAllGenericVirtualMethods(allTypes, readingTypesContext); DiscoverAllGenericMethodsOfInterfaces(allTypes, readingTypesContext); return(usedTypes); }
/// <summary> /// </summary> /// <param name="genericTypeSpecializations"> /// </param> /// <param name="requiredTypes"> /// </param> private static void ProcessGenericTypesAndAdditionalTypesToFindRequiredTypes( IList <IType> requiredTypes, ReadingTypesContext readingTypesContext, bool applyConccurent = false) { var subSetGenericTypeSpecializations = new NamespaceContainer <IType>(); var subSetAdditionalTypesToProcess = new NamespaceContainer <IType>(); var subSetReadingContext = new ReadingTypesContext(); subSetReadingContext.GenericTypeSpecializations = subSetGenericTypeSpecializations; subSetReadingContext.GenericMethodSpecializations = readingTypesContext.GenericMethodSpecializations; subSetReadingContext.AdditionalTypesToProcess = subSetAdditionalTypesToProcess; subSetReadingContext.ProcessedTypes = readingTypesContext.ProcessedTypes; // the same for generic specialized types if (concurrent && applyConccurent) { Parallel.ForEach( readingTypesContext.GenericTypeSpecializations.ToList(), type => AppendTypeWithRequiredTypePair(type, requiredTypes, subSetReadingContext)); Parallel.ForEach( readingTypesContext.AdditionalTypesToProcess.ToList(), type => AppendTypeWithRequiredTypePair(type, requiredTypes, subSetReadingContext)); } else { foreach (var type in readingTypesContext.GenericTypeSpecializations.ToList()) { Debug.Assert(type != null); if (type == null) { continue; } AppendTypeWithRequiredTypePair(type, requiredTypes, subSetReadingContext); } foreach (var type in readingTypesContext.AdditionalTypesToProcess.ToList()) { Debug.Assert(type != null); if (type == null) { continue; } AppendTypeWithRequiredTypePair(type, requiredTypes, subSetReadingContext); } } if (subSetGenericTypeSpecializations.Count > 0 || subSetAdditionalTypesToProcess.Count > 0) { foreach (var discoveredType in requiredTypes) { subSetGenericTypeSpecializations.Remove(discoveredType); } foreach (var discoveredType in requiredTypes) { Debug.Assert(discoveredType != null); subSetAdditionalTypesToProcess.Remove(discoveredType); } ProcessGenericTypesAndAdditionalTypesToFindRequiredTypes(requiredTypes, subSetReadingContext); // join types foreach (var discoveredType in subSetGenericTypeSpecializations) { Debug.Assert(discoveredType != null); readingTypesContext.GenericTypeSpecializations.Add(discoveredType); } // join types foreach (var discoveredType in subSetAdditionalTypesToProcess) { Debug.Assert(discoveredType != null); readingTypesContext.AdditionalTypesToProcess.Add(discoveredType); } } }