[vala] Refactor parser to avoid parse_*_member methods



commit 1e7d87f2efa1b5041fe8e460a06b879c8e69acee
Author: Jürg Billeter <j bitron ch>
Date:   Fri Feb 26 19:23:42 2010 +0100

    Refactor parser to avoid parse_*_member methods

 vala/valaclass.vala       |   56 ++++++-
 vala/valaenum.vala        |    4 +-
 vala/valaerrordomain.vala |    4 +-
 vala/valagenieparser.vala |    7 -
 vala/valagirparser.vala   |    3 +-
 vala/valainterface.vala   |   18 +-
 vala/valanamespace.vala   |   73 ++++++++--
 vala/valaparser.vala      |  380 +++++++++++++++------------------------------
 vala/valastruct.vala      |    8 +-
 vala/valasymbol.vala      |   56 +++++++
 10 files changed, 307 insertions(+), 302 deletions(-)
---
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 0380acb..ac6f332 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -274,7 +274,7 @@ public class Vala.Class : ObjectTypeSymbol {
 	 *
 	 * @param c a constant
 	 */
-	public void add_constant (Constant c) {
+	public override void add_constant (Constant c) {
 		constants.add (c);
 		scope.add (c.name, c);
 	}
@@ -284,7 +284,7 @@ public class Vala.Class : ObjectTypeSymbol {
 	 *
 	 * @param f a field
 	 */
-	public void add_field (Field f) {
+	public override void add_field (Field f) {
 		if (CodeContext.get ().profile == Profile.DOVA &&
 		    f.binding == MemberBinding.INSTANCE &&
 		    (f.access == SymbolAccessibility.PUBLIC || f.access == SymbolAccessibility.PROTECTED) &&
@@ -343,7 +343,7 @@ public class Vala.Class : ObjectTypeSymbol {
 	 *
 	 * @param m a method
 	 */
-	public void add_method (Method m) {
+	public override void add_method (Method m) {
 		if (m.binding == MemberBinding.INSTANCE || m is CreationMethod) {
 			if (m.this_parameter != null) {
 				m.scope.remove (m.this_parameter.name);
@@ -391,7 +391,7 @@ public class Vala.Class : ObjectTypeSymbol {
 	 *
 	 * @param prop a property
 	 */
-	public void add_property (Property prop) {
+	public override void add_property (Property prop) {
 		properties.add (prop);
 		scope.add (prop.name, prop);
 
@@ -417,7 +417,7 @@ public class Vala.Class : ObjectTypeSymbol {
 	 *
 	 * @param sig a signal
 	 */
-	public void add_signal (Signal sig) {
+	public override void add_signal (Signal sig) {
 		signals.add (sig);
 		scope.add (sig.name, sig);
 	}
@@ -436,7 +436,7 @@ public class Vala.Class : ObjectTypeSymbol {
 	 *
 	 * @param cl a class
 	 */
-	public void add_class (Class cl) {
+	public override void add_class (Class cl) {
 		classes.add (cl);
 		scope.add (cl.name, cl);
 	}
@@ -446,7 +446,7 @@ public class Vala.Class : ObjectTypeSymbol {
 	 *
 	 * @param st a struct
 	 */
-	public void add_struct (Struct st) {
+	public override void add_struct (Struct st) {
 		structs.add (st);
 		scope.add (st.name, st);
 	}
@@ -456,7 +456,7 @@ public class Vala.Class : ObjectTypeSymbol {
 	 *
 	 * @param en an enum
 	 */
-	public void add_enum (Enum en) {
+	public override void add_enum (Enum en) {
 		enums.add (en);
 		scope.add (en.name, en);
 	}
@@ -466,11 +466,49 @@ public class Vala.Class : ObjectTypeSymbol {
 	 *
 	 * @param d a delegate
 	 */
-	public void add_delegate (Delegate d) {
+	public override void add_delegate (Delegate d) {
 		delegates.add (d);
 		scope.add (d.name, d);
 	}
 
+	public override void add_constructor (Constructor c) {
+		if (c.binding == MemberBinding.INSTANCE) {
+			if (constructor != null) {
+				Report.error (c.source_reference, "class already contains a constructor");
+			}
+			constructor = c;
+		} else if (c.binding == MemberBinding.CLASS) {
+			if (class_constructor != null) {
+				Report.error (c.source_reference, "class already contains a class constructor");
+			}
+			class_constructor = c;
+		} else {
+			if (static_constructor != null) {
+				Report.error (c.source_reference, "class already contains a static constructor");
+			}
+			static_constructor = c;
+		}
+	}
+
+	public override void add_destructor (Destructor d) {
+		if (d.binding == MemberBinding.INSTANCE) {
+			if (destructor != null) {
+				Report.error (d.source_reference, "class already contains a destructor");
+			}
+			destructor = d;
+		} else if (d.binding == MemberBinding.CLASS) {
+			if (class_destructor != null) {
+				Report.error (d.source_reference, "class already contains a class destructor");
+			}
+			class_destructor = d;
+		} else {
+			if (static_destructor != null) {
+				Report.error (d.source_reference, "class already contains a static destructor");
+			}
+			static_destructor = d;
+		}
+	}
+
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_class (this);
 	}
diff --git a/vala/valaenum.vala b/vala/valaenum.vala
index 85bd3b4..27e950d 100644
--- a/vala/valaenum.vala
+++ b/vala/valaenum.vala
@@ -71,7 +71,7 @@ public class Vala.Enum : TypeSymbol {
 	 *
 	 * @param m a method
 	 */
-	public void add_method (Method m) {
+	public override void add_method (Method m) {
 		if (m is CreationMethod) {
 			Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
 		
@@ -96,7 +96,7 @@ public class Vala.Enum : TypeSymbol {
 	 *
 	 * @param c a constant
 	 */
-	public void add_constant (Constant c) {
+	public override void add_constant (Constant c) {
 		constants.add (c);
 		scope.add (c.name, c);
 	}
diff --git a/vala/valaerrordomain.vala b/vala/valaerrordomain.vala
index f80750f..b49683c 100644
--- a/vala/valaerrordomain.vala
+++ b/vala/valaerrordomain.vala
@@ -1,6 +1,6 @@
 /* valaerrordomain.vala
  *
- * Copyright (C) 2008-2009  Jürg Billeter
+ * Copyright (C) 2008-2010  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -59,7 +59,7 @@ public class Vala.ErrorDomain : TypeSymbol {
 	 *
 	 * @param m a method
 	 */
-	public void add_method (Method m) {
+	public override void add_method (Method m) {
 		if (m is CreationMethod) {
 			Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
 		
diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala
index 3ae29c7..5b4b39f 100644
--- a/vala/valagenieparser.vala
+++ b/vala/valagenieparser.vala
@@ -2528,7 +2528,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 		} else {
 			Report.error (sym.source_reference, "unexpected declaration in namespace");
 		}
-		scanner.source_file.add_node (sym);
 	}
 
 
@@ -2631,7 +2630,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 				ns.add_namespace ((Namespace) result);
 			} else {
 				ns.add_class ((Class) result);
-				scanner.source_file.add_node (result);
 			}
 			result = ns;
 		}
@@ -3256,7 +3254,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 				ns.add_namespace ((Namespace) result);
 			} else {
 				ns.add_struct ((Struct) result);
-				scanner.source_file.add_node (result);
 			}
 			result = ns;
 		}
@@ -3322,7 +3319,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 				ns.add_namespace ((Namespace) result);
 			} else {
 				ns.add_interface ((Interface) result);
-				scanner.source_file.add_node (result);
 			}
 			result = ns;
 		}
@@ -3405,7 +3401,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 				ns.add_namespace ((Namespace) result);
 			} else {
 				ns.add_enum ((Enum) result);
-				scanner.source_file.add_node (result);
 			}
 			result = ns;
 		}
@@ -3460,7 +3455,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 				ns.add_namespace ((Namespace) result);
 			} else {
 				ns.add_error_domain ((ErrorDomain) result);
-				scanner.source_file.add_node (result);
 			}
 			result = ns;
 		}
@@ -3712,7 +3706,6 @@ public class Vala.Genie.Parser : CodeVisitor {
 				ns.add_namespace ((Namespace) result);
 			} else {
 				ns.add_delegate ((Delegate) result);
-				scanner.source_file.add_node (result);
 			}
 			result = ns;
 		}
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 4ddfab7..871f4cb 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -1,6 +1,6 @@
 /* valagirparser.vala
  *
- * Copyright (C) 2008-2009  Jürg Billeter
+ * Copyright (C) 2008-2010  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -280,7 +280,6 @@ public class Vala.GirParser : CodeVisitor {
 			} else if (sym == null) {
 				continue;
 			}
-			current_source_file.add_node (sym);
 		}
 		end_element ("namespace");
 
diff --git a/vala/valainterface.vala b/vala/valainterface.vala
index f233954..dc7248c 100644
--- a/vala/valainterface.vala
+++ b/vala/valainterface.vala
@@ -127,7 +127,7 @@ public class Vala.Interface : ObjectTypeSymbol {
 	 *
 	 * @param m a method
 	 */
-	public void add_method (Method m) {
+	public override void add_method (Method m) {
 		if (m is CreationMethod) {
 			Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
 		
@@ -162,7 +162,7 @@ public class Vala.Interface : ObjectTypeSymbol {
 	 *
 	 * @param f a field
 	 */
-	public void add_field (Field f) {
+	public override void add_field (Field f) {
 		fields.add (f);
 		scope.add (f.name, f);
 	}
@@ -181,7 +181,7 @@ public class Vala.Interface : ObjectTypeSymbol {
 	 *
 	 * @param c a constant
 	 */
-	public void add_constant (Constant c) {
+	public override void add_constant (Constant c) {
 		constants.add (c);
 		scope.add (c.name, c);
 	}
@@ -200,7 +200,7 @@ public class Vala.Interface : ObjectTypeSymbol {
 	 *
 	 * @param prop a property
 	 */
-	public void add_property (Property prop) {
+	public override void add_property (Property prop) {
 		properties.add (prop);
 		scope.add (prop.name, prop);
 
@@ -222,7 +222,7 @@ public class Vala.Interface : ObjectTypeSymbol {
 	 *
 	 * @param sig a signal
 	 */
-	public void add_signal (Signal sig) {
+	public override void add_signal (Signal sig) {
 		signals.add (sig);
 		scope.add (sig.name, sig);
 	}
@@ -241,7 +241,7 @@ public class Vala.Interface : ObjectTypeSymbol {
 	 *
 	 * @param cl a class
 	 */
-	public void add_class (Class cl) {
+	public override void add_class (Class cl) {
 		classes.add (cl);
 		scope.add (cl.name, cl);
 	}
@@ -251,7 +251,7 @@ public class Vala.Interface : ObjectTypeSymbol {
 	 *
 	 * @param st a struct
 	 */
-	public void add_struct (Struct st) {
+	public override void add_struct (Struct st) {
 		structs.add (st);
 		scope.add (st.name, st);
 	}
@@ -261,7 +261,7 @@ public class Vala.Interface : ObjectTypeSymbol {
 	 *
 	 * @param en an enum
 	 */
-	public void add_enum (Enum en) {
+	public override void add_enum (Enum en) {
 		enums.add (en);
 		scope.add (en.name, en);
 	}
@@ -271,7 +271,7 @@ public class Vala.Interface : ObjectTypeSymbol {
 	 *
 	 * @param d a delegate
 	 */
-	public void add_delegate (Delegate d) {
+	public override void add_delegate (Delegate d) {
 		delegates.add (d);
 		scope.add (d.name, d);
 	}
diff --git a/vala/valanamespace.vala b/vala/valanamespace.vala
index e7b5109..38bf996 100644
--- a/vala/valanamespace.vala
+++ b/vala/valanamespace.vala
@@ -1,6 +1,6 @@
 /* valanamespace.vala
  *
- * Copyright (C) 2006-2009  Jürg Billeter
+ * Copyright (C) 2006-2010  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -84,7 +84,11 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param ns a namespace
 	 */
-	public void add_namespace (Namespace ns) {
+	public override void add_namespace (Namespace ns) {
+		if (ns.owner == null) {
+			ns.source_reference.file.add_node (ns);
+		}
+
 		if (scope.lookup (ns.name) is Namespace) {
 			// merge if namespace already exists
 			var old_ns = (Namespace) scope.lookup (ns.name);
@@ -148,12 +152,16 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param cl a class
 	 */
-	public void add_class (Class cl) {
+	public override void add_class (Class cl) {
 		// namespaces do not support private memebers
 		if (cl.access == SymbolAccessibility.PRIVATE) {
 			cl.access = SymbolAccessibility.INTERNAL;
 		}
 
+		if (cl.owner == null) {
+			cl.source_reference.file.add_node (cl);
+		}
+
 		classes.add (cl);
 		scope.add (cl.name, cl);
 	}
@@ -163,14 +171,19 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param iface an interface
 	 */
-	public void add_interface (Interface iface) {
+	public override void add_interface (Interface iface) {
 		// namespaces do not support private memebers
 		if (iface.access == SymbolAccessibility.PRIVATE) {
 			iface.access = SymbolAccessibility.INTERNAL;
 		}
 
+		if (iface.owner == null) {
+			iface.source_reference.file.add_node (iface);
+		}
+
 		interfaces.add (iface);
 		scope.add (iface.name, iface);
+
 	}
 	
 	/**
@@ -178,12 +191,16 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param st a struct
 	 */
-	public void add_struct (Struct st) {
+	public override void add_struct (Struct st) {
 		// namespaces do not support private memebers
 		if (st.access == SymbolAccessibility.PRIVATE) {
 			st.access = SymbolAccessibility.INTERNAL;
 		}
 
+		if (st.owner == null) {
+			st.source_reference.file.add_node (st);
+		}
+
 		structs.add (st);
 		scope.add (st.name, st);
 	}
@@ -203,12 +220,16 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param en an enum
 	 */
-	public void add_enum (Enum en) {
+	public override void add_enum (Enum en) {
 		// namespaces do not support private memebers
 		if (en.access == SymbolAccessibility.PRIVATE) {
 			en.access = SymbolAccessibility.INTERNAL;
 		}
 
+		if (en.owner == null) {
+			en.source_reference.file.add_node (en);
+		}
+
 		enums.add (en);
 		scope.add (en.name, en);
 	}
@@ -218,12 +239,16 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param edomain an error domain
 	 */
-	public void add_error_domain (ErrorDomain edomain) {
+	public override void add_error_domain (ErrorDomain edomain) {
 		// namespaces do not support private memebers
 		if (edomain.access == SymbolAccessibility.PRIVATE) {
 			edomain.access = SymbolAccessibility.INTERNAL;
 		}
 
+		if (edomain.owner == null) {
+			edomain.source_reference.file.add_node (edomain);
+		}
+
 		error_domains.add (edomain);
 		scope.add (edomain.name, edomain);
 	}
@@ -233,12 +258,16 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param d a delegate
 	 */
-	public void add_delegate (Delegate d) {
+	public override void add_delegate (Delegate d) {
 		// namespaces do not support private memebers
 		if (d.access == SymbolAccessibility.PRIVATE) {
 			d.access = SymbolAccessibility.INTERNAL;
 		}
 
+		if (d.owner == null) {
+			d.source_reference.file.add_node (d);
+		}
+
 		delegates.add (d);
 		scope.add (d.name, d);
 	}
@@ -329,12 +358,16 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param constant a constant
 	 */
-	public void add_constant (Constant constant) {
+	public override void add_constant (Constant constant) {
 		// namespaces do not support private memebers
 		if (constant.access == SymbolAccessibility.PRIVATE) {
 			constant.access = SymbolAccessibility.INTERNAL;
 		}
 
+		if (constant.owner == null) {
+			constant.source_reference.file.add_node (constant);
+		}
+
 		constants.add (constant);
 		scope.add (constant.name, constant);
 	}
@@ -344,7 +377,12 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param f a field
 	 */
-	public void add_field (Field f) {
+	public override void add_field (Field f) {
+		if (f.binding == MemberBinding.INSTANCE) {
+			// default to static member binding
+			f.binding = MemberBinding.STATIC;
+		}
+
 		// namespaces do not support private memebers
 		if (f.access == SymbolAccessibility.PRIVATE) {
 			f.access = SymbolAccessibility.INTERNAL;
@@ -360,6 +398,10 @@ public class Vala.Namespace : Symbol {
 			return;
 		}
 
+		if (f.owner == null) {
+			f.source_reference.file.add_node (f);
+		}
+
 		fields.add (f);
 		scope.add (f.name, f);
 	}
@@ -369,7 +411,12 @@ public class Vala.Namespace : Symbol {
 	 *
 	 * @param m a method
 	 */
-	public void add_method (Method m) {
+	public override void add_method (Method m) {
+		if (m.binding == MemberBinding.INSTANCE) {
+			// default to static member binding
+			m.binding = MemberBinding.STATIC;
+		}
+
 		// namespaces do not support private memebers
 		if (m.access == SymbolAccessibility.PRIVATE) {
 			m.access = SymbolAccessibility.INTERNAL;
@@ -394,6 +441,10 @@ public class Vala.Namespace : Symbol {
 			m.result_var.is_result = true;
 		}
 
+		if (m.owner == null) {
+			m.source_reference.file.add_node (m);
+		}
+
 		methods.add (m);
 		scope.add (m.name, m);
 	}
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index f7dc50b..04f0d59 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -2007,7 +2007,7 @@ public class Vala.Parser : CodeVisitor {
 		}
 	}
 
-	Method parse_main_block () throws ParseError {
+	void parse_main_block (Symbol parent) throws ParseError {
 		var begin = get_location ();
 
 		var method = new Method ("main", new VoidType (), get_src (begin));
@@ -2024,10 +2024,10 @@ public class Vala.Parser : CodeVisitor {
 			Report.warning (method.source_reference, "main blocks are experimental");
 		}
 
-		return method;
+		parent.add_method (method);
 	}
 
-	Symbol parse_declaration (bool root = false) throws ParseError {
+	void parse_declaration (Symbol parent, bool root = false) throws ParseError {
 		comment = scanner.pop_comment ();
 		var attrs = parse_attributes ();
 		
@@ -2044,12 +2044,14 @@ public class Vala.Parser : CodeVisitor {
 		case TokenType.CONSTRUCT:
 			if (context.profile == Profile.GOBJECT) {
 				rollback (begin);
-				return parse_constructor_declaration (attrs);
+				parse_constructor_declaration (parent, attrs);
+				return;
 			}
 			break;
 		case TokenType.TILDE:
 			rollback (begin);
-			return parse_destructor_declaration (attrs);
+			parse_destructor_declaration (parent, attrs);
+			return;
 		case TokenType.OPEN_BRACE:
 		case TokenType.SEMICOLON:
 		case TokenType.IF:
@@ -2083,13 +2085,15 @@ public class Vala.Parser : CodeVisitor {
 				throw new ParseError.SYNTAX (get_error ("statements outside blocks allowed only in root namespace"));
 			}
 			rollback (begin);
-			return parse_main_block ();
+			parse_main_block (parent);
+			return;
 		default:
 			if (root) {
 				bool is_expr = is_expression ();
 				if (is_expr) {
 					rollback (begin);
-					return parse_main_block ();
+					parse_main_block (parent);
+					return;
 				}
 			}
 
@@ -2100,39 +2104,64 @@ public class Vala.Parser : CodeVisitor {
 			case TokenType.COLON:
 				rollback (begin);
 				switch (last_keyword) {
-				case TokenType.CLASS:       return parse_class_declaration (attrs);
-				case TokenType.ENUM:        return parse_enum_declaration (attrs);
-				case TokenType.ERRORDOMAIN: return parse_errordomain_declaration (attrs);
-				case TokenType.INTERFACE:   return parse_interface_declaration (attrs);
-				case TokenType.NAMESPACE:   return parse_namespace_declaration (attrs);
-				case TokenType.STRUCT:      return parse_struct_declaration (attrs);
-				default:                    break;
+				case TokenType.CLASS:
+					parse_class_declaration (parent, attrs);
+					return;
+				case TokenType.ENUM:
+					parse_enum_declaration (parent, attrs);
+					return;
+				case TokenType.ERRORDOMAIN:
+					parse_errordomain_declaration (parent, attrs);
+					return;
+				case TokenType.INTERFACE:
+					parse_interface_declaration (parent, attrs);
+					return;
+				case TokenType.NAMESPACE:
+					parse_namespace_declaration (parent, attrs);
+					return;
+				case TokenType.STRUCT:
+					parse_struct_declaration (parent, attrs);
+					return;
+				default:
+					break;
 				}
 				break;
 			case TokenType.OPEN_PARENS:
 				rollback (begin);
-				return parse_creation_method_declaration (attrs);
+				parse_creation_method_declaration (parent, attrs);
+				return;
 			default:
 				skip_type (); // might contain type parameter list
 				switch (current ()) {
 				case TokenType.OPEN_PARENS:
 					rollback (begin);
 					switch (last_keyword) {
-					case TokenType.DELEGATE: return parse_delegate_declaration (attrs);
-					case TokenType.SIGNAL:   return parse_signal_declaration (attrs);
-					default:                 return parse_method_declaration (attrs);
+					case TokenType.DELEGATE:
+						parse_delegate_declaration (parent, attrs);
+						return;
+					case TokenType.SIGNAL:
+						parse_signal_declaration (parent, attrs);
+						return;
+					default:
+						parse_method_declaration (parent, attrs);
+						return;
 					}
 				case TokenType.ASSIGN:
 				case TokenType.SEMICOLON:
 					rollback (begin);
 					switch (last_keyword) {
-					case TokenType.CONST: return parse_constant_declaration (attrs);
-					default:              return parse_field_declaration (attrs);
+					case TokenType.CONST:
+						parse_constant_declaration (parent, attrs);
+						return;
+					default:
+						parse_field_declaration (parent, attrs);
+						return;
 					}
 				case TokenType.OPEN_BRACE:
 				case TokenType.THROWS:
 					rollback (begin);
-					return parse_property_declaration (attrs);
+					parse_property_declaration (parent, attrs);
+					return;
 				default:
 					break;
 				}
@@ -2152,15 +2181,7 @@ public class Vala.Parser : CodeVisitor {
 		}
 		while (current () != TokenType.CLOSE_BRACE && current () != TokenType.EOF) {
 			try {
-				if (parent is Namespace) {
-					parse_namespace_member ((Namespace) parent, (parent == context.root));
-				} else if (parent is Class) {
-					parse_class_member ((Class) parent);
-				} else if (parent is Struct) {
-					parse_struct_member ((Struct) parent);
-				} else if (parent is Interface) {
-					parse_interface_member ((Interface) parent);
-				}
+				parse_declaration (parent, (parent == context.root));
 			} catch (ParseError e) {
 				int r;
 				do {
@@ -2243,7 +2264,7 @@ public class Vala.Parser : CodeVisitor {
 		return RecoveryState.EOF;
 	}
 
-	Namespace parse_namespace_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_namespace_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		expect (TokenType.NAMESPACE);
 		var sym = parse_symbol_name ();
@@ -2271,53 +2292,14 @@ public class Vala.Parser : CodeVisitor {
 			}
 		}
 
-		Namespace result = ns;
-		while (sym.inner != null) {
+		Symbol result = ns;
+		while (sym != null) {
 			sym = sym.inner;
-			ns = new Namespace (sym.name, result.source_reference);
-			ns.add_namespace ((Namespace) result);
-			result = ns;
-		}
-		return result;
-	}
-
-	void parse_namespace_member (Namespace ns, bool root = false) throws ParseError {
-		var sym = parse_declaration (root);
-
-		if (sym is Namespace) {
-			ns.add_namespace ((Namespace) sym);
-		} else if (sym is Class) {
-			ns.add_class ((Class) sym);
-		} else if (sym is Interface) {
-			ns.add_interface ((Interface) sym);
-		} else if (sym is Struct) {
-			ns.add_struct ((Struct) sym);
-		} else if (sym is Enum) {
-			ns.add_enum ((Enum) sym);
-		} else if (sym is ErrorDomain) {
-			ns.add_error_domain ((ErrorDomain) sym);
-		} else if (sym is Delegate) {
-			ns.add_delegate ((Delegate) sym);
-		} else if (sym is Method) {
-			var method = (Method) sym;
-			if (method.binding == MemberBinding.INSTANCE) {
-				// default to static member binding
-				method.binding = MemberBinding.STATIC;
-			}
-			ns.add_method (method);
-		} else if (sym is Field) {
-			var field = (Field) sym;
-			if (field.binding == MemberBinding.INSTANCE) {
-				// default to static member binding
-				field.binding = MemberBinding.STATIC;
-			}
-			ns.add_field (field);
-		} else if (sym is Constant) {
-			ns.add_constant ((Constant) sym);
-		} else {
-			Report.error (sym.source_reference, "unexpected declaration in namespace");
+
+			Symbol next = (sym != null ? new Namespace (sym.name, ns.source_reference) : parent);
+			next.add_namespace ((Namespace) result);
+			result = next;
 		}
-		scanner.source_file.add_node (sym);
 	}
 
 	void parse_using_directives (Namespace ns) throws ParseError {
@@ -2333,7 +2315,7 @@ public class Vala.Parser : CodeVisitor {
 		}
 	}
 
-	Symbol parse_class_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_class_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_type_declaration_modifiers ();
@@ -2375,82 +2357,20 @@ public class Vala.Parser : CodeVisitor {
 		}
 
 		Symbol result = cl;
-		while (sym.inner != null) {
+		while (sym != null) {
 			sym = sym.inner;
-			var ns = new Namespace (sym.name, cl.source_reference);
+
+			Symbol next = (sym != null ? new Namespace (sym.name, cl.source_reference) : parent);
 			if (result is Namespace) {
-				ns.add_namespace ((Namespace) result);
-			} else {
-				ns.add_class ((Class) result);
-				scanner.source_file.add_node (result);
-			}
-			result = ns;
-		}
-		return result;
-	}
-
-	void parse_class_member (Class cl) throws ParseError {
-		var sym = parse_declaration ();
-		if (sym is Class) {
-			cl.add_class ((Class) sym);
-		} else if (sym is Struct) {
-			cl.add_struct ((Struct) sym);
-		} else if (sym is Enum) {
-			cl.add_enum ((Enum) sym);
-		} else if (sym is Delegate) {
-			cl.add_delegate ((Delegate) sym);
-		} else if (sym is Method) {
-			cl.add_method ((Method) sym);
-		} else if (sym is Signal) {
-			cl.add_signal ((Signal) sym);
-		} else if (sym is Field) {
-			cl.add_field ((Field) sym);
-		} else if (sym is Constant) {
-			cl.add_constant ((Constant) sym);
-		} else if (sym is Property) {
-			cl.add_property ((Property) sym);
-		} else if (sym is Constructor) {
-			var c = (Constructor) sym;
-			if (c.binding == MemberBinding.INSTANCE) {
-				if (cl.constructor != null) {
-					Report.error (c.source_reference, "class already contains a constructor");
-				}
-				cl.constructor = c;
-			} else if (c.binding == MemberBinding.CLASS) {
-				if (cl.class_constructor != null) {
-					Report.error (c.source_reference, "class already contains a class constructor");
-				}
-				cl.class_constructor = c;
-			} else {
-				if (cl.static_constructor != null) {
-					Report.error (c.source_reference, "class already contains a static constructor");
-				}
-				cl.static_constructor = c;
-			}
-		} else if (sym is Destructor) {
-			var d = (Destructor) sym;
-			if (d.binding == MemberBinding.STATIC) {
-				if (cl.static_destructor != null) {
-					Report.error (d.source_reference, "class already contains a static destructor");
-				}
-				cl.static_destructor = (Destructor) d;
-			} else if (d.binding == MemberBinding.CLASS) {
-				if (cl.class_destructor != null) {
-					Report.error (d.source_reference, "class already contains a class destructor");
-				}
-				cl.class_destructor = (Destructor) d;
+				next.add_namespace ((Namespace) result);
 			} else {
-				if (cl.destructor != null) {
-					Report.error (d.source_reference, "class already contains a destructor");
-				}
-				cl.destructor = (Destructor) d;
+				next.add_class ((Class) result);
 			}
-		} else {
-			Report.error (sym.source_reference, "unexpected declaration in class");
+			result = next;
 		}
 	}
 
-	Constant parse_constant_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_constant_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_member_declaration_modifiers ();
@@ -2481,10 +2401,11 @@ public class Vala.Parser : CodeVisitor {
 			c.hides = true;
 		}
 		set_attributes (c, attrs);
-		return c;
+
+		parent.add_constant (c);
 	}
 
-	Field parse_field_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_field_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_member_declaration_modifiers ();
@@ -2519,7 +2440,8 @@ public class Vala.Parser : CodeVisitor {
 			f.initializer = parse_expression ();
 		}
 		expect (TokenType.SEMICOLON);
-		return f;
+
+		parent.add_field (f);
 	}
 
 	InitializerList parse_initializer () throws ParseError {
@@ -2588,7 +2510,7 @@ public class Vala.Parser : CodeVisitor {
 		return map;
 	}
 
-	Method parse_method_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_method_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_member_declaration_modifiers ();
@@ -2681,10 +2603,11 @@ public class Vala.Parser : CodeVisitor {
 		} else if (scanner.source_file.external_package) {
 			method.external = true;
 		}
-		return method;
+
+		parent.add_method (method);
 	}
 
-	Property parse_property_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_property_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_member_declaration_modifiers ();
@@ -2823,10 +2746,10 @@ public class Vala.Parser : CodeVisitor {
 			}
 		}
 
-		return prop;
+		parent.add_property (prop);
 	}
 
-	Signal parse_signal_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_signal_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_member_declaration_modifiers ();
@@ -2859,10 +2782,10 @@ public class Vala.Parser : CodeVisitor {
 			sig.body = parse_block ();
 		}
 
-		return sig;
+		parent.add_signal (sig);
 	}
 
-	Constructor parse_constructor_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_constructor_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var flags = parse_member_declaration_modifiers ();
 		expect (TokenType.CONSTRUCT);
@@ -2876,10 +2799,11 @@ public class Vala.Parser : CodeVisitor {
 			c.binding = MemberBinding.CLASS;
 		}
 		c.body = parse_block ();
-		return c;
+
+		parent.add_constructor (c);
 	}
 
-	Destructor parse_destructor_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_destructor_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var flags = parse_member_declaration_modifiers ();
 		expect (TokenType.TILDE);
@@ -2896,10 +2820,11 @@ public class Vala.Parser : CodeVisitor {
 			d.binding = MemberBinding.CLASS;
 		}
 		d.body = parse_block ();
-		return d;
+
+		parent.add_destructor (d);
 	}
 
-	Symbol parse_struct_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_struct_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_type_declaration_modifiers ();
@@ -2926,37 +2851,20 @@ public class Vala.Parser : CodeVisitor {
 		parse_declarations (st);
 
 		Symbol result = st;
-		while (sym.inner != null) {
+		while (sym != null) {
 			sym = sym.inner;
 
-			var ns = new Namespace (sym.name, st.source_reference);
+			Symbol next = (sym != null ? new Namespace (sym.name, st.source_reference) : parent);
 			if (result is Namespace) {
-				ns.add_namespace ((Namespace) result);
+				next.add_namespace ((Namespace) result);
 			} else {
-				ns.add_struct ((Struct) result);
-				scanner.source_file.add_node (result);
+				next.add_struct ((Struct) result);
 			}
-			result = ns;
+			result = next;
 		}
-		return result;
 	}
 
-	void parse_struct_member (Struct st) throws ParseError {
-		var sym = parse_declaration ();
-		if (sym is Method) {
-			st.add_method ((Method) sym);
-		} else if (sym is Field) {
-			st.add_field ((Field) sym);
-		} else if (sym is Constant) {
-			st.add_constant ((Constant) sym);
-		} else if (sym is Property) {
-			st.add_property ((Property) sym);
-		} else {
-			Report.error (sym.source_reference, "unexpected declaration in struct");
-		}
-	}
-
-	Symbol parse_interface_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_interface_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_type_declaration_modifiers ();
@@ -2986,46 +2894,20 @@ public class Vala.Parser : CodeVisitor {
 		parse_declarations (iface);
 
 		Symbol result = iface;
-		while (sym.inner != null) {
+		while (sym != null) {
 			sym = sym.inner;
-			var ns = new Namespace (sym.name, iface.source_reference);
+
+			Symbol next = (sym != null ? new Namespace (sym.name, iface.source_reference) : parent);
 			if (result is Namespace) {
-				ns.add_namespace ((Namespace) result);
+				next.add_namespace ((Namespace) result);
 			} else {
-				ns.add_interface ((Interface) result);
-				scanner.source_file.add_node (result);
-			}
-			result = ns;
-		}
-		return result;
-	}
-
-	void parse_interface_member (Interface iface) throws ParseError {
-		var sym = parse_declaration ();
-		if (sym is Class) {
-			iface.add_class ((Class) sym);
-		} else if (sym is Struct) {
-			iface.add_struct ((Struct) sym);
-		} else if (sym is Enum) {
-			iface.add_enum ((Enum) sym);
-		} else if (sym is Delegate) {
-			iface.add_delegate ((Delegate) sym);
-		} else if (sym is Method) {
-			iface.add_method ((Method) sym);
-		} else if (sym is Signal) {
-			iface.add_signal ((Signal) sym);
-		} else if (sym is Field) {
-			iface.add_field ((Field) sym);
-		} else if (sym is Constant) {
-			iface.add_constant ((Constant) sym);
-		} else if (sym is Property) {
-			iface.add_property ((Property) sym);
-		} else {
-			Report.error (sym.source_reference, "unexpected declaration in interface");
+				next.add_interface ((Interface) result);
+			}
+			result = next;
 		}
 	}
 
-	Symbol parse_enum_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_enum_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_type_declaration_modifiers ();
@@ -3062,34 +2944,26 @@ public class Vala.Parser : CodeVisitor {
 		if (accept (TokenType.SEMICOLON)) {
 			// enum methods
 			while (current () != TokenType.CLOSE_BRACE) {
-				var member_sym = parse_declaration ();
-				if (member_sym is Method) {
-					en.add_method ((Method) member_sym);
-				} else if (member_sym is Constant) {
-					en.add_constant ((Constant) member_sym);
-				} else {
-					Report.error (member_sym.source_reference, "unexpected declaration in enum");
-				}
+				parse_declaration (en);
 			}
 		}
 		expect (TokenType.CLOSE_BRACE);
 
 		Symbol result = en;
-		while (sym.inner != null) {
+		while (sym != null) {
 			sym = sym.inner;
-			var ns = new Namespace (sym.name, en.source_reference);
+
+			Symbol next = (sym != null ? new Namespace (sym.name, en.source_reference) : parent);
 			if (result is Namespace) {
-				ns.add_namespace ((Namespace) result);
+				next.add_namespace ((Namespace) result);
 			} else {
-				ns.add_enum ((Enum) result);
-				scanner.source_file.add_node (result);
+				next.add_enum ((Enum) result);
 			}
-			result = ns;
+			result = next;
 		}
-		return result;
 	}
 
-	Symbol parse_errordomain_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_errordomain_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_type_declaration_modifiers ();
@@ -3123,29 +2997,23 @@ public class Vala.Parser : CodeVisitor {
 		if (accept (TokenType.SEMICOLON)) {
 			// errordomain methods
 			while (current () != TokenType.CLOSE_BRACE) {
-				var member_sym = parse_declaration ();
-				if (member_sym is Method) {
-					ed.add_method ((Method) member_sym);
-				} else {
-					Report.error (member_sym.source_reference, "unexpected declaration in errordomain");
-				}
+				parse_declaration (ed);
 			}
 		}
 		expect (TokenType.CLOSE_BRACE);
 
 		Symbol result = ed;
-		while (sym.inner != null) {
+		while (sym != null) {
 			sym = sym.inner;
-			var ns = new Namespace (sym.name, ed.source_reference);
+
+			Symbol next = (sym != null ? new Namespace (sym.name, ed.source_reference) : parent);
 			if (result is Namespace) {
-				ns.add_namespace ((Namespace) result);
+				next.add_namespace ((Namespace) result);
 			} else {
-				ns.add_error_domain ((ErrorDomain) result);
-				scanner.source_file.add_node (result);
+				next.add_error_domain ((ErrorDomain) result);
 			}
-			result = ns;
+			result = next;
 		}
-		return result;
 	}
 
 	SymbolAccessibility parse_access_modifier (SymbolAccessibility default_access = SymbolAccessibility.PRIVATE) {
@@ -3286,7 +3154,7 @@ public class Vala.Parser : CodeVisitor {
 		return param;
 	}
 
-	CreationMethod parse_creation_method_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_creation_method_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_member_declaration_modifiers ();
@@ -3352,10 +3220,11 @@ public class Vala.Parser : CodeVisitor {
 		} else if (scanner.source_file.external_package) {
 			method.external = true;
 		}
-		return method;
+
+		parent.add_method (method);
 	}
 
-	Symbol parse_delegate_declaration (List<Attribute>? attrs) throws ParseError {
+	void parse_delegate_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
 		var begin = get_location ();
 		var access = parse_access_modifier ();
 		var flags = parse_member_declaration_modifiers ();
@@ -3410,18 +3279,17 @@ public class Vala.Parser : CodeVisitor {
 		expect (TokenType.SEMICOLON);
 
 		Symbol result = d;
-		while (sym.inner != null) {
+		while (sym != null) {
 			sym = sym.inner;
-			var ns = new Namespace (sym.name, d.source_reference);
+
+			Symbol next = (sym != null ? new Namespace (sym.name, d.source_reference) : parent);
 			if (result is Namespace) {
-				ns.add_namespace ((Namespace) result);
+				next.add_namespace ((Namespace) result);
 			} else {
-				ns.add_delegate ((Delegate) result);
-				scanner.source_file.add_node (result);
+				next.add_delegate ((Delegate) result);
 			}
-			result = ns;
+			result = next;
 		}
-		return result;
 	}
 
 	List<TypeParameter> parse_type_parameter_list () throws ParseError {
diff --git a/vala/valastruct.vala b/vala/valastruct.vala
index 2f54119..a3fc4c3 100644
--- a/vala/valastruct.vala
+++ b/vala/valastruct.vala
@@ -134,7 +134,7 @@ public class Vala.Struct : TypeSymbol {
 	 *
 	 * @param c a constant
 	 */
-	public void add_constant (Constant c) {
+	public override void add_constant (Constant c) {
 		constants.add (c);
 		scope.add (c.name, c);
 	}
@@ -144,7 +144,7 @@ public class Vala.Struct : TypeSymbol {
 	 *
 	 * @param f a field
 	 */
-	public void add_field (Field f) {
+	public override void add_field (Field f) {
 		// TODO report error when `private' or `protected' has been specified
 		f.access = SymbolAccessibility.PUBLIC;
 
@@ -175,7 +175,7 @@ public class Vala.Struct : TypeSymbol {
 	 *
 	 * @param m a method
 	 */
-	public void add_method (Method m) {
+	public override void add_method (Method m) {
 		return_if_fail (m != null);
 		
 		if (m.binding == MemberBinding.INSTANCE || m is CreationMethod) {
@@ -219,7 +219,7 @@ public class Vala.Struct : TypeSymbol {
 	 *
 	 * @param prop a property
 	 */
-	public void add_property (Property prop) {
+	public override void add_property (Property prop) {
 		properties.add (prop);
 		scope.add (prop.name, prop);
 
diff --git a/vala/valasymbol.vala b/vala/valasymbol.vala
index a935bcb..a46112f 100644
--- a/vala/valasymbol.vala
+++ b/vala/valasymbol.vala
@@ -496,6 +496,62 @@ public abstract class Vala.Symbol : CodeNode {
 
 		return null;
 	}
+
+	public virtual void add_namespace (Namespace ns) {
+		Report.error (ns.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_class (Class cl) {
+		Report.error (cl.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_interface (Interface iface) {
+		Report.error (iface.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_struct (Struct st) {
+		Report.error (st.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_enum (Enum en) {
+		Report.error (en.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_error_domain (ErrorDomain edomain) {
+		Report.error (edomain.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_delegate (Delegate d) {
+		Report.error (d.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_constant (Constant constant) {
+		Report.error (constant.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_field (Field f) {
+		Report.error (f.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_method (Method m) {
+		Report.error (m.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_property (Property prop) {
+		Report.error (prop.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_signal (Signal sig) {
+		Report.error (sig.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_constructor (Constructor c) {
+		Report.error (c.source_reference, "unexpected declaration");
+	}
+
+	public virtual void add_destructor (Destructor d) {
+		Report.error (d.source_reference, "unexpected declaration");
+	}
 }
 
 public enum Vala.SymbolAccessibility {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]