2009-05-04 Christian Hoff <christian_hoff@gmx.net>

* 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]

svn path=/trunk/gtk-sharp/; revision=133514
This commit is contained in:
Christian Hoff 2009-05-04 17:39:45 +00:00
parent f11bd79000
commit 8996f860ad
8 changed files with 47 additions and 25 deletions

View File

@ -1,3 +1,12 @@
2009-05-04 Christian Hoff <christian_hoff@gmx.net>
* 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 <mkestner@novell.com> 2009-05-03 Mike Kestner <mkestner@novell.com>
* glib/Object.cs: revert to old LookupType behavior when Handle is * glib/Object.cs: revert to old LookupType behavior when Handle is

View File

@ -24,26 +24,20 @@ namespace GtkSharp.Generation {
using System.IO; using System.IO;
using System.Xml; using System.Xml;
public class ClassField { public class ClassField : StructField {
string name; protected new ObjectBase container_type;
IGeneratable igen;
public ClassField (XmlElement elem) public ClassField (XmlElement elem, ObjectBase container_type) : base (elem, container_type) {
{ this.container_type = container_type;
name = elem.GetAttribute ("name");
igen = SymbolTable.Table [elem.GetAttribute ("type")];
} }
public string Name { public override bool Validate () {
get { if (IsBitfield) {
return name; Console.WriteLine ("Field {0}.{1} is a bitfield which is not supported yet", container_type.ClassStructName, Name);
return false;
} }
}
public IGeneratable Generatable { return base.Validate ();
get {
return igen;
}
} }
} }
} }

View File

@ -28,7 +28,7 @@ namespace GtkSharp.Generation {
public abstract class FieldBase : PropertyBase { public abstract class FieldBase : PropertyBase {
public FieldBase (XmlElement elem, ClassBase container_type) : base (elem, container_type) {} public FieldBase (XmlElement elem, ClassBase container_type) : base (elem, container_type) {}
public bool Validate () public virtual bool Validate ()
{ {
if (!Ignored && !Hidden && CSType == "") { if (!Ignored && !Hidden && CSType == "") {
Console.Write("Field {0} has unknown Type {1} ", Name, CType); Console.Write("Field {0} has unknown Type {1} ", Name, CType);

View File

@ -79,7 +79,7 @@ namespace GtkSharp.Generation {
VMCodeType CodeType { VMCodeType CodeType {
get { get {
if (container_type.ParserVersion == 1 || force_glue_generation) { if (!(container_type as ObjectBase).CanGenerateClassStruct || force_glue_generation) {
if (BlockGlue) if (BlockGlue)
return VMCodeType.None; return VMCodeType.None;
else else

View File

@ -226,7 +226,7 @@ namespace GtkSharp.Generation {
sw.WriteLine (); sw.WriteLine ();
if (!IsConsumeOnly) { if (!IsConsumeOnly) {
GenerateClassStruct (sw); GenerateClassStruct (gen_info);
GenerateStaticCtor (sw); GenerateStaticCtor (sw);
GenerateCallbacks (sw); GenerateCallbacks (sw);
GenerateInitialize (sw); GenerateInitialize (sw);

View File

@ -30,6 +30,7 @@ namespace GtkSharp.Generation {
public abstract class ObjectBase : HandleBase { public abstract class ObjectBase : HandleBase {
bool is_interface; bool is_interface;
protected string class_struct_name = null; 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 (); ArrayList class_members = new ArrayList ();
protected ArrayList class_fields = new ArrayList (); protected ArrayList class_fields = new ArrayList ();
// The default handlers of these signals need to be overridden with g_signal_override_class_closure // The default handlers of these signals need to be overridden with g_signal_override_class_closure
@ -107,7 +108,7 @@ namespace GtkSharp.Generation {
break; break;
case "field": case "field":
if (node_idx == 0) continue; // Parent class if (node_idx == 0) continue; // Parent class
ClassField field = new ClassField (member); ClassField field = new ClassField (member, this);
class_fields.Add (field); class_fields.Add (field);
class_members.Add (field); class_members.Add (field);
break; 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
* <signal> and <virtual_method> 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\t[StructLayout (LayoutKind.Sequential)]");
sw.WriteLine ("\t\tstruct " + class_struct_name + " {"); sw.WriteLine ("\t\tstruct " + class_struct_name + " {");
@ -180,7 +194,7 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\t\t\tpublic {0}NativeDelegate {0};", vm.Name); sw.WriteLine ("\t\t\tpublic {0}NativeDelegate {0};", vm.Name);
} else if (member is ClassField) { } else if (member is ClassField) {
ClassField field = member as 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}"); sw.WriteLine ("\t\t}");
@ -253,6 +267,11 @@ namespace GtkSharp.Generation {
hidden_vms.Add (invalid_vm); hidden_vms.Add (invalid_vm);
} }
invalids.Clear (); 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) foreach (InterfaceVM vm in interface_vms)
if (!vm.Validate ()) if (!vm.Validate ())

View File

@ -301,9 +301,9 @@ namespace GtkSharp.Generation {
{ {
GenVirtualMethods (gen_info, null); 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; StreamWriter sw = gen_info.Writer;
GenerateClassStruct (sw); GenerateClassStruct (gen_info);
if (cs_parent == "") if (cs_parent == "")
sw.WriteLine ("\t\tstatic uint class_offset = 0;"); sw.WriteLine ("\t\tstatic uint class_offset = 0;");
else else

View File

@ -53,7 +53,7 @@ namespace GtkSharp.Generation {
} }
VMSignature signature; VMSignature signature;
protected VMSignature Signature { protected new VMSignature Signature {
get { get {
if (signature == null) if (signature == null)
signature = new VMSignature (parms); signature = new VMSignature (parms);