diff --git a/ChangeLog b/ChangeLog index 11c241171..edb8b0392 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-05-04 Christian Hoff + + * generator/ClassField.cs: Derive from StructField. + * generator/ObjectBase.cs: Implement validation mechanism for + class structures. If the structure contains bitfields or fields + of unknown types, we cannot generate it in managed code. + * generator/GObjectVM.cs: Fall back to glue if the class structure + cannot be generated. [Fixes #498051] + 2009-05-03 Mike Kestner * glib/Object.cs: revert to old LookupType behavior when Handle is diff --git a/generator/ClassField.cs b/generator/ClassField.cs index 00ccecaed..e5276d42b 100644 --- a/generator/ClassField.cs +++ b/generator/ClassField.cs @@ -24,26 +24,20 @@ namespace GtkSharp.Generation { using System.IO; using System.Xml; - public class ClassField { - string name; - IGeneratable igen; + public class ClassField : StructField { + protected new ObjectBase container_type; - public ClassField (XmlElement elem) - { - name = elem.GetAttribute ("name"); - igen = SymbolTable.Table [elem.GetAttribute ("type")]; + public ClassField (XmlElement elem, ObjectBase container_type) : base (elem, container_type) { + this.container_type = container_type; } - public string Name { - get { - return name; + public override bool Validate () { + if (IsBitfield) { + Console.WriteLine ("Field {0}.{1} is a bitfield which is not supported yet", container_type.ClassStructName, Name); + return false; } - } - public IGeneratable Generatable { - get { - return igen; - } + return base.Validate (); } } } diff --git a/generator/FieldBase.cs b/generator/FieldBase.cs index 9fac0cd2c..d2ba5fb5d 100644 --- a/generator/FieldBase.cs +++ b/generator/FieldBase.cs @@ -28,7 +28,7 @@ namespace GtkSharp.Generation { public abstract class FieldBase : PropertyBase { public FieldBase (XmlElement elem, ClassBase container_type) : base (elem, container_type) {} - public bool Validate () + public virtual bool Validate () { if (!Ignored && !Hidden && CSType == "") { Console.Write("Field {0} has unknown Type {1} ", Name, CType); diff --git a/generator/GObjectVM.cs b/generator/GObjectVM.cs index dde013e1b..da89fb315 100644 --- a/generator/GObjectVM.cs +++ b/generator/GObjectVM.cs @@ -79,7 +79,7 @@ namespace GtkSharp.Generation { VMCodeType CodeType { get { - if (container_type.ParserVersion == 1 || force_glue_generation) { + if (!(container_type as ObjectBase).CanGenerateClassStruct || force_glue_generation) { if (BlockGlue) return VMCodeType.None; else diff --git a/generator/InterfaceGen.cs b/generator/InterfaceGen.cs index da62ff509..d0dc77b84 100644 --- a/generator/InterfaceGen.cs +++ b/generator/InterfaceGen.cs @@ -226,7 +226,7 @@ namespace GtkSharp.Generation { sw.WriteLine (); if (!IsConsumeOnly) { - GenerateClassStruct (sw); + GenerateClassStruct (gen_info); GenerateStaticCtor (sw); GenerateCallbacks (sw); GenerateInitialize (sw); diff --git a/generator/ObjectBase.cs b/generator/ObjectBase.cs index 7e76eff94..7c5149ebe 100644 --- a/generator/ObjectBase.cs +++ b/generator/ObjectBase.cs @@ -30,6 +30,7 @@ namespace GtkSharp.Generation { public abstract class ObjectBase : HandleBase { bool is_interface; protected string class_struct_name = null; + bool class_fields_valid; // false if the class structure contains a bitfield or fields of unknown types ArrayList class_members = new ArrayList (); protected ArrayList class_fields = new ArrayList (); // The default handlers of these signals need to be overridden with g_signal_override_class_closure @@ -107,7 +108,7 @@ namespace GtkSharp.Generation { break; case "field": if (node_idx == 0) continue; // Parent class - ClassField field = new ClassField (member); + ClassField field = new ClassField (member, this); class_fields.Add (field); class_members.Add (field); break; @@ -165,9 +166,22 @@ namespace GtkSharp.Generation { } } - protected void GenerateClassStruct (StreamWriter sw) + public bool CanGenerateClassStruct { + get { + /* Generation of interface class structs was already supported by version 2.12 of the GAPI parser. Their layout was determined by the order + * in which the signal and virtual_method elements appeared in the XML. However, we cannot use that approach for old GObject class structs + * as they may contain class fields which don't appear in the old (version 1) API files. There are also cases in which the order of the + * and elements do not match the struct layout. + */ + return (is_interface || this.ParserVersion >= 2) && class_fields_valid; + } + } + + protected void GenerateClassStruct (GenerationInfo gen_info) { - if (class_struct_name == null) return; + if (class_struct_name == null || !CanGenerateClassStruct) return; + + StreamWriter sw = gen_info.Writer; sw.WriteLine ("\t\t[StructLayout (LayoutKind.Sequential)]"); sw.WriteLine ("\t\tstruct " + class_struct_name + " {"); @@ -180,7 +194,7 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t\t\tpublic {0}NativeDelegate {0};", vm.Name); } else if (member is ClassField) { ClassField field = member as ClassField; - sw.WriteLine ("\t\t\tpublic {0} {1};", field.Generatable.MarshalReturnType, field.Name); + field.Generate (gen_info, "\t\t\t"); } } sw.WriteLine ("\t\t}"); @@ -253,6 +267,11 @@ namespace GtkSharp.Generation { hidden_vms.Add (invalid_vm); } invalids.Clear (); + + class_fields_valid = true; + foreach (ClassField field in class_fields) + if (!field.Validate ()) + class_fields_valid = false; foreach (InterfaceVM vm in interface_vms) if (!vm.Validate ()) diff --git a/generator/ObjectGen.cs b/generator/ObjectGen.cs index 414f456b6..7a7d561da 100644 --- a/generator/ObjectGen.cs +++ b/generator/ObjectGen.cs @@ -301,9 +301,9 @@ namespace GtkSharp.Generation { { GenVirtualMethods (gen_info, null); - if (class_struct_name == null || this.ParserVersion == 1) return; + if (class_struct_name == null || !CanGenerateClassStruct) return; StreamWriter sw = gen_info.Writer; - GenerateClassStruct (sw); + GenerateClassStruct (gen_info); if (cs_parent == "") sw.WriteLine ("\t\tstatic uint class_offset = 0;"); else diff --git a/generator/VirtualMethod.cs b/generator/VirtualMethod.cs index ea85dd168..d7312c1c4 100644 --- a/generator/VirtualMethod.cs +++ b/generator/VirtualMethod.cs @@ -53,7 +53,7 @@ namespace GtkSharp.Generation { } VMSignature signature; - protected VMSignature Signature { + protected new VMSignature Signature { get { if (signature == null) signature = new VMSignature (parms);