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>
* 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.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 ();
}
}
}

View file

@ -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);

View file

@ -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

View file

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

View file

@ -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
* <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\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 ())

View file

@ -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

View file

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