Example #1
0
        public static void ProcessLibrary(LinkContext context, AssemblyDefinition assembly, RootVisibility rootVisibility = RootVisibility.Any)
        {
            var action = rootVisibility == RootVisibility.Any ? AssemblyAction.Copy : AssemblyAction.Link;

            SetAction(context, assembly, action);

            context.Annotations.Push(assembly);

            foreach (TypeDefinition type in assembly.MainModule.Types)
            {
                MarkType(context, type, rootVisibility);
            }

            if (assembly.MainModule.HasExportedTypes)
            {
                foreach (var exported in assembly.MainModule.ExportedTypes)
                {
                    bool isForwarder   = exported.IsForwarder;
                    var  declaringType = exported.DeclaringType;
                    while (!isForwarder && (declaringType != null))
                    {
                        isForwarder   = declaringType.IsForwarder;
                        declaringType = declaringType.DeclaringType;
                    }

                    if (!isForwarder)
                    {
                        continue;
                    }
                    TypeDefinition resolvedExportedType = null;
                    try {
                        resolvedExportedType = exported.Resolve();
                    } catch (AssemblyResolutionException) {
                        continue;
                    }

                    if (resolvedExportedType == null)
                    {
                        //
                        // It's quite common for assemblies to have broken exported types
                        //
                        // One source of them is from native csc which added all nested types of
                        // type-forwarded types automatically including private ones.
                        //
                        // Next source of broken type-forwarders is from custom metadata writers which
                        // simply write bogus information.
                        //
                        // Both cases are bugs not on our end but we still want to link all assemblies
                        // especially when such types cannot be used anyway
                        //
                        if (context.LogInternalExceptions)
                        {
                            System.Console.WriteLine($"Cannot find declaration of exported type '{exported}' from the assembly '{assembly}'");
                        }

                        continue;
                    }

                    context.Resolve(resolvedExportedType.Scope);
                    MarkType(context, resolvedExportedType, rootVisibility);
                    context.Annotations.Mark(exported);
                    if (context.KeepTypeForwarderOnlyAssemblies)
                    {
                        context.Annotations.Mark(assembly.MainModule);
                    }
                }
            }

            context.Annotations.Pop();
        }
Example #2
0
        static void MarkMethod(LinkContext context, MethodDefinition method, MethodAction action, RootVisibility rootVisibility)
        {
            bool markMethod = rootVisibility switch
            {
                RootVisibility.PublicAndFamily => method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly,
                RootVisibility.PublicAndFamilyAndAssembly => method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly || method.IsAssembly || method.IsFamilyAndAssembly,
                _ => true
            };

            if (markMethod)
            {
                context.Annotations.Mark(method, new DependencyInfo(DependencyKind.RootAssembly, method.Module.Assembly));
                context.Annotations.SetAction(method, action);
            }
        }
Example #3
0
 public ResolveFromAssemblyStep(string assembly, RootVisibility rootVisibility = RootVisibility.Any)
 {
     _file           = assembly;
     _rootVisibility = rootVisibility;
 }
Example #4
0
 static void MarkMethods(LinkContext context, Collection <MethodDefinition> methods, RootVisibility rootVisibility)
 {
     foreach (MethodDefinition method in methods)
     {
         MarkMethod(context, method, MethodAction.ForceParse, rootVisibility);
     }
 }
Example #5
0
 static void MarkFields(LinkContext context, Collection <FieldDefinition> fields, RootVisibility rootVisibility)
 {
     foreach (FieldDefinition field in fields)
     {
         bool markField = rootVisibility switch
         {
             RootVisibility.PublicAndFamily => field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly,
             RootVisibility.PublicAndFamilyAndAssembly => field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly || field.IsAssembly || field.IsFamilyAndAssembly,
             _ => true
         };
         if (markField)
         {
             context.Annotations.Mark(field, new DependencyInfo(DependencyKind.RootAssembly, field.Module.Assembly));
         }
     }
 }
        static void MarkMethod(LinkContext context, MethodDefinition method, MethodAction action, RootVisibility rootVisibility)
        {
            bool markMethod;

            switch (rootVisibility)
            {
            default:
                markMethod = true;
                break;

            case RootVisibility.PublicAndFamily:
                markMethod = method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly;
                break;

            case RootVisibility.PublicAndFamilyAndAssembly:
                markMethod = method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly || method.IsAssembly || method.IsFamilyAndAssembly;
                break;
            }

            if (markMethod)
            {
                context.Annotations.Mark(method);
                context.Annotations.SetAction(method, action);
            }
        }
        static void MarkFields(LinkContext context, Collection <FieldDefinition> fields, RootVisibility rootVisibility)
        {
            foreach (FieldDefinition field in fields)
            {
                bool markField;
                switch (rootVisibility)
                {
                default:
                    markField = true;
                    break;

                case RootVisibility.PublicAndFamily:
                    markField = field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly;
                    break;

                case RootVisibility.PublicAndFamilyAndAssembly:
                    markField = field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly || field.IsAssembly || field.IsFamilyAndAssembly;
                    break;
                }
                if (markField)
                {
                    context.Annotations.Mark(field);
                }
            }
        }
Example #8
0
        public static void ProcessLibrary(LinkContext context, AssemblyDefinition assembly, RootVisibility rootVisibility = RootVisibility.Any)
        {
            var action = rootVisibility == RootVisibility.Any ? AssemblyAction.Copy : AssemblyAction.Link;

            SetAction(context, assembly, action);

            context.Annotations.Push(assembly);

            foreach (TypeDefinition type in assembly.MainModule.Types)
            {
                MarkType(context, type, rootVisibility);
            }

            if (assembly.MainModule.HasExportedTypes)
            {
                foreach (var exported in assembly.MainModule.ExportedTypes)
                {
                    bool isForwarder   = exported.IsForwarder;
                    var  declaringType = exported.DeclaringType;
                    while (!isForwarder && (declaringType != null))
                    {
                        isForwarder   = declaringType.IsForwarder;
                        declaringType = declaringType.DeclaringType;
                    }

                    if (!isForwarder)
                    {
                        continue;
                    }
                    TypeDefinition resolvedExportedType = null;
                    try {
                        resolvedExportedType = exported.Resolve();
                    } catch (AssemblyResolutionException) {
                        continue;
                    }
                    if (resolvedExportedType == null)
                    {
                        // we ignore the nested forwarders here as a workaround for older csc bug,
                        // where it was adding nested forwarders to exported types, even when the nested type was not public
                        // see https://bugzilla.xamarin.com/show_bug.cgi?id=57645#c13
                        if (exported.DeclaringType != null)
                        {
                            if (context.LogInternalExceptions)
                            {
                                System.Console.WriteLine($"warning: unable to resolve exported nested type: {exported} (declaring type: {exported.DeclaringType}) from the assembly: {assembly}");
                            }

                            continue;
                        }
                        throw new LoadException($"unable to resolve exported forwarded type: {exported} from the assembly: {assembly}");
                    }

                    context.Resolve(resolvedExportedType.Scope);
                    MarkType(context, resolvedExportedType, rootVisibility);
                    context.Annotations.Mark(exported);
                    if (context.KeepTypeForwarderOnlyAssemblies)
                    {
                        context.Annotations.Mark(assembly.MainModule);
                    }
                }
            }

            context.Annotations.Pop();
        }