Copying latest mcs to the branch.
[mono.git] / mcs / gmcs / cs-parser.jay
index c07700c4ec0ea47726a17db1aa2a960eb870ab26..be36144170ea0afb54dcfe657549faccaf8e7861 100644 (file)
@@ -35,7 +35,7 @@ namespace Mono.CSharp
                TypeContainer   current_container;
                DeclSpace       current_class;
        
-               IIteratorContainer iterator_container;
+               IAnonymousHost anonymous_host;
 
                /// <summary>
                ///   Current block is used to add statements as we find
@@ -45,6 +45,9 @@ namespace Mono.CSharp
 
                Delegate   current_delegate;
 
+               GenericMethod current_generic_method;
+               AnonymousMethodExpression current_anonymous_method;
+
                /// <summary>
                ///   This is used by the unary_expression code to resolve
                ///   a name against a parameter.  
@@ -1062,7 +1065,7 @@ variable_initializer
 
 method_declaration
        : method_header {
-               iterator_container = (IIteratorContainer) $1;
+               anonymous_host = (IAnonymousHost) $1;
                if (RootContext.Documentation != null)
                        Lexer.doc_state = XmlCommentState.NotAllowed;
          }
@@ -1072,8 +1075,9 @@ method_declaration
                method.Block = (ToplevelBlock) $3;
                current_container.AddMethod (method);
 
+               anonymous_host = null;
+               current_generic_method = null;
                current_local_parameters = null;
-               iterator_container = null;
 
                if (RootContext.Documentation != null)
                        Lexer.doc_state = XmlCommentState.Allowed;
@@ -1130,7 +1134,9 @@ method_header
                method = new Method (current_class, generic, (Expression) $3, (int) $2, false,
                                     name, (Parameters) $6, (Attributes) $1);
 
+               anonymous_host = method;
                current_local_parameters = (Parameters) $6;
+               current_generic_method = generic;
 
                if (RootContext.Documentation != null)
                        method.DocComment = Lexer.consume_doc_comment ();
@@ -1166,7 +1172,9 @@ method_header
                method = new Method (current_class, generic, TypeManager.system_void_expr,
                                     (int) $2, false, name, (Parameters) $6, (Attributes) $1);
 
+               anonymous_host = method;
                current_local_parameters = (Parameters) $6;
+               current_generic_method = generic;
 
                if (RootContext.Documentation != null)
                        method.DocComment = Lexer.consume_doc_comment ();
@@ -1442,7 +1450,7 @@ get_accessor_declaration
                        current_local_parameters = indexer_parameters;
                lexer.PropertyParsing = false;
 
-               iterator_container = SimpleIteratorContainer.GetSimple ();
+               anonymous_host = SimpleAnonymousHost.GetSimple ();
          }
           accessor_body
          {
@@ -1455,10 +1463,8 @@ get_accessor_declaration
                current_local_parameters = null;
                lexer.PropertyParsing = true;
 
-               if (SimpleIteratorContainer.Simple.Yields)
-                       accessor.SetYields ();
-
-               iterator_container = null;
+               SimpleAnonymousHost.Simple.Propagate (accessor);
+               anonymous_host = null;
 
                if (RootContext.Documentation != null)
                        if (Lexer.doc_state == XmlCommentState.Error)
@@ -1497,7 +1503,7 @@ set_accessor_declaration
                
                lexer.PropertyParsing = false;
 
-               iterator_container = SimpleIteratorContainer.GetSimple ();
+               anonymous_host = SimpleAnonymousHost.GetSimple ();
          }
          accessor_body
          {
@@ -1510,10 +1516,8 @@ set_accessor_declaration
                current_local_parameters = null;
                lexer.PropertyParsing = true;
 
-               if (SimpleIteratorContainer.Simple.Yields)
-                       accessor.SetYields ();
-
-               iterator_container = null;
+               SimpleAnonymousHost.Simple.Propagate (accessor);
+               anonymous_host = null;
 
                if (RootContext.Documentation != null
                        && Lexer.doc_state == XmlCommentState.Error)
@@ -1931,7 +1935,7 @@ interface_indexer_declaration
 operator_declaration
        : opt_attributes opt_modifiers operator_declarator 
          {
-               iterator_container = SimpleIteratorContainer.GetSimple ();
+               anonymous_host = SimpleAnonymousHost.GetSimple ();
          }
          operator_body
          {
@@ -1956,14 +1960,13 @@ operator_declaration
                        Lexer.doc_state = XmlCommentState.Allowed;
                }
 
-               if (SimpleIteratorContainer.Simple.Yields)
-                       op.SetYields ();
+               SimpleAnonymousHost.Simple.Propagate (op);
+               anonymous_host = null;
 
                // Note again, checking is done in semantic analysis
                current_container.AddOperator (op);
 
                current_local_parameters = null;
-               iterator_container = null;
          }
        ;
 
@@ -2185,6 +2188,8 @@ constructor_declarator
                LocatedToken lt = (LocatedToken) $1;
                $$ = new Constructor (current_class, lt.Value, 0, (Parameters) $4,
                                      (ConstructorInitializer) $7, lt.Location);
+
+               anonymous_host = (IAnonymousHost) $$;
          }
        ;
 
@@ -2423,7 +2428,7 @@ indexer_declaration
                parsing_indexer  = true;
                
                indexer_parameters = decl.param_list;
-               iterator_container = SimpleIteratorContainer.GetSimple ();
+               anonymous_host = SimpleAnonymousHost.GetSimple ();
          }
           accessor_declarations 
          {
@@ -3374,6 +3379,7 @@ anonymous_method_expression
                if (oob_stack == null)
                        oob_stack = new Stack (6);
 
+               oob_stack.Push (current_anonymous_method);
                oob_stack.Push (current_local_parameters);
                current_local_parameters = (Parameters)$2;
 
@@ -3381,7 +3387,12 @@ anonymous_method_expression
                oob_stack.Push (current_block);
                oob_stack.Push (top_current_block);
                current_block = null;
-         } 
+
+               Location loc = (Location) $1;
+               current_anonymous_method = new AnonymousMethodExpression (
+                       current_anonymous_method, current_generic_method, current_container,
+                       (Parameters) $2, (ToplevelBlock) top_current_block, loc);
+         }
          block
          {
                Location loc = (Location) $1;
@@ -3394,11 +3405,20 @@ anonymous_method_expression
                        ToplevelBlock anon_block = (ToplevelBlock) $4;
 
                        anon_block.Parent = current_block;
-                       $$ = new AnonymousMethod (current_container, (Parameters) $2, (ToplevelBlock) top_current_block, 
-                               anon_block, loc);
-               }
-                       current_local_parameters = (Parameters) oob_stack.Pop ();
+
+                       Report.Debug (64, "PARSER", anon_block, current_anonymous_method, anonymous_host,
+                                     loc);
+
+                       current_anonymous_method.Block = anon_block;
+                       if ((anonymous_host != null) && (current_anonymous_method.Parent == null))
+                               anonymous_host.AddAnonymousMethod (current_anonymous_method);
+
+                       $$ = current_anonymous_method;
                }
+
+               current_local_parameters = (Parameters) oob_stack.Pop ();
+               current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
+       }
        ;
 
 opt_anonymous_method_signature
@@ -3979,7 +3999,8 @@ block
        : OPEN_BRACE 
          {
                if (current_block == null){
-                       current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, (Location) $1);
+                       current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters,
+                                                          current_generic_method, (Location) $1);
                        top_current_block = current_block;
                } else {
                        current_block = new Block (current_block, (Location) $1, Location.Null);
@@ -4294,7 +4315,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
        ;
@@ -4595,11 +4617,11 @@ yield_statement
                        Report.FeatureIsNotStandardized (lt.Location, "yield statement");
                        $$ = null;
                }
-               if (iterator_container == null){
+               if (anonymous_host == null){
                        Report.Error (204, lt.Location, "yield statement can only be used within a method, operator or property");
                        $$ = null;
                } else {
-                       iterator_container.SetYields ();
+                       anonymous_host.SetYields ();
                        $$ = new Yield ((Expression) $3, lt.Location); 
                }
          }
@@ -4620,11 +4642,11 @@ yield_statement
                        Report.FeatureIsNotStandardized (lt.Location, "yield statement");
                        $$ = null;
                }
-               if (iterator_container == null){
+               if (anonymous_host == null){
                        Report.Error (204, lt.Location, "yield statement can only be used within a method, operator or property");
                        $$ = null;
                } else {
-                       iterator_container.SetYields ();
+                       anonymous_host.SetYields ();
                        $$ = new YieldBreak (lt.Location);
                }
          }
@@ -4985,22 +5007,41 @@ public class IndexerDeclaration {
 }
 
 //
-// We use this when we do not have an object in advance that is an IIteratorContainer
+// We use this when we do not have an object in advance that is an IAnonymousHost
 //
-public class SimpleIteratorContainer : IIteratorContainer {
-       public bool Yields;
+public class SimpleAnonymousHost : IAnonymousHost {
+       public static readonly SimpleAnonymousHost Simple = new SimpleAnonymousHost ();
 
-       public static SimpleIteratorContainer Simple = new SimpleIteratorContainer ();
+       bool yields;
+       ArrayList anonymous_methods;
 
-       //
-       // Reset and return
-       //
-       public static SimpleIteratorContainer GetSimple () { 
-               Simple.Yields = false;
+       public static SimpleAnonymousHost GetSimple () {
+               Simple.yields = false;
+               Simple.anonymous_methods = null;
                return Simple;
        }
 
-       public void SetYields () { Yields = true; } 
+       public void SetYields ()
+       {
+               yields = true;
+       }
+
+       public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
+       {
+               if (anonymous_methods == null)
+                       anonymous_methods = new ArrayList ();
+               anonymous_methods.Add (anonymous);
+       }
+
+       public void Propagate (IAnonymousHost real_host)
+       {
+               if (yields)
+                       real_host.SetYields ();
+               if (anonymous_methods != null) {
+                       foreach (AnonymousMethodExpression ame in anonymous_methods)
+                               real_host.AddAnonymousMethod (ame);
+               }
+       }
 }
 
 // <summary>