예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        static void SweepAssemblyReferences(AssemblyDefinition assembly)
        {
            //
            // We used to run over list returned by GetTypeReferences but
            // that returns typeref(s) of original assembly and we don't track
            // which types are needed for which assembly which left us
            // with dangling assembly references
            //
            assembly.MainModule.AssemblyReferences.Clear();

            var ars = new AssemblyReferencesCorrector(assembly);

            ars.Process();
        }
예제 #4
0
        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;
            }
        }