Inheritance: TypedEntity
 /// <summary>
 ///   Gets the properties of the superclass and own.
 /// </summary>
 protected static IEnumerable<PropertyEntity> GetProperties(ClassEntity classEntity, bool withOwn)
 {
     List<PropertyEntity> properties = (classEntity.SuperClass != null) ? classEntity.SuperClass.GetProperties (true, true).ToList () : new List<PropertyEntity> ();
     if (withOwn) {
         properties.AddRange (classEntity.Properties);
     }
     return properties.Distinct ();
 }
 protected void ExtractProperties(ClassEntity classEntity, XElement root)
 {
     IEnumerable<XElement> propertyElements = from el in root.Descendants ("div")
                                              where (String)el.Attribute ("class") == "api propertyObjC"
                                              select el;
     foreach (XElement propertyElement in propertyElements) {
         PropertyEntity propertyEntity = this.PropertyParser.Parse (classEntity, propertyElement);
         classEntity.Properties.Add (propertyEntity);
     }
 }
 /// <summary>
 ///   Gets all methods of the superclass and own.
 /// </summary>
 protected static IEnumerable<MethodEntity> GetAllMethods(ClassEntity classEntity, bool withOwn)
 {
     List<MethodEntity> methods = (classEntity.SuperClass != null) ? classEntity.SuperClass.GetMethods (true, true).ToList () : new List<MethodEntity> ();
     if (withOwn) {
         methods.AddRange (classEntity.Methods);
     }
     return methods.Distinct ();
 }
        protected void ExtractProperties(ClassEntity classEntity, XElement root)
        {
            // Extract name
            String compoundname = (from el in root.Descendants ("compoundname")
                                   select el.TrimAll ()).FirstOrDefault ();

            IEnumerable<XElement> memberDefs = (from el in root.Descendants ("memberdef")
                                                where el.Attribute ("kind").Value == "property"
                                                select el);
            foreach (XElement memberDef in memberDefs) {
                String definition = memberDef.Element ("definition").TrimAll ();
                if (!definition.Contains (compoundname + "::")) {
                    continue;
                }
                PropertyEntity propertyEntity = this.PropertyParser.Parse (classEntity, memberDef);
                classEntity.Properties.Add (propertyEntity);
            }
        }
 protected void ExtractInstanceMethods(ClassEntity classEntity, XElement root)
 {
     IEnumerable<XElement> methods = from el in root.Descendants ("div")
                                     where (String)el.Attribute ("class") == "api instanceMethod"
                                     select el;
     foreach (XElement methodElement in methods) {
         MethodEntity methodEntity = this.MethodParser.Parse (classEntity, methodElement);
         classEntity.Methods.Add (methodEntity);
     }
 }
        protected void ExtractProperties(ClassEntity classEntity, XElement root)
        {
            XElement listMaker = (from el in root.Descendants ("h2")
                                  where el.Value == "Properties"
                                  select el).FirstOrDefault ();
            XElement list = listMaker != null ? listMaker.ElementsAfterSelf ("dl").FirstOrDefault () : null;
            if (list != null) {
                // Collect names
                List<String> names = new List<string> ();
                foreach (XElement term in list.Descendants("dt")) {
                    String name = term.Value.TrimAll ();
                    names.Add (name);
                }

                // Search for a table with preceding by an anchor containing the name
                foreach (String name in names) {
                    XElement marker = (from el in list.ElementsAfterSelf ("a")
                                       where el.Attribute ("name") != null &&
                        el.Attribute ("name").Value.EndsWith ("/" + name)
                                       select el).FirstOrDefault ();
                    if (marker != null) {
                        //XElement startElement = marker.ElementsAfterSelf ("table").FirstOrDefault ();
                        IEnumerable<XElement> elements = marker.ElementsAfterSelf ().TakeWhile (el => el.Name != "a");

                        PropertyEntity propertyEntity = this.PropertyParser.Parse (classEntity, name, elements);
                        classEntity.Properties.Add (propertyEntity);
                    } else {
                        this.Logger.WriteLine ("MISSING marker for property " + name);
                    }
                }
            }
        }
        private void Convert(Framework f, FrameworkEntity e, String sourcePath, String destinationPath, TextWriter writer = null)
        {
            switch (e.type) {
            case FrameworkEntityType.T:
                {
                    IXhtmlTypeParser parser = this.GetTypeParser (f, e, writer);

                    TypedEntity entity = new TypedEntity ();
                    entity.Namespace = f.name;
                    entity.Name = e.name;
                    entity.Nature = e.type;

                    parser.Parse (entity, sourcePath);
                    entity.SaveTo (destinationPath);
                }
                break;
            case FrameworkEntityType.C:
                {
                    IXhtmlClassParser parser = this.GetClassParser (f, e, writer);

                    ClassEntity entity = new ClassEntity ();
                    entity.Namespace = f.name;
                    entity.Name = e.name;
                    entity.Nature = e.type;

                    parser.Parse (entity, sourcePath);
                    entity.SaveTo (destinationPath);
                }
                break;
            case FrameworkEntityType.P:
                {
                    IXhtmlClassParser parser = this.GetProtocolParser (f, e, writer);

                    ProtocolEntity entity = new ProtocolEntity ();
                    entity.Namespace = f.name;
                    entity.Name = e.name;
                    entity.Nature = e.type;

                    parser.Parse (entity, sourcePath);
                    entity.SaveTo (destinationPath);
                }
                break;
            default:
                break;
            }
        }
        /// <summary>
        ///   Generates the specified entity.
        /// </summary>
        /// <param name = "classEntity">The class entity.</param>
        /// <param name = "propertyEntity">The property entity.</param>
        /// <param name = "implementation">if set to <c>true</c> generate the implementation.</param>
        public void Generate(ClassEntity classEntity, PropertyEntity propertyEntity, bool implementation = true, bool markedAsNew = false)
        {
            // Don't generate if required
            if (!propertyEntity.Generate) {
                return;
            }

            // Append static condition if needed
            this.AppendStartCondition (propertyEntity);

            // Append property comments
            this.AppendDocumentation (propertyEntity);

            // Append Obsolete attribute
            this.AppendObsoleteAttribute (propertyEntity);

            // Special case for delegates
            String type = propertyEntity.Type;
            if (String.Equals (propertyEntity.Name, "Delegate")) {
                type = "Id";
            }

            this.Writer.WriteLineFormat (2, "{0}{1} {2}",
                                        GetKeywords (propertyEntity, implementation, markedAsNew),
                                        type,
                                        propertyEntity.Name);

            //String type32 = GetRealType (type, false);
            //String type64 = GetRealType (type, true);
            //bool useMixedInvocation = !String.Equals (type32, type64);

            // Append getter
            if (implementation) {
                this.Writer.WriteLineFormat (2, "{{");

            //                if (useMixedInvocation)
            //                {
            //                    this.Writer.WriteLineFormat(3, "get {{");
            //#if MIXED_MODE
            //                    this.Writer.WriteLineFormat(4, "if (ObjectiveCRuntime.Is64Bits)");
            //                    this.Writer.WriteLineFormat(4, "{{");
            //
            //                    this.Writer.WriteLineFormat(5, "return ({0}) ObjectiveCRuntime.SendMessage<{1}>({2}, \"{3}\");", type, GetRealType(type, true), propertyEntity.Static ? classEntity.Name + "Class" : "this",
            //                                                "" + propertyEntity.Getter.Selector);
            //
            //                    this.Writer.WriteLineFormat(4, "}}");
            //                    this.Writer.WriteLineFormat(4, "else");
            //                    this.Writer.WriteLineFormat(4, "{{");
            //#endif
            //                    this.Writer.WriteLineFormat(5, "return ({0}) ObjectiveCRuntime.SendMessage<{1}>({2}, \"{3}\");", type, GetRealType(type, false), propertyEntity.Static ? classEntity.Name + "Class" : "this",
            //                                                "" + propertyEntity.Getter.Selector);
            //#if MIXED_MODE
            //                    this.Writer.WriteLineFormat(4, "}}");
            //#endif
            //                    this.Writer.WriteLineFormat(3, "}}");
            //                }
            //                else
                {
                    this.Writer.WriteLineFormat (3, "get {{ return ObjectiveCRuntime.SendMessage<{0}>({1}, \"{2}\"); }}", type, propertyEntity.Static ? classEntity.Name + "." + classEntity.Name + "Class" : "this", "" + propertyEntity.Getter.Selector);
                }

                // Append setter
                if (propertyEntity.Setter != null) {
            //                    if (useMixedInvocation)
            //                    {
            //                        this.Writer.WriteLineFormat(3, "set {{");
            //#if MIXED_MODE
            //                        this.Writer.WriteLineFormat(4, "if (ObjectiveCRuntime.Is64Bits)");
            //                        this.Writer.WriteLineFormat(4, "{{");
            //
            //                        this.Writer.WriteLineFormat(5, "ObjectiveCRuntime.SendMessage({0}, \"{1}\", ({2}) value);", propertyEntity.Static ? classEntity.Name + "Class" : "this", "" + propertyEntity.Setter.Selector, GetRealType(type, true));
            //
            //                        this.Writer.WriteLineFormat(4, "}}");
            //                        this.Writer.WriteLineFormat(4, "else");
            //                        this.Writer.WriteLineFormat(4, "{{");
            //#endif
            //                        this.Writer.WriteLineFormat(5, "ObjectiveCRuntime.SendMessage({0}, \"{1}\", ({2}) value);", propertyEntity.Static ? classEntity.Name + "Class" : "this", "" + propertyEntity.Setter.Selector, GetRealType(type, false));
            //#if MIXED_MODE
            //                        this.Writer.WriteLineFormat(4, "}}");
            //#endif
            //                        this.Writer.WriteLineFormat(3, "}}");
            //                    }
            //                    else
                    {
                        this.Writer.WriteLineFormat (3, "set {{ ObjectiveCRuntime.SendMessage({0}, \"{1}\", value); }}", propertyEntity.Static ? classEntity.Name + "." + classEntity.Name + "Class" : "this", "" + propertyEntity.Setter.Selector);
                    }
                }

                this.Writer.WriteLineFormat (2, "}}");
            } else {
                this.Writer.WriteLineFormat (2, "{{");

                // Append getter
                this.Writer.WriteLineFormat (3, "[ObjectiveCMessage(\"{0}\")]", propertyEntity.Getter.Selector);
                this.Writer.WriteLineFormat (3, "get;");

                // Append setter
                if (propertyEntity.Setter != null) {
                    this.Writer.WriteLineFormat (3, "[ObjectiveCMessage(\"{0}\")]", propertyEntity.Setter.Selector);
                    this.Writer.WriteLineFormat (3, "set;");
                }

                this.Writer.WriteLineFormat (2, "}}");
            }

            // Append static condition if needed
            this.AppendEndCondition(propertyEntity);

            // Update statistics
            this.Statistics.Properties++;
        }
 private static String GetTarget(ClassEntity classEntity, MethodEntity methodEntity, bool extension)
 {
     if (methodEntity.Static) {
         if (extension) {
             return String.Format ("{0}.{0}Class", classEntity.Name);
         }
         return String.Format ("{0}Class", classEntity.Name);
     }
     if (extension) {
         return "__target";
     }
     return "this";
 }
 private static string GetExtraParameter(ClassEntity classEntity, MethodEntity methodEntity, bool extension)
 {
     if (extension && !methodEntity.Static) {
         return String.Format ("this {0} __target", classEntity.Name);
     }
     return String.Empty;
 }
        /// <summary>
        ///   Generates the specified entity.
        /// </summary>
        /// <param name = "classEntity">The class entity.</param>
        /// <param name = "methodEntity">The method entity.</param>
        /// <param name = "implementation">if set to <c>true</c> generate the implementation.</param>
        /// <param name = "extension">if set to <c>true</c> this method is an extension method.</param>
        public void Generate(ClassEntity classEntity, MethodEntity methodEntity, bool implementation = true, bool extension = false, bool markedAsNew = false)
        {
            // Don't generate if required
            if (!methodEntity.Generate) {
                return;
            }

            // Append static condition if needed
            this.AppendStartCondition (methodEntity);

            // Append documentation
            this.AppendDocumentation (methodEntity, extension && !methodEntity.Static);

            // Append method selector
            if (!implementation) {
                this.Writer.WriteLineFormat (2, "[ObjectiveCMessage(\"{0}\")]", methodEntity.Selector);
            }

            // Append Obsolete attribute
            this.AppendObsoleteAttribute (methodEntity);

            // Create Method signature
            StringBuilder signature = new StringBuilder ();

            // Append keywords
            String keywords = GetKeywords (methodEntity, implementation, extension, markedAsNew);
            signature.Append (keywords);

            // Append return type and name
            signature.AppendFormat ("{0} {1}", methodEntity.ReturnType, methodEntity.Name);
            signature.Append ("(");

            // Append parameters
            List<String> parameters = new List<String> ();
            String extraParameter = GetExtraParameter (classEntity, methodEntity, extension);
            if (!String.IsNullOrEmpty (extraParameter)) {
                parameters.Add (extraParameter);
            }
            foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) {
                parameters.Add (GetTypeSignature (methodParameterEntity));
            }
            signature.Append (String.Join (", ", parameters.ToArray ()));
            signature.Append (")");
            signature.Append (implementation ? String.Empty : ";");

            this.Writer.WriteLineFormat (2, signature.ToString ());

            // Write implementation
            if (implementation) {
                // Collect information
                bool needStorage = false;
                bool varargs = false;
                CollectInformations (methodEntity, ref needStorage, ref varargs);

                // Collect information on 32/64 bits invocations to check if they differ
                MethodEntity methodEntity32 = DeriveMethodEntity (methodEntity, false);
                MethodEntity methodEntity64 = DeriveMethodEntity (methodEntity, true);
                bool useMixedInvocation = !AreMethodTypesEqual (methodEntity32, methodEntity64);

                this.Writer.WriteLineFormat (2, "{{");

                String target = GetTarget (classEntity, methodEntity, extension);

                if (useMixedInvocation && needStorage) {
            #if MIXED_MODE
                    this.Writer.WriteLineFormat(3, "if (ObjectiveCRuntime.Is64Bits)");
                    this.Writer.WriteLineFormat(3, "{{");

                    this.GenerateMethodBody(4, target, methodEntity, methodEntity64, needStorage, varargs);

                    this.Writer.WriteLineFormat(3, "}}");
                    this.Writer.WriteLineFormat(3, "else");
                    this.Writer.WriteLineFormat(3, "{{");
            #endif
                    this.GenerateMethodBody (4, target, methodEntity, methodEntity32, needStorage, varargs);
            #if MIXED_MODE
                    this.Writer.WriteLineFormat(3, "}}");
            #endif
                } else {
                    this.GenerateMethodBody (3, target, methodEntity, null, needStorage, varargs);
                }

                this.Writer.WriteLineFormat (2, "}}");
            }

            // Append static condition if needed
            this.AppendEndCondition(methodEntity);

            // Update statistics
            this.Statistics.Methods++;
        }
        public void GenerateConstructor(ClassEntity classEntity, MethodEntity methodEntity)
        {
            // Don't generate if required
            if (!methodEntity.Generate) {
                return;
            }

            // Clone the method and change the return type
            methodEntity = new MethodEntity (methodEntity);
            methodEntity.ReturnType = "IntPtr";

            // Collect information
            bool needStorage = false;
            bool varargs = false;
            CollectInformations (methodEntity, ref needStorage, ref varargs);

            // Don't generate if varargs
            if (varargs) {
                return;
            }

            // Collect information about the return type and the parameters
            bool hasReturn = !String.Equals (methodEntity.ReturnType, "void");
            bool hasReturnParameters = hasReturn && needStorage;

            // Collect information on 32/64 bits invocations to check if they differ
            MethodEntity methodEntity32 = DeriveMethodEntity (methodEntity, false);
            MethodEntity methodEntity64 = DeriveMethodEntity (methodEntity, true);
            bool useMixedInvocation = false; // !AreMethodTypesEqual(methodEntity32, methodEntity64);

            // Append static condition if needed
            this.AppendStartCondition (methodEntity);

            // Append documentation
            this.AppendDocumentation (methodEntity);

            // Append Method signature
            StringBuilder signature = new StringBuilder ();
            signature.AppendFormat ("public {0}(", classEntity.Name);

            // Append parameters
            List<String> parameters = new List<String> ();
            foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) {
                parameters.Add (GetTypeSignature (methodParameterEntity));
            }
            signature.Append (String.Join (", ", parameters.ToArray ()));
            signature.Append (")");

            this.Writer.WriteLineFormat (2, signature.ToString ());

            // Write base call
            StringBuilder baseCall = new StringBuilder ();
            if (useMixedInvocation || hasReturnParameters) {
                baseCall.AppendFormat (" : this(ObjectiveCRuntime.SendMessage<IntPtr>({0}Class, \"alloc\"))", classEntity.Name);
            } else {
                baseCall.AppendFormat (" : base(\"{0}\"", methodEntity.Selector);
                foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) {
                    baseCall.AppendFormat (", {0}", methodParameterEntity.Name);
                }
                baseCall.Append (")");
            }
            this.Writer.WriteLineFormat (3, baseCall.ToString ());

            // Write implementation
            this.Writer.WriteLineFormat (2, "{{");

            String target = "this";
            if (useMixedInvocation) {
            #if MIXED_MODE
                this.Writer.WriteLineFormat(3, "if (ObjectiveCRuntime.Is64Bits)");
                this.Writer.WriteLineFormat(3, "{{");

                this.GenerateConstructorBody(4, target, methodEntity, methodEntity64, needStorage, varargs);

                this.Writer.WriteLineFormat(3, "}}");
                this.Writer.WriteLineFormat(3, "else");
                this.Writer.WriteLineFormat(3, "{{");
            #endif
                this.GenerateConstructorBody (4, target, methodEntity, methodEntity32, needStorage, varargs);
            #if MIXED_MODE
                this.Writer.WriteLineFormat(3, "}}");
            #endif
            } else if (hasReturnParameters) {
                this.GenerateConstructorBody (4, target, methodEntity, null, needStorage, varargs);
            }

            this.Writer.WriteLineFormat (2, "}}");

            // Append static condition if needed
            this.AppendEndCondition (methodEntity);

            // Update statistics
            this.Statistics.Methods++;
        }