X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fcs-parser.jay;h=06a28d3720836dc77878610a274d24e38e913586;hb=60e8d68027b115d6b4c1df3e179bb0cd7b5ee171;hp=c769b58186d279a52daa1f6529d9979d86d8716a;hpb=ee4eddbeae2d76e5ab021b6b7eada13add7b12ac;p=mono.git diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay old mode 100755 new mode 100644 index c769b58186d..06a28d37208 --- a/mcs/gmcs/cs-parser.jay +++ b/mcs/gmcs/cs-parser.jay @@ -8,6 +8,7 @@ // Licensed under the terms of the GNU GPL // // (C) 2001 Ximian, Inc (http://www.ximian.com) +// (C) 2004 Novell, Inc // // TODO: // (1) Figure out why error productions dont work. `type-declaration' is a @@ -40,13 +41,7 @@ namespace Mono.CSharp /// Current block is used to add statements as we find /// them. /// - Block current_block; - - /// - /// If true, creates a toplevel block in the block production - /// This is flagged by the delegate creation - /// - bool create_toplevel_block; + Block current_block, top_current_block; Delegate current_delegate; @@ -80,7 +75,7 @@ namespace Mono.CSharp /// Stack switch_stack; - public bool yacc_verbose_flag; + static public int yacc_verbose_flag; // Name of the file we are parsing public string name; @@ -89,13 +84,21 @@ namespace Mono.CSharp /// The current file. /// SourceFile file; - - + + /// + /// Temporary Xml documentation cache. + /// For enum types, we need one more temporary store. + /// + string tmpComment; + string enumTypeComment; + /// Current attribute target string current_attr_target; /// assembly and module attribute definition is enabled bool global_attrs_enabled = true; + bool has_get, has_set; + %} %token EOF @@ -296,7 +299,13 @@ compilation_unit opt_EOF : /* empty */ + { + Lexer.check_incorrect_doc_comment (); + } | EOF + { + Lexer.check_incorrect_doc_comment (); + } ; outer_declarations @@ -316,7 +325,15 @@ using_directives using_directive : using_alias_directive + { + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } | using_namespace_directive + { + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } ; using_alias_directive @@ -333,7 +350,7 @@ using_alias_directive using_namespace_directive : USING namespace_name SEMICOLON { - current_namespace.Using ((string) $2, lexer.Location); + current_namespace.Using ((MemberName) $2, lexer.Location); } ; @@ -346,19 +363,13 @@ namespace_declaration : opt_attributes NAMESPACE namespace_or_type_name { if ($1 != null) { - Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces." - + " Expected class, delegate, enum, interface, or struct"); + Report.Error(1671, Lexer.Location, "A namespace declaration cannot have modifiers or attributes"); } MemberName name = (MemberName) $3; if (name.TypeArguments != null) syntax_error (lexer.Location, "namespace name expected"); - else if ((current_namespace.Parent != null) && (name.Left != null)) { - Report.Error (134, lexer.Location, - "Cannot use qualified namespace names in nested " + - "namespace declarations"); - } current_namespace = new NamespaceEntry ( current_namespace, file, name.GetName (), lexer.Location); @@ -386,17 +397,19 @@ namespace_name if (name.TypeArguments != null) syntax_error (lexer.Location, "namespace name expected"); - $$ = name.GetName (); + $$ = name; } ; namespace_body : OPEN_BRACE + { + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } opt_using_directives opt_namespace_member_declarations CLOSE_BRACE - { - } ; opt_using_directives @@ -417,25 +430,13 @@ namespace_member_declarations namespace_member_declaration : type_declaration { - string name = ""; - int mod_flags; - - if ($1 is Class){ - Class c = (Class) $1; - mod_flags = c.ModFlags; - name = c.Name; - } else if ($1 is Struct){ - Struct s = (Struct) $1; - mod_flags = s.ModFlags; - name = s.Name; - } else - break; + if ($1 != null) { + DeclSpace ds = (DeclSpace)$1; - if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){ - Report.Error ( - 1527, lexer.Location, - "Namespace elements cant be explicitly " + - "declared private or protected in `" + name + "'"); + if ((ds.ModFlags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){ + Report.Error (1527, lexer.Location, + "Namespace elements cannot be explicitly declared as private, protected or protected internal"); + } } current_namespace.DeclarationFound = true; } @@ -508,6 +509,13 @@ attribute_sections } else { $$ = new Attributes (sect); } + if ($$ == null) { + if (RootContext.Documentation != null) { + Lexer.check_incorrect_doc_comment (); + Lexer.doc_state = + XmlCommentState.Allowed; + } + } } else { $$ = new Attributes (sect); } @@ -596,19 +604,23 @@ attribute } opt_attribute_arguments { + Location loc = (Location) $2; MemberName mname = (MemberName) $1; if (mname.IsGeneric) { Report.Error (404, lexer.Location, "'<' unexpected: attributes cannot be generic"); } - string name = mname.GetName (); + MemberName left = mname.Left; + string identifier = mname.Name; + + Expression left_expr = left == null ? null : left.GetTypeExpression (loc); + if (current_attr_target == "assembly" || current_attr_target == "module") - $$ = new GlobalAttribute (current_container, current_attr_target, - name, (ArrayList) $3, (Location) $2); + $$ = new GlobalAttribute (current_class, current_attr_target, + left_expr, identifier, (ArrayList) $3, loc); else - $$ = new Attribute (current_attr_target, name, (ArrayList) $3, - (Location) $2); + $$ = new Attribute (current_attr_target, left_expr, identifier, (ArrayList) $3, loc); } ; @@ -693,6 +705,11 @@ named_argument_list $$ = args; } + | named_argument_list COMMA expression + { + Report.Error (1016, lexer.Location, "Named attribute argument expected"); + $$ = null; + } ; named_argument @@ -737,48 +754,53 @@ struct_declaration : opt_attributes opt_modifiers opt_partial - STRUCT member_name + STRUCT + { + lexer.ConstraintsParsing = true; + } + member_name { - MemberName name = MakeName ((MemberName) $5); + MemberName name = MakeName ((MemberName) $6); bool partial = (bool) $3; if (partial) { ClassPart part = PartialContainer.CreatePart ( - current_namespace, current_container, name, (int) $2, + current_namespace, current_class, name, (int) $2, (Attributes) $1, Kind.Struct, lexer.Location); current_container = part.PartialContainer; current_class = part; } else { current_class = new Struct ( - current_namespace, current_container, name, (int) $2, + current_namespace, current_class, name, (int) $2, (Attributes) $1, lexer.Location); + current_container.AddClassOrStruct (current_class); current_container = current_class; - RootContext.Tree.RecordDecl (name.GetName (true), current_class); + RootContext.Tree.RecordDecl (name, current_class); } - - lexer.ConstraintsParsing = true; } opt_class_base opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; - if ($7 != null) - current_class.Bases = (ArrayList) $7; + if ($8 != null) + current_class.Bases = (ArrayList) $8; - current_class.SetParameterInfo ((ArrayList) $8); + current_class.SetParameterInfo ((ArrayList) $9); - current_class.Register (); + if (RootContext.Documentation != null) + current_class.DocComment = Lexer.consume_doc_comment (); } struct_body + { + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } opt_semicolon { - $$ = current_class; - - current_container = current_container.Parent; - current_class = current_container; + $$ = pop_current_class (); } | opt_attributes opt_modifiers opt_partial STRUCT error { CheckIdentifierToken (yyToken); @@ -786,7 +808,12 @@ struct_declaration ; struct_body - : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE + : OPEN_BRACE + { + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } + opt_struct_member_declarations CLOSE_BRACE ; opt_struct_member_declarations @@ -838,6 +865,10 @@ constant_declaration (Expression) constant.expression_or_array_initializer, modflags, (Attributes) $1, l); + if (RootContext.Documentation != null) { + c.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } current_container.AddConstant (c); } } @@ -884,15 +915,38 @@ field_declaration int mod = (int) $2; foreach (VariableDeclaration var in (ArrayList) $4){ - Location l = var.Location; - Field field = new Field (current_class, type, mod, var.identifier, var.expression_or_array_initializer, - (Attributes) $1, l); + (Attributes) $1, var.Location); + if (RootContext.Documentation != null) { + field.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } current_container.AddField (field); } } + | opt_attributes + opt_modifiers + FIXED + type + fixed_variable_declarators + SEMICOLON + { + Expression type = (Expression) $4; + int mod = (int) $2; + + 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); + + if (RootContext.Documentation != null) { + field.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + current_container.AddField (field); + } + } | opt_attributes opt_modifiers VOID @@ -902,11 +956,34 @@ field_declaration } ; +fixed_variable_declarators + : fixed_variable_declarator + { + ArrayList decl = new ArrayList (2); + decl.Add ($1); + $$ = decl; + } + | fixed_variable_declarators COMMA fixed_variable_declarator + { + ArrayList decls = (ArrayList) $1; + decls.Add ($3); + $$ = $1; + } + ; + +fixed_variable_declarator + : IDENTIFIER OPEN_BRACKET expression CLOSE_BRACKET + { + $$ = new VariableDeclaration ((string) $1, $3, lexer.Location); + } + ; + variable_declarators : variable_declarator { ArrayList decl = new ArrayList (4); - decl.Add ($1); + if ($1 != null) + decl.Add ($1); $$ = decl; } | variable_declarators COMMA variable_declarator @@ -926,6 +1003,12 @@ variable_declarator { $$ = new VariableDeclaration ((string) $1, null, lexer.Location); } + | IDENTIFIER OPEN_BRACKET opt_expression CLOSE_BRACKET + { + Report.Error (650, lexer.Location, "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. " + + "To declare a fixed size buffer field, use the fixed keyword before the field type"); + $$ = null; + } ; variable_initializer @@ -941,11 +1024,18 @@ variable_initializer { $$ = new StackAlloc ((Expression) $2, (Expression) $4, lexer.Location); } + | STACKALLOC type + { + Report.Error (1575, lexer.Location, "A stackalloc expression requires [] after type"); + $$ = null; + } ; method_declaration : method_header { iterator_container = (IIteratorContainer) $1; + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.NotAllowed; } method_body { @@ -967,30 +1057,14 @@ method_declaration } } - method.Block = (Block) $3; + method.Block = (ToplevelBlock) $3; current_container.AddMethod (method); current_local_parameters = null; iterator_container = null; - } - ; -opt_error_modifier - : /* empty */ - | modifiers - { - int m = (int) $1; - int i = 1; - - while (m != 0){ - if ((i & m) != 0){ - Report.Error ( - 1585, lexer.Location, "Member modifier `" + - Modifiers.Name (i) + "' must precede member type and name"); - } - m &= ~i; - i = i << 1; - } + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; } ; @@ -1027,6 +1101,9 @@ method_header current_local_parameters = (Parameters) $6; + if (RootContext.Documentation != null) + method.DocComment = Lexer.consume_doc_comment (); + $$ = method; } | opt_attributes @@ -1060,6 +1137,10 @@ method_header lexer.Location); current_local_parameters = (Parameters) $6; + + if (RootContext.Documentation != null) + method.DocComment = Lexer.consume_doc_comment (); + $$ = method; } | opt_attributes @@ -1077,6 +1158,10 @@ method_header lexer.Location); current_local_parameters = (Parameters) $6; + + if (RootContext.Documentation != null) + method.DocComment = Lexer.consume_doc_comment (); + $$ = method; } ; @@ -1099,7 +1184,7 @@ formal_parameter_list Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars, null, lexer.Location); + $$ = new Parameters (pars, null); } | fixed_parameters COMMA parameter_array { @@ -1108,7 +1193,7 @@ formal_parameter_list Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars, (Parameter) $3, lexer.Location); + $$ = new Parameters (pars, (Parameter) $3); } | fixed_parameters COMMA ARGLIST { @@ -1117,15 +1202,25 @@ formal_parameter_list Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars, true, lexer.Location); + $$ = new Parameters (pars, true); + } + | parameter_array COMMA fixed_parameters + { + Report.Error (231, lexer.Location, "A params parameter must be the last parameter in a formal parameter list"); + $$ = null; + } + | ARGLIST COMMA fixed_parameters + { + Report.Error (257, lexer.Location, "An __arglist parameter must be the last parameter in a formal parameter list"); + $$ = null; } | parameter_array { - $$ = new Parameters (null, (Parameter) $1, lexer.Location); + $$ = new Parameters (null, (Parameter) $1); } | ARGLIST { - $$ = new Parameters (null, true, lexer.Location); + $$ = new Parameters (null, true); } ; @@ -1152,7 +1247,22 @@ fixed_parameter type IDENTIFIER { - $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1); + $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1, lexer.Location); + } + | opt_attributes + opt_parameter_modifier + type + IDENTIFIER OPEN_BRACKET CLOSE_BRACKET + { + Report.Error (1552, lexer.Location, "Array type specifier, [], must appear before parameter name"); + $$ = null; + } + | opt_attributes + opt_parameter_modifier + type + { + Report.Error (1001, lexer.Location, "Identifier expected"); + $$ = null; } | opt_attributes opt_parameter_modifier @@ -1186,9 +1296,14 @@ parameter_modifier parameter_array : opt_attributes PARAMS type IDENTIFIER { - $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1); + $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1, lexer.Location); note ("type must be a single-dimension array type"); } + | opt_attributes PARAMS parameter_modifier type IDENTIFIER + { + Report.Error (1611, lexer.Location, "The params parameter cannot be declared as ref or out"); + $$ = null; + } | opt_attributes PARAMS type error { CheckIdentifierToken (yyToken); $$ = null; @@ -1198,7 +1313,12 @@ parameter_array property_declaration : opt_attributes opt_modifiers - type namespace_or_type_name + type + namespace_or_type_name + { + if (RootContext.Documentation != null) + tmpComment = Lexer.consume_doc_comment (); + } OPEN_BRACE { implicit_value_parameter_type = (Expression) $3; @@ -1212,21 +1332,25 @@ property_declaration accessor_declarations { lexer.PropertyParsing = false; + has_get = has_set = false; } CLOSE_BRACE { + if ($8 == null) + break; + Property prop; - Pair pair = (Pair) $7; + Pair pair = (Pair) $8; Accessor get_block = (Accessor) pair.First; Accessor set_block = (Accessor) pair.Second; - Location loc = (Location) $6; + Location loc = (Location) $7; MemberName name = (MemberName) $4; if (name.TypeArguments != null) syntax_error (lexer.Location, "a property can't have type arguments"); - prop = new Property (current_container, (Expression) $3, (int) $2, false, + prop = new Property (current_class, (Expression) $3, (int) $2, false, name, (Attributes) $1, get_block, set_block, loc); if (SimpleIteratorContainer.Simple.Yields) prop.SetYields (); @@ -1234,32 +1358,43 @@ property_declaration current_container.AddProperty (prop); implicit_value_parameter_type = null; iterator_container = null; + + if (RootContext.Documentation != null) + prop.DocComment = ConsumeStoredComment (); + } ; accessor_declarations - : get_accessor_declaration opt_set_accessor_declaration - { - $$ = new Pair ($1, $2); - } - | set_accessor_declaration opt_get_accessor_declaration + : get_accessor_declaration + { + $$ = new Pair ($1, null); + } + | get_accessor_declaration accessor_declarations + { + Pair pair = (Pair) $2; + pair.First = $1; + $$ = pair; + } + | set_accessor_declaration + { + $$ = new Pair (null, $1); + } + | set_accessor_declaration accessor_declarations + { + Pair pair = (Pair) $2; + pair.Second = $1; + $$ = pair; + } + | error { - $$ = new Pair ($2, $1); + Report.Error (1014, lexer.Location, "A get or set accessor expected"); + $$ = null; } ; -opt_get_accessor_declaration - : /* empty */ { $$ = null; } - | get_accessor_declaration - ; - -opt_set_accessor_declaration - : /* empty */ { $$ = null; } - | set_accessor_declaration - ; - get_accessor_declaration - : opt_attributes GET + : opt_attributes opt_modifiers GET { // If this is not the case, then current_local_parameters has already // been set in indexer_declaration @@ -1271,24 +1406,33 @@ get_accessor_declaration } accessor_body { - $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location); + if (has_get) { + Report.Error (1007, lexer.Location, "Property accessor already defined"); + break; + } + $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location); + has_get = true; current_local_parameters = null; lexer.PropertyParsing = true; + + if (RootContext.Documentation != null) + if (Lexer.doc_state == XmlCommentState.Error) + Lexer.doc_state = XmlCommentState.NotAllowed; } ; set_accessor_declaration - : opt_attributes SET + : opt_attributes opt_modifiers SET { Parameter [] args; Parameter implicit_value_parameter = new Parameter ( implicit_value_parameter_type, "value", - Parameter.Modifier.NONE, null); + Parameter.Modifier.NONE, null, lexer.Location); if (parsing_indexer == false) { args = new Parameter [1]; args [0] = implicit_value_parameter; - current_local_parameters = new Parameters (args, null, lexer.Location); + current_local_parameters = new Parameters (args, null); } else { Parameter [] fpars = indexer_parameters.FixedParameters; @@ -1301,16 +1445,25 @@ set_accessor_declaration } else args = null; current_local_parameters = new Parameters ( - args, indexer_parameters.ArrayParameter, lexer.Location); + args, indexer_parameters.ArrayParameter); } lexer.PropertyParsing = false; } accessor_body { - $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location); + if (has_set) { + Report.Error (1007, lexer.Location, "Property accessor already defined"); + break; + } + $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location); + has_set = true; current_local_parameters = null; lexer.PropertyParsing = true; + + if (RootContext.Documentation != null + && Lexer.doc_state == XmlCommentState.Error) + Lexer.doc_state = XmlCommentState.NotAllowed; } ; @@ -1323,47 +1476,55 @@ interface_declaration : opt_attributes opt_modifiers opt_partial - INTERFACE member_name + INTERFACE + { + lexer.ConstraintsParsing = true; + } + member_name { - MemberName name = MakeName ((MemberName) $5); + MemberName name = MakeName ((MemberName) $6); bool partial = (bool) $3; if (partial) { ClassPart part = PartialContainer.CreatePart ( - current_namespace, current_container, name, (int) $2, + current_namespace, current_class, name, (int) $2, (Attributes) $1, Kind.Interface, lexer.Location); current_container = part.PartialContainer; current_class = part; } else { current_class = new Interface ( - current_namespace, current_container, name, (int) $2, + current_namespace, current_class, name, (int) $2, (Attributes) $1, lexer.Location); + current_container.AddInterface (current_class); current_container = current_class; - RootContext.Tree.RecordDecl (name.GetName (true), current_class); + RootContext.Tree.RecordDecl (name, current_class); } - - lexer.ConstraintsParsing = true; } opt_class_base opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; - if ($7 != null) - current_class.Bases = (ArrayList) $7; + if ($8 != null) + current_class.Bases = (ArrayList) $8; - current_class.SetParameterInfo ((ArrayList) $8); + current_class.SetParameterInfo ((ArrayList) $9); - current_class.Register (); + if (RootContext.Documentation != null) { + current_class.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } } - interface_body opt_semicolon + interface_body { - $$ = current_class; - - current_container = current_container.Parent; - current_class = current_container; + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } + opt_semicolon + { + $$ = pop_current_class (); } | opt_attributes opt_modifiers opt_partial INTERFACE error { CheckIdentifierToken (yyToken); @@ -1389,28 +1550,90 @@ interface_member_declarations interface_member_declaration : interface_method_declaration { + if ($1 == null) + break; + Method m = (Method) $1; + if (m.IsExplicitImpl) + Report.Error (541, lexer.Location, + "Explicit interface declaration can only be declared in a class or struct"); + current_container.AddMethod (m); + + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; } | interface_property_declaration { + if ($1 == null) + break; + Property p = (Property) $1; + if (p.IsExplicitImpl) + Report.Error (541, lexer.Location, + "Explicit interface declaration can only be declared in a class or struct"); + current_container.AddProperty (p); - } + + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } | interface_event_declaration { if ($1 != null){ Event e = (Event) $1; + + if (e.IsExplicitImpl) + Report.Error (541, lexer.Location, + "Explicit interface declaration can only be declared in a class or struct"); + current_container.AddEvent (e); } + + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; } | interface_indexer_declaration { + if ($1 == null) + break; + Indexer i = (Indexer) $1; + if (i.IsExplicitImpl) + Report.Error (541, lexer.Location, + "Explicit interface declaration can only be declared in a class or struct"); + current_container.AddIndexer (i); + + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } + | delegate_declaration + { + Report.Error (524, lexer.Location, "Interfaces can not declare delegates"); + } + | class_declaration + { + Report.Error (524, lexer.Location, "Interfaces can not declare classes"); + } + | struct_declaration + { + Report.Error (524, lexer.Location, "Interfaces can not declare structures"); + } + | enum_declaration + { + Report.Error (524, lexer.Location, "Interfaces can not declare enumerations"); + } + | interface_declaration + { + Report.Error (524, lexer.Location, "Interfaces can not declare interfaces"); + } + | constant_declaration + { + Report.Error (525, lexer.Location, "Interfaces cannot contain constants"); } ; @@ -1450,6 +1673,8 @@ interface_method_declaration $$ = new Method (current_class, generic, (Expression) $3, (int) $2, true, name, (Parameters) $6, (Attributes) $1, lexer.Location); + if (RootContext.Documentation != null) + ((Method) $$).DocComment = Lexer.consume_doc_comment (); } | opt_attributes opt_new VOID namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS @@ -1477,7 +1702,22 @@ interface_method_declaration $$ = new Method (current_class, generic, TypeManager.system_void_expr, (int) $2, true, name, (Parameters) $6, (Attributes) $1, lexer.Location); + if (RootContext.Documentation != null) + ((Method) $$).DocComment = Lexer.consume_doc_comment (); } + | opt_attributes opt_new type namespace_or_type_name + OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + { + lexer.ConstraintsParsing = true; + } + opt_type_parameter_constraints_clauses + OPEN_BRACE opt_statement_list CLOSE_BRACE + { + lexer.ConstraintsParsing = false; + Report.Error (531, lexer.Location, "'{0}': interface members cannot have a definition", $4); + $$ = null; + } + ; interface_property_declaration @@ -1490,11 +1730,21 @@ interface_property_declaration { lexer.PropertyParsing = false; } CLOSE_BRACE { + if ($3 == TypeManager.system_void_expr) { + Report.Error (547, lexer.Location, "'{0}': property cannot have void type", $4); + break; + } + + if ($7 == null) + break; + InterfaceAccessorInfo pinfo = (InterfaceAccessorInfo) $7; $$ = new Property (current_class, (Expression) $3, (int) $2, true, new MemberName ((string) $4), (Attributes) $1, pinfo.Get, pinfo.Set, lexer.Location); + if (RootContext.Documentation != null) + ((Property) $$).DocComment = Lexer.consume_doc_comment (); } | opt_attributes opt_new @@ -1505,12 +1755,23 @@ interface_property_declaration ; interface_accessors - : opt_attributes GET SEMICOLON { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null, lexer.Location, lexer.Location); } - | opt_attributes SET SEMICOLON { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1, lexer.Location, lexer.Location); } - | opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON - { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $3, lexer.Location, lexer.Location); } - | opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON - { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $3, (Attributes) $1, lexer.Location, lexer.Location); } + : opt_attributes opt_modifiers GET SEMICOLON + { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null, (int) $2, 0, lexer.Location, lexer.Location); } + | opt_attributes opt_modifiers GET OPEN_BRACE + { + Report.Error (531, lexer.Location, "'{0}': interface members cannot have a definition", ".get"); + $$ = null; + } + | opt_attributes opt_modifiers SET SEMICOLON + { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1, 0, (int) $2, lexer.Location, lexer.Location); } + | opt_attributes opt_modifiers GET SEMICOLON opt_attributes opt_modifiers SET SEMICOLON + { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $5, (int) $2, (int) $6, lexer.Location, lexer.Location); } + | opt_attributes opt_modifiers SET SEMICOLON opt_attributes opt_modifiers GET SEMICOLON + { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $5, (Attributes) $1, (int) $6, (int) $2, lexer.Location, lexer.Location); } + | + { + Report.Error (548, lexer.Location, "'{0}' : property or indexer must have at least one accessor", ""); + } ; interface_event_declaration @@ -1519,6 +1780,8 @@ interface_event_declaration $$ = new EventField (current_class, (Expression) $4, (int) $2, true, new MemberName ((string) $5), null, (Attributes) $1, lexer.Location); + if (RootContext.Documentation != null) + ((EventField) $$).DocComment = Lexer.consume_doc_comment (); } | opt_attributes opt_new EVENT type error { CheckIdentifierToken (yyToken); @@ -1528,8 +1791,16 @@ interface_event_declaration Report.Error (68, lexer.Location, "Event declarations on interfaces can not be initialized."); $$ = null; } - | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE event_accessor_declarations CLOSE_BRACE { - Report.Error (69, lexer.Location, "Event accessors not valid on interfaces"); + | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE + { + lexer.EventParsing = true; + } + event_accessor_declarations + { + lexer.EventParsing = false; + } + CLOSE_BRACE { + Report.Error (69, lexer.Location, "Event in interface cannot have add or remove accessors"); $$ = null; } ; @@ -1543,12 +1814,17 @@ interface_indexer_declaration { lexer.PropertyParsing = false; } CLOSE_BRACE { + if ($10 == null) + break; + InterfaceAccessorInfo info = (InterfaceAccessorInfo) $10; $$ = new Indexer (current_class, (Expression) $3, new MemberName (TypeContainer.DefaultIndexerName), (int) $2, true, (Parameters) $6, (Attributes) $1, info.Get, info.Set, lexer.Location); + if (RootContext.Documentation != null) + ((Indexer) $$).DocComment = ConsumeStoredComment (); } ; @@ -1559,18 +1835,26 @@ operator_declaration } operator_body { + if ($3 == null) + break; + OperatorDeclaration decl = (OperatorDeclaration) $3; Parameter [] param_list = new Parameter [decl.arg2type != null ? 2 : 1]; - param_list[0] = new Parameter (decl.arg1type, decl.arg1name, Parameter.Modifier.NONE, null); + param_list[0] = new Parameter (decl.arg1type, decl.arg1name, Parameter.Modifier.NONE, null, decl.location); if (decl.arg2type != null) - param_list[1] = new Parameter (decl.arg2type, decl.arg2name, Parameter.Modifier.NONE, null); + param_list[1] = new Parameter (decl.arg2type, decl.arg2name, Parameter.Modifier.NONE, null, decl.location); Operator op = new Operator ( current_class, decl.optype, decl.ret_type, (int) $2, - new Parameters (param_list, null, decl.location), - (Block) $5, (Attributes) $1, decl.location); + new Parameters (param_list, null), + (ToplevelBlock) $5, (Attributes) $1, decl.location); + + if (RootContext.Documentation != null) { + op.DocComment = tmpComment; + Lexer.doc_state = XmlCommentState.Allowed; + } if (SimpleIteratorContainer.Simple.Yields) op.SetYields (); @@ -1601,12 +1885,18 @@ operator_declarator op = Operator.OpType.UnaryNegation; Parameter [] pars = new Parameter [1]; + Expression type = (Expression) $5; - pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null); + pars [0] = new Parameter (type, (string) $6, Parameter.Modifier.NONE, null, lexer.Location); - current_local_parameters = new Parameters (pars, null, lexer.Location); + current_local_parameters = new Parameters (pars, null); + + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.NotAllowed; + } - $$ = new OperatorDeclaration (op, (Expression) $1, (Expression) $5, (string) $6, + $$ = new OperatorDeclaration (op, (Expression) $1, type, (string) $6, null, null, lexer.Location); } | type OPERATOR overloadable_operator @@ -1615,20 +1905,44 @@ operator_declarator type IDENTIFIER CLOSE_PARENS { - CheckBinaryOperator ((Operator.OpType) $3); + CheckBinaryOperator ((Operator.OpType) $3); - Parameter [] pars = new Parameter [2]; + Parameter [] pars = new Parameter [2]; - pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null); - pars [1] = new Parameter ((Expression) $8, (string) $9, Parameter.Modifier.NONE, null); + Expression typeL = (Expression) $5; + Expression typeR = (Expression) $8; - current_local_parameters = new Parameters (pars, null, lexer.Location); + pars [0] = new Parameter (typeL, (string) $6, Parameter.Modifier.NONE, null, lexer.Location); + pars [1] = new Parameter (typeR, (string) $9, Parameter.Modifier.NONE, null, lexer.Location); + + current_local_parameters = new Parameters (pars, null); + + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.NotAllowed; + } $$ = new OperatorDeclaration ((Operator.OpType) $3, (Expression) $1, - (Expression) $5, (string) $6, - (Expression) $8, (string) $9, lexer.Location); + typeL, (string) $6, + typeR, (string) $9, lexer.Location); } | conversion_operator_declarator + | type OPERATOR overloadable_operator + OPEN_PARENS + type IDENTIFIER COMMA + type IDENTIFIER COMMA + type IDENTIFIER + CLOSE_PARENS + { + Report.Error (1534, lexer.Location, "Overloaded binary operator '{0}' takes two parameters", $3); + $$ = null; + } + | type OPERATOR overloadable_operator + OPEN_PARENS CLOSE_PARENS + { + Report.Error (1535, lexer.Location, "Overloaded unary operator '{0}' takes one parameter", $3); + $$ = null; + } ; overloadable_operator @@ -1664,10 +1978,15 @@ conversion_operator_declarator { Parameter [] pars = new Parameter [1]; - pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null); + pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null, lexer.Location); - current_local_parameters = new Parameters (pars, null, lexer.Location); + current_local_parameters = new Parameters (pars, null); + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.NotAllowed; + } + $$ = new OperatorDeclaration (Operator.OpType.Implicit, (Expression) $3, (Expression) $5, (string) $6, null, null, lexer.Location); } @@ -1675,10 +1994,15 @@ conversion_operator_declarator { Parameter [] pars = new Parameter [1]; - pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null); + pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null, lexer.Location); - current_local_parameters = new Parameters (pars, null, lexer.Location); + current_local_parameters = new Parameters (pars, null); + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.NotAllowed; + } + $$ = new OperatorDeclaration (Operator.OpType.Explicit, (Expression) $3, (Expression) $5, (string) $6, null, null, lexer.Location); } @@ -1699,10 +2023,13 @@ constructor_declaration constructor_body { Constructor c = (Constructor) $3; - c.Block = (Block) $4; + c.Block = (ToplevelBlock) $4; c.OptAttributes = (Attributes) $1; c.ModFlags = (int) $2; + if (RootContext.Documentation != null) + c.DocComment = ConsumeStoredComment (); + if (c.Name == current_container.Basename){ if ((c.ModFlags & Modifiers.STATIC) != 0){ if ((c.ModFlags & Modifiers.Accessibility) != 0){ @@ -1736,22 +2063,27 @@ constructor_declaration current_container.AddConstructor (c); current_local_parameters = null; + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; } ; constructor_declarator - : IDENTIFIER - OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + : IDENTIFIER { - oob_stack.Push (lexer.Location); - - current_local_parameters = (Parameters) $3; + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + } + OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS _mark_ + { + current_local_parameters = (Parameters) $4; } opt_constructor_initializer { - Location l = (Location) oob_stack.Pop (); - $$ = new Constructor (current_class, (string) $1, 0, (Parameters) $3, - (ConstructorInitializer) $6, l); + $$ = new Constructor (current_class, (string) $1, 0, (Parameters) $4, + (ConstructorInitializer) $8, (Location) $6); } ; @@ -1768,11 +2100,11 @@ opt_constructor_initializer constructor_initializer : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS { - $$ = new ConstructorBaseInitializer ((ArrayList) $4, current_local_parameters, lexer.Location); + $$ = new ConstructorBaseInitializer ((ArrayList) $4, lexer.Location); } | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS { - $$ = new ConstructorThisInitializer ((ArrayList) $4, current_local_parameters, lexer.Location); + $$ = new ConstructorThisInitializer ((ArrayList) $4, lexer.Location); } | COLON error { Report.Error (1018, lexer.Location, "Keyword this or base expected"); @@ -1787,11 +2119,18 @@ opt_finalizer ; destructor_declaration - : opt_attributes opt_finalizer TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block + : opt_attributes opt_finalizer TILDE { - if ((string) $4 != current_container.Basename){ + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.NotAllowed; + } + } + IDENTIFIER OPEN_PARENS CLOSE_PARENS block + { + if ((string) $5 != current_container.MemberName.Name){ Report.Error (574, lexer.Location, "Name of destructor must match name of class"); - } else if (!(current_container is Class)){ + } else if (current_container.Kind != Kind.Class){ Report.Error (575, lexer.Location, "Destructors are only allowed in class types"); } else { Location l = lexer.Location; @@ -1812,9 +2151,11 @@ destructor_declaration Method d = new Destructor ( current_class, TypeManager.system_void_expr, m, "Finalize", - new Parameters (null, null, l), (Attributes) $1, l); + new Parameters (null, null), (Attributes) $1, l); + if (RootContext.Documentation != null) + d.DocComment = ConsumeStoredComment (); - d.Block = (Block) $7; + d.Block = (ToplevelBlock) $8; current_container.AddMethod (d); } } @@ -1835,17 +2176,20 @@ event_declaration lexer.Location); current_container.AddEvent (e); - + + if (RootContext.Documentation != null) { + e.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } } } | opt_attributes opt_modifiers EVENT type namespace_or_type_name - OPEN_BRACE + OPEN_BRACE _mark_ { implicit_value_parameter_type = (Expression) $4; lexer.EventParsing = true; - oob_stack.Push (lexer.Location); } event_accessor_declarations { @@ -1853,13 +2197,13 @@ event_declaration } CLOSE_BRACE { - Location loc = (Location) oob_stack.Pop (); + Location loc = (Location) $7; - if ($8 == null){ + if ($9 == null){ Report.Error (65, lexer.Location, "Event must have both add and remove accesors"); $$ = null; } else { - Pair pair = (Pair) $8; + Pair pair = (Pair) $9; MemberName name = (MemberName) $5; @@ -1870,7 +2214,11 @@ event_declaration current_class, (Expression) $4, (int) $2, false, name, null, (Attributes) $1, (Accessor) pair.First, (Accessor) pair.Second, loc); - + if (RootContext.Documentation != null) { + e.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + current_container.AddEvent (e); implicit_value_parameter_type = null; } @@ -1882,6 +2230,9 @@ event_declaration Report.Error (71, lexer.Location, "Explicit implementation of events requires property syntax"); else Report.Error (71, lexer.Location, "Event declaration should use property syntax"); + + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; } ; @@ -1896,6 +2247,12 @@ event_accessor_declarations } | add_accessor_declaration { $$ = null; } | remove_accessor_declaration { $$ = null; } + | error + { + Report.Error (1055, lexer.Location, "An add or remove accessor expected"); + $$ = null; + } + | { $$ = null; } ; add_accessor_declaration @@ -1904,22 +2261,26 @@ add_accessor_declaration Parameter [] args = new Parameter [1]; Parameter implicit_value_parameter = new Parameter ( implicit_value_parameter_type, "value", - Parameter.Modifier.NONE, null); + Parameter.Modifier.NONE, null, lexer.Location); args [0] = implicit_value_parameter; - current_local_parameters = new Parameters (args, null, lexer.Location); + current_local_parameters = new Parameters (args, null); lexer.EventParsing = false; } block { - $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location); + $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, lexer.Location); lexer.EventParsing = true; } | opt_attributes ADD error { Report.Error (73, lexer.Location, "Add or remove accessor must have a body"); $$ = null; } + | opt_attributes modifiers ADD { + Report.Error (1609, lexer.Location, "Modifiers cannot be placed on event accessor declarations"); + $$ = null; + } ; remove_accessor_declaration @@ -1928,27 +2289,31 @@ remove_accessor_declaration Parameter [] args = new Parameter [1]; Parameter implicit_value_parameter = new Parameter ( implicit_value_parameter_type, "value", - Parameter.Modifier.NONE, null); + Parameter.Modifier.NONE, null, lexer.Location); args [0] = implicit_value_parameter; - current_local_parameters = new Parameters (args, null, lexer.Location); + current_local_parameters = new Parameters (args, null); lexer.EventParsing = false; } block { - $$ = new Accessor ((Block) $4, (Attributes) $1, lexer.Location); + $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, lexer.Location); lexer.EventParsing = true; } | opt_attributes REMOVE error { Report.Error (73, lexer.Location, "Add or remove accessor must have a body"); $$ = null; } + | opt_attributes modifiers REMOVE { + Report.Error (1609, lexer.Location, "Modifiers cannot be placed on event accessor declarations"); + $$ = null; + } ; indexer_declaration : opt_attributes opt_modifiers indexer_declarator - OPEN_BRACE + OPEN_BRACE _mark_ { IndexerDeclaration decl = (IndexerDeclaration) $3; @@ -1958,21 +2323,24 @@ indexer_declaration parsing_indexer = true; indexer_parameters = decl.param_list; - oob_stack.Push (lexer.Location); } accessor_declarations { lexer.PropertyParsing = false; + has_get = has_set = false; parsing_indexer = false; } CLOSE_BRACE { + if ($7 == null) + break; + // The signature is computed from the signature of the indexer. Look // at section 3.6 on the spec - Location loc = (Location) oob_stack.Pop (); + Location loc = (Location) $5; Indexer indexer; IndexerDeclaration decl = (IndexerDeclaration) $3; - Pair pair = (Pair) $6; + Pair pair = (Pair) $7; Accessor get_block = (Accessor) pair.First; Accessor set_block = (Accessor) pair.Second; @@ -1986,6 +2354,8 @@ indexer_declaration indexer = new Indexer (current_class, decl.type, name, (int) $2, false, decl.param_list, (Attributes) $1, get_block, set_block, loc); + if (RootContext.Documentation != null) + indexer.DocComment = ConsumeStoredComment (); current_container.AddIndexer (indexer); @@ -2005,6 +2375,10 @@ indexer_declarator } else if (pars.FixedParameters == null && pars.ArrayParameter == null){ Report.Error (1551, lexer.Location, "Indexers must have at least one parameter"); } + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } $$ = new IndexerDeclaration ((Expression) $1, null, pars); } @@ -2018,37 +2392,56 @@ indexer_declarator } else if (pars.FixedParameters == null && pars.ArrayParameter == null){ Report.Error (1551, lexer.Location, "Indexers must have at least one parameter"); } + MemberName name = (MemberName) $2; - if (name.TypeArguments != null) - syntax_error (lexer.Location, "an indexer can't have type arguments"); $$ = new IndexerDeclaration ((Expression) $1, name, pars); + + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } } ; enum_declaration : opt_attributes opt_modifiers + opt_partial ENUM IDENTIFIER - opt_enum_base + opt_enum_base { + if (RootContext.Documentation != null) + enumTypeComment = Lexer.consume_doc_comment (); + } enum_body opt_semicolon - { + { + bool partial = (bool) $3; + + if (partial) { + Report.Error (267, lexer.Location, "The partial modifier can only appear before a 'class', 'struct', or 'interface'"); + break; // assumes that the parser put us in a switch + } + Location enum_location = lexer.Location; - MemberName full_name = MakeName (new MemberName ((string) $4)); - Enum e = new Enum (current_namespace, current_container, (Expression) $5, (int) $2, - full_name, (Attributes) $1, enum_location); + MemberName name = MakeName (new MemberName ((string) $5)); + Enum e = new Enum (current_namespace, current_class, (Expression) $6, (int) $2, + name, (Attributes) $1, enum_location); - foreach (VariableDeclaration ev in (ArrayList) $6) { + if (RootContext.Documentation != null) + e.DocComment = enumTypeComment; + + foreach (VariableDeclaration ev in (ArrayList) $8) { e.AddEnumMember (ev.identifier, (Expression) ev.expression_or_array_initializer, - ev.Location, ev.OptAttributes); + ev.Location, ev.OptAttributes, + ev.DocComment); } - string name = full_name.GetName (); current_container.AddEnum (e); RootContext.Tree.RecordDecl (name, e); + $$ = e; } ; @@ -2059,9 +2452,20 @@ opt_enum_base ; enum_body - : OPEN_BRACE opt_enum_member_declarations CLOSE_BRACE + : OPEN_BRACE { - $$ = $2; + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } + opt_enum_member_declarations + { + // here will be evaluated after CLOSE_BLACE is consumed. + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } + CLOSE_BRACE + { + $$ = $3; } ; @@ -2091,35 +2495,58 @@ enum_member_declarations enum_member_declaration : opt_attributes IDENTIFIER { - $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1); + VariableDeclaration vd = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1); + + if (RootContext.Documentation != null) { + vd.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + + $$ = vd; } | opt_attributes IDENTIFIER { - $$ = lexer.Location; + $$ = lexer.Location; + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.NotAllowed; + } } ASSIGN expression { - $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1); + VariableDeclaration vd = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1); + + if (RootContext.Documentation != null) + vd.DocComment = ConsumeStoredComment (); + + $$ = vd; } ; delegate_declaration : opt_attributes opt_modifiers - DELEGATE type member_name + DELEGATE + { + lexer.ConstraintsParsing = true; + } + type member_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { Location l = lexer.Location; - MemberName name = MakeName ((MemberName) $5); - Delegate del = new Delegate (current_namespace, current_container, (Expression) $4, - (int) $2, name, (Parameters) $7, (Attributes) $1, l); + MemberName name = MakeName ((MemberName) $6); + Delegate del = new Delegate (current_namespace, current_class, (Expression) $5, + (int) $2, name, (Parameters) $8, (Attributes) $1, l); + + if (RootContext.Documentation != null) { + del.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } current_container.AddDelegate (del); - RootContext.Tree.RecordDecl (name.GetName (true), del); + RootContext.Tree.RecordDecl (name, del); current_delegate = del; - - lexer.ConstraintsParsing = true; } opt_type_parameter_constraints_clauses { @@ -2127,38 +2554,23 @@ delegate_declaration } SEMICOLON { - current_delegate.SetParameterInfo ((ArrayList) $9); + current_delegate.SetParameterInfo ((ArrayList) $10); + $$ = current_delegate; current_delegate = null; } - | opt_attributes - opt_modifiers - DELEGATE VOID member_name - OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS - { - Location l = lexer.Location; - MemberName name = MakeName ((MemberName) $5); - Delegate del = new Delegate ( - current_namespace, current_container, - TypeManager.system_void_expr, (int) $2, name, - (Parameters) $7, (Attributes) $1, l); - - current_container.AddDelegate (del); - RootContext.Tree.RecordDecl (name.GetName (true), del); - - current_delegate = del; + ; - lexer.ConstraintsParsing = true; - } - opt_type_parameter_constraints_clauses +opt_nullable + : /* empty */ { - lexer.ConstraintsParsing = false; + lexer.CheckNullable (false); + $$ = false; } - SEMICOLON + | INTERR { - current_delegate.SetParameterInfo ((ArrayList) $9); - - current_delegate = null; + lexer.CheckNullable (true); + $$ = true; } ; @@ -2207,16 +2619,22 @@ type_arguments * gets rid of a shift/reduce couple */ type - : namespace_or_type_name + : namespace_or_type_name opt_nullable { $$ = ((MemberName) $1).GetTypeExpression (lexer.Location); + + if ((bool) $2) + $$ = new ComposedCast ((Expression) $$, "?", lexer.Location); + } + | builtin_types opt_nullable + { + if ((bool) $2) + $$ = new ComposedCast ((Expression) $1, "?", lexer.Location); } - | builtin_types | array_type - | pointer_type + | pointer_type ; - pointer_type : type STAR { @@ -2234,7 +2652,11 @@ pointer_type ; non_expression_type - : builtin_types + : builtin_types opt_nullable + { + if ((bool) $2) + $$ = new ComposedCast ((Expression) $1, "?", lexer.Location); + } | non_expression_type rank_specifier { $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); @@ -2307,9 +2729,13 @@ integral_type ; array_type - : type rank_specifiers + : type rank_specifiers opt_nullable { - $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); + string rank_specifiers = (string) $2; + if ((bool) $3) + rank_specifiers += "?"; + + $$ = new ComposedCast ((Expression) $1, rank_specifiers, lexer.Location); } ; @@ -2321,8 +2747,7 @@ primary_expression { // 7.5.1: Literals } - - | member_name + | member_name { $$ = ((MemberName) $1).GetTypeExpression (lexer.Location); } @@ -2447,6 +2872,18 @@ invocation_expression { $$ = new InvocationOrCast ((Expression) $1, (Expression) $3, lexer.Location); } + | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS non_simple_argument CLOSE_PARENS + { + ArrayList args = new ArrayList (1); + args.Add ($4); + $$ = new Invocation ((Expression) $1, args, lexer.Location); + } + | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS argument_list COMMA argument CLOSE_PARENS + { + ArrayList args = ((ArrayList) $4); + args.Add ($6); + $$ = new Invocation ((Expression) $1, args, lexer.Location); + } ; opt_argument_list @@ -2477,7 +2914,14 @@ argument { $$ = new Argument ((Expression) $1, Argument.AType.Expression); } - | REF variable_reference + | non_simple_argument + { + $$ = $1; + } + ; + +non_simple_argument + : REF variable_reference { $$ = new Argument ((Expression) $2, Argument.AType.Ref); } @@ -2610,6 +3054,11 @@ array_creation_expression { $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, lexer.Location); } + | NEW error + { + Report.Error (1031, lexer.Location, "Type expected"); + $$ = null; + } | NEW type error { Report.Error (1526, lexer.Location, "new expression requires () or [] after type"); @@ -2627,6 +3076,31 @@ opt_rank_specifier } ; +opt_rank_specifier_or_nullable + : /* empty */ + { + $$ = ""; + } + | INTERR + { + $$ = "?"; + } + | opt_nullable rank_specifiers + { + if ((bool) $1) + $$ = "?" + $2; + else + $$ = $2; + } + | opt_nullable rank_specifiers INTERR + { + if ((bool) $1) + $$ = "?" + $2 + "?"; + else + $$ = $2 + "?"; + } + ; + rank_specifiers : rank_specifier opt_rank_specifier { @@ -2701,11 +3175,26 @@ 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 (lexer.Location); } + | TYPEOF OPEN_PARENS void_pointer_expression CLOSE_PARENS + { + $$ = new TypeOf ((Expression) $3, lexer.Location); + } | TYPEOF OPEN_PARENS { lexer.TypeOfParsing = true; @@ -2748,28 +3237,37 @@ pointer_member_access ; anonymous_method_expression - : DELEGATE opt_anonymous_method_signature { + : DELEGATE opt_anonymous_method_signature _mark_ + { oob_stack.Push (current_local_parameters); current_local_parameters = (Parameters)$2; - create_toplevel_block = true; - } block { - if (true){ - Report.Error (-213, lexer.Location, "Anonymous methods are not supported in this branch"); - $$ = null; - } else { - create_toplevel_block = false; - if (RootContext.Version == LanguageVersion.ISO_1){ + + // Force the next block to be created as a ToplevelBlock + oob_stack.Push (current_block); + oob_stack.Push (top_current_block); + current_block = null; + } + block + { + Location loc = (Location) $3; + top_current_block = (Block) oob_stack.Pop (); + current_block = (Block) oob_stack.Pop (); + if (RootContext.Version == LanguageVersion.ISO_1){ Report.FeatureIsNotStandardized (lexer.Location, "anonymous methods"); $$ = null; - } else - $$ = new AnonymousMethod ((Parameters) $2, (Block) $4, lexer.Location); + } else { + ToplevelBlock anon_block = (ToplevelBlock) $5; + + anon_block.Parent = current_block; + $$ = new AnonymousMethod ((Parameters) $2, (ToplevelBlock) top_current_block, + anon_block, loc); + } current_local_parameters = (Parameters) oob_stack.Pop (); } - } ; opt_anonymous_method_signature - : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; } + : /* empty */ { $$ = null; } | anonymous_method_signature ; @@ -2782,7 +3280,7 @@ anonymous_method_signature ArrayList par_list = (ArrayList) $2; Parameter [] pars = new Parameter [par_list.Count]; par_list.CopyTo (pars); - $$ = new Parameters (pars, null, lexer.Location); + $$ = new Parameters (pars, null); } } ; @@ -2809,7 +3307,11 @@ anonymous_method_parameter_list anonymous_method_parameter : opt_parameter_modifier type IDENTIFIER { - $$ = new Parameter ((Expression) $2, (string) $2, (Parameter.Modifier) $1, null); + $$ = new Parameter ((Expression) $2, (string) $3, (Parameter.Modifier) $1, null, lexer.Location); + } + | PARAMS type IDENTIFIER { + Report.Error (1670, lexer.Location, "params modifier not allowed in anonymous method declaration"); + $$ = null; } ; @@ -2949,6 +3451,28 @@ shift_expression } ; +opt_error + : /* empty */ + { + $$ = false; + } + | error + { + lexer.PutbackNullable (); + $$ = true; + } + ; + +nullable_type_or_conditional + : type opt_error + { + if (((bool) $2) && ($1 is ComposedCast)) + $$ = ((ComposedCast) $1).RemoveNullable (); + else + $$ = $1; + } + ; + relational_expression : shift_expression | relational_expression OP_LT shift_expression @@ -2971,13 +3495,19 @@ relational_expression $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3, lexer.Location); } - | relational_expression IS type + | relational_expression IS + { + yyErrorFlag = 3; + } nullable_type_or_conditional { - $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location); + $$ = new Is ((Expression) $1, (Expression) $4, lexer.Location); } - | relational_expression AS type + | relational_expression AS { - $$ = new As ((Expression) $1, (Expression) $3, lexer.Location); + yyErrorFlag = 3; + } nullable_type_or_conditional + { + $$ = new As ((Expression) $1, (Expression) $4, lexer.Location); } ; @@ -3046,6 +3576,16 @@ conditional_expression { $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5, lexer.Location); } + | conditional_or_expression INTERR INTERR expression + { + $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $4, lexer.Location); + } + // We'll be resolved into a `parenthesized_expression_0' later on. + | conditional_or_expression INTERR CLOSE_PARENS + { + $$ = new ComposedCast ((Expression) $1, "?", lexer.Location); + lexer.PutbackCloseParens (); + } ; assignment_expression @@ -3145,15 +3685,19 @@ class_declaration : opt_attributes opt_modifiers opt_partial - CLASS member_name + CLASS { - MemberName name = MakeName ((MemberName) $5); + lexer.ConstraintsParsing = true; + } + member_name + { + MemberName name = MakeName ((MemberName) $6); bool partial = (bool) $3; int mod_flags = (int) $2; if (partial) { ClassPart part = PartialContainer.CreatePart ( - current_namespace, current_container, name, mod_flags, + current_namespace, current_class, name, mod_flags, (Attributes) $1, Kind.Class, lexer.Location); current_container = part.PartialContainer; @@ -3161,45 +3705,48 @@ class_declaration } else { if ((mod_flags & Modifiers.STATIC) != 0) { current_class = new StaticClass ( - current_namespace, current_container, name, + current_namespace, current_class, name, mod_flags, (Attributes) $1, lexer.Location); } else { current_class = new Class ( - current_namespace, current_container, name, + current_namespace, current_class, name, mod_flags, (Attributes) $1, lexer.Location); } + current_container.AddClassOrStruct (current_class); current_container = current_class; - RootContext.Tree.RecordDecl (name.GetName (true), current_class); + RootContext.Tree.RecordDecl (name, current_class); } - - lexer.ConstraintsParsing = true; } opt_class_base opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; - if ($7 != null) { + if ($8 != null) { if (current_class.Name == "System.Object") { Report.Error (537, current_class.Location, "The class System.Object cannot have a base " + "class or implement an interface."); } - current_class.Bases = (ArrayList) $7; + current_class.Bases = (ArrayList) $8; } - current_class.SetParameterInfo ((ArrayList) $8); + current_class.SetParameterInfo ((ArrayList) $9); - current_class.Register (); + if (RootContext.Documentation != null) { + current_class.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + } + class_body + { + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; } - class_body opt_semicolon { - $$ = current_class; - - current_container = current_container.Parent; - current_class = current_container; + $$ = pop_current_class (); } ; @@ -3325,11 +3872,11 @@ type_parameter_constraint block : OPEN_BRACE { - if (current_block == null || create_toplevel_block){ - current_block = new ToplevelBlock (current_local_parameters, lexer.Location); + if (current_block == null){ + current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, lexer.Location); + top_current_block = current_block; } else { - current_block = new Block (current_block, current_local_parameters, - lexer.Location, Location.Null); + current_block = new Block (current_block, lexer.Location, Location.Null); } } opt_statement_list CLOSE_BRACE @@ -3339,6 +3886,8 @@ block $$ = current_block; current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; + if (current_block == null) + top_current_block = null; } ; @@ -3442,7 +3991,7 @@ declaration_statement * > The expressions are converted into types during semantic analysis. */ local_variable_type - : primary_expression opt_rank_specifier + : primary_expression opt_rank_specifier_or_nullable { // FIXME: Do something smart here regarding the composition of the type. @@ -3476,7 +4025,7 @@ local_variable_type $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location); } } - | builtin_types opt_rank_specifier + | builtin_types opt_rank_specifier_or_nullable { if ((string) $2 == "") $$ = $1; @@ -3520,7 +4069,7 @@ local_variable_declaration else $$ = null; } - | local_variable_pointer_type opt_rank_specifier variable_declarators + | local_variable_pointer_type opt_rank_specifier_or_nullable variable_declarators { if ($1 != null){ Expression t; @@ -3581,52 +4130,37 @@ selection_statement ; if_statement - : if_statement_open if_statement_rest - { - $$ = $2; - } - ; - -if_statement_open - : IF OPEN_PARENS - { - oob_stack.Push (lexer.Location); - } - ; - -if_statement_rest - : boolean_expression CLOSE_PARENS + : IF OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS embedded_statement { - Location l = (Location) oob_stack.Pop (); + Location l = (Location) $3; - $$ = new If ((Expression) $1, (Statement) $3, l); + $$ = new If ((Expression) $4, (Statement) $6, l); - if (RootContext.WarningLevel >= 3){ - if ($3 == EmptyStatement.Value) + if (RootContext.WarningLevel >= 4){ + if ($6 == EmptyStatement.Value) Report.Warning (642, lexer.Location, "Possible mistaken empty statement"); } } - | boolean_expression CLOSE_PARENS + | IF OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS embedded_statement ELSE embedded_statement { - Location l = (Location) oob_stack.Pop (); + Location l = (Location) $3; - $$ = new If ((Expression) $1, (Statement) $3, (Statement) $5, l); + $$ = new If ((Expression) $4, (Statement) $6, (Statement) $8, l); } ; switch_statement - : SWITCH OPEN_PARENS + : SWITCH OPEN_PARENS _mark_ { - oob_stack.Push (lexer.Location); switch_stack.Push (current_block); } expression CLOSE_PARENS switch_block { - $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) oob_stack.Pop ()); + $$ = new Switch ((Expression) $5, (ArrayList) $7, (Location) $3); current_block = (Block) switch_stack.Pop (); } ; @@ -3715,16 +4249,12 @@ iteration_statement ; while_statement - : WHILE OPEN_PARENS + : WHILE OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS embedded_statement { - oob_stack.Push (lexer.Location); - } - boolean_expression CLOSE_PARENS embedded_statement - { - Location l = (Location) oob_stack.Pop (); + Location l = (Location) $3; $$ = new While ((Expression) $4, (Statement) $6, l); - if (RootContext.WarningLevel >= 3){ + if (RootContext.WarningLevel >= 4){ if ($6 == EmptyStatement.Value) Report.Warning (642, lexer.Location, "Possible mistaken empty statement"); } @@ -3733,12 +4263,9 @@ while_statement do_statement : DO embedded_statement - WHILE OPEN_PARENS { - oob_stack.Push (lexer.Location); - } - boolean_expression CLOSE_PARENS SEMICOLON + WHILE OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS SEMICOLON { - Location l = (Location) oob_stack.Pop (); + Location l = (Location) $5; $$ = new Do ((Statement) $2, (Expression) $6, l); } @@ -3746,7 +4273,7 @@ do_statement for_statement : FOR OPEN_PARENS - opt_for_initializer SEMICOLON + opt_for_initializer SEMICOLON _mark_ { Block assign_block = new Block (current_block); current_block = assign_block; @@ -3761,8 +4288,7 @@ for_statement LocalInfo vi; - vi = current_block.AddVariable ( - type, decl.identifier, current_local_parameters, decl.Location); + vi = current_block.AddVariable (type, decl.identifier, decl.Location); if (vi == null) continue; @@ -3787,20 +4313,23 @@ for_statement } } - $3 = null; - } - oob_stack.Push (lexer.Location); + // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal. + // This can be referred to as $6 below. + $$ = null; + } else { + $$ = $3; + } } opt_for_condition SEMICOLON opt_for_iterator CLOSE_PARENS embedded_statement { - Location l = (Location) oob_stack.Pop (); + Location l = (Location) $5; - For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l); + For f = new For ((Statement) $6, (Expression) $7, (Statement) $9, (Statement) $11, l); - if (RootContext.WarningLevel >= 3){ - if ($10 == EmptyStatement.Value) + if (RootContext.WarningLevel >= 4){ + if ($11 == EmptyStatement.Value) Report.Warning (642, lexer.Location, "Possible mistaken empty statement"); } @@ -3855,46 +4384,47 @@ statement_expression_list ; foreach_statement - : FOREACH OPEN_PARENS type IDENTIFIER IN - { - oob_stack.Push (lexer.Location); - } + : FOREACH OPEN_PARENS type IN expression CLOSE_PARENS + { + Report.Error (230, lexer.Location, "Type and identifier are both required in a foreach statement"); + $$ = null; + } + | FOREACH OPEN_PARENS type IDENTIFIER IN _mark_ expression CLOSE_PARENS { - oob_stack.Push (current_block); - Block foreach_block = new Block (current_block); - LocalVariableReference v = null; + current_block = foreach_block; + Location l = lexer.Location; LocalInfo vi; - vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l); + vi = foreach_block.AddVariable ((Expression) $3, (string) $4, l); if (vi != null) { - vi.ReadOnly = true; + vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Foreach); // Get a writable reference to this read-only variable. - v = new LocalVariableReference (foreach_block, (string) $4, l, vi, false); + // + // Note that the $$ here refers to the value of _this_ code block, + // not the value of the LHS non-terminal. This can be referred to as $9 below. + $$ = new LocalVariableReference (foreach_block, (string) $4, l, vi, false); + } else { + $$ = null; } - current_block = foreach_block; - - oob_stack.Push (v); - oob_stack.Push (current_block); } embedded_statement { - Block foreach_block = (Block) oob_stack.Pop (); - LocalVariableReference v = (LocalVariableReference) oob_stack.Pop (); - Block prev_block = (Block) oob_stack.Pop (); - Location l = (Location) oob_stack.Pop (); - - current_block = prev_block; + LocalVariableReference v = (LocalVariableReference) $9; + Location l = (Location) $6; if (v != null) { Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l); - foreach_block.AddStatement (f); + current_block.AddStatement (f); } - $$ = foreach_block; + while (current_block.Implicit) + current_block = current_block.Parent; + $$ = current_block; + current_block = current_block.Parent; } ; @@ -3924,7 +4454,7 @@ continue_statement goto_statement : GOTO IDENTIFIER SEMICOLON { - $$ = new Goto (current_block, (string) $2, lexer.Location); + $$ = new Goto ((string) $2, lexer.Location); } | GOTO CASE constant_expression SEMICOLON { @@ -3970,6 +4500,11 @@ yield_statement $$ = new Yield ((Expression) $3, lexer.Location); } } + | IDENTIFIER RETURN SEMICOLON + { + Report.Error (1627, lexer.Location, "Expression expected after yield return"); + $$ = null; + } | IDENTIFIER BREAK SEMICOLON { string s = (string) $1; @@ -4085,7 +4620,6 @@ catch_clause one.Add (new VariableDeclaration (id, null, loc)); - $1 = current_block; current_block = new Block (current_block); Block b = declare_local_variables (type, one, loc); current_block = b; @@ -4100,17 +4634,14 @@ catch_clause type = (Expression) cc.Key; id = (string) cc.Value; - if ($1 != null){ - // - // FIXME: I can change this for an assignment. - // - while (current_block != (Block) $1) + if (id != null){ + while (current_block.Implicit) current_block = current_block.Parent; + current_block = current_block.Parent; } } - - $$ = new Catch (type, id , (Block) $4, ((Block) $4).loc); + $$ = new Catch (type, id, (Block) $4, ((Block) $4).loc); } ; @@ -4145,7 +4676,7 @@ unsafe_statement { if (!RootContext.Unsafe){ Report.Error (227, lexer.Location, - "Unsafe code can only be used if --unsafe is used"); + "Unsafe code can only be used if -unsafe is used"); } } block { $$ = new Unsafe ((Block) $3); @@ -4155,7 +4686,7 @@ unsafe_statement fixed_statement : FIXED OPEN_PARENS type fixed_pointer_declarators - CLOSE_PARENS + CLOSE_PARENS _mark_ { ArrayList list = (ArrayList) $4; Expression type = (Expression) $3; @@ -4169,26 +4700,24 @@ fixed_statement Pair p = (Pair) list [i]; LocalInfo v; - v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l); + v = current_block.AddVariable (type, (string) p.First, l); if (v == null) continue; - v.ReadOnly = true; + v.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed); v.Pinned = true; p.First = v; list [i] = p; } - - oob_stack.Push (l); } embedded_statement { - Location l = (Location) oob_stack.Pop (); + Location l = (Location) $6; - Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l); + Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $8, l); - if (RootContext.WarningLevel >= 3){ - if ($7 == EmptyStatement.Value) + if (RootContext.WarningLevel >= 4){ + if ($8 == EmptyStatement.Value) Report.Warning (642, lexer.Location, "Possible mistaken empty statement"); } @@ -4240,13 +4769,11 @@ lock_statement ; using_statement - : USING OPEN_PARENS resource_acquisition CLOSE_PARENS + : USING OPEN_PARENS resource_acquisition CLOSE_PARENS _mark_ { Block assign_block = new Block (current_block); current_block = assign_block; - oob_stack.Push (lexer.Location); - if ($3 is DictionaryEntry){ DictionaryEntry de = (DictionaryEntry) $3; Location l = lexer.Location; @@ -4258,12 +4785,10 @@ using_statement foreach (VariableDeclaration decl in var_declarators){ - LocalInfo vi = current_block.AddVariable ( - type, decl.identifier, - current_local_parameters, decl.Location); + LocalInfo vi = current_block.AddVariable (type, decl.identifier, decl.Location); if (vi == null) continue; - vi.ReadOnly = true; + vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using); Expression expr; if (decl.expression_or_array_initializer is Expression){ @@ -4290,12 +4815,17 @@ using_statement // Assign a = new Assign (var, expr, decl.Location); // assign_block.AddStatement (new StatementExpression (a, lexer.Location)); } - $3 = new DictionaryEntry (type, vars); + + // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal. + // It can be referred to as $6 below. + $$ = new DictionaryEntry (type, vars); + } else { + $$ = $3; } } embedded_statement { - Using u = new Using ($3, (Statement) $6, (Location) oob_stack.Pop ()); + Using u = new Using ($6, (Statement) $7, (Location) $5); current_block.AddStatement (u); while (current_block.Implicit) current_block = current_block.Parent; @@ -4309,6 +4839,11 @@ resource_acquisition | expression ; +// Utility rule to save location information +_mark_ + : /* empty */ + { $$ = lexer.Location; } + %% // @@ -4319,6 +4854,7 @@ public class VariableDeclaration { public object expression_or_array_initializer; public Location Location; public Attributes OptAttributes; + public string DocComment; public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) { @@ -4341,13 +4877,19 @@ public class InterfaceAccessorInfo { public readonly Accessor Get, Set; public InterfaceAccessorInfo (bool has_get, bool has_set, - Attributes get_attrs, Attributes set_attrs, Location get_loc, Location set_loc) + Attributes get_attrs, Attributes set_attrs, int get_mod, int set_mod, Location get_loc, Location set_loc) { + if (get_mod != 0) + Report.Error (275, get_loc, "Accessibility modifiers can not be used on accessors in interfaces"); + if (set_mod != 0) + Report.Error (275, set_loc, "Accessibility modifiers can not be used on accessors in interfaces"); + if (has_get) - Get = new Accessor (null, get_attrs, get_loc); + Get = new Accessor (null, 0, get_attrs, get_loc); if (has_set) - Set = new Accessor (null, set_attrs, set_loc); + Set = new Accessor (null, 0, set_attrs, set_loc); } + } @@ -4420,6 +4962,23 @@ void Error_ExpectingTypeName (Location l, Expression expr) } } +TypeContainer pop_current_class () +{ + TypeContainer 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; + + return retval; +} + // // Given the @class_name name, it creates a fully qualified name // based on the containing declaration space @@ -4427,11 +4986,11 @@ void Error_ExpectingTypeName (Location l, Expression expr) MemberName MakeName (MemberName class_name) { - string ns = current_namespace.FullName; + Namespace ns = current_namespace.NS; if (current_container.Name == ""){ - if (ns != "") - return new MemberName (new MemberName (ns), class_name); + if (ns.Name != "") + return new MemberName (ns.MemberName, class_name); else return class_name; } else { @@ -4466,7 +5025,7 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators, foreach (VariableDeclaration decl in variable_declarators){ - if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) { + if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) { if (decl.expression_or_array_initializer != null){ if (inits == null) inits = new ArrayList (4); @@ -4512,8 +5071,7 @@ Block declare_local_constants (Expression type, ArrayList declarators) implicit_block = current_block; foreach (VariableDeclaration decl in declarators){ - implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer, - current_local_parameters, decl.Location); + implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer, decl.Location); } return implicit_block; @@ -4592,11 +5150,6 @@ void syntax_error (Location l, string msg) Report.Error (1003, l, "Syntax error, " + msg); } -void output (string s) -{ - Console.WriteLine (s); -} - void note (string s) { // Used to put annotations @@ -4616,6 +5169,8 @@ public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList def 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 (); @@ -4626,21 +5181,23 @@ public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList def public void parse () { try { - if (yacc_verbose_flag) + if (yacc_verbose_flag > 1) yyparse (lexer, new yydebug.yyDebugSimple ()); else yyparse (lexer); Tokenizer tokenizer = lexer as Tokenizer; - tokenizer.cleanup (); + tokenizer.cleanup (); } catch (Exception e){ // // Removed for production use, use parser verbose to get the output. // // Console.WriteLine (e); Report.Error (-25, lexer.Location, "Parsing error"); - if (Driver.parser_verbose) + if (yacc_verbose_flag > 0) Console.WriteLine (e); } + + RootContext.Tree.Types.NamespaceEntry = null; } void CheckToken (int error, int yyToken, string msg) @@ -4657,5 +5214,13 @@ void CheckIdentifierToken (int yyToken) CheckToken (1041, yyToken, "Identifier expected"); } +string ConsumeStoredComment () +{ + string s = tmpComment; + tmpComment = null; + Lexer.doc_state = XmlCommentState.Allowed; + return s; +} + /* end end end */ }