Example #1
0
 protected IEnumerable <ProcessedFieldInfo> PostProcessFields(IEnumerable <FieldInfo> fields)
 {
     foreach (FieldInfo field in fields)
     {
         ProcessedFieldInfo processedField = new ProcessedFieldInfo(field, this);
         yield return(processedField);
     }
 }
        protected void Generate(ProcessedFieldInfo field)
        {
            FieldInfo fi        = field.Field;
            bool      read_only = fi.IsInitOnly || fi.IsLiteral;

            headers.Write("@property (nonatomic");
            if (fi.IsStatic)
            {
                headers.Write(", class");
            }
            if (read_only)
            {
                headers.Write(", readonly");
            }
            var ft    = fi.FieldType;
            var bound = types.Contains(ft);

            if (bound && ft.IsValueType)
            {
                headers.Write(", nonnull");
            }

            var field_type = NameGenerator.GetTypeName(ft);

            if (bound)
            {
                field_type += " *";
            }

            var name = fi.Name.CamelCase();

            var spacing = field_type [field_type.Length - 1] == '*' ? string.Empty : " ";

            headers.WriteLine($") {field_type}{spacing}{name};");

            // it's similar, but different from implementing a method

            var type = fi.DeclaringType;
            var managed_type_name = NameGenerator.GetObjCName(type);
            var return_type       = GetReturnType(type, fi.FieldType);

            implementation.Write(fi.IsStatic ? '+' : '-');
            implementation.WriteLine($" ({return_type}) {name}");
            implementation.WriteLine("{");
            implementation.Indent++;
            implementation.WriteLine("static MonoClassField* __field = nil;");
            implementation.WriteLine("if (!__field) {");
            implementation.Indent++;
            implementation.WriteLineUnindented("#if TOKENLOOKUP");
            implementation.WriteLine($"__field = mono_class_get_field ({managed_type_name}_class, 0x{fi.MetadataToken:X8});");
            implementation.WriteLineUnindented("#else");
            implementation.WriteLine($"const char __field_name [] = \"{fi.Name}\";");
            implementation.WriteLine($"__field = mono_class_get_field_from_name ({managed_type_name}_class, __field_name);");
            implementation.WriteLineUnindented("#endif");
            implementation.Indent--;
            implementation.WriteLine("}");
            var instance = "nil";

            if (!fi.IsStatic)
            {
                implementation.WriteLine($"MonoObject* __instance = mono_gchandle_get_target (_object->_handle);");
                instance = "__instance";
            }
            implementation.WriteLine($"MonoObject* __result = mono_field_get_value_object (__mono_context.domain, __field, {instance});");
            if (types.Contains(ft))
            {
                implementation.WriteLine("if (!__result)");
                implementation.Indent++;
                implementation.WriteLine("return nil;");
                implementation.Indent--;
            }
            ReturnValue(fi.FieldType);
            implementation.Indent--;
            implementation.WriteLine("}");
            implementation.WriteLine();

            if (read_only)
            {
                return;
            }
            implementation.Write(fi.IsStatic ? '+' : '-');
            implementation.WriteLine($" (void) set{fi.Name}:({field_type})value");
            implementation.WriteLine("{");
            implementation.Indent++;
            implementation.WriteLine("static MonoClassField* __field = nil;");
            implementation.WriteLine("if (!__field) {");
            implementation.Indent++;
            implementation.WriteLineUnindented("#if TOKENLOOKUP");
            implementation.WriteLine($"__field = mono_class_get_field ({managed_type_name}_class, 0x{fi.MetadataToken:X8});");
            implementation.WriteLineUnindented("#else");
            implementation.WriteLine($"const char __field_name [] = \"{fi.Name}\";");
            implementation.WriteLine($"__field = mono_class_get_field_from_name ({managed_type_name}_class, __field_name);");
            implementation.WriteLineUnindented("#endif");
            implementation.Indent--;
            implementation.WriteLine("}");
            StringBuilder sb = null;

            implementation.WriteLine($"void* __value;");
            GenerateArgument("value", "__value", fi.FieldType, ref sb);
            if (fi.IsStatic)
            {
                implementation.WriteLine($"MonoVTable *__vtable = mono_class_vtable (__mono_context.domain, {managed_type_name}_class);");
                implementation.WriteLine("mono_field_static_set_value (__vtable, __field, __value);");
            }
            else
            {
                implementation.WriteLine($"MonoObject* __instance = mono_gchandle_get_target (_object->_handle);");
                implementation.WriteLine("mono_field_set_value (__instance, __field, __value);");
            }
            implementation.Indent--;
            implementation.WriteLine("}");
            implementation.WriteLine();
        }