protected virtual void SweepAssembly(AssemblyDefinition assembly) { var types = new List <TypeDefinition> (); ModuleDefinition main = assembly.MainModule; bool updateScopes = false; foreach (TypeDefinition type in main.Types) { if (!ShouldRemove(type)) { SweepType(type); types.Add(type); updateScopes = true; continue; } // Is <Module> type. if (type.MetadataToken.RID == 1) { types.Add(type); } else { ElementRemoved(type); } } main.Types.Clear(); foreach (TypeDefinition type in types) { main.Types.Add(type); } SweepResources(assembly); updateScopes |= SweepCustomAttributes(assembly); foreach (var module in assembly.Modules) { updateScopes |= SweepCustomAttributes(module); } // // MainModule module references are used by pinvoke // if (main.HasModuleReferences) { updateScopes |= SweepCollectionMetadata(main.ModuleReferences); } if (main.EntryPoint != null && !Annotations.IsMarked(main.EntryPoint)) { main.EntryPoint = null; } if (SweepTypeForwarders(assembly) || updateScopes) { AssemblyReferencesCorrector.SweepAssemblyReferences(assembly); } }
protected override void Process() { // To keep facades, scan all references so that even unused facades are kept var assemblies = Context.KeepTypeForwarderOnlyAssemblies ? Context.GetReferencedAssemblies().ToArray() : Annotations.GetAssemblies().ToArray(); // Ensure that any assemblies which need to be removed are marked for deletion, // including assemblies which are not referenced by any others. foreach (var assembly in assemblies) { RemoveUnmarkedAssembly(assembly); } // Look for references (included to previously unresolved assemblies) marked for deletion foreach (var assembly in assemblies) { UpdateAssemblyReferencesToRemovedAssemblies(assembly); } // Update scopes before removing any type forwarder. foreach (var assembly in assemblies) { var action = Annotations.GetAction(assembly); switch (action) { case AssemblyAction.CopyUsed: case AssemblyAction.Link: case AssemblyAction.Save: bool changed = AssemblyReferencesCorrector.SweepAssemblyReferences(assembly); if (changed && action == AssemblyAction.CopyUsed) { Annotations.SetAction(assembly, AssemblyAction.Save); } break; } } foreach (var assembly in assemblies) { ProcessAssemblyAction(assembly); } if (Context.KeepTypeForwarderOnlyAssemblies) { return; } // Ensure that we remove any assemblies which were resolved while sweeping references foreach (var assembly in Annotations.GetAssemblies().ToArray()) { if (!assemblies.Any(processedAssembly => processedAssembly == assembly)) { Debug.Assert(!IsUsedAssembly(assembly)); Annotations.SetAction(assembly, AssemblyAction.Delete); } } }
protected void ProcessAssemblyAction(AssemblyDefinition assembly) { switch (Annotations.GetAction(assembly)) { case AssemblyAction.AddBypassNGenUsed: Annotations.SetAction(assembly, AssemblyAction.AddBypassNGen); goto case AssemblyAction.AddBypassNGen; case AssemblyAction.AddBypassNGen: // FIXME: AddBypassNGen is just wrong, it should not be action as we need to // turn it to Action.Save here to e.g. correctly update debug symbols if (!Context.KeepTypeForwarderOnlyAssemblies || BypassNGenToSave.Contains(assembly)) { goto case AssemblyAction.Save; } break; case AssemblyAction.CopyUsed: AssemblyAction assemblyAction = AssemblyAction.Copy; if (!Context.KeepTypeForwarderOnlyAssemblies && SweepTypeForwarders(assembly)) { // Need to sweep references, in case sweeping type forwarders removed any AssemblyReferencesCorrector.SweepAssemblyReferences(assembly); assemblyAction = AssemblyAction.Save; } Annotations.SetAction(assembly, assemblyAction); break; case AssemblyAction.Copy: break; case AssemblyAction.Link: SweepAssembly(assembly); break; case AssemblyAction.Save: if (!Context.KeepTypeForwarderOnlyAssemblies && SweepTypeForwarders(assembly)) { // Need to sweep references, in case sweeping type forwarders removed any AssemblyReferencesCorrector.SweepAssemblyReferences(assembly); } break; } }