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(); }
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); } }
public ResolveFromAssemblyStep(string assembly, RootVisibility rootVisibility = RootVisibility.Any) { _file = assembly; _rootVisibility = rootVisibility; }
static void MarkMethods(LinkContext context, Collection <MethodDefinition> methods, RootVisibility rootVisibility) { foreach (MethodDefinition method in methods) { MarkMethod(context, method, MethodAction.ForceParse, rootVisibility); } }
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); } } }
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(); }