2008-07-08 Mike Kestner <mkestner@novell.com>

Patch from Christian Hoff with a few minor tweaks.
	* generator/CallbackGen.cs: refactor to use ManagedCallString
	and drop a ton of redundant, half-baked code.
	* generator/ManagedCallString.cs: add Unconditional setup
	method for stuff that has to happen before the try block.
	Add "drop_first" concept so it can be reused by CallbackGen
	which doesn't drop first params.
	* generator/Signal.cs: use Unconditional method for prep.
	* generator/VirtualMethod.cs: use Unconditional method for prep.
	* gtk/Gtk.metadata: mark a ref param. [Fixes #394352]

svn path=/trunk/gtk-sharp/; revision=107494
This commit is contained in:
Mike Kestner 2008-07-08 21:12:22 +00:00
parent d47afc7f66
commit 7d611f77e4
6 changed files with 64 additions and 69 deletions

View file

@ -1,3 +1,16 @@
2008-07-08 Mike Kestner <mkestner@novell.com>
Patch from Christian Hoff with a few minor tweaks.
* generator/CallbackGen.cs: refactor to use ManagedCallString
and drop a ton of redundant, half-baked code.
* generator/ManagedCallString.cs: add Unconditional setup
method for stuff that has to happen before the try block.
Add "drop_first" concept so it can be reused by CallbackGen
which doesn't drop first params.
* generator/Signal.cs: use Unconditional method for prep.
* generator/VirtualMethod.cs: use Unconditional method for prep.
* gtk/Gtk.metadata: mark a ref param.
2008-06-28 Mike Kestner <mkestner@novell.com>
* gtk/Gtk.metadata: mark ListStore.Reorder array param.

View file

@ -207,76 +207,37 @@ namespace GtkSharp.Generation {
GenInvoker (gen_info, sw);
sw.WriteLine ("\tinternal class " + Name + "Wrapper {");
sw.WriteLine ();
ManagedCallString call = new ManagedCallString (parms, false);
sw.WriteLine ("\t\tpublic " + retval.MarshalType + " NativeCallback (" + parms.ImportSignature + ")");
sw.WriteLine ("\t\t{");
string unconditional = call.Unconditional ("\t\t\t");
if (unconditional.Length > 0)
sw.WriteLine (unconditional);
sw.WriteLine ("\t\t\ttry {");
string call_setup = call.Setup ("\t\t\t\t");
if (call_setup.Length > 0)
sw.WriteLine (call_setup);
if (retval.CSType == "void")
sw.WriteLine ("\t\t\t\tmanaged ({0});", call);
else
sw.WriteLine ("\t\t\t\t{0} __ret = managed ({1});", retval.CSType, call);
string finish = call.Finish ("\t\t\t\t");
if (finish.Length > 0)
sw.WriteLine (finish);
sw.WriteLine ("\t\t\t\tif (release_on_call)\n\t\t\t\t\tgch.Free ();");
if (retval.CSType != "void")
sw.WriteLine ("\t\t\t\treturn {0};", retval.ToNative ("__ret"));
bool need_sep = false;
bool throws_error = false;
string call_str = "";
string cleanup_str = "";
for (int i = 0, idx = 0; i < parms.Count; i++)
{
Parameter p = parms [i];
if (p.CType == "GError**") {
sw.WriteLine ("\t\t\t\t" + p.Name + " = IntPtr.Zero;");
throws_error = true;
continue;
} else if (parms.IsHidden (p))
continue;
IGeneratable gen = p.Generatable;
sw.Write("\t\t\t\t" + p.CSType + " _arg" + idx);
if (p.PassAs == "out") {
sw.WriteLine(";");
cleanup_str += "\t\t\t\t" + p.Name + " = " + gen.CallByName ("_arg" + idx) + ";\n";
} else
sw.WriteLine(" = " + gen.FromNative (p.Name) + ";");
if (need_sep)
call_str += ", ";
else
need_sep = true;
call_str += String.Format ("{0} _arg{1}", p.PassAs, idx);
idx++;
}
bool has_out_params = cleanup_str.Length > 0;
cleanup_str += "\t\t\t\tif (release_on_call)\n\t\t\t\t\tgch.Free ();\n";
sw.Write ("\t\t\t\t");
string invoke = "managed (" + call_str + ")";
if (retval.MarshalType != "void") {
sw.Write (retval.MarshalType + " ret = ");
cleanup_str += "\t\t\t\treturn ret;\n";
SymbolTable table = SymbolTable.Table;
ClassBase ret_wrapper = table.GetClassGen (retval.CType);
if (ret_wrapper != null && ret_wrapper is HandleBase)
sw.WriteLine ("(({0}) {1}).Handle;", retval.CSType, invoke);
else if (table.IsStruct (retval.CType) || table.IsBoxed (retval.CType)) {
// Shoot. I have no idea what to do here.
Console.WriteLine ("Struct return type {0} in callback {1}", retval.CType, CName);
sw.WriteLine ("IntPtr.Zero;");
} else if (table.IsEnum (retval.CType))
sw.WriteLine ("(int) {0};", invoke);
else
sw.WriteLine ("({0}) ({1});", retval.MarshalType, table.ToNativeReturn (retval.CType, invoke));
} else
sw.WriteLine (invoke + ";");
sw.Write (cleanup_str);
bool fatal = (retval.MarshalType != "void" && retval.MarshalType != "bool") || has_out_params || throws_error;
/* If the function expects one or more "out" parameters(error parameters are excluded) or has a return value different from void and bool, exceptions
* thrown in the managed function have to be considered fatal meaning that an exception is to be thrown and the function call cannot not return
*/
bool fatal = (retval.MarshalType != "void" && retval.MarshalType != "bool") || call.HasOutParam;
sw.WriteLine ("\t\t\t} catch (Exception e) {");
sw.WriteLine ("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");");
if (fatal) {
sw.WriteLine ("\t\t\t\t// NOTREACHED: Above call does not return.");
sw.WriteLine ("\t\t\t\tthrow e;");
} else if (retval.MarshalType == "bool") {
if (throws_error)
sw.WriteLine ("\t\t\t\terror = IntPtr.Zero;");
sw.WriteLine ("\t\t\t\treturn false;");
}
sw.WriteLine ("\t\t\t}");

View file

@ -33,17 +33,17 @@ namespace GtkSharp.Generation {
string user_data_param = null;
string destroy_param = null;
public ManagedCallString (Parameters parms)
public ManagedCallString (Parameters parms, bool drop_first)
{
for (int i = 1; i < parms.Count; i ++) {
for (int i = drop_first ? 1 : 0; i < parms.Count; i ++) {
Parameter p = parms [i];
if (p.IsLength && parms [i-1].IsString)
if (p.IsLength && i > 0 && parms [i-1].IsString)
continue;
else if (p.Scope == "notified") {
user_data_param = parms[i+1].Name;
destroy_param = parms[i+2].Name;
i += 2;
} else if (p.IsUserData && parms [i-1].Generatable is CallbackGen) {
} else if (p.IsUserData && (i == parms.Count - 1) && (parms.HideData || parms [i-1].Generatable is CallbackGen)) {
user_data_param = p.Name;
continue;
} else if (p is ErrorParameter) {
@ -61,13 +61,27 @@ namespace GtkSharp.Generation {
}
}
public bool HasOutParam {
get {
foreach (Parameter p in parms) {
if (p.PassAs == "out")
return true;
}
return false;
}
}
public string Unconditional (string indent) {
string ret = "";
if (error_param != null)
ret = indent + error_param + " = IntPtr.Zero;\n";
return ret;
}
public string Setup (string indent)
{
string ret = "";
if (error_param != null)
ret = indent + error_param + " = IntPtr.Zero;\n";
for (int i = 0; i < parms.Count; i ++) {
if ((bool)special[i] == false)
continue;

View file

@ -380,7 +380,7 @@ namespace GtkSharp.Generation {
StreamWriter glue;
bool use_glue = gen_info.GlueEnabled && implementor == null && ClassFieldName.Length > 0;
string glue_name = String.Empty;
ManagedCallString call = new ManagedCallString (parms);
ManagedCallString call = new ManagedCallString (parms, true);
sw.WriteLine ("\t\t[GLib.CDeclCallback]");
sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + Name + "VMDelegate (" + parms.ImportSignature + ");\n");
@ -402,6 +402,9 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\t\tstatic {0} {1};\n", Name + "VMDelegate", Name + "VMCallback");
sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + Name.ToLower() + "_cb (" + parms.ImportSignature + ")");
sw.WriteLine ("\t\t{");
string unconditional = call.Unconditional ("\t\t\t");
if (unconditional.Length > 0)
sw.WriteLine (unconditional);
sw.WriteLine ("\t\t\ttry {");
sw.WriteLine ("\t\t\t\t{0} {1}_managed = GLib.Object.GetObject ({1}, false) as {0};", implementor != null ? implementor.Name : container_type.Name, parms[0].Name);
sw.Write (call.Setup ("\t\t\t\t"));

View file

@ -70,7 +70,7 @@ namespace GtkSharp.Generation {
if (!Validate ())
return;
ManagedCallString call = new ManagedCallString (parms);
ManagedCallString call = new ManagedCallString (parms, true);
string type = parms [0].CSType + "Implementor";
string name = parms [0].Name;
string call_string = "__obj." + Name + " (" + call + ")";
@ -84,6 +84,9 @@ namespace GtkSharp.Generation {
sw.WriteLine ();
sw.WriteLine ("\t\tstatic " + MarshalReturnType + " " + Name + "Callback (" + parms.ImportSignature + ")");
sw.WriteLine ("\t\t{");
string unconditional = call.Unconditional ("\t\t\t");
if (unconditional.Length > 0)
sw.WriteLine (unconditional);
sw.WriteLine ("\t\t\ttry {");
sw.WriteLine ("\t\t\t\t" + type + " __obj = GLib.Object.GetObject (" + name + ", false) as " + type + ";");
sw.Write (call.Setup ("\t\t\t\t"));

View file

@ -53,6 +53,7 @@
<attr path="/api/namespace/boxed[@cname='GtkTreeRowReference']/method[@name='GetPath']/return-type" name="owned">true</attr>
<attr path="/api/namespace/callback[@cname='GtkClipboardRichTextReceivedFunc']" name="hidden">1</attr>
<attr path="/api/namespace/callback[@cname='GtkItemFactoryCallback2']" name="hidden">1</attr>
<attr path="/api/namespace/callback[@cname='GtkTreeModelFilterModifyFunc']/parameters/parameter[@name='value']" name="pass_as">ref</attr>
<attr path="/api/namespace/callback[@cname='GtkModuleDisplayInitFunc']" name="hidden">1</attr>
<attr path="/api/namespace/callback[@cname='GtkModuleInitFunc']" name="hidden">1</attr>
<attr path="/api/namespace/class[@cname='GtkAccel_']/method[@name='GroupsFromObject']" name="hidden">1</attr>