* XmlTypeAttribute.cs: added property AnonymousType for 2.0
[mono.git] / mcs / mcs / cs-parser.jay
index 8a70d97127d9d21f756c92f973ccb079ef876c8a..b93d179b6331a198ad7c4f014be78946c526c3f3 100644 (file)
@@ -33,7 +33,7 @@ namespace Mono.CSharp
        public class CSharpParser {
                NamespaceEntry  current_namespace;
                TypeContainer   current_container;
-               TypeContainer   current_class;
+               DeclSpace       current_class;
        
                IIteratorContainer iterator_container;
 
@@ -61,6 +61,7 @@ namespace Mono.CSharp
                ///   Hack to help create non-typed array initializer
                /// </summary>
                public static Expression current_array_type;
+               Expression pushed_current_array_type;
 
                /// <summary>
                ///   Used to determine if we are parsing the get/set pair
@@ -391,11 +392,15 @@ namespace_declaration
                }
 
                current_namespace = new NamespaceEntry (
-                       current_namespace, file, name.GetName (), name.Location);
+                       current_namespace, file, name.GetName ());
+               current_class = current_namespace.SlaveDeclSpace;
+               current_container = current_class.PartialContainer;
          } 
          namespace_body opt_semicolon
          { 
                current_namespace = current_namespace.Parent;
+               current_class = current_namespace.SlaveDeclSpace;
+               current_container = current_class.PartialContainer;
          }
        ;
 
@@ -620,7 +625,7 @@ attribute
        : attribute_name opt_attribute_arguments
          {
                MemberName mname = (MemberName) $1;
-               ArrayList arguments = (ArrayList) $2;
+               object[] arguments = (object[]) $2;
                MemberName left = mname.Left;
                string identifier = mname.Name;
 
@@ -654,29 +659,18 @@ attribute_arguments
                if ($1 == null)
                        $$ = null;
                else {
-                       ArrayList args = new ArrayList (4);
-                       args.Add ($1);
-               
-                       $$ = args;
+                       $$ = new object [] { $1, null };
                }
          }
-        | positional_argument_list COMMA named_argument_list
+    | positional_argument_list COMMA named_argument_list
          {
-               ArrayList args = new ArrayList (4);
-               args.Add ($1);
-               args.Add ($3);
-
-               $$ = args;
+               $$ = new object[] { $1, $3 };
          }
-        | named_argument_list
+    | named_argument_list
          {
-               ArrayList args = new ArrayList (4);
-               args.Add (null);
-               args.Add ($1);
-               
-               $$ = args;
+               $$ = new object [] { null, $1 };
          }
-        ;
+    ;
 
 
 opt_positional_argument_list
@@ -769,30 +763,18 @@ struct_declaration
          STRUCT member_name
          { 
                MemberName name = MakeName ((MemberName) $5);
-               if ($3 != null) {
-                       ClassPart part = PartialContainer.CreatePart (
-                               current_namespace, current_class, name, (int) $2,
-                               (Attributes) $1, Kind.Struct, (Location) $3);
+               push_current_class (new Struct (
+                       current_namespace, current_class, name, (int) $2,
+                       (Attributes) $1), false, $3);
 
-                       current_container = part.PartialContainer;
-                       current_class = part;
-               } else {
-                       current_class = new Struct (
-                               current_namespace, current_class, name, (int) $2,
-                               (Attributes) $1);
-
-                       current_container.AddClassOrStruct (current_class);
-                       current_container = current_class;
-                       RootContext.Tree.RecordDecl (current_namespace.NS, name, current_class);
-               }
          }
          opt_class_base
          {
                if ($7 != null)
-                       current_class.Bases = (ArrayList) $7;
+                       current_container.AddBasesForPart (current_class, (ArrayList) $7);
 
                if (RootContext.Documentation != null)
-                       current_class.DocComment = Lexer.consume_doc_comment ();
+                       current_container.DocComment = Lexer.consume_doc_comment ();
          }
          struct_body
          {
@@ -915,6 +897,8 @@ field_declaration
                Expression type = (Expression) $3;
                int mod = (int) $2;
 
+               current_array_type = null;
+
                foreach (VariableDeclaration var in (ArrayList) $4){
                        Field field = new Field (current_class, type, mod, var.identifier, 
                                                 (Attributes) $1, var.Location);
@@ -939,6 +923,8 @@ field_declaration
                        Expression type = (Expression) $4;
                        int mod = (int) $2;
 
+                       current_array_type = null;
+
                        foreach (VariableDeclaration var in (ArrayList) $5) {
                                FixedField field = new FixedField (current_class, type, mod, var.identifier,
                                        (Expression)var.expression_or_array_initializer, (Attributes) $1, var.Location);
@@ -956,6 +942,7 @@ field_declaration
          VOID  
          variable_declarators
          SEMICOLON {
+               current_array_type = null;
                Report.Error (670, (Location) $3, "Fields cannot have void type");
          }
        ;
@@ -1033,6 +1020,10 @@ variable_initializer
          {
                $$ = new StackAlloc ((Expression) $2, (Expression) $4, (Location) $1);
          }
+       | ARGLIST
+         {
+               $$ = new ArglistAccess ((Location) $1);
+         }
        | STACKALLOC type
          {
                Report.Error (1575, (Location) $1, "A stackalloc expression requires [] after type");
@@ -1182,11 +1173,22 @@ formal_parameter_list
                        Report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list");
                $$ = null;
          }
+       | fixed_parameters COMMA parameter_array COMMA error
+         {
+               if ($3 != null)
+                       Report.Error (231, ((Parameter) $3).Location, "A params parameter must be the last parameter in a formal parameter list");
+               $$ = null;
+         }
        | ARGLIST COMMA error
          {
                Report.Error (257, (Location) $1, "An __arglist parameter must be the last parameter in a formal parameter list");
                $$ = null;
          }
+       | fixed_parameters COMMA ARGLIST COMMA error 
+         {
+               Report.Error (257, (Location) $3, "An __arglist parameter must be the last parameter in a formal parameter list");
+               $$ = null;
+         }
        | parameter_array 
          {
                $$ = new Parameters (new Parameter[] { (Parameter) $1 } );
@@ -1464,29 +1466,16 @@ interface_declaration
          {
                MemberName name = MakeName ((MemberName) $5);
 
-               if ($3 != null) {
-                       ClassPart part = PartialContainer.CreatePart (
-                               current_namespace, current_class, name, (int) $2,
-                               (Attributes) $1, Kind.Interface, (Location) $3);
-
-                       current_container = part.PartialContainer;
-                       current_class = part;
-               } else {
-                       current_class = new Interface (
-                               current_namespace, current_class, name, (int) $2,
-                               (Attributes) $1);
-
-                       current_container.AddInterface (current_class);
-                       current_container = current_class;
-                       RootContext.Tree.RecordDecl (current_namespace.NS, name, current_class);
-               }
+               push_current_class (new Interface (
+                       current_namespace, current_class, name, (int) $2,
+                       (Attributes) $1), true, $3);
          }
          opt_class_base
          {
-               current_class.Bases = (ArrayList) $7;
+               current_container.AddBasesForPart (current_class, (ArrayList) $7);
 
                if (RootContext.Documentation != null) {
-                       current_class.DocComment = Lexer.consume_doc_comment ();
+                       current_container.DocComment = Lexer.consume_doc_comment ();
                        Lexer.doc_state = XmlCommentState.Allowed;
                }
          }
@@ -2023,11 +2012,6 @@ constructor_declaration
                                                "`{0}': static constructor cannot have an explicit `this' or `base' constructor call",
                                                c.GetSignatureForError ());
                                }
-       
-                               if (!c.Parameters.Empty){
-                                       Report.Error (132, c.Location,
-                                               "`{0}': The static constructor must be parameterless", c.GetSignatureForError ());
-                               }
                        } else {
                                c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
                        }
@@ -2136,6 +2120,7 @@ event_declaration
          opt_modifiers
          EVENT type variable_declarators SEMICOLON
          {
+               current_array_type = null;
                foreach (VariableDeclaration var in (ArrayList) $5) {
 
                        MemberName name = new MemberName (var.identifier,
@@ -2414,7 +2399,6 @@ enum_declaration
                }
 
                current_container.AddEnum (e);
-               RootContext.Tree.RecordDecl (current_namespace.NS, name, e);
                $$ = e;
 
          }
@@ -2506,8 +2490,14 @@ delegate_declaration
          SEMICOLON
          {
                MemberName name = MakeName ((MemberName) $5);
+               Parameters p = (Parameters) $7;
+               if (p.HasArglist) {
+                       // TODO: wrong location
+                       Report.Error (1669, name.Location, "__arglist is not valid in this context");
+               }
+
                Delegate del = new Delegate (current_namespace, current_class, (Expression) $4,
-                                            (int) $2, name, (Parameters) $7, (Attributes) $1);
+                                            (int) $2, name, p, (Attributes) $1);
 
                if (RootContext.Documentation != null) {
                        del.DocComment = Lexer.consume_doc_comment ();
@@ -2515,7 +2505,6 @@ delegate_declaration
                }
 
                current_container.AddDelegate (del);
-               RootContext.Tree.RecordDecl (current_namespace.NS, name, del);
                $$ = del;
          }     
        ;
@@ -2764,11 +2753,12 @@ member_access
        : primary_expression DOT IDENTIFIER
          {
                LocatedToken lt = (LocatedToken) $3;
-               $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);
+               $$ = new MemberAccess ((Expression) $1, lt.Value);
          }
        | predefined_type DOT IDENTIFIER
          {
                LocatedToken lt = (LocatedToken) $3;
+               // TODO: Location is wrong as some predefined types doesn't hold a location
                $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);
          }
        ;
@@ -3076,13 +3066,18 @@ variable_initializer_list
        ;
 
 typeof_expression
-       : TYPEOF OPEN_PARENS VOID CLOSE_PARENS
-         {
-               $$ = new TypeOfVoid ((Location) $1);
+       : TYPEOF
+      {
+               pushed_current_array_type = current_array_type;
          }
-       | TYPEOF OPEN_PARENS type CLOSE_PARENS
+         OPEN_PARENS type CLOSE_PARENS
          {
-               $$ = new TypeOf ((Expression) $3, (Location) $1);
+               Expression type = (Expression)$4;
+               if (type == TypeManager.system_void_expr)
+                       $$ = new TypeOfVoid ((Location) $1);
+               else
+                       $$ = new TypeOf (type, (Location) $1);
+               current_array_type = pushed_current_array_type;
          }
        ;
 
@@ -3113,13 +3108,16 @@ pointer_member_access
                LocatedToken lt = (LocatedToken) $3;
 
                deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lt.Location);
-               $$ = new MemberAccess (deref, lt.Value, lt.Location);
+               $$ = new MemberAccess (deref, lt.Value);
          }
        ;
 
 anonymous_method_expression
        : DELEGATE opt_anonymous_method_signature
          {
+               if (oob_stack == null)
+                       oob_stack = new Stack (6);
+
                oob_stack.Push (current_local_parameters);
                current_local_parameters = (Parameters)$2;
 
@@ -3140,7 +3138,7 @@ anonymous_method_expression
                        ToplevelBlock anon_block = (ToplevelBlock) $4;
 
                        anon_block.Parent = current_block;
-                       $$ = new AnonymousMethod ((Parameters) $2, (ToplevelBlock) top_current_block, 
+                       $$ = new AnonymousMethod (current_container, (Parameters) $2, (ToplevelBlock) top_current_block, 
                                anon_block, loc);
                }
                current_local_parameters = (Parameters) oob_stack.Pop ();
@@ -3508,28 +3506,9 @@ class_declaration
                MemberName name = MakeName ((MemberName) $5);
                int mod_flags = (int) $2;
 
-               if ($3 != null) {
-                       ClassPart part = PartialContainer.CreatePart (
-                               current_namespace, current_class, name, mod_flags,
-                               (Attributes) $1, Kind.Class, (Location) $3);
-
-                       current_container = part.PartialContainer;
-                       current_class = part;
-               } else {
-                       if ((mod_flags & Modifiers.STATIC) != 0) {
-                               current_class = new StaticClass (
-                                       current_namespace, current_class, name,
-                                       mod_flags, (Attributes) $1);
-                       } else {
-                               current_class = new Class (
-                                       current_namespace, current_class, name,
-                                       mod_flags, (Attributes) $1);
-                       }
-
-                       current_container.AddClassOrStruct (current_class);
-                       current_container = current_class;
-                       RootContext.Tree.RecordDecl (current_namespace.NS, name, current_class);
-               }
+               push_current_class (new Class (
+                       current_namespace, current_class, name,
+                       mod_flags, (Attributes) $1), false, $3);
          }
          opt_class_base
          {
@@ -3539,11 +3518,11 @@ class_declaration
                                              "The class System.Object cannot have a base " +
                                              "class or implement an interface.");
                        }
-                       current_class.Bases = (ArrayList) $7;
+                       current_container.AddBasesForPart (current_class, (ArrayList) $7);
                }
 
                if (RootContext.Documentation != null) {
-                       current_class.DocComment = Lexer.consume_doc_comment ();
+                       current_container.DocComment = Lexer.consume_doc_comment ();
                        Lexer.doc_state = XmlCommentState.Allowed;
                }
          }
@@ -3631,7 +3610,7 @@ block
                        current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, (Location) $1);
                        top_current_block = current_block;
                } else {
-               current_block = new Block (current_block, (Location) $1, Location.Null);
+                       current_block = new Block (current_block, (Location) $1, Location.Null);
                }
          } 
          opt_statement_list CLOSE_BRACE 
@@ -3714,7 +3693,7 @@ labeled_statement
                LocatedToken lt = (LocatedToken) $1;
                LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location);
 
-               if (current_block.AddLabel (lt.Value, labeled, lt.Location))
+               if (current_block.AddLabel (labeled))
                        current_block.AddStatement (labeled);
          }
          statement
@@ -3723,6 +3702,7 @@ labeled_statement
 declaration_statement
        : local_variable_declaration SEMICOLON
          {
+               current_array_type = null;
                if ($1 != null){
                        DictionaryEntry de = (DictionaryEntry) $1;
                        Expression e = (Expression) de.Key;
@@ -3733,6 +3713,7 @@ declaration_statement
 
        | local_constant_declaration SEMICOLON
          {
+               current_array_type = null;
                if ($1 != null){
                        DictionaryEntry de = (DictionaryEntry) $1;
 
@@ -3917,6 +3898,8 @@ if_statement
 switch_statement
        : SWITCH OPEN_PARENS
          { 
+               if (switch_stack == null)
+                       switch_stack = new Stack (2);
                switch_stack.Push (current_block);
          }
          expression CLOSE_PARENS 
@@ -3939,7 +3922,8 @@ switch_block
 opt_switch_sections
        : /* empty */           
           {
-               Report.Error (1522, lexer.Location, "Empty switch block"); 
+               Report.Warning (1522, 1, lexer.Location, "Empty switch block"); 
+               $$ = new ArrayList ();
          }
        | switch_sections
        ;
@@ -4376,6 +4360,7 @@ catch_clause
          } block {
                Expression type = null;
                string id = null;
+               Block var_block = null;
 
                if ($2 != null){
                        DictionaryEntry cc = (DictionaryEntry) $2;
@@ -4386,11 +4371,12 @@ catch_clause
                                id = lt.Value;
                                while (current_block.Implicit)
                                        current_block = current_block.Parent;
+                               var_block = current_block;
                                current_block = current_block.Parent;
                        }
                }
 
-               $$ = new Catch (type, id, (Block) $4, ((Block) $4).loc);
+               $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc);
          }
         ;
 
@@ -4599,7 +4585,6 @@ public class VariableDeclaration {
                } else {
                        this.expression_or_array_initializer = (Expression)eoai;
                }
-               CSharpParser.current_array_type = null;
                this.Location = lt.Location;
                this.OptAttributes = opt_attrs;
        }
@@ -4680,18 +4665,21 @@ void Error_ExpectingTypeName (Expression expr)
        }
 }
 
-TypeContainer pop_current_class ()
+void push_current_class (TypeContainer tc, bool is_interface, object partial_token)
 {
-       TypeContainer retval = current_class;
+       if (partial_token != null)
+               current_container = current_container.AddPartial (tc, is_interface);
+       else
+               current_container = current_container.AddTypeContainer (tc, is_interface);
+       current_class = tc;
+}
 
-       current_class = (TypeContainer) current_class.Parent;
-       current_container = (TypeContainer) current_container.Parent;
+DeclSpace pop_current_class ()
+{
+       DeclSpace retval = current_class;
 
-       if (current_class != current_container) {
-               if (((ClassPart) current_class).PartialContainer != current_container)
-                       throw new InternalErrorException ("current_container and current_class are out of sync");
-       } else if (current_container is ClassPart)
-               current_container = ((ClassPart) current_class).PartialContainer;
+       current_class = current_class.Parent;
+       current_container = current_class.PartialContainer;
 
        return retval;
 }
@@ -4705,8 +4693,8 @@ MakeName (MemberName class_name)
 {
        Namespace ns = current_namespace.NS;
 
-       if (current_container.Name == ""){
-               if (ns.Name != "")
+       if (current_container.Name.Length == 0){
+               if (ns.Name.Length != 0)
                        return new MemberName (ns.MemberName, class_name);
                else
                        return class_name;
@@ -4870,15 +4858,11 @@ public Tokenizer Lexer {
 
 public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
 {
-       current_namespace = new NamespaceEntry (null, file, null, Location.Null);
        this.name = file.Name;
        this.file = file;
-       current_container = RootContext.Tree.Types;
-       // TODO: Make RootContext.Tree.Types a PartialContainer.
-       current_class = current_container;
-       current_container.NamespaceEntry = current_namespace;
-       oob_stack = new Stack ();
-       switch_stack = new Stack ();
+       current_namespace = new NamespaceEntry (null, file, null);
+       current_class = current_namespace.SlaveDeclSpace;
+       current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes
 
        lexer = new Tokenizer (reader, file, defines);
 }
@@ -4904,10 +4888,11 @@ public void parse ()
                        Console.WriteLine (e);
        }
 
-       RootContext.Tree.Types.NamespaceEntry = null;
+       if (RootContext.ToplevelTypes.NamespaceEntry != null)
+               throw new InternalErrorException ("who set it?");
 }
 
-void CheckToken (int error, int yyToken, string msg, Location loc)
+static void CheckToken (int error, int yyToken, string msg, Location loc)
 {
        if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
                Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ());