X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fcs-parser.jay;h=be36144170ea0afb54dcfe657549faccaf8e7861;hb=10ce0a085680204df3dcc9e779f617efb487db58;hp=c07700c4ec0ea47726a17db1aa2a960eb870ab26;hpb=2cb792105c091b47d178e9343e25a1cfce3b8497;p=mono.git diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay index c07700c4ec0..be36144170e 100644 --- a/mcs/gmcs/cs-parser.jay +++ b/mcs/gmcs/cs-parser.jay @@ -35,7 +35,7 @@ namespace Mono.CSharp TypeContainer current_container; DeclSpace current_class; - IIteratorContainer iterator_container; + IAnonymousHost anonymous_host; /// /// 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; + /// /// 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); + } + } } //