ProcessedAssembly GetMscorlib(Type t) { var a = t.Assembly; if (a.GetName().Name != "mscorlib") { throw ErrorHelper.CreateError(99, "Internal error: incorrect assembly for `{t}`. Please file a bug report with a test case (https://github.com/mono/Embeddinator-4000/issues)"); } if (mscorlib_assembly == null) { mscorlib_assembly = new ProcessedAssembly(a) { UserCode = false, }; } return(mscorlib_assembly); }
public override void Process(IEnumerable <Assembly> input) { foreach (var a in input) { var pa = new ProcessedAssembly(a); // ignoring/warning one is not an option as they could be different (e.g. different builds/versions) if (!AddIfUnique(pa)) { throw ErrorHelper.CreateError(12, $"The assembly name `{pa.Name}` is not unique"); } foreach (var t in GetTypes(a)) { if (t.IsEnum) { enums.Add(new ProcessedType(t)); continue; } if (t.IsInterface) { protocols.Add(new ProcessedType(t)); } else { types.Add(new ProcessedType(t)); } extension_type = t.HasCustomAttribute("System.Runtime.CompilerServices", "ExtensionAttribute"); implement_system_icomparable = t.Implements("System", "IComparable"); implement_system_icomparable_t = t.Implements("System", "IComparable`1"); var constructors = GetConstructors(t).OrderBy((arg) => arg.ParameterCount).ToList(); var processedConstructors = PostProcessConstructors(constructors).ToList(); if (processedConstructors.Count > 0) { ctors.Add(t, processedConstructors); } var typeEquals = equals.Where(x => x.Key == t).Select(x => x.Value); var meths = GetMethods(t).OrderBy((arg) => arg.Name).ToList(); var processedMethods = PostProcessMethods(meths, typeEquals).ToList(); if (processedMethods.Count > 0) { methods.Add(t, processedMethods); } var props = new List <PropertyInfo> (); var subscriptProps = new List <PropertyInfo> (); foreach (var pi in GetProperties(t)) { var getter = pi.GetGetMethod(); var setter = pi.GetSetMethod(); // setter only property are valid in .NET and we need to generate a method in ObjC (there's no writeonly properties) if (getter == null) { continue; } // indexers are implemented as methods and object subscripting if ((getter.ParameterCount > 0) || ((setter != null) && setter.ParameterCount > 1)) { subscriptProps.Add(pi); continue; } // we can do better than methods for the more common cases (readonly and readwrite) processedMethods.RemoveAll(x => x.Method == getter); processedMethods.RemoveAll(x => x.Method == setter); props.Add(pi); } props = props.OrderBy((arg) => arg.Name).ToList(); var processedProperties = PostProcessProperties(props).ToList(); if (processedProperties.Count > 0) { properties.Add(t, processedProperties); } if (subscriptProps.Count > 0) { if (subscriptProps.Count > 1) { delayed.Add(ErrorHelper.CreateWarning(1041, $"Indexed properties on {t.Name} is not generated because multiple indexed properties not supported.")); } else { subscriptProperties.Add(t, PostProcessSubscriptProperties(subscriptProps).ToList()); } } // fields will need to be wrapped within properties var f = GetFields(t).OrderBy((arg) => arg.Name).ToList(); var processedFields = PostProcessFields(f).ToList(); if (processedFields.Count > 0) { fields.Add(t, processedFields); } } } types = types.OrderBy((arg) => arg.Type.FullName).OrderBy((arg) => types.Contains(arg.Type.BaseType)).ToList(); Console.WriteLine($"\t{types.Count} types found"); ErrorHelper.Show(delayed); }
protected override void Generate(ProcessedAssembly a) { var originalName = a.Name; var name = a.SafeName; implementation.WriteLine($"static void __lookup_assembly_{name} ()"); implementation.WriteLine("{"); implementation.Indent++; implementation.WriteLine($"if (__{name}_image)"); implementation.Indent++; implementation.WriteLine("return;"); implementation.Indent--; implementation.WriteLine("__initialize_mono ();"); implementation.WriteLine($"__{name}_image = mono_embeddinator_load_assembly (&__mono_context, \"{originalName}.dll\");"); implementation.WriteLine($"assert (__{name}_image && \"Could not load the assembly '{originalName}.dll'.\");"); var categories = extensions_methods.Keys; if (categories.Count > 0) { implementation.WriteLine("// we cannot use `+initialize` inside categories as they would replace the original type code"); implementation.WriteLine("// since there should not be tons of them we're pre-loading them when loading the assembly"); foreach (var definedType in extensions_methods.Keys) { var managed_name = NameGenerator.GetObjCName(definedType); implementation.WriteLineUnindented("#if TOKENLOOKUP"); implementation.WriteLine($"{managed_name}_class = mono_class_get (__{name}_image, 0x{definedType.MetadataToken:X8});"); implementation.WriteLineUnindented("#else"); implementation.WriteLine($"{managed_name}_class = mono_class_from_name (__{name}_image, \"{definedType.Namespace}\", \"{definedType.Name}\");"); implementation.WriteLineUnindented("#endif"); } } implementation.Indent--; implementation.WriteLine("}"); implementation.WriteLine(); var assembly = a.Assembly; foreach (var t in enums.Where((ProcessedType arg) => arg.Type.Assembly == assembly)) { GenerateEnum(t); } foreach (var t in protocols.Where((ProcessedType arg) => arg.Type.Assembly == assembly)) { GenerateProtocol(t); } foreach (var t in types.Where((ProcessedType arg) => arg.Type.Assembly == assembly)) { Generate(t); } foreach (var extension in extensions_methods) { var defining_type = extension.Key; if (defining_type.Assembly != assembly) { continue; } foreach (var category in extension.Value) { GenerateCategory(defining_type, category.Key, category.Value); } } }