X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fcs-parser.jay;h=06a28d3720836dc77878610a274d24e38e913586;hb=60e8d68027b115d6b4c1df3e179bb0cd7b5ee171;hp=112788986c9d52bac6f08d7b0e8de11dfebd1320;hpb=ca1ca15642673854814f48dc4bef71dbb0f7a97c;p=mono.git diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay old mode 100755 new mode 100644 index 112788986c9..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 @@ -32,6 +33,7 @@ namespace Mono.CSharp public class CSharpParser { NamespaceEntry current_namespace; TypeContainer current_container; + TypeContainer current_class; IIteratorContainer iterator_container; @@ -39,22 +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; - - /// - /// - /// Current interface is used by the various declaration - /// productions in the interface declaration to "add" - /// the interfaces as we find them. - /// - Interface current_interface; + Block current_block, top_current_block; Delegate current_delegate; @@ -88,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; @@ -97,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 @@ -197,6 +192,7 @@ namespace Mono.CSharp %token WHERE %token WHILE %token ARGLIST +%token PARTIAL /* C# keywords which are not really keywords */ %token GET "get" @@ -270,6 +266,7 @@ namespace Mono.CSharp %token CLOSE_PARENS_OPEN_PARENS %token CLOSE_PARENS_MINUS %token DEFAULT_OPEN_PARENS +%token GENERIC_DIMENSION /* Add precedence rules to solve dangling else s/r conflict */ %nonassoc LOWPREC @@ -302,7 +299,13 @@ compilation_unit opt_EOF : /* empty */ + { + Lexer.check_incorrect_doc_comment (); + } | EOF + { + Lexer.check_incorrect_doc_comment (); + } ; outer_declarations @@ -322,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 @@ -339,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); } ; @@ -349,15 +360,20 @@ using_namespace_directive // detach them // namespace_declaration - : opt_attributes NAMESPACE namespace_name + : 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"); } - current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3, lexer.Location); - } + MemberName name = (MemberName) $3; + + if (name.TypeArguments != null) + syntax_error (lexer.Location, "namespace name expected"); + + current_namespace = new NamespaceEntry ( + current_namespace, file, name.GetName (), lexer.Location); + } namespace_body opt_semicolon { current_namespace = current_namespace.Parent; @@ -381,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 @@ -412,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; } @@ -475,7 +481,7 @@ global_attributes } opt_attributes - : /* empty */ + : /* empty */ { global_attrs_enabled = false; $$ = null; @@ -485,7 +491,7 @@ opt_attributes global_attrs_enabled = false; $$ = $1; } - ; + ; attribute_sections @@ -496,16 +502,23 @@ attribute_sections if (global_attrs_enabled) { if (current_attr_target == "module") { CodeGen.Module.AddAttributes (sect); - $$ = null; + $$ = null; } else if (current_attr_target == "assembly") { CodeGen.Assembly.AddAttributes (sect); - $$ = null; + $$ = null; } else { $$ = new Attributes (sect); - } + } + if ($$ == null) { + if (RootContext.Documentation != null) { + Lexer.check_incorrect_doc_comment (); + Lexer.doc_state = + XmlCommentState.Allowed; + } + } } else { $$ = new Attributes (sect); - } + } current_attr_target = null; } | attribute_sections attribute_section @@ -525,13 +538,13 @@ attribute_sections attrs = new Attributes (sect); else attrs.AddAttributes (sect); - } + } } else { if (attrs == null) attrs = new Attributes (sect); else attrs.AddAttributes (sect); - } + } $$ = attrs; current_attr_target = null; } @@ -591,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); } ; @@ -688,6 +705,11 @@ named_argument_list $$ = args; } + | named_argument_list COMMA expression + { + Report.Error (1016, lexer.Location, "Named attribute argument expected"); + $$ = null; + } ; named_argument @@ -731,43 +753,67 @@ class_member_declaration struct_declaration : opt_attributes opt_modifiers - STRUCT member_name + opt_partial + STRUCT + { + lexer.ConstraintsParsing = true; + } + member_name { - Struct new_struct; - MemberName full_struct_name = MakeName ((MemberName) $4); + MemberName name = MakeName ((MemberName) $6); + bool partial = (bool) $3; - new_struct = new Struct (current_namespace, current_container, full_struct_name, - (int) $2, (Attributes) $1, lexer.Location); - current_container = new_struct; - RootContext.Tree.RecordDecl (full_struct_name.GetName (true), new_struct); - lexer.ConstraintsParsing = true; + if (partial) { + ClassPart part = PartialContainer.CreatePart ( + 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_class, name, (int) $2, + (Attributes) $1, lexer.Location); + + current_container.AddClassOrStruct (current_class); + current_container = current_class; + RootContext.Tree.RecordDecl (name, current_class); + } } opt_class_base opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; + + if ($8 != null) + current_class.Bases = (ArrayList) $8; + + current_class.SetParameterInfo ((ArrayList) $9); + + if (RootContext.Documentation != null) + current_class.DocComment = Lexer.consume_doc_comment (); } struct_body + { + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } opt_semicolon { - Struct new_struct = (Struct) current_container; - - CheckDef (new_struct.SetParameterInfo ((ArrayList) $7), new_struct.Name, new_struct.Location); - - if ($6 != null) - new_struct.Bases = (ArrayList) $6; - - current_container = current_container.Parent; - CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location); - $$ = new_struct; + $$ = pop_current_class (); } - | opt_attributes opt_modifiers STRUCT error { + | opt_attributes opt_modifiers opt_partial STRUCT error { CheckIdentifierToken (yyToken); } ; 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 @@ -806,15 +852,24 @@ constant_declaration constant_declarators SEMICOLON { + int modflags = (int) $2; foreach (VariableDeclaration constant in (ArrayList) $5){ Location l = constant.Location; + if ((modflags & Modifiers.STATIC) != 0) { + Report.Error (504, l, "The constant '{0}' cannot be marked static", current_container.GetSignatureForError () + '.' + (string) constant.identifier); + continue; + } Const c = new Const ( - (Expression) $4, (string) constant.identifier, - (Expression) constant.expression_or_array_initializer, (int) $2, + current_class, (Expression) $4, (string) constant.identifier, + (Expression) constant.expression_or_array_initializer, modflags, (Attributes) $1, l); - CheckDef (current_container.AddConstant (c), c.Name, l); + if (RootContext.Documentation != null) { + c.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + current_container.AddConstant (c); } } ; @@ -823,14 +878,16 @@ constant_declarators : constant_declarator { ArrayList constants = new ArrayList (4); - constants.Add ($1); + if ($1 != null) + constants.Add ($1); $$ = constants; } | constant_declarators COMMA constant_declarator { - ArrayList constants = (ArrayList) $1; - - constants.Add ($3); + if ($3 != null) { + ArrayList constants = (ArrayList) $1; + constants.Add ($3); + } } ; @@ -839,6 +896,12 @@ constant_declarator { $$ = new VariableDeclaration ((string) $1, $3, lexer.Location); } + | IDENTIFIER + { + // A const field requires a value to be provided + Report.Error (145, lexer.Location, "A const field requires a value to be provided"); + $$ = null; + } ; field_declaration @@ -852,15 +915,38 @@ field_declaration int mod = (int) $2; foreach (VariableDeclaration var in (ArrayList) $4){ - Location l = var.Location; - - Field field = new Field (type, mod, var.identifier, + Field field = new Field (current_class, type, mod, var.identifier, var.expression_or_array_initializer, - (Attributes) $1, l); + (Attributes) $1, var.Location); - CheckDef (current_container.AddField (field), field.Name, l); + 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 @@ -870,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 @@ -894,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 @@ -909,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 { @@ -935,30 +1057,14 @@ method_declaration } } - method.Block = (Block) $3; - CheckDef (current_container.AddMethod (method), method.Name, method.Location); + 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; } ; @@ -984,20 +1090,20 @@ method_header GenericMethod generic = null; if (name.TypeArguments != null) { - generic = new GenericMethod (current_namespace, current_container, + generic = new GenericMethod (current_namespace, current_class, name, lexer.Location); - CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location); + generic.SetParameterInfo ((ArrayList) $9); + } - method = new Method (generic, (Expression) $3, (int) $2, false, name, - (Parameters) $6, (Attributes) $1, lexer.Location); - } else - method = new Method (current_container, (Expression) $3, (int) $2, - false, name, (Parameters) $6, (Attributes) $1, - lexer.Location); + method = new Method (current_class, generic, (Expression) $3, (int) $2, false, + name, (Parameters) $6, (Attributes) $1, lexer.Location); current_local_parameters = (Parameters) $6; + if (RootContext.Documentation != null) + method.DocComment = Lexer.consume_doc_comment (); + $$ = method; } | opt_attributes @@ -1020,22 +1126,21 @@ method_header Method method; GenericMethod generic = null; if (name.TypeArguments != null) { - generic = new GenericMethod (current_namespace, current_container, + generic = new GenericMethod (current_namespace, current_class, name, lexer.Location); + generic.SetParameterInfo ((ArrayList) $9); + } - CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location); - - method = new Method (generic, TypeManager.system_void_expr, (int) $2, - false, name, (Parameters) $6, (Attributes) $1, - lexer.Location); - } else - method = new Method (current_container, TypeManager.system_void_expr, - (int) $2, false, name, (Parameters) $6, - (Attributes) $1, lexer.Location); + method = new Method (current_class, generic, TypeManager.system_void_expr, + (int) $2, false, name, (Parameters) $6, (Attributes) $1, + lexer.Location); current_local_parameters = (Parameters) $6; + if (RootContext.Documentation != null) + method.DocComment = Lexer.consume_doc_comment (); + $$ = method; } | opt_attributes @@ -1048,11 +1153,15 @@ method_header Modifiers.Name ((int) $4))); MemberName name = (MemberName) $4; - Method method = new Method (current_container, TypeManager.system_void_expr, + Method method = new Method (current_class, null, TypeManager.system_void_expr, 0, false, name, (Parameters) $6, (Attributes) $1, lexer.Location); current_local_parameters = (Parameters) $6; + + if (RootContext.Documentation != null) + method.DocComment = Lexer.consume_doc_comment (); + $$ = method; } ; @@ -1075,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 { @@ -1084,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 { @@ -1093,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); } ; @@ -1128,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 @@ -1137,6 +1271,16 @@ fixed_parameter CheckIdentifierToken (yyToken); $$ = null; } + | opt_attributes + opt_parameter_modifier + type + IDENTIFIER + ASSIGN + constant_expression + { + Report.Error (241, lexer.Location, "Default parameter specifiers are not permitted"); + $$ = null; + } ; opt_parameter_modifier @@ -1152,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; @@ -1164,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; @@ -1178,53 +1332,69 @@ 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) $7; MemberName name = (MemberName) $4; + if (name.TypeArguments != null) syntax_error (lexer.Location, "a property can't have type arguments"); - Location loc = (Location) $6; - 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 (); - CheckDef (current_container.AddProperty (prop), prop.Name, loc); + 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 @@ -1236,24 +1406,33 @@ get_accessor_declaration } accessor_body { - $$ = new Accessor ((Block) $4, (Attributes) $1); + 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; @@ -1266,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); + 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; } ; @@ -1287,42 +1475,58 @@ accessor_body interface_declaration : opt_attributes opt_modifiers - INTERFACE member_name + opt_partial + INTERFACE + { + lexer.ConstraintsParsing = true; + } + member_name { - Interface new_interface; - MemberName full_interface_name = MakeName ((MemberName) $4); + MemberName name = MakeName ((MemberName) $6); + bool partial = (bool) $3; - new_interface = new Interface (current_namespace, current_container, full_interface_name, - (int) $2, (Attributes) $1, lexer.Location); - if (current_interface != null) { - Location l = lexer.Location; - Report.Error (-2, l, "Internal compiler error: interface inside interface"); + if (partial) { + ClassPart part = PartialContainer.CreatePart ( + 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_class, name, (int) $2, + (Attributes) $1, lexer.Location); + + current_container.AddInterface (current_class); + current_container = current_class; + RootContext.Tree.RecordDecl (name, current_class); } - current_interface = new_interface; - current_container = new_interface; - RootContext.Tree.RecordDecl ( - full_interface_name.GetName (true), new_interface); - lexer.ConstraintsParsing = true; } opt_class_base opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; - } - interface_body opt_semicolon - { - Interface new_interface = (Interface) current_interface; - CheckDef (new_interface.SetParameterInfo ((ArrayList) $7), new_interface.Name, new_interface.Location); - if ($6 != null) - new_interface.Bases = (ArrayList) $6; + if ($8 != null) + current_class.Bases = (ArrayList) $8; + + current_class.SetParameterInfo ((ArrayList) $9); - current_interface = null; - current_container = current_container.Parent; - CheckDef (current_container.AddInterface (new_interface), - new_interface.Name, new_interface.Location); + if (RootContext.Documentation != null) { + current_class.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + } + interface_body + { + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + } + opt_semicolon + { + $$ = pop_current_class (); } - | opt_attributes opt_modifiers INTERFACE error { + | opt_attributes opt_modifiers opt_partial INTERFACE error { CheckIdentifierToken (yyToken); } ; @@ -1346,28 +1550,90 @@ interface_member_declarations interface_member_declaration : interface_method_declaration { + if ($1 == null) + break; + Method m = (Method) $1; - CheckDef (current_interface.AddMethod (m), m.Name, m.Location); + 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; - CheckDef (current_interface.AddProperty (p), p.Name, p.Location); - } + 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; - CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location); + + 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; - current_interface.AddIndexer (i); + 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"); } ; @@ -1399,17 +1665,16 @@ interface_method_declaration GenericMethod generic = null; if (name.TypeArguments != null) { - generic = new GenericMethod (current_namespace, current_container, + generic = new GenericMethod (current_namespace, current_class, name, lexer.Location); - CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location); + generic.SetParameterInfo ((ArrayList) $9); + } - $$ = new Method (generic, (Expression) $3, (int) $2, true, name, - (Parameters) $6, (Attributes) $1, lexer.Location); - } else - $$ = new Method (current_container, (Expression) $3, (int) $2, true, - name, (Parameters) $6, (Attributes) $1, - lexer.Location); + $$ = 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 @@ -1429,19 +1694,30 @@ interface_method_declaration GenericMethod generic = null; if (name.TypeArguments != null) { - generic = new GenericMethod (current_namespace, current_container, + generic = new GenericMethod (current_namespace, current_class, name, lexer.Location); - CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location); + generic.SetParameterInfo ((ArrayList) $9); + } - $$ = new Method (generic, TypeManager.system_void_expr, (int) $2, - true, name, (Parameters) $6, (Attributes) $1, - lexer.Location); - } else - $$ = new Method (current_container, TypeManager.system_void_expr, - (int) $2, true, name, (Parameters) $6, - (Attributes) $1, lexer.Location); + $$ = 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 @@ -1454,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_container, (Expression) $3, (int) $2, true, + $$ = 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 @@ -1469,20 +1755,33 @@ interface_property_declaration ; interface_accessors - : opt_attributes GET SEMICOLON { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null); } - | opt_attributes SET SEMICOLON { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1); } - | opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON - { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $3); } - | opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON - { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $3, (Attributes) $1); } + : 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 : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON { - $$ = new EventField (current_container, (Expression) $4, (int) $2, true, + $$ = 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); @@ -1492,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; } ; @@ -1507,11 +1814,17 @@ interface_indexer_declaration { lexer.PropertyParsing = false; } CLOSE_BRACE { + if ($10 == null) + break; + InterfaceAccessorInfo info = (InterfaceAccessorInfo) $10; - $$ = new Indexer (current_container, (Expression) $3, (int) $2, true, - MemberName.Null, (Parameters) $6, (Attributes) $1, + $$ = 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 (); } ; @@ -1522,10 +1835,26 @@ operator_declaration } operator_body { + if ($3 == null) + break; + OperatorDeclaration decl = (OperatorDeclaration) $3; - Operator op = new Operator (decl.optype, decl.ret_type, (int) $2, decl.arg1type, decl.arg1name, - decl.arg2type, decl.arg2name, (Block) $5, (Attributes) $1, decl.location); + Parameter [] param_list = new Parameter [decl.arg2type != null ? 2 : 1]; + + 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, decl.location); + + Operator op = new Operator ( + current_class, decl.optype, decl.ret_type, (int) $2, + 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 (); @@ -1556,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); - $$ = new OperatorDeclaration (op, (Expression) $1, (Expression) $5, (string) $6, + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.NotAllowed; + } + + $$ = new OperatorDeclaration (op, (Expression) $1, type, (string) $6, null, null, lexer.Location); } | type OPERATOR overloadable_operator @@ -1570,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]; + Expression typeL = (Expression) $5; + Expression typeR = (Expression) $8; - pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null); - pars [1] = new Parameter ((Expression) $8, (string) $9, Parameter.Modifier.NONE, null); + 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, 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 @@ -1619,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); } @@ -1630,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); } @@ -1654,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){ @@ -1685,28 +2057,33 @@ constructor_declaration } } else { // We let another layer check the validity of the constructor. - Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename); + //Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename); } - CheckDef (current_container.AddConstructor (c), c.Name, c.Location); + 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_container, (string) $1, 0, (Parameters) $3, - (ConstructorInitializer) $6, l); + $$ = new Constructor (current_class, (string) $1, 0, (Parameters) $4, + (ConstructorInitializer) $8, (Location) $6); } ; @@ -1723,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"); @@ -1742,11 +2119,18 @@ opt_finalizer ; destructor_declaration - : opt_attributes opt_finalizer TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block + : opt_attributes opt_finalizer TILDE + { + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.NotAllowed; + } + } + IDENTIFIER OPEN_PARENS CLOSE_PARENS block { - if ((string) $4 != current_container.Basename){ + 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; @@ -1766,21 +2150,15 @@ destructor_declaration } Method d = new Destructor ( - current_container, TypeManager.system_void_expr, m, "Finalize", - new Parameters (null, null, l), (Attributes) $1, l); + current_class, TypeManager.system_void_expr, m, "Finalize", + new Parameters (null, null), (Attributes) $1, l); + if (RootContext.Documentation != null) + d.DocComment = ConsumeStoredComment (); - d.Block = (Block) $7; - CheckDef (current_container.AddMethod (d), d.Name, d.Location); + d.Block = (ToplevelBlock) $8; + current_container.AddMethod (d); } } - | opt_attributes opt_modifiers EVENT type member_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS block { - string mn = (string) $5; - - if (mn.IndexOf ('.') != -1) - Report.Error (71, lexer.Location, "Explicit implementation of events requires property syntax"); - else - Report.Error (71, lexer.Location, "Event declaration should use property syntax"); - } ; event_declaration @@ -1792,23 +2170,26 @@ event_declaration MemberName name = new MemberName (var.identifier); - Event e = new EventField (current_container, (Expression) $4, (int) $2, - false, name, - var.expression_or_array_initializer, - (Attributes) $1, lexer.Location); + Event e = new EventField ( + current_class, (Expression) $4, (int) $2, false, name, + var.expression_or_array_initializer, (Attributes) $1, + lexer.Location); - CheckDef (current_container.AddEvent (e), e.Name, e.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 { @@ -1816,26 +2197,42 @@ 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; - - MemberName name = (MemberName) $5; - if (name.TypeArguments != null) - syntax_error (lexer.Location, "an event can't have type arguments"); + Pair pair = (Pair) $9; + + MemberName name = (MemberName) $5; + + if (name.TypeArguments != null) + syntax_error (lexer.Location, "an event can't have type arguments"); + + Event e = new EventProperty ( + 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; + } - Event e = new EventProperty (current_container, (Expression) $4, (int) $2, - false, name, null, (Attributes) $1, - (Accessor) pair.First, (Accessor) pair.Second, - loc); - - CheckDef (current_container.AddEvent (e), e.Name, loc); - implicit_value_parameter_type = null; + current_container.AddEvent (e); + implicit_value_parameter_type = null; + } } + | opt_attributes opt_modifiers EVENT type namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS block { + MemberName mn = (MemberName) $5; + + if (mn.Left != null) + 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; } ; @@ -1850,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 @@ -1858,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); + $$ = 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 @@ -1882,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); + $$ = 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; @@ -1912,37 +2323,40 @@ 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; MemberName name; if (decl.interface_type != null) - name = new MemberName (decl.interface_type, "", null); + name = new MemberName (decl.interface_type, + TypeContainer.DefaultIndexerName, null); else - name = MemberName.Null; + name = new MemberName (TypeContainer.DefaultIndexerName); - indexer = new Indexer (current_container, decl.type, (int) $2, false, - name, decl.param_list, (Attributes) $1, + 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 (); - // Note that there is no equivalent of CheckDef for this case - // We shall handle this in semantic analysis - current_container.AddIndexer (indexer); current_local_parameters = null; @@ -1955,10 +2369,16 @@ indexer_declarator : type THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET { Parameters pars = (Parameters) $4; - - if (pars.FixedParameters == null && pars.ArrayParameter == null){ + if (pars.HasArglist) { + // "__arglist is not valid in this context" + Report.Error (1669, lexer.Location, "__arglist is not valid in this context"); + } 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); } @@ -1966,43 +2386,62 @@ indexer_declarator { Parameters pars = (Parameters) $6; - if (pars.FixedParameters == null && pars.ArrayParameter == null){ + if (pars.HasArglist) { + // "__arglist is not valid in this context" + Report.Error (1669, lexer.Location, "__arglist is not valid in this context"); + } 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) { - Location loc = (Location) ev.Location; - - CheckDef (e.AddEnumMember (ev.identifier, - (Expression) ev.expression_or_array_initializer, - loc, ev.OptAttributes), - ev.identifier, loc); + 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.DocComment); } - string name = full_name.GetName (false); - CheckDef (current_container.AddEnum (e), name, enum_location); + current_container.AddEnum (e); RootContext.Tree.RecordDecl (name, e); + $$ = e; } ; @@ -2013,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; } ; @@ -2045,34 +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; - Delegate del = new Delegate ( - current_namespace, current_container, (Expression) $4, (int) $2, - MakeName ((MemberName) $5), (Parameters) $7, (Attributes) $1, l); - - CheckDef (current_container.AddDelegate (del), del.Name, l); + MemberName name = MakeName ((MemberName) $6); + Delegate del = new Delegate (current_namespace, current_class, (Expression) $5, + (int) $2, name, (Parameters) $8, (Attributes) $1, l); - current_delegate = del; + if (RootContext.Documentation != null) { + del.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } - lexer.ConstraintsParsing = true; + current_container.AddDelegate (del); + RootContext.Tree.RecordDecl (name, del); + + current_delegate = del; } opt_type_parameter_constraints_clauses { @@ -2080,36 +2554,23 @@ delegate_declaration } SEMICOLON { - CheckDef (current_delegate.SetParameterInfo ((ArrayList) $9), current_delegate.Name, current_delegate.Location); + 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; - Delegate del = new Delegate ( - current_namespace, current_container, - TypeManager.system_void_expr, (int) $2, MakeName ((MemberName) $5), - (Parameters) $7, (Attributes) $1, l); - - CheckDef (current_container.AddDelegate (del), del.Name, l); - - current_delegate = del; + ; - lexer.ConstraintsParsing = true; - } - opt_type_parameter_constraints_clauses +opt_nullable + : /* empty */ { - lexer.ConstraintsParsing = false; + lexer.CheckNullable (false); + $$ = false; } - SEMICOLON + | INTERR { - CheckDef (current_delegate.SetParameterInfo ((ArrayList) $9), current_delegate.Name, current_delegate.Location); - - current_delegate = null; + lexer.CheckNullable (true); + $$ = true; } ; @@ -2132,6 +2593,10 @@ opt_type_argument_list { $$ = $2; } + | GENERIC_DIMENSION + { + $$ = new TypeArguments ((int) $1, lexer.Location); + } ; type_arguments @@ -2154,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 { @@ -2181,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); @@ -2254,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); } ; @@ -2268,8 +2747,7 @@ primary_expression { // 7.5.1: Literals } - - | member_name + | member_name { $$ = ((MemberName) $1).GetTypeExpression (lexer.Location); } @@ -2394,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 @@ -2424,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); } @@ -2464,7 +2961,7 @@ element_access // Foo.Bar.Blah i; // SimpleName is when you have // Blah i; - + Expression expr = (Expression) $1; if (expr is ComposedCast){ $$ = new ComposedCast (expr, (string) $2, lexer.Location); @@ -2513,7 +3010,7 @@ base_access $$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location); } | BASE error { - Report.Error (175, "Use of keyword `base' is not valid in this context"); + Report.Error (175, lexer.Location, "Use of keyword `base' is not valid in this context"); $$ = null; } ; @@ -2557,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"); @@ -2574,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 { @@ -2648,15 +3175,35 @@ 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 type CLOSE_PARENS + | TYPEOF OPEN_PARENS void_pointer_expression CLOSE_PARENS { $$ = new TypeOf ((Expression) $3, lexer.Location); } + | TYPEOF OPEN_PARENS + { + lexer.TypeOfParsing = true; + } + type CLOSE_PARENS + { + lexer.TypeOfParsing = false; + $$ = new TypeOf ((Expression) $4, lexer.Location); + } ; sizeof_expression @@ -2690,29 +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; - Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2"); - if (!RootContext.V2){ - Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2"); + + // 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 ; @@ -2725,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); } } ; @@ -2752,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; } ; @@ -2892,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 @@ -2914,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); } ; @@ -2989,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 @@ -3087,44 +3684,79 @@ boolean_expression class_declaration : opt_attributes opt_modifiers - CLASS member_name + opt_partial + CLASS + { + lexer.ConstraintsParsing = true; + } + member_name { - Class new_class; + MemberName name = MakeName ((MemberName) $6); + bool partial = (bool) $3; + int mod_flags = (int) $2; - MemberName name = MakeName ((MemberName) $4); + if (partial) { + ClassPart part = PartialContainer.CreatePart ( + current_namespace, current_class, name, mod_flags, + (Attributes) $1, Kind.Class, lexer.Location); - new_class = new Class (current_namespace, current_container, name, (int) $2, - (Attributes) $1, lexer.Location); - current_container = new_class; - RootContext.Tree.RecordDecl (name.GetName (true), new_class); + 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, lexer.Location); + } else { + current_class = new Class ( + current_namespace, current_class, name, + mod_flags, (Attributes) $1, lexer.Location); + } - lexer.ConstraintsParsing = true; + current_container.AddClassOrStruct (current_class); + current_container = current_class; + RootContext.Tree.RecordDecl (name, current_class); + } } opt_class_base opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; - } - class_body - opt_semicolon - { - Class new_class = (Class) current_container; - CheckDef (new_class.SetParameterInfo ((ArrayList) $7), new_class.Name, new_class.Location); - if ($6 != null) { - if (new_class.Name == "System.Object") { - Report.Error (537, new_class.Location, "The class System.Object cannot have a base class or implement an interface."); + 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."); } - - new_class.Bases = (ArrayList) $6; + current_class.Bases = (ArrayList) $8; } - current_container = current_container.Parent; - CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location); - $$ = new_class; + current_class.SetParameterInfo ((ArrayList) $9); + + 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; + } + opt_semicolon + { + $$ = pop_current_class (); } ; +opt_partial + : /* empty */ + { $$ = (bool) false; } + | PARTIAL + { $$ = (bool) true; } + ; + opt_modifiers : /* empty */ { $$ = (int) 0; } | modifiers @@ -3240,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 @@ -3254,6 +3886,8 @@ block $$ = current_block; current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; + if (current_block == null) + top_current_block = null; } ; @@ -3357,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. @@ -3391,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; @@ -3435,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; @@ -3496,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) - Report.Warning (642, lexer.Location, "Possibly mistaken empty statement"); + 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 (); } ; @@ -3630,30 +4249,23 @@ iteration_statement ; while_statement - : WHILE OPEN_PARENS - { - oob_stack.Push (lexer.Location); - } - boolean_expression CLOSE_PARENS embedded_statement + : WHILE OPEN_PARENS _mark_ 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, "Possibly mistaken empty statement"); + Report.Warning (642, lexer.Location, "Possible mistaken empty 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); } @@ -3661,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; @@ -3676,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; @@ -3702,21 +4313,24 @@ 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) - Report.Warning (642, lexer.Location, "Possibly mistaken empty statement"); + if (RootContext.WarningLevel >= 4){ + if ($11 == EmptyStatement.Value) + Report.Warning (642, lexer.Location, "Possible mistaken empty statement"); } current_block.AddStatement (f); @@ -3770,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; } ; @@ -3839,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 { @@ -3873,8 +4488,8 @@ yield_statement Report.Error (1003, lexer.Location, "; expected"); $$ = null; } - if (!RootContext.V2){ - Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode"); + if (RootContext.Version == LanguageVersion.ISO_1){ + Report.FeatureIsNotStandardized (lexer.Location, "yield statement"); $$ = null; } if (iterator_container == null){ @@ -3885,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; @@ -3892,8 +4512,8 @@ yield_statement Report.Error (1003, lexer.Location, "; expected"); $$ = null; } - if (!RootContext.V2){ - Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode"); + if (RootContext.Version == LanguageVersion.ISO_1){ + Report.FeatureIsNotStandardized (lexer.Location, "yield statement"); $$ = null; } if (iterator_container == null){ @@ -3915,19 +4535,23 @@ try_statement : TRY block catch_clauses { Catch g = null; - ArrayList s = new ArrayList (4); - foreach (Catch cc in (ArrayList) $3) { - if (cc.IsGeneral) + ArrayList c = (ArrayList)$3; + for (int i = 0; i < c.Count; ++i) { + Catch cc = (Catch) c [i]; + if (cc.IsGeneral) { + if (i != c.Count - 1) + Report.Error (1017, cc.loc, "Empty catch block must be the last in a series of catch blocks"); g = cc; - else - s.Add (cc); + c.RemoveAt (i); + i--; + } } // Now s contains the list of specific catch clauses // and g contains the general one. - $$ = new Try ((Block) $2, s, g, null, lexer.Location); + $$ = new Try ((Block) $2, c, g, null, ((Block) $2).loc); } | TRY block opt_catch_clauses FINALLY block { @@ -3944,7 +4568,7 @@ try_statement } } - $$ = new Try ((Block) $2, s, g, (Block) $5, lexer.Location); + $$ = new Try ((Block) $2, s, g, (Block) $5, ((Block) $2).loc); } | TRY block error { @@ -3996,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; @@ -4011,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, lexer.Location); + $$ = new Catch (type, id, (Block) $4, ((Block) $4).loc); } ; @@ -4056,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); @@ -4066,49 +4686,61 @@ unsafe_statement fixed_statement : FIXED OPEN_PARENS type fixed_pointer_declarators - CLOSE_PARENS + CLOSE_PARENS _mark_ { - Block assign_block = new Block (current_block, Block.Flags.Implicit); ArrayList list = (ArrayList) $4; Expression type = (Expression) $3; Location l = lexer.Location; int top = list.Count; + Block assign_block = new Block (current_block); + current_block = assign_block; + for (int i = 0; i < top; i++){ 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; } - current_block.AddStatement (assign_block); - current_block = assign_block; - oob_stack.Push (assign_block); - oob_stack.Push (l); } embedded_statement { - Location l = (Location) oob_stack.Pop (); - oob_stack.Pop (); + Location l = (Location) $6; + + Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $8, l); - $$ = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l); + if (RootContext.WarningLevel >= 4){ + if ($8 == EmptyStatement.Value) + Report.Warning (642, lexer.Location, "Possible mistaken empty statement"); + } + + current_block.AddStatement (f); + while (current_block.Implicit) + current_block = current_block.Parent; + $$ = current_block; + current_block = current_block.Parent; } ; fixed_pointer_declarators : fixed_pointer_declarator { - ArrayList declarators = new ArrayList (4); - declarators.Add ($1); + ArrayList declarators = new ArrayList (4); + if ($1 != null) + declarators.Add ($1); $$ = declarators; } | fixed_pointer_declarators COMMA fixed_pointer_declarator { ArrayList declarators = (ArrayList) $1; - declarators.Add ($3); + if ($3 != null) + declarators.Add ($3); $$ = declarators; } ; @@ -4118,6 +4750,11 @@ fixed_pointer_declarator { $$ = new Pair ($1, $3); } + | IDENTIFIER + { + Report.Error (210, lexer.Location, "You must provide an initializer in a fixed or using statement declaration"); + $$ = null; + } ; lock_statement @@ -4132,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; @@ -4150,18 +4785,19 @@ 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){ 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); } @@ -4179,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; @@ -4198,6 +4839,11 @@ resource_acquisition | expression ; +// Utility rule to save location information +_mark_ + : /* empty */ + { $$ = lexer.Location; } + %% // @@ -4208,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) { @@ -4230,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) + 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 = new Accessor (null, 0, get_attrs, get_loc); if (has_set) - Set = new Accessor (null, set_attrs); + Set = new Accessor (null, 0, set_attrs, set_loc); } + } @@ -4309,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 @@ -4316,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 { @@ -4328,57 +4998,6 @@ MakeName (MemberName class_name) } } -// -// Used to report back to the user the result of a declaration -// in the current declaration space -// -void -CheckDef (DeclSpace.AdditionResult result, string name, Location l) -{ - if (result == DeclSpace.AdditionResult.Success) - return; - - switch (result){ - case DeclSpace.AdditionResult.NameExists: - Report.Error (102, l, "The container `" + current_container.Name + - "' already contains a definition for `"+ - name + "'"); - break; - - - // - // This is handled only for static Constructors, because - // in reality we handle these by the semantic analysis later - // - case DeclSpace.AdditionResult.MethodExists: - Report.Error ( - 111, l, "Class `"+current_container.Name+ - "' already defines a member called '" + - name + "' with the same parameter types (more than one default constructor)"); - break; - - case DeclSpace.AdditionResult.EnclosingClash: - Report.Error (542, l, "Member names cannot be the same as their enclosing type"); - break; - - case DeclSpace.AdditionResult.NotAConstructor: - Report.Error (1520, l, "Class, struct, or interface method must have a return type"); - break; - - case DeclSpace.AdditionResult.Error: - // Error has already been reported. - break; - } -} - -void -CheckDef (bool result, string name, Location l) -{ - if (result) - return; - CheckDef (DeclSpace.AdditionResult.NameExists, name, l); -} - Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc) { Block implicit_block; @@ -4406,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); @@ -4452,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; @@ -4532,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 @@ -4556,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 (); @@ -4566,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){ - // Please do not remove this, it is used during debugging - // of the grammar // - Console.WriteLine (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) @@ -4597,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 */ }