GetProperties() public method

public GetProperties ( ) : IKVM.Reflection.PropertyInfo[]
return IKVM.Reflection.PropertyInfo[]
Ejemplo n.º 1
0
        internal static MemberInfo[] GetInstanceFieldsAndProperties(Type type, bool publicOnly)
        {
#if WINRT
            System.Collections.Generic.List<MemberInfo> members = new System.Collections.Generic.List<MemberInfo>();
            foreach(FieldInfo field in type.GetRuntimeFields())
            {
                if(field.IsStatic) continue;
                if(field.IsPublic || !publicOnly) members.Add(field);
            }
            foreach(PropertyInfo prop in type.GetRuntimeProperties())
            {
                MethodInfo getter = Helpers.GetGetMethod(prop, true, true);
                if(getter == null || getter.IsStatic) continue;
                if(getter.IsPublic || !publicOnly) members.Add(prop);
            }
            return members.ToArray();
#else
            BindingFlags flags = publicOnly ? BindingFlags.Public | BindingFlags.Instance : BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
            PropertyInfo[] props = type.GetProperties(flags);
            FieldInfo[] fields = type.GetFields(flags);
            MemberInfo[] members = new MemberInfo[fields.Length + props.Length];
            props.CopyTo(members, 0);
            fields.CopyTo(members, props.Length);
            return members;
#endif
        }
Ejemplo n.º 2
0
 protected IEnumerable <PropertyInfo> GetProperties(Type t)
 {
     foreach (var pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly))
     {
         var pt = pi.PropertyType;
         if (!IsSupported(pt))
         {
             Delayed.Add(ErrorHelper.CreateWarning(1040, $"Property `{pi}` is not generated because of parameter type `{pt}` is not supported."));
             continue;
         }
         yield return(pi);
     }
 }
Ejemplo n.º 3
0
    public void GenerateFilter(Type type)
    {
        var is_abstract = AttributeManager.HasAttribute <AbstractAttribute> (type);
        var filter      = AttributeManager.GetCustomAttribute <CoreImageFilterAttribute> (type);
        var base_type   = AttributeManager.GetCustomAttribute <BaseTypeAttribute> (type);
        var type_name   = type.Name;
        var native_name = base_type.Name ?? type_name;
        var base_name   = base_type.BaseType.Name;

        // internal static CIFilter FromName (string filterName, IntPtr handle)
        filters.Add(type_name);

        // type declaration
        print("public{0} partial class {1} : {2} {{",
              is_abstract ? " abstract" : String.Empty,
              type_name, base_name);
        print("");
        indent++;

        // default constructor - if type is not abstract
        string v;

        if (!is_abstract)
        {
            v = GetVisibility(filter.DefaultCtorVisibility);
            if (v.Length > 0)
            {
                print_generated_code();
                print("{0}{1} () : base (\"{2}\")", v, type.Name, native_name);
                PrintEmptyBody();
            }
        }

        // IntPtr constructor - always present
        var intptrctor_visibility = filter.IntPtrCtorVisibility;

        if (intptrctor_visibility == MethodAttributes.PrivateScope)
        {
            // since it was not generated code we never fixed the .ctor(IntPtr) visibility for unified
            if (Generator.XamcoreVersion >= 3)
            {
                intptrctor_visibility = MethodAttributes.FamORAssem;
            }
            else
            {
                intptrctor_visibility = MethodAttributes.Public;
            }
        }
        print_generated_code();
        print("{0}{1} (IntPtr handle) : base (handle)", GetVisibility(intptrctor_visibility), type_name);
        PrintEmptyBody();

        // NSObjectFlag constructor - always present (needed to implement NSCoder for subclasses)
        print_generated_code();
        print("[EditorBrowsable (EditorBrowsableState.Advanced)]");
        print("protected {0} (NSObjectFlag t) : base (t)", type_name);
        PrintEmptyBody();

        // NSCoder constructor - all filters conforms to NSCoding
        print_generated_code();
        print("[EditorBrowsable (EditorBrowsableState.Advanced)]");
        print("[Export (\"initWithCoder:\")]");
        print("public {0} (NSCoder coder) : base (NSObjectFlag.Empty)", type_name);
        print("{");
        indent++;
        print("IntPtr h;");
        print("if (IsDirectBinding) {");
        indent++;
        print("h = global::{0}.Messaging.IntPtr_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle (\"initWithCoder:\"), coder.Handle);", ns.CoreObjCRuntime);
        indent--;
        print("} else {");
        indent++;
        print("h = global::{0}.Messaging.IntPtr_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle (\"initWithCoder:\"), coder.Handle);", ns.CoreObjCRuntime);
        indent--;
        print("}");
        print("InitializeHandle (h, \"initWithCoder:\");");
        indent--;
        print("}");
        print("");

        // string constructor
        // default is protected (for abstract) but backward compatibility (XAMCORE_2_0) requires some hacks
        v = GetVisibility(filter.StringCtorVisibility);
        if (is_abstract && (v.Length == 0))
        {
            v = "protected ";
        }
        if (v.Length > 0)
        {
            print_generated_code();
            print("{0} {1} (string name) : base (CreateFilter (name))", v, type_name);
            PrintEmptyBody();
        }

        // properties
        foreach (var p in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
        {
            if (p.IsUnavailable())
            {
                continue;
            }

            print("");
            print_generated_code();
            var ptype = p.PropertyType.Name;
            // keep C# names as they are reserved keywords (e.g. Boolean also exists in OpenGL for Mac)
            switch (ptype)
            {
            case "Boolean":
                ptype = "bool";
                break;

            case "Int32":
                ptype = "int";
                break;

            case "Single":
                ptype = "float";
                break;

            case "String":
                ptype = "string";
                break;
            }
            print("public {0} {1} {{", ptype, p.Name);
            indent++;

            var name = AttributeManager.GetCustomAttribute <CoreImageFilterPropertyAttribute> (p)?.Name;
            if (p.GetGetMethod() != null)
            {
                GenerateFilterGetter(ptype, name);
            }
            if (p.GetSetMethod() != null)
            {
                GenerateFilterSetter(ptype, name);
            }

            indent--;
            print("}");
        }

        indent--;
        print("}");

        // namespace closing (it's optional to use namespaces even if it's a bad practice, ref #35283)
        if (indent > 0)
        {
            indent--;
            print("}");
        }
    }
Ejemplo n.º 4
0
        public void OutlineType()
        {
            bool first;

            OutlineAttributes();
            o.Write(GetTypeVisibility(t));

            if (t.IsClass && !t.IsSubclassOf(type_multicast_delegate))
            {
                if (t.IsSealed)
                {
                    o.Write(t.IsAbstract ? " static" : " sealed");
                }
                else if (t.IsAbstract)
                {
                    o.Write(" abstract");
                }
            }

            o.Write(" ");
            o.Write(GetTypeKind(t));
            o.Write(" ");

            Type [] interfaces = (Type [])Comparer.Sort(TypeGetInterfaces(t, declared_only));
            Type    parent     = t.BaseType;

            if (t.IsSubclassOf(type_multicast_delegate))
            {
                MethodInfo method;

                method = t.GetMethod("Invoke");

                o.Write(FormatType(method.ReturnType));
                o.Write(" ");
                o.Write(GetTypeName(t));
                o.Write(" (");
                OutlineParams(method.GetParameters());
                o.Write(")");

                WriteGenericConstraints(t.GetGenericArguments());

                o.WriteLine(";");
                return;
            }

            o.Write(GetTypeName(t));
            if (((parent != null && parent != type_object && parent != type_value_type) || interfaces.Length != 0) && !t.IsEnum)
            {
                first = true;
                o.Write(" : ");

                if (parent != null && parent != type_object && parent != type_value_type)
                {
                    o.Write(FormatType(parent));
                    first = false;
                }

                foreach (Type intf in interfaces)
                {
                    if (!first)
                    {
                        o.Write(", ");
                    }
                    first = false;

                    o.Write(FormatType(intf));
                }
            }

            if (t.IsEnum)
            {
                Type underlyingType = t.GetEnumUnderlyingType();
                if (underlyingType != type_int)
                {
                    o.Write(" : {0}", FormatType(underlyingType));
                }
            }
            WriteGenericConstraints(t.GetGenericArguments());
            o.WriteLine(" {");
            o.Indent++;

            if (t.IsEnum)
            {
                bool is_first = true;
                foreach (FieldInfo fi in t.GetFields(BindingFlags.Public | BindingFlags.Static))
                {
                    if (!is_first)
                    {
                        o.WriteLine(",");
                    }
                    is_first = false;
                    o.Write(fi.Name);
                }
                o.WriteLine();
                o.Indent--; o.WriteLine("}");
                return;
            }

            first = true;

            foreach (ConstructorInfo ci in t.GetConstructors(DefaultFlags))
            {
                if (!ShowMember(ci))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(ci);
                OutlineConstructor(ci);

                o.WriteLine();
            }


            first = true;

            foreach (MethodInfo m in Comparer.Sort(t.GetMethods(DefaultFlags)))
            {
                if (!ShowMember(m))
                {
                    continue;
                }

                if ((m.Attributes & MethodAttributes.SpecialName) != 0)
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(m);
                OutlineMethod(m);

                o.WriteLine();
            }

            first = true;

            foreach (MethodInfo m in t.GetMethods(DefaultFlags))
            {
                if (!ShowMember(m))
                {
                    continue;
                }

                if ((m.Attributes & MethodAttributes.SpecialName) == 0)
                {
                    continue;
                }
                if (!(m.Name.StartsWith("op_")))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(m);
                OutlineOperator(m);

                o.WriteLine();
            }

            first = true;

            foreach (PropertyInfo pi in Comparer.Sort(t.GetProperties(DefaultFlags)))
            {
                if (!((pi.CanRead && ShowMember(pi.GetGetMethod(true))) ||
                      (pi.CanWrite && ShowMember(pi.GetSetMethod(true)))))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(pi);
                OutlineProperty(pi);

                o.WriteLine();
            }

            first = true;

            foreach (FieldInfo fi in t.GetFields(DefaultFlags))
            {
                if (!ShowMember(fi))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(fi);
                OutlineField(fi);

                o.WriteLine();
            }

            first = true;

            foreach (EventInfo ei in Comparer.Sort(t.GetEvents(DefaultFlags)))
            {
                if (!ShowMember(ei.GetAddMethod(true)))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(ei);
                OutlineEvent(ei);

                o.WriteLine();
            }

            first = true;

            foreach (Type ntype in Comparer.Sort(t.GetNestedTypes(DefaultFlags)))
            {
                if (!ShowMember(ntype))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

#if STATIC
                new Outline(universe, mscorlib, ntype, o, declared_only, show_private, filter_obsolete).OutlineType();
#else
                new Outline(ntype, o, declared_only, show_private, filter_obsolete).OutlineType();
#endif
            }

            o.Indent--; o.WriteLine("}");
        }
Ejemplo n.º 5
0
    void GenerateProperties(Type type)
    {
        foreach (var p in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
        {
            if (p.IsUnavailable(this))
            {
                continue;
            }
            if (AttributeManager.HasAttribute <StaticAttribute> (p))
            {
                continue;
            }

            print("");
            PrintPropertyAttributes(p);
            print_generated_code();

            var ptype = p.PropertyType.Name;
            // keep C# names as they are reserved keywords (e.g. Boolean also exists in OpenGL for Mac)
            switch (ptype)
            {
            case "Boolean":
                ptype = "bool";
                break;

            case "Int32":
                ptype = "int";
                break;

            case "Single":
                ptype = "float";
                break;

            case "String":
                ptype = "string";
                break;

            // adding `using ImageIO;` would lead to `error CS0104: 'CGImageProperties' is an ambiguous reference between 'CoreGraphics.CGImageProperties' and 'ImageIO.CGImageProperties'`
            case "CGImageMetadata":
                ptype = "ImageIO.CGImageMetadata";
                break;
            }
            print("public {0} {1} {{", ptype, p.Name);
            indent++;

            // an export will be present (only) if it's defined in a protocol
            var export = AttributeManager.GetCustomAttribute <ExportAttribute> (p);

            var name = AttributeManager.GetCustomAttribute <CoreImageFilterPropertyAttribute> (p)?.Name;
            // we can skip the name when it's identical to a protocol selector
            if (name == null)
            {
                if (export == null)
                {
                    throw new BindingException(1072, true, $"Missing [CoreImageFilterProperty] attribute on {0} property {1}", type.Name, p.Name);
                }

                var sel = export.Selector;
                if (sel.StartsWith("input", StringComparison.Ordinal))
                {
                    name = sel;
                }
                else
                {
                    name = "input" + Capitalize(sel);
                }
            }

            if (p.GetGetMethod() != null)
            {
                PrintFilterExport(p, export, setter: false);
                GenerateFilterGetter(ptype, name);
            }
            if (p.GetSetMethod() != null)
            {
                PrintFilterExport(p, export, setter: true);
                GenerateFilterSetter(ptype, name);
            }

            indent--;
            print("}");
        }
    }
Ejemplo n.º 6
0
        internal static Type GetListItemType(TypeModel model, Type listType)
        {
            Helpers.DebugAssert(listType != null);

#if WINRT
            TypeInfo listTypeInfo = listType.GetTypeInfo();
            if (listType == typeof(string) || listType.IsArray ||
                !typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(listTypeInfo))
            {
                return(null);
            }
#else
            if (listType == model.MapType(typeof(string)) || listType.IsArray ||
                !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType))
            {
                return(null);
            }
#endif

            BasicList candidates = new BasicList();
#if WINRT
            foreach (MethodInfo method in listType.GetRuntimeMethods())
#else
            foreach (MethodInfo method in listType.GetMethods())
#endif
            {
                if (method.IsStatic || method.Name != "Add")
                {
                    continue;
                }
                ParameterInfo[] parameters = method.GetParameters();
                Type            paramType;
                if (parameters.Length == 1 && !candidates.Contains(paramType = parameters[0].ParameterType))
                {
                    candidates.Add(paramType);
                }
            }

            string name         = listType.Name;
            bool   isQueueStack = name != null && (name.IndexOf("Queue", System.StringComparison.Ordinal) >= 0 || name.IndexOf("Stack", System.StringComparison.Ordinal) >= 0);
#if !NO_GENERICS
            if (!isQueueStack)
            {
                TestEnumerableListPatterns(model, candidates, listType);
#if WINRT
                foreach (Type iType in listTypeInfo.ImplementedInterfaces)
                {
                    TestEnumerableListPatterns(model, candidates, iType);
                }
#else
                foreach (Type iType in listType.GetInterfaces())
                {
                    TestEnumerableListPatterns(model, candidates, iType);
                }
#endif
            }
#endif

#if WINRT
            // more convenient GetProperty overload not supported on all platforms
            foreach (PropertyInfo indexer in listType.GetRuntimeProperties())
            {
                if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType))
                {
                    continue;
                }
                ParameterInfo[] args = indexer.GetIndexParameters();
                if (args.Length != 1 || args[0].ParameterType != typeof(int))
                {
                    continue;
                }
                MethodInfo getter = indexer.GetMethod;
                if (getter == null || getter.IsStatic)
                {
                    continue;
                }
                candidates.Add(indexer.PropertyType);
            }
#else
            // more convenient GetProperty overload not supported on all platforms
            foreach (PropertyInfo indexer in listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType))
                {
                    continue;
                }
                ParameterInfo[] args = indexer.GetIndexParameters();
                if (args.Length != 1 || args[0].ParameterType != model.MapType(typeof(int)))
                {
                    continue;
                }
                candidates.Add(indexer.PropertyType);
            }
#endif

            switch (candidates.Count)
            {
            case 0:
                return(null);

            case 1:
                return((Type)candidates[0]);

            case 2:
                if (CheckDictionaryAccessors(model, (Type)candidates[0], (Type)candidates[1]))
                {
                    return((Type)candidates[0]);
                }
                if (CheckDictionaryAccessors(model, (Type)candidates[1], (Type)candidates[0]))
                {
                    return((Type)candidates[1]);
                }
                break;
            }

            return(null);
        }
Ejemplo n.º 7
0
    void GenerateProperties(Type type, Type originalType = null, bool fromProtocol = false)
    {
        foreach (var p in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
        {
            if (p.IsUnavailable(this))
            {
                continue;
            }
            if (AttributeManager.HasAttribute <StaticAttribute> (p))
            {
                continue;
            }

            print("");

            // an export will be present (only) if it's defined in a protocol
            var export = AttributeManager.GetCustomAttribute <ExportAttribute> (p);

            // this is a bit special since CoreImage filter protocols are much newer than the our generated, key-based bindings
            // so we do not want to advertise the protocol versions since most properties would be incorrectly advertised
            PrintPropertyAttributes(p, originalType, skipTypeInjection: export != null);
            print_generated_code();

            var ptype    = p.PropertyType.Name;
            var nullable = false;
            // keep C# names as they are reserved keywords (e.g. Boolean also exists in OpenGL for Mac)
            switch (ptype)
            {
            case "Boolean":
                ptype = "bool";
                break;

            case "Int32":
                ptype = "int";
                break;

            case "Single":
                ptype = "float";
                break;

            case "String":
                ptype = "string";
                break;

            // adding `using ImageIO;` would lead to `error CS0104: 'CGImageProperties' is an ambiguous reference between 'CoreGraphics.CGImageProperties' and 'ImageIO.CGImageProperties'`
            case "CGImageMetadata":
                ptype = "ImageIO.CGImageMetadata";
                break;

            case "CIVector":
            case "CIColor":
            case "CIImage":
                // protocol-based bindings have annotations - but the older, key-based, versions did not
                if (!fromProtocol)
                {
                    nullable = true;
                }
                break;
            }
            if (AttributeManager.HasAttribute <NullAllowedAttribute> (p))
            {
                nullable = true;
            }
            print("public {0}{1} {2} {{", ptype, nullable ? "?" : "", p.Name);
            indent++;

            var name = AttributeManager.GetCustomAttribute <CoreImageFilterPropertyAttribute> (p)?.Name;
            // we can skip the name when it's identical to a protocol selector
            if (name == null)
            {
                if (export == null)
                {
                    throw new BindingException(1074, true, type.Name, p.Name);
                }

                var sel = export.Selector;
                if (sel.StartsWith("input", StringComparison.Ordinal))
                {
                    name = sel;
                }
                else
                {
                    name = "input" + Capitalize(sel);
                }
            }

            if (p.GetGetMethod() != null)
            {
                PrintFilterExport(p, export, setter: false);
                GenerateFilterGetter(ptype, name);
            }
            if (p.GetSetMethod() != null)
            {
                PrintFilterExport(p, export, setter: true);
                GenerateFilterSetter(ptype, name);
            }

            indent--;
            print("}");
        }
    }
Ejemplo n.º 8
0
        internal static MemberInfo[] GetInstanceFieldsAndProperties(Type type, bool publicOnly)
        {
#if WINRT
            System.Collections.Generic.List<MemberInfo> members = new System.Collections.Generic.List<MemberInfo>();
            foreach(FieldInfo field in type.GetRuntimeFields())
            {
                if(field.IsStatic) continue;
                if(field.IsPublic || !publicOnly) members.Add(field);
            }
            foreach(PropertyInfo prop in type.GetRuntimeProperties())
            {
                MethodInfo getter = Helpers.GetGetMethod(prop, true, true);
                if(getter == null || getter.IsStatic) continue;
                if(getter.IsPublic || !publicOnly) members.Add(prop);
            }
            return members.ToArray();
#else
            BindingFlags flags = publicOnly ? BindingFlags.Public | BindingFlags.Instance : BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
            PropertyInfo[] props = type.GetProperties(flags);
            FieldInfo[] fields = type.GetFields(flags);
            MemberInfo[] members = new MemberInfo[fields.Length + props.Length];
            props.CopyTo(members, 0);
            fields.CopyTo(members, props.Length);
            return members;
#endif
        }
Ejemplo n.º 9
0
        protected override void Generate(Type t)
        {
            var managed_name = t.Name;

            implementation.WriteLine($"static void __lookup_class_{managed_name} ()");
            implementation.WriteLine("{");
            implementation.WriteLine($"\tif (!{managed_name}_class) {{");
            implementation.WriteLine("\t\t__initialize_mono ();");
            implementation.WriteLine("\t\t__lookup_assembly_managed ();");
            implementation.WriteLine($"\t\t{managed_name}_class = mono_class_from_name (__{t.Assembly.GetName ().Name}_image, \"{t.Namespace}\", \"{managed_name}\");");
            implementation.WriteLine("\t}");
            implementation.WriteLine("}");
            implementation.WriteLine();

            var native_name = GetTypeName(t);

            headers.WriteLine();
            headers.WriteLine($"// {t.AssemblyQualifiedName}");
            headers.WriteLine($"@interface {native_name} : {GetTypeName (t.BaseType)} {{");
            headers.WriteLine("\tMonoEmbedObject* _object;");
            headers.WriteLine("}");
            headers.WriteLine();

            implementation.WriteLine();
            implementation.WriteLine($"// {t.AssemblyQualifiedName}");
            implementation.WriteLine($"@implementation {native_name}");
            implementation.WriteLine();

            var default_init = false;
            List <ConstructorInfo> constructors;

            if (ctors.TryGetValue(t, out constructors))
            {
                foreach (var ctor in constructors)
                {
                    var pcount = ctor.ParameterCount;
                    default_init |= pcount == 0;

                    var           parameters = ctor.GetParameters();
                    StringBuilder name       = new StringBuilder("init");
                    foreach (var p in parameters)
                    {
                        if (name.Length == 4)
                        {
                            name.Append("With");
                        }
                        else
                        {
                            name.Append(' ');
                        }
                        name.Append(PascalCase(p.Name));
                        name.Append(":(").Append(GetTypeName(p.ParameterType)).Append(") ").Append(p.Name);
                    }

                    var signature = new StringBuilder(".ctor(");
                    foreach (var p in parameters)
                    {
                        if (signature.Length > 6)
                        {
                            signature.Append(',');
                        }
                        signature.Append(GetMonoName(p.ParameterType));
                    }
                    signature.Append(")");

                    headers.WriteLine($"- (instancetype){name};");

                    implementation.WriteLine($"- (instancetype){name}");
                    implementation.WriteLine("{");
                    implementation.WriteLine($"\tconst char __method_name [] = \"{t.FullName}:{signature}\";");
                    implementation.WriteLine("\tstatic MonoMethod* __method = nil;");
                    implementation.WriteLine("\tif (!__method) {");
                    implementation.WriteLine($"\t\t__lookup_class_{managed_name} ();");
                    implementation.WriteLine($"\t\t__method = mono_embeddinator_lookup_method (__method_name, {managed_name}_class);");
                    implementation.WriteLine("\t}");
                    // TODO: this logic will need to be update for managed NSObject types (e.g. from XI / XM) not to call [super init]
                    implementation.WriteLine("\tif (self = [super init]) {");
                    implementation.WriteLine($"\t\tMonoObject* __instance = mono_object_new (__mono_context.domain, {managed_name}_class);");
                    implementation.WriteLine("\t\tMonoObject* __exception = nil;");
                    var args = "nil";
                    if (pcount > 0)
                    {
                        implementation.WriteLine($"\t\tvoid* __args [{pcount}];");
                        for (int i = 0; i < pcount; i++)
                        {
                            var p = parameters [i];
                            switch (Type.GetTypeCode(p.ParameterType))
                            {
                            case TypeCode.String:
                                implementation.WriteLine($"\t\t__args [{i}] = mono_string_new (__mono_context.domain, [{p.Name} UTF8String]);");
                                break;

                            case TypeCode.Boolean:
                            case TypeCode.Char:
                            case TypeCode.SByte:
                            case TypeCode.Int16:
                            case TypeCode.Int32:
                            case TypeCode.Int64:
                            case TypeCode.Byte:
                            case TypeCode.UInt16:
                            case TypeCode.UInt32:
                            case TypeCode.UInt64:
                            case TypeCode.Single:
                            case TypeCode.Double:
                                implementation.WriteLine($"\t\t__args [{i}] = &{p.Name};");
                                break;

                            default:
                                throw new NotImplementedException($"Converting type {p.ParameterType.FullName} to mono code");
                            }
                        }
                        args = "__args";
                    }
                    implementation.WriteLine($"\t\tmono_runtime_invoke (__method, __instance, {args}, &__exception);");
                    implementation.WriteLine("\t\tif (__exception)");
                    // TODO: Apple often do NSLog (or asserts but they are more brutal) and returning nil is allowed (and common)
                    implementation.WriteLine("\t\t\treturn nil;");
                    //implementation.WriteLine ("\t\t\tmono_embeddinator_throw_exception (__exception);");
                    implementation.WriteLine("\t\t_object = mono_embeddinator_create_object (__instance);");
                    implementation.WriteLine("\t\t_object->_handle = mono_gchandle_new (__instance, /*pinned=*/false);");
                    implementation.WriteLine("\t}");
                    implementation.WriteLine("\treturn self;");
                    implementation.WriteLine("}");
                    implementation.WriteLine();
                }
            }

            var static_type = t.IsSealed && t.IsAbstract;

            if (!default_init || static_type)
            {
                if (static_type)
                {
                    headers.WriteLine("// a .net static type cannot be initialized");
                }
                headers.WriteLine("- (instancetype)init NS_UNAVAILABLE;");
            }

            headers.WriteLine();
            foreach (var pi in t.GetProperties())
            {
                Generate(pi);
            }

            headers.WriteLine("@end");
            headers.WriteLine();

            implementation.WriteLine("@end");
            implementation.WriteLine();
        }
Ejemplo n.º 10
0
        void GenerateCode(Type type)
        {
            if (type.IsGenericType && !type.IsGenericTypeDefinition)
                return; // generate nothing.

            var implprops = new List<PropertyInfo> ();
            var miscprops = new List<PropertyInfo> ();
            foreach (var p in type.GetProperties (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) {
                if (targets.Contains (p.PropertyType) && !p.PropertyType.IsEnum)
                    implprops.Add (p);
                else
                    miscprops.Add (p);
            }

            output.WriteLine ("// generic ordinal type for " + type);
            string template = @"
            public {10}partial class {0} : {1} {2}
            {{
            {7} impl;

            // constructor, if not abstract.
            {9}

            // impl-to-wrapper constructor
            internal protected {8} ({7} impl) {6}
            {{
            this.impl = impl;
            {11}
            Initialize ();
            }}

            // initializer
            void Initialize ()
            {{
            // repeat for all auto (new-Android-type) properties
            {3}
            }}

            // explicit conversion operator
            public static explicit operator {7} ({0} source)
            {{
            return source.impl;
            }}

            // For a property whose type is wrapper for Android type, just make it auto property (use private set for get-only ones)
            {4}

            // Non-Android properties follow.
            {5}
            }}
            ";

            var actx = android_ass.GetType ("Android.Content.Context");
            var aaset = android_ass.GetType ("Android.Util.IAttributeSet");
            // somehow GetConstructor() returns weird results, so this workarounds that.
            string args =
                type.GetConstructors ().Any (c => c.GetParameters ().Length == 1 && c.GetParameters () [0].ParameterType.FullName == actx.FullName) ? "XamlView.CurrentContext" :
                type.GetConstructors ().Any (c => c.GetParameters ().Length == 2 && c.GetParameters () [0].ParameterType.FullName == actx.FullName && c.GetParameters () [1].ParameterType.FullName == aaset.FullName) ? "XamlView.CurrentContext, null" :
                "";
            //if (type.Name == "SlidingDrawer") foreach (var ccc in type.GetConstructors ()) Console.WriteLine ("!!!! " + ccc + " / " +  type.GetConstructor (new Type [] {actx}).GetParameters ().Length);
            string publicConstructor = type.IsAbstract ? String.Empty : String.Format (@"
            public {0} ()
            : this (new {1} ({2}))
            {{

            }}", type.NonGenericName (), type.CSFullName (), args);

            string templateInit = @"
            if (impl.{0} != null)
                {0} = Extensions.GetWrappedItem<{1}> (impl.{0});";
            var isw = new StringWriter () { NewLine = "\n" };
            foreach (var p in implprops)
                if (!p.IsAbstract ())
                    isw.WriteLine (templateInit, p.Name, p.PropertyType.CSName ());

            string templateImplProp = @"
            public {3}{0} {1} {{ get; {2}set; }}";
            var dpsw = new StringWriter () { NewLine = "\n" };
            foreach (var p in implprops)
                dpsw.WriteLine (templateImplProp, p.PropertyType.CSSwitchName (), p.Name, p.IsSetterPublic () ? null : "internal ", GetModifier (p));

            string templateOrdProp1 = @"
            public {3}{0} {1} {{
            get {{ return {4}; }}
            {2}
            }}";
            string templateOrdProp2 = @"
            public {3}{0} {1} {{ get; {5} }}";
            var nsw = new StringWriter () { NewLine = "\n" };
            foreach (var p in miscprops) {
                var setter = String.Format ("set {{ impl.{0} = value; }}", p.Name);
                nsw.WriteLine (p.IsAbstract () ? templateOrdProp2 : templateOrdProp1, p.PropertyType.CSSwitchName (), p.Name, p.IsSetterPublic () ? setter : null, GetModifier (p), GetValueExpression (p), p.IsSetterPublic () ? "set;" : null);
            }

            string gconsts = null;
            foreach (var arg in type.GetGenericArguments ()) {
                var gca = String.Join (",", (from t in arg.GetGenericParameterConstraints () select t.CSSwitchName ()).ToArray ());
                gconsts += String.IsNullOrEmpty (gca) ? null : "where " + arg.Name + " : " + gca;
            }

            // FIXME: write custom attributes
            bool callBase = targets.Contains (type.BaseType);
            output.WriteLine (template, type.CSName (), type.BaseType.CSSwitchName (), gconsts, isw, dpsw, nsw, callBase ? " : base (impl)" : null, type.CSFullName (), type.NonGenericName (), publicConstructor, type.IsAbstract ? "abstract " : null, callBase ? null : "XamlView.Register (impl, this);");
        }