From 33cb5d82b4e7f600101eda212388c3a836c76d0a Mon Sep 17 00:00:00 2001
From: Mike Kestner <mkestner@gmail.com>
Date: Wed, 26 Jan 2005 19:17:07 +0000
Subject: [PATCH] 2005-01-26  Mike Kestner  <mkestner@novell.com>

	* generator/*.cs : refactoring of Parameters class. Added IEnumerable
	to Parameters and gracefully handle elem == null instead of special
	casing parms == null all over the place. Parameter logic is now Count
	driven. [Fixes #71750]

svn path=/trunk/gtk-sharp/; revision=39594
---
 ChangeLog                    |  7 +++++++
 generator/CallbackGen.cs     | 14 +++++---------
 generator/Ctor.cs            |  2 +-
 generator/ImportSignature.cs |  2 +-
 generator/Method.cs          | 12 ++++++------
 generator/MethodBase.cs      |  9 +++------
 generator/MethodBody.cs      |  9 +++------
 generator/Parameters.cs      | 37 +++++++++++++++++++++++++-----------
 generator/Signal.cs          | 37 +++++++++++++++++-------------------
 generator/SignalHandler.cs   | 14 ++++++--------
 generator/Signature.cs       |  3 ---
 generator/VMSignature.cs     |  3 ---
 generator/VirtualMethod.cs   |  9 +++++----
 13 files changed, 80 insertions(+), 78 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0999d535d..46cbbd0a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-01-26  Mike Kestner  <mkestner@novell.com>
+
+	* generator/*.cs : refactoring of Parameters class. Added IEnumerable
+	to Parameters and gracefully handle elem == null instead of special
+	casing parms == null all over the place. Parameter logic is now Count
+	driven. [Fixes #71750]
+
 2005-01-26  Dan Winship  <danw@novell.com>
 
 	* generator/Property.cs (Generate): Remove a redundant WriteLine (that
diff --git a/generator/CallbackGen.cs b/generator/CallbackGen.cs
index 860b019f7..85c186752 100644
--- a/generator/CallbackGen.cs
+++ b/generator/CallbackGen.cs
@@ -35,10 +35,8 @@ namespace GtkSharp.Generation {
 		public CallbackGen (XmlElement ns, XmlElement elem) : base (ns, elem) 
 		{
 			retval = new ReturnValue (elem ["return-type"]);
-			if (elem ["parameters"] != null) {
-				parms = new Parameters (elem ["parameters"], NS);
-				parms.HideData = true;
-			}
+			parms = new Parameters (elem ["parameters"]);
+			parms.HideData = true;
 		}
 
 		public override string MarshalType {
@@ -78,18 +76,17 @@ namespace GtkSharp.Generation {
 			sw.WriteLine ("\t\tpublic " + retval.MarshalType + " NativeCallback (" + isig.ToString() + ")");
 			sw.WriteLine ("\t\t{");
 
-			int count = (parms != null) ? parms.Count : 0;
 			bool need_sep = false;
 			string call_str = "";
 			string cleanup_str = "";
-			for (int i = 0, idx = 0; i < count; i++)
+			for (int i = 0, idx = 0; i < parms.Count; i++)
 			{
 				Parameter p = parms [i];
 
 				if (i > 0 && p.IsLength && parms[i-1].IsString)
 					continue;
 
-				if ((i == count - 1) && p.IsUserData) 
+				if ((i == parms.Count - 1) && p.IsUserData) 
 					continue;
 
 				if (p.CType == "GError**") {
@@ -169,10 +166,9 @@ namespace GtkSharp.Generation {
 				return;
 			}
 
-			if ((parms != null) && !parms.Validate ()) {
+			if (!parms.Validate ()) {
 				Console.WriteLine(" in callback " + CName + " **** Stubbing it out ****");
 				Statistics.ThrottledCount++;
-				parms = null;
 			}
 
 			sig = new Signature (parms);
diff --git a/generator/Ctor.cs b/generator/Ctor.cs
index 9a6f7a444..fecc769d8 100644
--- a/generator/Ctor.cs
+++ b/generator/Ctor.cs
@@ -101,7 +101,7 @@ namespace GtkSharp.Generation {
 				if (needs_chaining) {
 					sw.WriteLine ("\t\t\tif (GetType () != typeof (" + name + ")) {");
 					
-					if (Parameters == null || Parameters.Count == 0) {
+					if (Parameters.Count == 0) {
 						sw.WriteLine ("\t\t\t\tCreateNativeObject (new string [0], new GLib.Value[0]);");
 						sw.WriteLine ("\t\t\t\treturn;");
 					} else {
diff --git a/generator/ImportSignature.cs b/generator/ImportSignature.cs
index 8dda9c395..3d324b54c 100644
--- a/generator/ImportSignature.cs
+++ b/generator/ImportSignature.cs
@@ -43,7 +43,7 @@ namespace GtkSharp.Generation {
 
 		public override string ToString ()
 		{
-			if (parameters == null)
+			if (parameters.Count == 0)
 				return "";
 
 			string[] parms = new string [parameters.Count];
diff --git a/generator/Method.cs b/generator/Method.cs
index 4f58e4283..bc62990e8 100644
--- a/generator/Method.cs
+++ b/generator/Method.cs
@@ -120,10 +120,10 @@ namespace GtkSharp.Generation {
 				return true;
 
 			Parameters parms = Parameters;
-			is_get = (((parms != null && ((parms.IsAccessor && retval.CSType == "void") || (parms.Count == 0 && retval.CSType != "void"))) || (parms == null && retval.CSType != "void")) && Name.Length > 3 && (Name.StartsWith ("Get") || Name.StartsWith ("Is") || Name.StartsWith ("Has")));
-			is_set = ((parms != null && (parms.IsAccessor || (parms.Count == 1 && retval.CSType == "void"))) && (Name.Length > 3 && Name.Substring(0, 3) == "Set"));
+			is_get = ((((parms.IsAccessor && retval.CSType == "void") || (parms.Count == 0 && retval.CSType != "void")) || (parms.Count == 0 && retval.CSType != "void")) && Name.Length > 3 && (Name.StartsWith ("Get") || Name.StartsWith ("Is") || Name.StartsWith ("Has")));
+			is_set = ((parms.IsAccessor || (parms.Count == 1 && retval.CSType == "void")) && (Name.Length > 3 && Name.Substring(0, 3) == "Set"));
 			
-			call = "(" + (IsStatic ? "" : container_type.CallByName () + (parms != null ? ", " : "")) + Body.GetCallString (is_set) + ")";
+			call = "(" + (IsStatic ? "" : container_type.CallByName () + (parms.Count > 0 ? ", " : "")) + Body.GetCallString (is_set) + ")";
 
 			initialized = true;
 			return true;
@@ -170,7 +170,7 @@ namespace GtkSharp.Generation {
 			if (implementor != null)
 				dup = implementor.GetMethodRecursively (Name);
 
-			if (Name == "ToString" && Parameters == null)
+			if (Name == "ToString" && Parameters.Count == 0)
 				sw.Write("override ");
 			else if (Name == "GetGType" && container_type is ObjectGen)
 				sw.Write("new ");
@@ -235,7 +235,7 @@ namespace GtkSharp.Generation {
 		public void GenerateImport (StreamWriter sw)
 		{
 			string import_sig = IsStatic ? "" : container_type.MarshalType + " raw";
-			import_sig += !IsStatic && Parameters != null ? ", " : "";
+			import_sig += !IsStatic && Parameters.Count > 0 ? ", " : "";
 			import_sig += ImportSignature.ToString();
 			sw.WriteLine("\t\t[DllImport(\"" + LibraryName + "\")]");
 			if (retval.MarshalType.StartsWith ("[return:"))
@@ -346,7 +346,7 @@ namespace GtkSharp.Generation {
 			Body.Finish (sw, indent);
 			Body.HandleException (sw, indent);
 
-			if (is_get && Parameters != null) 
+			if (is_get && Parameters.Count > 0) 
 				sw.WriteLine (indent + "\t\t\treturn " + Parameters.AccessorName + ";");
 			else if (retval.MarshalType != "void")
 				sw.WriteLine (indent + "\t\t\treturn ret;");
diff --git a/generator/MethodBase.cs b/generator/MethodBase.cs
index 81c2123e0..d65729251 100644
--- a/generator/MethodBase.cs
+++ b/generator/MethodBase.cs
@@ -37,9 +37,7 @@ namespace GtkSharp.Generation {
 		{
 			this.elem = elem;
 			this.container_type = container_type;
-			XmlElement parms_elem = elem ["parameters"];
-			if (parms_elem != null)
-				parms = new Parameters (parms_elem, container_type.NS);
+			parms = new Parameters (elem ["parameters"]);
 			IsStatic = elem.GetAttribute ("shared") == "true";
 			if (elem.HasAttribute ("new_flag"))
 				mods = "new ";
@@ -75,8 +73,7 @@ namespace GtkSharp.Generation {
 			}
 			set {
 				is_static = value;
-				if (parms != null)
-					parms.Static = value;
+				parms.Static = value;
 			}
 		}
 
@@ -120,7 +117,7 @@ namespace GtkSharp.Generation {
 
 		public virtual bool Validate ()
 		{
-			if (parms != null && !parms.Validate ()) {
+			if (!parms.Validate ()) {
 				Console.Write("in ctor ");
 				Statistics.ThrottledCount++;
 				return false;
diff --git a/generator/MethodBody.cs b/generator/MethodBody.cs
index 95e4acf9d..c6beae864 100644
--- a/generator/MethodBody.cs
+++ b/generator/MethodBody.cs
@@ -57,7 +57,7 @@ namespace GtkSharp.Generation {
 
 		public string GetCallString (bool is_set)
 		{
-			if (parameters == null)
+			if (parameters.Count == 0)
 				return "";
 
 			string[] result = new string [parameters.Count];
@@ -116,7 +116,7 @@ namespace GtkSharp.Generation {
 
 		public void Initialize (GenerationInfo gen_info, bool is_get, bool is_set, string indent)
 		{
-			if (parameters == null)
+			if (parameters.Count == 0)
 				return;
 
 			StreamWriter sw = gen_info.Writer;
@@ -165,9 +165,6 @@ namespace GtkSharp.Generation {
 
 		public void Finish (StreamWriter sw, string indent)
 		{
-			if (parameters == null)
-				return;
-
 			for (int i = 0; i < parameters.Count; i++) {
 				Parameter p = parameters [i];
 
@@ -198,7 +195,7 @@ namespace GtkSharp.Generation {
 		
 		public bool ThrowsException {
 			get {
-				if (parameters == null || parameters.Count < 1)
+				if (parameters.Count < 1)
 					return false;
 
 				return parameters [parameters.Count - 1].CType == "GError**";
diff --git a/generator/Parameters.cs b/generator/Parameters.cs
index 769d9748c..6fe2f701f 100644
--- a/generator/Parameters.cs
+++ b/generator/Parameters.cs
@@ -216,19 +216,15 @@ namespace GtkSharp.Generation {
 		}
 	}
 
-	public class Parameters  {
+	public class Parameters : IEnumerable {
 		
-		private ArrayList param_list;
-		private XmlElement elem;
-		private string impl_ns;
-		private bool hide_data;
-		private bool is_static;
+		ArrayList param_list = new ArrayList ();
 
-		public Parameters (XmlElement elem, string impl_ns) {
+		public Parameters (XmlElement elem) {
 			
-			this.elem = elem;
-			this.impl_ns = impl_ns;
-			param_list = new ArrayList ();
+			if (elem == null)
+				return;
+
 			foreach (XmlNode node in elem.ChildNodes) {
 				XmlElement parm = node as XmlElement;
 				if (parm != null && parm.Name == "parameter")
@@ -248,28 +244,48 @@ namespace GtkSharp.Generation {
 			}
 		}
 
+		bool hide_data;
 		public bool HideData {
 			get { return hide_data; }
 			set { hide_data = value; }
 		}
 
+		bool is_static;
 		public bool Static {
 			get { return is_static; }
 			set { is_static = value; }
 		}
 
+		bool cleared = false;
+		void Clear ()
+		{
+			cleared = true;
+			param_list.Clear ();
+		}
+
+		public IEnumerator GetEnumerator ()
+		{
+			return param_list.GetEnumerator ();
+		}
+
 		public bool Validate ()
 		{
+			if (cleared)
+				return false;
+
 			foreach (Parameter p in param_list) {
 				
 				if (p.IsEllipsis) {
 					Console.Write("Ellipsis parameter ");
+					Clear ();
+					
 					return false;
 				}
 
 				if ((p.CSType == "") || (p.Name == "") || 
 				    (p.MarshalType == "") || (SymbolTable.Table.CallByName(p.CType, p.Name) == "")) {
 					Console.Write("Name: " + p.Name + " Type: " + p.CType + " ");
+					Clear ();
 					return false;
 				}
 			}
@@ -300,7 +316,6 @@ namespace GtkSharp.Generation {
 					return null;
 			}
 		}
-
 	}
 }
 
diff --git a/generator/Signal.cs b/generator/Signal.cs
index 0f996dee0..56977059b 100644
--- a/generator/Signal.cs
+++ b/generator/Signal.cs
@@ -39,10 +39,9 @@ namespace GtkSharp.Generation {
 		public Signal (XmlElement elem, ClassBase container_type)
 		{
 			this.elem = elem;
-			this.name = elem.GetAttribute ("name");
-			this.retval = new ReturnValue (elem ["return-type"]);
-			if (elem["parameters"] != null)
-				parms = new Parameters (elem["parameters"], container_type.NS);
+			name = elem.GetAttribute ("name");
+			retval = new ReturnValue (elem ["return-type"]);
+			parms = new Parameters (elem["parameters"]);
 			this.container_type = container_type;
 			sig_handler = new SignalHandler (elem, container_type.NS);
 		}
@@ -64,7 +63,7 @@ namespace GtkSharp.Generation {
 				return false;
 			}
 			
-			if (parms != null && !parms.Validate ())
+			if (!parms.Validate ())
 				return false;
 
 			if (!retval.Validate ())
@@ -169,22 +168,20 @@ namespace GtkSharp.Generation {
 			sw.WriteLine ("\tpublic delegate void " + EventHandlerName + "(object o, " + EventArgsName + " args);");
 			sw.WriteLine ();
 			sw.WriteLine ("\tpublic class " + EventArgsName + " : GLib.SignalArgs {");
-			if (parms != null) {
-				for (int i = 1; i < parms.Count; i++) {
-					sw.WriteLine ("\t\tpublic " + parms[i].CSType + " " + parms[i].StudlyName + "{");
-					if (parms[i].PassAs != "out") {
-						sw.WriteLine ("\t\t\tget {");
-						sw.WriteLine ("\t\t\t\treturn (" + parms[i].CSType + ") Args[" + (i - 1) + "];");
-						sw.WriteLine ("\t\t\t}");
-					}
-					if (parms[i].PassAs != "") {
-						sw.WriteLine ("\t\t\tset {");
-						sw.WriteLine ("\t\t\t\tArgs[" + (i - 1) + "] = (" + parms[i].CSType + ")value;");
-						sw.WriteLine ("\t\t\t}");
-					}
-					sw.WriteLine ("\t\t}");
-					sw.WriteLine ();
+			for (int i = 1; i < parms.Count; i++) {
+				sw.WriteLine ("\t\tpublic " + parms[i].CSType + " " + parms[i].StudlyName + "{");
+				if (parms[i].PassAs != "out") {
+					sw.WriteLine ("\t\t\tget {");
+					sw.WriteLine ("\t\t\t\treturn (" + parms[i].CSType + ") Args[" + (i - 1) + "];");
+					sw.WriteLine ("\t\t\t}");
 				}
+				if (parms[i].PassAs != "") {
+					sw.WriteLine ("\t\t\tset {");
+					sw.WriteLine ("\t\t\t\tArgs[" + (i - 1) + "] = (" + parms[i].CSType + ")value;");
+					sw.WriteLine ("\t\t\t}");
+				}
+				sw.WriteLine ("\t\t}");
+				sw.WriteLine ();
 			}
 			sw.WriteLine ("\t}");
 			sw.WriteLine ("}");
diff --git a/generator/SignalHandler.cs b/generator/SignalHandler.cs
index cc2c6b5c9..7bd5b5039 100644
--- a/generator/SignalHandler.cs
+++ b/generator/SignalHandler.cs
@@ -38,9 +38,7 @@ namespace GtkSharp.Generation {
 			this.sig = sig;
 			this.ns = ns;
 			retval = new ReturnValue (sig["return-type"]);
-			XmlElement params_elem = sig["parameters"] as XmlElement;
-			if (params_elem != null)
-				parms = new Parameters (params_elem, ns);
+			parms = new Parameters (sig ["parameters"]);
 		}
 
 		public bool Validate ()
@@ -50,7 +48,7 @@ namespace GtkSharp.Generation {
 				return false;
 			}
 			
-			if (parms == null || !parms.Validate ()) {
+			if (!parms.Validate ()) {
 				Console.Write("Missing parameters ");
 				return false;
 			}
@@ -80,12 +78,12 @@ namespace GtkSharp.Generation {
 		private string BaseName {
 			get {
 				string result = SymbolTable.Table.GetName (retval.CType);
-				for (int i = 0; i < parms.Count; i++) {
-					result += parms[i].PassAs;
-					if (parms[i].Generatable is ObjectGen || parms[i].Generatable is InterfaceGen) {
+				foreach (Parameter p in parms) {
+					result += p.PassAs;
+					if (p.Generatable is ObjectGen || p.Generatable is InterfaceGen) {
 						result += "Object";
 					} else {
-						result += SymbolTable.Table.GetName(parms[i].CType);
+						result += SymbolTable.Table.GetName(p.CType);
 					}
 				}		 
 				result = result.Replace ("[]", "Array");
diff --git a/generator/Signature.cs b/generator/Signature.cs
index e3f55bad6..05c28baec 100644
--- a/generator/Signature.cs
+++ b/generator/Signature.cs
@@ -31,9 +31,6 @@ namespace GtkSharp.Generation {
 
 		public Signature (Parameters parms) 
 		{
-			if (parms == null)
-				return;
-
 			bool has_cb = parms.HideData;
 			for (int i = 0; i < parms.Count; i++) {
 				Parameter p = parms [i];
diff --git a/generator/VMSignature.cs b/generator/VMSignature.cs
index f8da45ae5..240bf88a8 100644
--- a/generator/VMSignature.cs
+++ b/generator/VMSignature.cs
@@ -31,9 +31,6 @@ namespace GtkSharp.Generation {
 
 		public VMSignature (Parameters parms) 
 		{
-			if (parms == null)
-				return;
-
 			bool has_cb = parms.HideData;
 			for (int i = 1; i < parms.Count; i++) {
 				Parameter p = parms [i];
diff --git a/generator/VirtualMethod.cs b/generator/VirtualMethod.cs
index 56cb985db..443470add 100644
--- a/generator/VirtualMethod.cs
+++ b/generator/VirtualMethod.cs
@@ -26,18 +26,19 @@ namespace GtkSharp.Generation {
 	using System.IO;
 	using System.Xml;
 
+	// FIXME: handle static VMs
 	public class VirtualMethod  {
 		
-		private XmlElement elem;
-		private ReturnValue retval;
-		private Parameters parms;
+		XmlElement elem;
+		ReturnValue retval;
+		Parameters parms;
 		ImportSignature isig;
 
 		public VirtualMethod (XmlElement elem, ClassBase container_type) 
 		{
 			this.elem = elem;
 			retval = new ReturnValue (elem ["return-type"]);
-			parms = new Parameters (elem["parameters"], container_type.NS);
+			parms = new Parameters (elem["parameters"]);
 			isig = new ImportSignature (parms, container_type.NS);
 		}