]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Refactor parser to avoid parse_*_member methods
authorJürg Billeter <j@bitron.ch>
Fri, 26 Feb 2010 18:23:42 +0000 (19:23 +0100)
committerJürg Billeter <j@bitron.ch>
Sat, 21 Aug 2010 11:39:13 +0000 (13:39 +0200)
vala/valaclass.vala
vala/valaenum.vala
vala/valaerrordomain.vala
vala/valagenieparser.vala
vala/valagirparser.vala
vala/valainterface.vala
vala/valanamespace.vala
vala/valaparser.vala
vala/valastruct.vala
vala/valasymbol.vala

index 0380acb76b6cab60a2290d3adee8f06865d91c75..ac6f332c2637b4077d218409f17ffc060c134022 100644 (file)
@@ -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);
        }
index 85bd3b4d1870c0db209ef83d7d2b60875679487e..27e950d2c88d61b51c0af6ff0a3ca317cad3a6cc 100644 (file)
@@ -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);
        }
index f80750f96fb8440e59194a5180b1da0a948bf422..b49683ca2f4b02bb74aa5806f5c9145bdeef65fb 100644 (file)
@@ -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");
                
index 3ae29c7ba4e9708eeb208a121710554dd4f56b9f..5b4b39f6d79095897e62fcf6baf7a58fd6f7e4f5 100644 (file)
@@ -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;
                }
index 4ddfab7327ad60db4f2501996c3fa46da63e53ea..871f4cb7f3566b607497c267b3ff152be8639e4f 100644 (file)
@@ -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");
 
index f2339542bf17617b0286f84583842c90200de510..dc7248c77d84606bfc6027271c6f73a904506bcd 100644 (file)
@@ -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);
        }
index e7b51095885c2373bbbd805123fd8f5235d8c3b6..38bf9966b5dc4fdd5d54a4662280b120ea50f749 100644 (file)
@@ -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);
        }
index f7dc50b35c4cc5e63b0a61d0419bff0b650267bb..04f0d59adeab3612c0ca7cfb2417bb487ebae25a 100644 (file)
@@ -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 {
index 2f541197220e0709c82df84a67aef4a6fb975d23..a3fc4c335493d9269955673d5c2ecede08966986 100644 (file)
@@ -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);
 
index a935bcb76c6cdd6a1a00c2c341eb850ad02589c5..a46112fac84b3e2e19ebfb3bf6ed4a494f1b166f 100644 (file)
@@ -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 {