X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fcs-parser.jay;h=807588e532597d94b4b928874de9a3464e7ec311;hb=7d956e0d400f0b42f824d0ea2c1f13fe65360a22;hp=a00fe36cee88f57b4e641ae4d7ff6bfe761dd370;hpb=95f68fbf2127dde95a184c84d77e9903b7bb55a1;p=mono.git diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay index a00fe36cee8..807588e5325 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. @@ -69,7 +72,9 @@ namespace Mono.CSharp /// Used to determine if we are parsing the get/set pair /// of an indexer or a property /// - bool parsing_indexer; + bool parsing_indexer; + + bool parsing_anonymous_method; /// /// An out-of-band stack. @@ -1062,7 +1067,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 +1077,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 +1136,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 +1174,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 +1452,7 @@ get_accessor_declaration current_local_parameters = indexer_parameters; lexer.PropertyParsing = false; - iterator_container = SimpleIteratorContainer.GetSimple (); + anonymous_host = SimpleAnonymousHost.GetSimple (); } accessor_body { @@ -1455,10 +1465,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 +1505,7 @@ set_accessor_declaration lexer.PropertyParsing = false; - iterator_container = SimpleIteratorContainer.GetSimple (); + anonymous_host = SimpleAnonymousHost.GetSimple (); } accessor_body { @@ -1510,10 +1518,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 +1937,7 @@ interface_indexer_declaration operator_declaration : opt_attributes opt_modifiers operator_declarator { - iterator_container = SimpleIteratorContainer.GetSimple (); + anonymous_host = SimpleAnonymousHost.GetSimple (); } operator_body { @@ -1956,14 +1962,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 +2190,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 +2430,7 @@ indexer_declaration parsing_indexer = true; indexer_parameters = decl.param_list; - iterator_container = SimpleIteratorContainer.GetSimple (); + anonymous_host = SimpleAnonymousHost.GetSimple (); } accessor_declarations { @@ -2957,9 +2964,9 @@ parenthesized_expression_0 : OPEN_PARENS expression CLOSE_PARENS { $$ = $2; - lexer.Deambiguate_CloseParens (); + lexer.Deambiguate_CloseParens ($$); // After this, the next token returned is one of - // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST, CLOSE_PARENS_OPEN_PARENS + // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST (CLOSE_PARENS), CLOSE_PARENS_OPEN_PARENS // or CLOSE_PARENS_MINUS. } | OPEN_PARENS expression error { CheckToken (1026, yyToken, "Expecting ')'", lexer.Location); } @@ -2969,7 +2976,11 @@ parenthesized_expression : parenthesized_expression_0 CLOSE_PARENS_NO_CAST { $$ = $1; - } + } + | parenthesized_expression_0 CLOSE_PARENS + { + $$ = $1; + } | parenthesized_expression_0 CLOSE_PARENS_MINUS { // If a parenthesized expression is followed by a minus, we need to wrap @@ -3375,19 +3386,27 @@ 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; // Force the next block to be created as a ToplevelBlock 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); + + parsing_anonymous_method = true; + } block { Location loc = (Location) $1; top_current_block = (Block) oob_stack.Pop (); current_block = (Block) oob_stack.Pop (); + if (RootContext.Version == LanguageVersion.ISO_1){ Report.FeatureIsNotStandardized (loc, "anonymous methods"); $$ = null; @@ -3395,11 +3414,17 @@ 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 (); + + 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 @@ -3983,8 +4008,18 @@ type_parameter_constraint block : OPEN_BRACE { - if (current_block == null){ - current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, (Location) $1); + if (parsing_anonymous_method) { + top_current_block = new ToplevelBlock ( + current_block, current_local_parameters, current_generic_method, + (Location) $1); + if (current_block != null) + current_block.AddAnonymousChild ((ToplevelBlock) top_current_block); + current_block = top_current_block; + parsing_anonymous_method = false; + } else if (current_block == null) { + 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); @@ -4601,11 +4636,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); } } @@ -4626,11 +4661,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); } } @@ -4991,22 +5026,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); + } + } } //