X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fcs-parser.jay;h=be36144170ea0afb54dcfe657549faccaf8e7861;hb=10ce0a085680204df3dcc9e779f617efb487db58;hp=1dff5a2e77dc7be33a544094cf88b8594df728c5;hpb=6cfd2055426c190ca2f6a9f8ca3af2da6f6a79d0;p=mono.git diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay index 1dff5a2e77d..be36144170e 100644 --- a/mcs/gmcs/cs-parser.jay +++ b/mcs/gmcs/cs-parser.jay @@ -33,9 +33,9 @@ namespace Mono.CSharp public class CSharpParser { NamespaceEntry current_namespace; TypeContainer current_container; - TypeContainer current_class; + 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. @@ -59,6 +62,12 @@ namespace Mono.CSharp Expression implicit_value_parameter_type; Parameters indexer_parameters; + /// + /// Hack to help create non-typed array initializer + /// + public static Expression current_array_type; + Expression pushed_current_array_type; + /// /// Used to determine if we are parsing the get/set pair /// of an indexer or a property @@ -364,7 +373,6 @@ using_alias_directive { LocatedToken lt = (LocatedToken) $2; current_namespace.UsingAlias (lt.Value, (MemberName) $4, (Location) $1); - current_namespace.UsingFound = true; } | USING error { CheckIdentifierToken (yyToken, GetLocation ($2)); @@ -375,7 +383,6 @@ using_namespace_directive : USING namespace_name SEMICOLON { current_namespace.Using ((MemberName) $2, (Location) $1); - current_namespace.UsingFound = true; } ; @@ -397,11 +404,15 @@ namespace_declaration syntax_error (lexer.Location, "namespace name expected"); 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; } ; @@ -638,7 +649,7 @@ attribute "'<' unexpected: attributes cannot be generic"); } - ArrayList arguments = (ArrayList) $2; + object [] arguments = (object []) $2; MemberName left = mname.Left; string identifier = mname.Name; @@ -646,7 +657,7 @@ attribute if (current_attr_target == "assembly" || current_attr_target == "module") // FIXME: supply "nameEscaped" parameter here. - $$ = new GlobalAttribute (current_class, current_attr_target, + $$ = new GlobalAttribute (current_namespace, current_attr_target, left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location)); else $$ = new Attribute (current_attr_target, left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location)); @@ -672,29 +683,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 @@ -791,22 +791,9 @@ struct_declaration member_name { MemberName name = MakeName ((MemberName) $6); - if ($3 != null) { - ClassPart part = PartialContainer.CreatePart ( - current_namespace, current_class, name, (int) $2, - (Attributes) $1, Kind.Struct, (Location) $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); - } + push_current_class (new Struct ( + current_namespace, current_class, name, (int) $2, + (Attributes) $1), false, $3); } opt_class_base opt_type_parameter_constraints_clauses @@ -814,12 +801,12 @@ struct_declaration lexer.ConstraintsParsing = false; if ($8 != null) - current_class.Bases = (ArrayList) $8; + current_container.AddBasesForPart (current_class, (ArrayList) $8); current_class.SetParameterInfo ((ArrayList) $9); if (RootContext.Documentation != null) - current_class.DocComment = Lexer.consume_doc_comment (); + current_container.DocComment = Lexer.consume_doc_comment (); } struct_body { @@ -942,11 +929,14 @@ 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, - var.expression_or_array_initializer, (Attributes) $1, var.Location); + field.Initializer = var.expression_or_array_initializer; + if (RootContext.Documentation != null) { field.DocComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; @@ -965,6 +955,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); @@ -982,6 +974,7 @@ field_declaration VOID variable_declarators SEMICOLON { + current_array_type = null; Report.Error (670, (Location) $3, "Fields cannot have void type"); } ; @@ -1059,6 +1052,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"); @@ -1068,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; } @@ -1078,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; @@ -1136,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 (); @@ -1172,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 (); @@ -1218,44 +1220,57 @@ formal_parameter_list Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars, null); + $$ = new Parameters (pars); } | fixed_parameters COMMA parameter_array { ArrayList pars_list = (ArrayList) $1; + pars_list.Add ($3); Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars, (Parameter) $3); + $$ = new Parameters (pars); } | fixed_parameters COMMA ARGLIST { ArrayList pars_list = (ArrayList) $1; + //pars_list.Add (new ArglistParameter (GetLocation ($3))); Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); $$ = new Parameters (pars, true); } - | parameter_array COMMA fixed_parameters + | parameter_array COMMA error { if ($1 != null) Report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list"); $$ = null; } - | ARGLIST COMMA fixed_parameters + | 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 (null, (Parameter) $1); + $$ = new Parameters (new Parameter[] { (Parameter) $1 } ); } | ARGLIST { - $$ = new Parameters (null, true); + $$ = new Parameters (new Parameter[0], true); } ; @@ -1327,15 +1342,15 @@ opt_parameter_modifier ; parameter_modifier - : REF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; } - | OUT { $$ = Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF; } + : REF { $$ = Parameter.Modifier.REF; } + | OUT { $$ = Parameter.Modifier.OUT; } ; parameter_array : opt_attributes PARAMS type IDENTIFIER { LocatedToken lt = (LocatedToken) $4; - $$ = new Parameter ((Expression) $3, lt.Value, Parameter.Modifier.PARAMS, (Attributes) $1, lt.Location); + $$ = new ParamsParameter ((Expression) $3, lt.Value, (Attributes) $1, lt.Location); note ("type must be a single-dimension array type"); } | opt_attributes PARAMS parameter_modifier type IDENTIFIER @@ -1435,7 +1450,7 @@ get_accessor_declaration current_local_parameters = indexer_parameters; lexer.PropertyParsing = false; - iterator_container = SimpleIteratorContainer.GetSimple (); + anonymous_host = SimpleAnonymousHost.GetSimple (); } accessor_body { @@ -1448,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) @@ -1472,7 +1485,7 @@ set_accessor_declaration if (parsing_indexer == false) { args = new Parameter [1]; args [0] = implicit_value_parameter; - current_local_parameters = new Parameters (args, null); + current_local_parameters = new Parameters (args); } else { Parameter [] fpars = indexer_parameters.FixedParameters; @@ -1485,12 +1498,12 @@ set_accessor_declaration } else args = null; current_local_parameters = new Parameters ( - args, indexer_parameters.ArrayParameter); + args); } lexer.PropertyParsing = false; - iterator_container = SimpleIteratorContainer.GetSimple (); + anonymous_host = SimpleAnonymousHost.GetSimple (); } accessor_body { @@ -1503,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) @@ -1533,22 +1544,9 @@ interface_declaration { MemberName name = MakeName ((MemberName) $6); - 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 opt_type_parameter_constraints_clauses @@ -1556,12 +1554,12 @@ interface_declaration lexer.ConstraintsParsing = false; if ($8 != null) - current_class.Bases = (ArrayList) $8; + current_container.AddBasesForPart (current_class, (ArrayList) $8); current_class.SetParameterInfo ((ArrayList) $9); if (RootContext.Documentation != null) { - current_class.DocComment = Lexer.consume_doc_comment (); + current_container.DocComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } } @@ -1858,7 +1856,7 @@ interface_event_declaration { LocatedToken lt = (LocatedToken) $5; $$ = new EventField (current_class, (Expression) $4, (int) $2, true, - new MemberName (lt.Value, lt.Location), null, + new MemberName (lt.Value, lt.Location), (Attributes) $1); if (RootContext.Documentation != null) ((EventField) $$).DocComment = Lexer.consume_doc_comment (); @@ -1937,7 +1935,7 @@ interface_indexer_declaration operator_declaration : opt_attributes opt_modifiers operator_declarator { - iterator_container = SimpleIteratorContainer.GetSimple (); + anonymous_host = SimpleAnonymousHost.GetSimple (); } operator_body { @@ -1954,7 +1952,7 @@ operator_declaration Operator op = new Operator ( current_class, decl.optype, decl.ret_type, (int) $2, - new Parameters (param_list, null), + new Parameters (param_list), (ToplevelBlock) $5, (Attributes) $1, decl.location); if (RootContext.Documentation != null) { @@ -1962,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; } ; @@ -1996,7 +1993,7 @@ operator_declarator pars [0] = new Parameter (type, lt.Value, Parameter.Modifier.NONE, null, lt.Location); - current_local_parameters = new Parameters (pars, null); + current_local_parameters = new Parameters (pars); if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); @@ -2024,7 +2021,7 @@ operator_declarator pars [0] = new Parameter (typeL, ltParam1.Value, Parameter.Modifier.NONE, null, ltParam1.Location); pars [1] = new Parameter (typeR, ltParam2.Value, Parameter.Modifier.NONE, null, ltParam2.Location); - current_local_parameters = new Parameters (pars, null); + current_local_parameters = new Parameters (pars); if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); @@ -2092,7 +2089,7 @@ conversion_operator_declarator pars [0] = new Parameter ((Expression) $5, lt.Value, Parameter.Modifier.NONE, null, lt.Location); - current_local_parameters = new Parameters (pars, null); + current_local_parameters = new Parameters (pars); if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); @@ -2109,7 +2106,7 @@ conversion_operator_declarator pars [0] = new Parameter ((Expression) $5, lt.Value, Parameter.Modifier.NONE, null, lt.Location); - current_local_parameters = new Parameters (pars, null); + current_local_parameters = new Parameters (pars); if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); @@ -2158,11 +2155,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); } @@ -2196,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) $$; } ; @@ -2256,7 +2250,7 @@ destructor_declaration Method d = new Destructor ( current_class, TypeManager.system_void_expr, m, "Finalize", - new Parameters (null, null), (Attributes) $1, l); + Parameters.EmptyReadOnlyParameters, (Attributes) $1, l); if (RootContext.Documentation != null) d.DocComment = ConsumeStoredComment (); @@ -2271,14 +2265,17 @@ 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, var.Location); - Event e = new EventField ( + EventField e = new EventField ( current_class, (Expression) $4, (int) $2, false, name, - var.expression_or_array_initializer, (Attributes) $1); + (Attributes) $1); + + e.Initializer = var.expression_or_array_initializer; current_container.AddEvent (e); @@ -2319,7 +2316,7 @@ event_declaration $$ = null; else { Event e = new EventProperty ( - current_class, (Expression) $4, (int) $2, false, name, null, + current_class, (Expression) $4, (int) $2, false, name, (Attributes) $1, (Accessor) pair.First, (Accessor) pair.Second); if (RootContext.Documentation != null) { e.DocComment = Lexer.consume_doc_comment (); @@ -2373,7 +2370,7 @@ add_accessor_declaration args [0] = implicit_value_parameter; - current_local_parameters = new Parameters (args, null); + current_local_parameters = new Parameters (args); lexer.EventParsing = false; } block @@ -2401,7 +2398,7 @@ remove_accessor_declaration args [0] = implicit_value_parameter; - current_local_parameters = new Parameters (args, null); + current_local_parameters = new Parameters (args); lexer.EventParsing = false; } block @@ -2431,7 +2428,7 @@ indexer_declaration parsing_indexer = true; indexer_parameters = decl.param_list; - iterator_container = SimpleIteratorContainer.GetSimple (); + anonymous_host = SimpleAnonymousHost.GetSimple (); } accessor_declarations { @@ -2481,7 +2478,7 @@ indexer_declarator if (pars.HasArglist) { // "__arglist is not valid in this context" Report.Error (1669, (Location) $2, "__arglist is not valid in this context"); - } else if (pars.FixedParameters == null && pars.ArrayParameter == null){ + } else if (pars.Empty){ Report.Error (1551, (Location) $2, "Indexers must have at least one parameter"); } if (RootContext.Documentation != null) { @@ -2498,7 +2495,7 @@ indexer_declarator if (pars.HasArglist) { // "__arglist is not valid in this context" Report.Error (1669, (Location) $4, "__arglist is not valid in this context"); - } else if (pars.FixedParameters == null && pars.ArrayParameter == null){ + } else if (pars.Empty){ Report.Error (1551, (Location) $4, "Indexers must have at least one parameter"); } @@ -2552,7 +2549,6 @@ enum_declaration } current_container.AddEnum (e); - RootContext.Tree.RecordDecl (current_namespace.NS, name, e); $$ = e; } @@ -2647,8 +2643,14 @@ delegate_declaration OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { MemberName name = MakeName ((MemberName) $6); + Parameters p = (Parameters) $8; + 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) $5, - (int) $2, name, (Parameters) $8, (Attributes) $1); + (int) $2, name, p, (Attributes) $1); if (RootContext.Documentation != null) { del.DocComment = Lexer.consume_doc_comment (); @@ -2656,8 +2658,6 @@ delegate_declaration } current_container.AddDelegate (del); - RootContext.Tree.RecordDecl (current_namespace.NS, name, del); - current_delegate = del; } opt_type_parameter_constraints_clauses @@ -2723,17 +2723,32 @@ opt_type_argument_list ; type_arguments - : type { + : opt_attributes type { TypeArguments type_args = new TypeArguments (lexer.Location); - type_args.Add ((Expression) $1); + if ($1 != null) { + SimpleName sn = $2 as SimpleName; + if (sn == null) + Report.Error (1031, lexer.Location, "Type expected"); + else + $2 = new TypeParameterName (sn.Name, (Attributes) $1, lexer.Location); + } + type_args.Add ((Expression) $2); $$ = type_args; } - | type_arguments COMMA type { + | type_arguments COMMA opt_attributes type { TypeArguments type_args = (TypeArguments) $1; - type_args.Add ((Expression) $3); + if ($3 != null) { + SimpleName sn = $4 as SimpleName; + if (sn == null) + Report.Error (1031, lexer.Location, "Type expected"); + else + $4 = new TypeParameterName (sn.Name, (Attributes) $3, lexer.Location); + } + type_args.Add ((Expression) $4); $$ = type_args; } ; + /* * Before you think of adding a return_type, notice that we have been @@ -2865,7 +2880,7 @@ array_type if ((bool) $3) rank_specifiers += "?"; - $$ = new ComposedCast ((Expression) $1, rank_specifiers); + $$ = current_array_type = new ComposedCast ((Expression) $1, rank_specifiers); } ; @@ -2952,6 +2967,7 @@ parenthesized_expression_0 // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST, CLOSE_PARENS_OPEN_PARENS // or CLOSE_PARENS_MINUS. } + | OPEN_PARENS expression error { CheckToken (1026, yyToken, "Expecting ')'", lexer.Location); } ; parenthesized_expression @@ -2966,20 +2982,18 @@ parenthesized_expression // in Binary.DoResolve(). $$ = new ParenthesizedExpression ((Expression) $1); } - ;; + ; member_access : primary_expression DOT IDENTIFIER opt_type_argument_list { LocatedToken lt = (LocatedToken) $3; - $$ = new MemberAccess ((Expression) $1, lt.Value, - (TypeArguments) $4, lt.Location); + $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4); } | predefined_type DOT IDENTIFIER opt_type_argument_list { LocatedToken lt = (LocatedToken) $3; - $$ = new MemberAccess ((Expression) $1, lt.Value, - (TypeArguments) $4, lt.Location); + $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4); } ; @@ -2988,15 +3002,12 @@ predefined_type ; invocation_expression - : primary_expression { - $$ = lexer.Location; - } OPEN_PARENS opt_argument_list CLOSE_PARENS + : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS { - if ($1 == null) { - Location l = (Location) $3; - Report.Error (1, l, "Parse error"); - } - $$ = new Invocation ((Expression) $1, (ArrayList) $4); + if ($1 == null) + Report.Error (1, (Location) $2, "Parse error"); + else + $$ = new Invocation ((Expression) $1, (ArrayList) $3); } | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS { @@ -3110,6 +3121,7 @@ element_access // $$ = new ComposedCast (expr, (string) $2); } + current_array_type = (Expression)$$; } ; @@ -3136,10 +3148,10 @@ this_access ; base_access - : BASE DOT IDENTIFIER + : BASE DOT IDENTIFIER opt_type_argument_list { LocatedToken lt = (LocatedToken) $3; - $$ = new BaseAccess (lt.Value, lt.Location); + $$ = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location); } | BASE OPEN_BRACKET expression_list CLOSE_BRACKET { @@ -3312,34 +3324,21 @@ variable_initializer_list } ; -void_pointer_expression - : void_pointer_expression STAR - { - $$ = new ComposedCast ((Expression) $1, "*", lexer.Location); - } - | VOID STAR - { - $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);; - } - ; - typeof_expression - : TYPEOF OPEN_PARENS VOID CLOSE_PARENS - { - $$ = new TypeOfVoid ((Location) $1); - } - | TYPEOF OPEN_PARENS void_pointer_expression CLOSE_PARENS - { - $$ = new TypeOf ((Expression) $3, (Location) $1); + : TYPEOF + { + pushed_current_array_type = current_array_type; + lexer.TypeOfParsing = true; } - | TYPEOF OPEN_PARENS + OPEN_PARENS type CLOSE_PARENS { - lexer.TypeOfParsing = true; - } - type CLOSE_PARENS - { - lexer.TypeOfParsing = false; - $$ = new TypeOf ((Expression) $4, lexer.Location); + lexer.TypeOfParsing = false; + 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; } ; @@ -3370,13 +3369,17 @@ 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_anonymous_method); oob_stack.Push (current_local_parameters); current_local_parameters = (Parameters)$2; @@ -3384,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; @@ -3397,11 +3405,20 @@ anonymous_method_expression ToplevelBlock anon_block = (ToplevelBlock) $4; anon_block.Parent = current_block; - $$ = new AnonymousMethod ((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 @@ -3418,7 +3435,7 @@ anonymous_method_signature ArrayList par_list = (ArrayList) $2; Parameter [] pars = new Parameter [par_list.Count]; par_list.CopyTo (pars); - $$ = new Parameters (pars, null); + $$ = new Parameters (pars); } } ; @@ -3814,28 +3831,9 @@ class_declaration MemberName name = MakeName ((MemberName) $6); 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 opt_type_parameter_constraints_clauses @@ -3848,13 +3846,13 @@ class_declaration "The class System.Object cannot have a base " + "class or implement an interface."); } - current_class.Bases = (ArrayList) $8; + current_container.AddBasesForPart (current_class, (ArrayList) $8); } current_class.SetParameterInfo ((ArrayList) $9); if (RootContext.Documentation != null) { - current_class.DocComment = Lexer.consume_doc_comment (); + current_container.DocComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } } @@ -3936,8 +3934,16 @@ type_parameter_constraints_clauses } | type_parameter_constraints_clauses type_parameter_constraints_clause { ArrayList constraints = (ArrayList) $1; + Constraints new_constraint = (Constraints)$2; - constraints.Add ($2); + foreach (Constraints c in constraints) { + if (new_constraint.TypeParameter == c.TypeParameter) { + Report.Error (409, new_constraint.Location, "A constraint clause has already been specified for type parameter `{0}'", + new_constraint.TypeParameter); + } + } + + constraints.Add (new_constraint); $$ = constraints; } ; @@ -3993,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); @@ -4079,7 +4086,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 @@ -4088,6 +4095,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; @@ -4098,6 +4106,7 @@ declaration_statement | local_constant_declaration SEMICOLON { + current_array_type = null; if ($1 != null){ DictionaryEntry de = (DictionaryEntry) $1; @@ -4152,7 +4161,7 @@ local_variable_type if ((string) $2 == "") $$ = $1; else - $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); + $$ = current_array_type = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); } ; @@ -4216,10 +4225,7 @@ local_constant_declaration ; expression_statement - : statement_expression SEMICOLON - { - $$ = $1; - } + : statement_expression SEMICOLON { $$ = $1; } ; // @@ -4227,14 +4233,18 @@ expression_statement // because statement_expression is used for example in for_statement // statement_expression - : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | post_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | post_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | pre_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); } - | error { + : expression + { + Expression expr = (Expression) $1; + ExpressionStatement s = expr as ExpressionStatement; + if (s == null) { + Report.Error (201, expr.Location, "Only assignment, call, increment, decrement, and new object expressions can be used as a statement"); + $$ = null; + } + $$ = new StatementExpression (s); + } + | error + { Report.Error (1002, GetLocation ($1), "Expecting `;'"); $$ = null; } @@ -4281,6 +4291,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 @@ -4303,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 ; @@ -4414,15 +4427,7 @@ for_statement continue; Location l = lexer.Location; - Expression expr; - if (decl.expression_or_array_initializer is Expression){ - expr = (Expression) decl.expression_or_array_initializer; - } else if (decl.expression_or_array_initializer == null) { - expr = null; - } else { - ArrayList init = (ArrayList) decl.expression_or_array_initializer; - expr = new ArrayCreation (type, "", init, decl.Location); - } + Expression expr = decl.expression_or_array_initializer; LocalVariableReference var; var = new LocalVariableReference (assign_block, decl.identifier, l); @@ -4612,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); } } @@ -4637,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); } } @@ -4748,6 +4753,7 @@ catch_clause } block { Expression type = null; string id = null; + Block var_block = null; if ($2 != null){ DictionaryEntry cc = (DictionaryEntry) $2; @@ -4758,11 +4764,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); } ; @@ -4906,16 +4913,9 @@ using_statement continue; vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using); - Expression expr; - if (decl.expression_or_array_initializer is Expression){ - expr = (Expression) decl.expression_or_array_initializer; - } else { - ArrayList init = (ArrayList) decl.expression_or_array_initializer; - if (init == null) { - Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration"); - } - - expr = new ArrayCreation (type, "", init, decl.Location); + Expression expr = decl.expression_or_array_initializer; + if (expr == null) { + Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration"); } LocalVariableReference var; @@ -4962,7 +4962,7 @@ resource_acquisition // public class VariableDeclaration { public string identifier; - public object expression_or_array_initializer; + public Expression expression_or_array_initializer; public Location Location; public Attributes OptAttributes; public string DocComment; @@ -4970,7 +4970,14 @@ public class VariableDeclaration { public VariableDeclaration (LocatedToken lt, object eoai, Attributes opt_attrs) { this.identifier = lt.Value; - this.expression_or_array_initializer = eoai; + if (eoai is ArrayList) { + if (CSharpParser.current_array_type == null) + Report.Error (622, lt.Location, + "Can only use array initializer expressions to assign to array types. Try using a new expression instead."); + this.expression_or_array_initializer = new ArrayCreation (CSharpParser.current_array_type, "", (ArrayList)eoai, lt.Location); + } else { + this.expression_or_array_initializer = (Expression)eoai; + } this.Location = lt.Location; this.OptAttributes = opt_attrs; } @@ -5000,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); + } + } } // @@ -5051,19 +5077,21 @@ void Error_ExpectingTypeName (Expression expr) } } -TypeContainer pop_current_class () +void push_current_class (TypeContainer tc, bool is_interface, object partial_token) +{ + if (partial_token != null) + current_container = current_container.AddPartial (tc, is_interface); + else + current_container = current_container.AddTypeContainer (tc, is_interface); + current_class = tc; +} + +DeclSpace pop_current_class () { - TypeContainer retval = current_class; + DeclSpace retval = current_class; current_class = current_class.Parent; - current_container = current_container.Parent; - - if (current_class != current_container) { - if (!(current_class is ClassPart) || - ((ClassPart) current_class).PartialContainer != current_container) - throw new InternalErrorException (); - } else if (current_container is ClassPart) - current_container = ((ClassPart) current_class).PartialContainer; + current_container = current_class.PartialContainer; return retval; } @@ -5077,8 +5105,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; @@ -5128,17 +5156,8 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators, foreach (VariableDeclaration decl in inits){ Assign assign; - Expression expr; + Expression expr = decl.expression_or_array_initializer; - if (decl.expression_or_array_initializer is Expression){ - expr = (Expression) decl.expression_or_array_initializer; - - } else { - ArrayList init = (ArrayList) decl.expression_or_array_initializer; - - expr = new ArrayCreation (type, "", init, decl.Location); - } - LocalVariableReference var; var = new LocalVariableReference (implicit_block, decl.identifier, loc); @@ -5251,21 +5270,18 @@ 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); } public void parse () { + int errors = Report.Errors; try { if (yacc_verbose_flag > 1) yyparse (lexer, new yydebug.yyDebugSimple ()); @@ -5278,21 +5294,22 @@ public void parse () // Removed for production use, use parser verbose to get the output. // // Console.WriteLine (e); - Report.Error (-25, lexer.Location, "Parsing error"); + if (Report.Errors == errors) + Report.Error (-25, lexer.Location, "Parsing error"); if (yacc_verbose_flag > 0) 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, String.Format ("{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ())); - return; - } - Report.Error (error, loc, msg); + if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD) + Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ()); + else + Report.Error (error, loc, msg); } void CheckIdentifierToken (int yyToken, Location loc)