X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcs-parser.jay;h=714b381bf53bb1d046d1d41139f0ecb8d7d67b48;hb=9f075fd34a9d9afcc6a4d2fdef6bd8b4200e3a7a;hp=a7f6a1830ad44def51573592ca1c308cb3291edd;hpb=d38a0253749b9a44acda589c728dd8071a701d5f;p=mono.git diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index a7f6a1830ad..714b381bf53 100644 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -6,7 +6,7 @@ // Ravi Pratap (ravi@ximian.com) // Marek Safar (marek.safar@gmail.com) // -// Licensed under the terms of the GNU GPL +// Dual Licensed under the terms of the GNU GPL and the MIT X11 license // // (C) 2001 Ximian, Inc (http://www.ximian.com) // (C) 2004 Novell, Inc @@ -16,26 +16,41 @@ // great spot to put an `error' because you can reproduce it with this input: // "public X { }" // -// Possible optimization: -// Run memory profiler with parsing only, and consider dropping -// arraylists where not needed. Some pieces can use linked lists. - using System.Text; using System.IO; using System; +using System.Collections.Generic; namespace Mono.CSharp { - using System.Collections; - /// /// The C# Parser /// - public class CSharpParser { + public class CSharpParser + { + [Flags] + enum ParameterModifierType + { + Ref = 1 << 1, + Out = 1 << 2, + This = 1 << 3, + Params = 1 << 4, + Arglist = 1 << 5, + DefaultValue = 1 << 6, + + All = Ref | Out | This | Params | Arglist | DefaultValue + } + + static readonly object ModifierNone = 0; + NamespaceEntry current_namespace; TypeContainer current_container; DeclSpace current_class; + PropertyBase current_property; + EventProperty current_event; + EventField current_event_field; + FieldBase current_field; /// /// Current block is used to add statements as we find @@ -45,7 +60,6 @@ namespace Mono.CSharp Delegate current_delegate; - GenericMethod current_generic_method; AnonymousMethodExpression current_anonymous_method; /// @@ -57,37 +71,17 @@ namespace Mono.CSharp // on all places, especially when some parameters are autogenerated. ParametersCompiled current_local_parameters; - /// - /// Using during property parsing to describe the implicit - /// value parameter that is passed to the "set" and "get"accesor - /// methods (properties and indexers). - /// - FullNamedExpression implicit_value_parameter_type; - ParametersCompiled indexer_parameters; - - /// - /// Hack to help create non-typed array initializer - /// - public static FullNamedExpression current_array_type; - FullNamedExpression pushed_current_array_type; - - /// - /// Used to determine if we are parsing the get/set pair - /// of an indexer or a property - /// - bool parsing_indexer; - bool parsing_anonymous_method; /// /// An out-of-band stack. /// - static Stack oob_stack; + static Stack oob_stack; /// /// Switch stack. /// - Stack switch_stack; + Stack switch_stack; /// /// Controls the verbosity of the errors produced by the parser @@ -117,11 +111,10 @@ namespace Mono.CSharp /// assembly and module attribute definitions are enabled bool global_attrs_enabled = true; - bool has_get, has_set; - bool parameter_modifiers_not_allowed; - bool params_modifiers_not_allowed; - bool arglist_allowed; - + + ParameterModifierType valid_param_mod; + + bool default_parameter_used; /// When using the interactive parser, this holds the /// resulting expression @@ -132,11 +125,26 @@ namespace Mono.CSharp // public Undo undo; - // Stack - Stack linq_clause_blocks; + Stack linq_clause_blocks; // A counter to create new class names in interactive mode static int class_count; + + CompilerContext compiler; + + // + // Instead of allocating carrier array everytime we + // share the bucket for very common constructs which can never + // be recursive + // + static List parameters_bucket = new List (6); + static List variables_bucket = new List (6); + + // + // Full AST support members + // + LocationsBag lbag; + List> mod_locations; %} %token EOF @@ -311,26 +319,29 @@ namespace Mono.CSharp %token OP_PTR %token OP_COALESCING -/* Numbers */ -%token LITERAL_INTEGER -%token LITERAL_FLOAT -%token LITERAL_DOUBLE -%token LITERAL_DECIMAL -%token LITERAL_CHARACTER -%token LITERAL_STRING +%token LITERAL %token IDENTIFIER %token OPEN_PARENS_LAMBDA %token OPEN_PARENS_CAST %token GENERIC_DIMENSION %token DEFAULT_COLON +%token OPEN_BRACKET_EXPR // Make the parser go into eval mode parsing (statements and compilation units). %token EVAL_STATEMENT_PARSER %token EVAL_COMPILATION_UNIT_PARSER %token EVAL_USING_DECLARATIONS_UNIT_PARSER +// +// This token is generated to trigger the completion engine at this point +// %token GENERATE_COMPLETION + +// +// This token is return repeatedly after the first GENERATE_COMPLETION +// token is produced and before the final EOF +// %token COMPLETE_COMPLETION /* Add precedence rules to solve dangling else s/r conflict */ @@ -395,15 +406,15 @@ extern_alias_directives extern_alias_directive : EXTERN_ALIAS IDENTIFIER IDENTIFIER SEMICOLON { - LocatedToken lt = (LocatedToken) $2; + var lt = (Tokenizer.LocatedToken) $2; string s = lt.Value; if (s != "alias"){ syntax_error (lt.Location, "`alias' expected"); } else if (RootContext.Version == LanguageVersion.ISO_1) { Report.FeatureIsNotAvailable (lt.Location, "external alias"); } else { - lt = (LocatedToken) $3; - current_namespace.AddUsingExternalAlias (lt.Value, lt.Location); + lt = (Tokenizer.LocatedToken) $3; + current_namespace.AddUsingExternalAlias (lt.Value, lt.Location, Report); } } | EXTERN_ALIAS error @@ -433,8 +444,8 @@ using_directive using_alias_directive : USING IDENTIFIER ASSIGN namespace_or_type_name SEMICOLON { - LocatedToken lt = (LocatedToken) $2; - current_namespace.AddUsingAlias (lt.Value, (MemberName) $4, (Location) $1); + var lt = (Tokenizer.LocatedToken) $2; + current_namespace.AddUsingAlias (lt.Value, (MemberName) $4, GetLocation ($1)); } | USING error { CheckIdentifierToken (yyToken, GetLocation ($2)); @@ -445,7 +456,7 @@ using_alias_directive using_namespace_directive : USING namespace_name SEMICOLON { - current_namespace.AddUsing ((MemberName) $2, (Location) $1); + current_namespace.AddUsing ((MemberName) $2, GetLocation ($1)); } ; @@ -479,17 +490,18 @@ namespace_declaration qualified_identifier : IDENTIFIER { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; $$ = new MemberName (lt.Value, lt.Location); } | qualified_identifier DOT IDENTIFIER { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberName ((MemberName) $1, lt.Value, lt.Location); } | error { syntax_error (lexer.Location, "`.' expected"); + $$ = new MemberName ("", lexer.Location); } ; @@ -613,7 +625,7 @@ global_attributes if ($1 != null) { Attributes attrs = (Attributes)$1; if (global_attrs_enabled) { - CodeGen.Assembly.AddAttributes (attrs.Attrs); + CodeGen.Assembly.AddAttributes (attrs.Attrs, current_namespace); } else { foreach (Attribute a in attrs.Attrs) { Report.Error (1730, a.Location, "Assembly and module attributes must precede all other elements except using clauses and extern alias declarations"); @@ -642,14 +654,14 @@ attribute_sections : attribute_section { if (current_attr_target != String.Empty) { - ArrayList sect = (ArrayList) $1; + var sect = (List) $1; if (global_attrs_enabled) { if (current_attr_target == "module") { - current_container.Module.AddAttributes (sect); + current_container.Module.Compiled.AddAttributes (sect); $$ = null; } else if (current_attr_target != null && current_attr_target.Length > 0) { - CodeGen.Assembly.AddAttributes (sect); + CodeGen.Assembly.AddAttributes (sect, current_namespace); $$ = null; } else { $$ = new Attributes (sect); @@ -673,14 +685,14 @@ attribute_sections { if (current_attr_target != String.Empty) { Attributes attrs = $1 as Attributes; - ArrayList sect = (ArrayList) $2; + var sect = (List) $2; if (global_attrs_enabled) { if (current_attr_target == "module") { - current_container.Module.AddAttributes (sect); + current_container.Module.Compiled.AddAttributes (sect); $$ = null; } else if (current_attr_target == "assembly") { - CodeGen.Assembly.AddAttributes (sect); + CodeGen.Assembly.AddAttributes (sect, current_namespace); $$ = null; } else { if (attrs == null) @@ -724,7 +736,7 @@ attribute_target_specifier attribute_target : IDENTIFIER { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; $$ = CheckAttributeTarget (lt.Value, lt.Location); } | EVENT { $$ = "event"; } @@ -739,16 +751,12 @@ attribute_target attribute_list : attribute { - ArrayList attrs = new ArrayList (4); - attrs.Add ($1); - - $$ = attrs; - + $$ = new List (4) { (Attribute) $1 }; } | attribute_list COMMA attribute { - ArrayList attrs = (ArrayList) $1; - attrs.Add ($3); + var attrs = (List) $1; + attrs.Add ((Attribute) $3); $$ = attrs; } @@ -759,7 +767,7 @@ attribute { ++lexer.parsing_block; } - opt_attribute_arguments + opt_attribute_arguments { --lexer.parsing_block; MemberName mname = (MemberName) $1; @@ -768,20 +776,17 @@ attribute "'<' unexpected: attributes cannot be generic"); } - object [] arguments = (object []) $3; - MemberName left = mname.Left; - string identifier = mname.Name; - - Expression left_expr = left == null ? null : left.GetTypeExpression (); + Arguments [] arguments = (Arguments []) $3; + ATypeNameExpression expr = mname.GetTypeExpression (); if (current_attr_target == String.Empty) $$ = null; else if (global_attrs_enabled && (current_attr_target == "assembly" || current_attr_target == "module")) // FIXME: supply "nameEscaped" parameter here. $$ = new GlobalAttribute (current_namespace, current_attr_target, - left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location)); + expr, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location)); else - $$ = new Attribute (current_attr_target, left_expr, identifier, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location)); + $$ = new Attribute (current_attr_target, expr, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location)); } ; @@ -799,84 +804,91 @@ opt_attribute_arguments attribute_arguments - : opt_positional_argument_list + : /* empty */ { $$ = null; } + | positional_or_named_argument { - if ($1 == null) - $$ = null; - else { - $$ = new object [] { $1, null }; - } + Arguments a = new Arguments (4); + a.Add ((Argument) $1); + $$ = new Arguments [] { a, null }; } - | positional_argument_list COMMA named_argument_list + | named_attribute_argument { - $$ = new object[] { $1, $3 }; + Arguments a = new Arguments (4); + a.Add ((Argument) $1); + $$ = new Arguments [] { null, a }; } - | named_argument_list + | attribute_arguments COMMA positional_or_named_argument { - $$ = new object [] { null, $1 }; + Arguments[] o = (Arguments[]) $1; + if (o [1] != null) { + Report.Error (1016, ((Argument) $3).Expr.Location, "Named attribute arguments must appear after the positional arguments"); + o [0] = new Arguments (4); + } + + Arguments args = ((Arguments) o [0]); + if (args.Count > 0 && !($3 is NamedArgument) && args [args.Count - 1] is NamedArgument) + Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]); + + args.Add ((Argument) $3); } - ; - - -opt_positional_argument_list - : /* empty */ { $$ = null; } - | positional_argument_list - ; - -positional_argument_list - : expression + | attribute_arguments COMMA named_attribute_argument { - ArrayList args = new ArrayList (4); - args.Add (new Argument ((Expression) $1, Argument.AType.Expression)); + Arguments[] o = (Arguments[]) $1; + if (o [1] == null) { + o [1] = new Arguments (4); + } - $$ = args; + ((Arguments) o [1]).Add ((Argument) $3); } - | positional_argument_list COMMA expression - { - ArrayList args = (ArrayList) $1; - args.Add (new Argument ((Expression) $3, Argument.AType.Expression)); - - $$ = args; - } - ; + ; -named_argument_list - : named_argument +positional_or_named_argument + : expression { - ArrayList args = new ArrayList (4); - args.Add ($1); - - $$ = args; + $$ = new Argument ((Expression) $1); } - | named_argument_list COMMA named_argument - { - ArrayList args = (ArrayList) $1; - args.Add ($3); + | named_argument + ; - $$ = args; +named_attribute_argument + : IDENTIFIER ASSIGN + { + ++lexer.parsing_block; } - | named_argument_list COMMA expression + expression { - Report.Error (1016, ((Expression) $3).Location, "Named attribute argument expected"); - $$ = null; + --lexer.parsing_block; + var lt = (Tokenizer.LocatedToken) $1; + $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4); } ; - + named_argument - : IDENTIFIER ASSIGN expression + : IDENTIFIER COLON opt_named_modifier expression { - // FIXME: keep location - $$ = new DictionaryEntry ( - ((LocatedToken) $1).Value, - new Argument ((Expression) $3, Argument.AType.Expression)); + if (RootContext.Version <= LanguageVersion.V_3) + Report.FeatureIsNotAvailable (GetLocation ($1), "named argument"); + + // Avoid boxing in common case (no modifier) + var arg_mod = $3 == null ? Argument.AType.None : (Argument.AType) $3; + + var lt = (Tokenizer.LocatedToken) $1; + $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4, arg_mod); } ; - - -class_body - : OPEN_BRACE opt_class_member_declarations CLOSE_BRACE + +opt_named_modifier + : /* empty */ { $$ = null; } + | REF + { + $$ = Argument.AType.Ref; + } + | OUT + { + $$ = Argument.AType.Out; + } ; - + opt_class_member_declarations : /* empty */ | class_member_declarations @@ -919,17 +931,19 @@ struct_declaration type_declaration_name { MemberName name = MakeName ((MemberName) $6); - push_current_class (new Struct (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3); + push_current_class (new Struct (current_namespace, current_class, name, (Modifiers) $2, (Attributes) $1), $3); } opt_class_base opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; - current_class.SetParameterInfo ((ArrayList) $9); + current_class.SetParameterInfo ((List) $9); if (RootContext.Documentation != null) current_container.DocComment = Lexer.consume_doc_comment (); + + lbag.AddMember (current_class, mod_locations, GetLocation ($4)); } struct_body { @@ -939,6 +953,7 @@ struct_declaration } opt_semicolon { + lbag.AppendToMember (current_class, GetLocation ($13)); $$ = pop_current_class (); } | opt_attributes opt_modifiers opt_partial STRUCT error { @@ -953,6 +968,9 @@ struct_body Lexer.doc_state = XmlCommentState.Allowed; } opt_struct_member_declarations CLOSE_BRACE + { + lbag.AppendToMember (current_class, GetLocation ($1), GetLocation ($4)); + } ; opt_struct_member_declarations @@ -982,73 +1000,79 @@ struct_member_declaration */ | destructor_declaration ; - + constant_declaration : opt_attributes opt_modifiers - CONST - type - constant_declarators - SEMICOLON + CONST type IDENTIFIER { - 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 ( - current_class, (FullNamedExpression) $4, (string) constant.identifier, - (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); + var lt = (Tokenizer.LocatedToken) $5; + var mod = (Modifiers) $2; + current_field = new Const (current_class, (FullNamedExpression) $4, mod, new MemberName (lt.Value, lt.Location), (Attributes) $1); + current_container.AddConstant ((Const) current_field); + + if ((mod & Modifiers.STATIC) != 0) { + Report.Error (504, current_field.Location, "The constant `{0}' cannot be marked static", current_field.GetSignatureForError ()); + } + + $$ = current_field; + } + constant_initializer opt_constant_declarators SEMICOLON + { + if (RootContext.Documentation != null) { + current_field.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; } + + current_field.Initializer = (ConstInitializer) $7; + lbag.AddMember (current_field, mod_locations, GetLocation ($3), GetLocation ($9)); + current_field = null; } ; - + +opt_constant_declarators + : /* empty */ + | constant_declarators + ; + constant_declarators - : constant_declarator + : constant_declarator { - ArrayList constants = new ArrayList (4); - if ($1 != null) - constants.Add ($1); - $$ = constants; + current_field.AddDeclarator ((FieldDeclarator) $1); } - | constant_declarators COMMA constant_declarator + | constant_declarators constant_declarator { - if ($3 != null) { - ArrayList constants = (ArrayList) $1; - constants.Add ($3); - } + current_field.AddDeclarator ((FieldDeclarator) $2); } ; - + constant_declarator - : IDENTIFIER ASSIGN + : COMMA IDENTIFIER constant_initializer { - ++lexer.parsing_block; - } - constant_initializer + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3); + lbag.AddLocation ($$, GetLocation ($1)); + } + ; + +constant_initializer + : ASSIGN { - --lexer.parsing_block; - $$ = new VariableDeclaration ((LocatedToken) $1, $4); + ++lexer.parsing_block; } - | IDENTIFIER + constant_initializer_expr { - // A const field requires a value to be provided - Report.Error (145, ((LocatedToken) $1).Location, "A const field requires a value to be provided"); - $$ = null; + --lexer.parsing_block; + $$ = new ConstInitializer (current_field, (Expression) $3, GetLocation ($1)); } + | error + { + Report.Error (145, lexer.Location, "A const field requires a value to be provided"); + $$ = null; + } ; -constant_initializer +constant_initializer_expr : constant_expression | array_initializer ; @@ -1056,106 +1080,172 @@ constant_initializer field_declaration : opt_attributes opt_modifiers - member_type - variable_declarators - SEMICOLON - { + member_type IDENTIFIER + { + lexer.parsing_generic_declaration = false; + FullNamedExpression type = (FullNamedExpression) $3; - if (type == TypeManager.system_void_expr) + if (type.Type == TypeManager.void_type) Report.Error (670, GetLocation ($3), "Fields cannot have void type"); - - int mod = (int) $2; - - current_array_type = null; - - foreach (VariableMemberDeclaration var in (ArrayList) $4){ - Field field = new Field (current_class, type, mod, var.MemberName, (Attributes) $1); - - field.Initializer = var.expression_or_array_initializer; - - if (RootContext.Documentation != null) { - field.DocComment = Lexer.consume_doc_comment (); - Lexer.doc_state = XmlCommentState.Allowed; - } - current_container.AddField (field); - $$ = field; // FIXME: might be better if it points to the top item + + var lt = (Tokenizer.LocatedToken) $4; + current_field = new Field (current_class, type, (Modifiers) $2, new MemberName (lt.Value, lt.Location), (Attributes) $1); + current_container.AddField (current_field); + $$ = current_field; + } + opt_field_initializer + opt_field_declarators + SEMICOLON + { + if (RootContext.Documentation != null) { + current_field.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; } + + lbag.AddMember (current_field, mod_locations, GetLocation ($8)); + $$ = current_field; + current_field = null; } | opt_attributes opt_modifiers - FIXED - member_type - fixed_variable_declarators - SEMICOLON + FIXED simple_type IDENTIFIER { - FullNamedExpression type = (FullNamedExpression) $4; - - int mod = (int) $2; - - current_array_type = null; + if (RootContext.Version < LanguageVersion.ISO_2) + Report.FeatureIsNotAvailable (GetLocation ($3), "fixed size buffers"); - 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); + var lt = (Tokenizer.LocatedToken) $5; + current_field = new FixedField (current_class, (FullNamedExpression) $4, (Modifiers) $2, + new MemberName (lt.Value, lt.Location), (Attributes) $1); + + current_container.AddField (current_field); + } + fixed_field_size opt_fixed_field_declarators SEMICOLON + { + if (RootContext.Documentation != null) { + current_field.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } - if (RootContext.Documentation != null) { - field.DocComment = Lexer.consume_doc_comment (); - Lexer.doc_state = XmlCommentState.Allowed; - } - current_container.AddField (field); - $$ = field; // FIXME: might be better if it points to the top item - } + current_field.Initializer = (ConstInitializer) $7; + lbag.AddMember (current_field, mod_locations, GetLocation ($9)); + $$ = current_field; + current_field = null; } | opt_attributes opt_modifiers - FIXED - member_type - error + FIXED simple_type error + SEMICOLON + { + Report.Error (1641, GetLocation ($5), "A fixed size buffer field must have the array size specifier after the field name"); + } + ; + +opt_field_initializer + : /* empty */ + | ASSIGN + { + ++lexer.parsing_block; + } + variable_initializer + { + --lexer.parsing_block; + current_field.Initializer = (Expression) $3; + } + ; + +opt_field_declarators + : /* empty */ + | field_declarators + ; + +field_declarators + : field_declarator + { + current_field.AddDeclarator ((FieldDeclarator) $1); + } + | field_declarators field_declarator { - Report.Error (1641, GetLocation ($4), "A fixed size buffer field must have the array size specifier after the field name"); + current_field.AddDeclarator ((FieldDeclarator) $2); } ; + +field_declarator + : COMMA IDENTIFIER + { + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null); + lbag.AddLocation ($$, GetLocation ($1)); + } + | COMMA IDENTIFIER ASSIGN + { + ++lexer.parsing_block; + } + variable_initializer + { + --lexer.parsing_block; + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); + } + ; -fixed_variable_declarators - : fixed_variable_declarator +opt_fixed_field_declarators + : /* empty */ + | fixed_field_declarators + ; + +fixed_field_declarators + : fixed_field_declarator { - ArrayList decl = new ArrayList (2); - decl.Add ($1); - $$ = decl; - } - | fixed_variable_declarators COMMA fixed_variable_declarator + current_field.AddDeclarator ((FieldDeclarator) $1); + } + | fixed_field_declarator fixed_field_declarator { - ArrayList decls = (ArrayList) $1; - decls.Add ($3); - $$ = $1; + current_field.AddDeclarator ((FieldDeclarator) $2); + } + ; + +fixed_field_declarator + : COMMA IDENTIFIER fixed_field_size + { + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3); + lbag.AddLocation ($$, GetLocation ($1)); } ; -fixed_variable_declarator - : IDENTIFIER OPEN_BRACKET expression CLOSE_BRACKET +fixed_field_size + : OPEN_BRACKET + { + ++lexer.parsing_block; + } + expression CLOSE_BRACKET { - $$ = new VariableDeclaration ((LocatedToken) $1, $3); + --lexer.parsing_block; + $$ = new ConstInitializer (current_field, (Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($4)); } - | IDENTIFIER OPEN_BRACKET CLOSE_BRACKET + | OPEN_BRACKET error { Report.Error (443, lexer.Location, "Value or constant expected"); - $$ = new VariableDeclaration ((LocatedToken) $1, null); - } + $$ = null; + } ; local_variable_declarators : local_variable_declarator { - ArrayList decl = new ArrayList (4); + variables_bucket.Clear (); if ($1 != null) - decl.Add ($1); - $$ = decl; + variables_bucket.Add ($1); + $$ = variables_bucket; } | local_variable_declarators COMMA local_variable_declarator { - ArrayList decls = (ArrayList) $1; + var decls = (List) $1; decls.Add ($3); + lbag.AppendTo ($3, GetLocation ($2)); $$ = $1; } ; @@ -1163,11 +1253,12 @@ local_variable_declarators local_variable_declarator : IDENTIFIER ASSIGN local_variable_initializer { - $$ = new VariableDeclaration ((LocatedToken) $1, $3); + $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, (Expression) $3); + lbag.AddLocation ($$, GetLocation ($2)); } | IDENTIFIER { - $$ = new VariableDeclaration ((LocatedToken) $1, null); + $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, null); } | IDENTIFIER variable_bad_array { @@ -1178,62 +1269,24 @@ local_variable_declarator local_variable_initializer : expression | array_initializer - | STACKALLOC simple_type OPEN_BRACKET expression CLOSE_BRACKET + | STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET { - $$ = new StackAlloc ((Expression) $2, (Expression) $4, (Location) $1); + $$ = new StackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5)); } | ARGLIST { - $$ = new ArglistAccess ((Location) $1); + $$ = new ArglistAccess (GetLocation ($1)); } | STACKALLOC simple_type { - Report.Error (1575, (Location) $1, "A stackalloc expression requires [] after type"); - $$ = new StackAlloc ((Expression) $2, null, (Location) $1); - } - ; - -variable_declarators - : variable_declarator - { - ArrayList decl = new ArrayList (4); - if ($1 != null) - decl.Add ($1); - $$ = decl; - } - | variable_declarators COMMA variable_declarator - { - ArrayList decls = (ArrayList) $1; - decls.Add ($3); - $$ = $1; + Report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type"); + $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1)); } ; -variable_declarator - : member_declaration_name ASSIGN - { - ++lexer.parsing_block; - lexer.parsing_generic_declaration = false; - } - variable_initializer - { - --lexer.parsing_block; - $$ = new VariableMemberDeclaration ((MemberName) $1, $4); - } - | member_declaration_name - { - lexer.parsing_generic_declaration = false; - $$ = new VariableMemberDeclaration ((MemberName) $1, null); - } - | member_declaration_name variable_bad_array - { - lexer.parsing_generic_declaration = false; - $$ = null; - } - ; - variable_bad_array - : OPEN_BRACKET opt_expression CLOSE_BRACKET + : OPEN_BRACKET_EXPR opt_expression CLOSE_BRACKET { Report.Error (650, GetLocation ($1), "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"); @@ -1256,11 +1309,10 @@ method_declaration method.Block = (ToplevelBlock) $3; current_container.AddMethod (method); - if (current_container.Kind == Kind.Interface && method.Block != null) { + if (current_container.Kind == MemberKind.Interface && method.Block != null) { Report.Error (531, method.Location, "`{0}': interface members cannot have a definition", method.GetSignatureForError ()); } - current_generic_method = null; current_local_parameters = null; if (RootContext.Documentation != null) @@ -1274,59 +1326,66 @@ method_header member_type method_declaration_name OPEN_PARENS { - arglist_allowed = true; + valid_param_mod = ParameterModifierType.All; } - opt_formal_parameter_list CLOSE_PARENS + opt_formal_parameter_list CLOSE_PARENS { lexer.ConstraintsParsing = true; } opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; - arglist_allowed = false; + valid_param_mod = 0; MemberName name = (MemberName) $4; current_local_parameters = (ParametersCompiled) $7; - if ($10 != null && name.TypeArguments == null) - Report.Error (80, lexer.Location, - "Constraints are not allowed on non-generic declarations"); - - Method method; - GenericMethod generic = null; if (name.TypeArguments != null) { generic = new GenericMethod (current_namespace, current_class, name, (FullNamedExpression) $3, current_local_parameters); - generic.SetParameterInfo ((ArrayList) $10); + generic.SetParameterInfo ((List) $10); + } else if ($10 != null) { + Report.Error (80, GetLocation ($10), + "Constraints are not allowed on non-generic declarations"); } - method = new Method (current_class, generic, (FullNamedExpression) $3, (int) $2, + Method method = new Method (current_class, generic, (FullNamedExpression) $3, (Modifiers) $2, name, current_local_parameters, (Attributes) $1); - - current_generic_method = generic; + + if ($10 != null && ((method.ModFlags & Modifiers.OVERRIDE) != 0 || method.IsExplicitImpl)) { + Report.Error (460, method.Location, + "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods", + method.GetSignatureForError ()); + } if (RootContext.Documentation != null) method.DocComment = Lexer.consume_doc_comment (); + lbag.AddMember (method, mod_locations, GetLocation ($5), GetLocation ($8)); $$ = method; } | opt_attributes opt_modifiers PARTIAL VOID method_declaration_name - OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + OPEN_PARENS + { + valid_param_mod = ParameterModifierType.All; + } + opt_formal_parameter_list CLOSE_PARENS { lexer.ConstraintsParsing = true; } opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; + valid_param_mod = 0; MemberName name = (MemberName) $5; - current_local_parameters = (ParametersCompiled) $7; + current_local_parameters = (ParametersCompiled) $8; - if ($9 != null && name.TypeArguments == null) + if ($10 != null && name.TypeArguments == null) Report.Error (80, lexer.Location, "Constraints are not allowed on non-generic declarations"); @@ -1334,15 +1393,16 @@ method_header GenericMethod generic = null; if (name.TypeArguments != null) { generic = new GenericMethod (current_namespace, current_class, name, - TypeManager.system_void_expr, current_local_parameters); + new TypeExpression (TypeManager.void_type, GetLocation ($4)), + current_local_parameters); - generic.SetParameterInfo ((ArrayList) $10); + generic.SetParameterInfo ((List) $11); } - int modifiers = (int) $2; + var modifiers = (Modifiers) $2; - const int invalid_partial_mod = Modifiers.Accessibility | Modifiers.ABSTRACT | Modifiers.EXTERN | + const Modifiers invalid_partial_mod = Modifiers.AccessibilityMask | Modifiers.ABSTRACT | Modifiers.EXTERN | Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.SEALED | Modifiers.VIRTUAL; if ((modifiers & invalid_partial_mod) != 0) { @@ -1355,17 +1415,18 @@ method_header Report.Error (751, name.Location, "A partial method must be declared within a " + "partial class or partial struct"); } - + modifiers |= Modifiers.PARTIAL | Modifiers.PRIVATE; - method = new Method (current_class, generic, TypeManager.system_void_expr, + method = new Method (current_class, generic, new TypeExpression (TypeManager.void_type, GetLocation ($4)), modifiers, name, current_local_parameters, (Attributes) $1); - current_generic_method = generic; - if (RootContext.Documentation != null) method.DocComment = Lexer.consume_doc_comment (); + // TODO: lbag, push void + StoreModifierLocation (Modifiers.PARTIAL, GetLocation ($3)); + lbag.AddMember (method, mod_locations, GetLocation ($6), GetLocation ($9)); $$ = method; } | opt_attributes @@ -1375,9 +1436,9 @@ method_header { MemberName name = (MemberName) $5; Report.Error (1585, name.Location, - "Member modifier `{0}' must precede the member type and name", Modifiers.Name ((int) $4)); + "Member modifier `{0}' must precede the member type and name", ModifiersExtensions.Name ((Modifiers) $4)); - Method method = new Method (current_class, null, TypeManager.system_void_expr, + Method method = new Method (current_class, null, (FullNamedExpression) $3, 0, name, (ParametersCompiled) $7, (Attributes) $1); current_local_parameters = (ParametersCompiled) $7; @@ -1385,7 +1446,7 @@ method_header if (RootContext.Documentation != null) method.DocComment = Lexer.consume_doc_comment (); - $$ = null; + $$ = method; } ; @@ -1399,98 +1460,93 @@ opt_formal_parameter_list | formal_parameter_list ; -opt_parameter_list_no_mod - : /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; } - | - { - parameter_modifiers_not_allowed = true; - } - formal_parameter_list - { - parameter_modifiers_not_allowed = false; - $$ = $2; - } - ; - formal_parameter_list - : fixed_parameters + : fixed_parameters { - ArrayList pars_list = (ArrayList) $1; - - Parameter [] pars = new Parameter [pars_list.Count]; - pars_list.CopyTo (pars); - - $$ = new ParametersCompiled (pars); + var pars_list = (List) $1; + $$ = new ParametersCompiled (compiler, pars_list.ToArray ()); } | fixed_parameters COMMA parameter_array { - ArrayList pars_list = (ArrayList) $1; - pars_list.Add ($3); + var pars_list = (List) $1; + pars_list.Add ((Parameter) $3); - Parameter [] pars = new Parameter [pars_list.Count]; - pars_list.CopyTo (pars); - - $$ = new ParametersCompiled (pars); + $$ = new ParametersCompiled (compiler, pars_list.ToArray ()); } | fixed_parameters COMMA arglist_modifier { - ArrayList pars_list = (ArrayList) $1; + var pars_list = (List) $1; pars_list.Add (new ArglistParameter (GetLocation ($3))); - - Parameter [] pars = new Parameter [pars_list.Count]; - pars_list.CopyTo (pars); - - $$ = new ParametersCompiled (pars, true); + $$ = new ParametersCompiled (compiler, pars_list.ToArray (), true); } | parameter_array COMMA error { if ($1 != null) Report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list"); - $$ = null; + + $$ = new ParametersCompiled (compiler, new Parameter[] { (Parameter) $1 } ); } | fixed_parameters COMMA parameter_array COMMA error { if ($3 != null) Report.Error (231, ((Parameter) $3).Location, "A params parameter must be the last parameter in a formal parameter list"); - $$ = null; + + var pars_list = (List) $1; + pars_list.Add (new ArglistParameter (GetLocation ($3))); + + $$ = new ParametersCompiled (compiler, pars_list.ToArray (), true); } | arglist_modifier COMMA error { - Report.Error (257, (Location) $1, "An __arglist parameter must be the last parameter in a formal parameter list"); - $$ = null; + Report.Error (257, GetLocation ($1), "An __arglist parameter must be the last parameter in a formal parameter list"); + + $$ = new ParametersCompiled (compiler, new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true); } | fixed_parameters COMMA ARGLIST COMMA error { - Report.Error (257, (Location) $3, "An __arglist parameter must be the last parameter in a formal parameter list"); - $$ = null; + Report.Error (257, GetLocation ($3), "An __arglist parameter must be the last parameter in a formal parameter list"); + + var pars_list = (List) $1; + pars_list.Add (new ArglistParameter (GetLocation ($3))); + + $$ = new ParametersCompiled (compiler, pars_list.ToArray (), true); } | parameter_array { - $$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } ); + $$ = new ParametersCompiled (compiler, new Parameter[] { (Parameter) $1 } ); } | arglist_modifier { - $$ = new ParametersCompiled (new Parameter [] { new ArglistParameter ((Location) $1) }, true); + $$ = new ParametersCompiled (compiler, new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true); } ; fixed_parameters : fixed_parameter { - ArrayList pars = new ArrayList (4); - - pars.Add ($1); - $$ = pars; + parameters_bucket.Clear (); + Parameter p = (Parameter) $1; + parameters_bucket.Add (p); + + default_parameter_used = p.HasDefaultValue; + $$ = parameters_bucket; } | fixed_parameters COMMA fixed_parameter { - ArrayList pars = (ArrayList) $1; - Parameter p = (Parameter)$3; + var pars = (List) $1; + Parameter p = (Parameter) $3; if (p != null) { if (p.HasExtensionMethodModifier) Report.Error (1100, p.Location, "The parameter modifier `this' can only be used on the first parameter"); + else if (!p.HasDefaultValue && default_parameter_used) + Report.Error (1737, p.Location, "Optional parameter cannot precede required parameters"); + + default_parameter_used |= p.HasDefaultValue; pars.Add (p); + + lbag.AddLocation (p, GetLocation ($2)); } + $$ = $1; } ; @@ -1498,46 +1554,75 @@ fixed_parameters fixed_parameter : opt_attributes opt_parameter_modifier - type + parameter_type IDENTIFIER { - LocatedToken lt = (LocatedToken) $4; + var lt = (Tokenizer.LocatedToken) $4; $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location); } | opt_attributes opt_parameter_modifier - type + parameter_type IDENTIFIER OPEN_BRACKET CLOSE_BRACKET { - LocatedToken lt = (LocatedToken) $4; + var lt = (Tokenizer.LocatedToken) $4; Report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name"); - $$ = null; + $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location); } | opt_attributes opt_parameter_modifier - type + parameter_type + error { - Report.Error (1001, GetLocation ($3), "Identifier expected"); - $$ = new Parameter ((FullNamedExpression) $3, "NeedSomeGeneratorHere", (Parameter.Modifier) $2, (Attributes) $1, lexer.Location); + Location l = GetLocation ($4); + CheckIdentifierToken (yyToken, l); + $$ = new Parameter ((FullNamedExpression) $3, "NeedSomeGeneratorHere", (Parameter.Modifier) $2, (Attributes) $1, l); } | opt_attributes opt_parameter_modifier - type - error { - CheckIdentifierToken (yyToken, GetLocation ($4)); - $$ = null; - } - | opt_attributes - opt_parameter_modifier - type + parameter_type IDENTIFIER ASSIGN + { + ++lexer.parsing_block; + } constant_expression - { - LocatedToken lt = (LocatedToken) $4; - Report.Error (241, lt.Location, "Default parameter specifiers are not permitted"); - $$ = null; - } + { + --lexer.parsing_block; + if (RootContext.Version <= LanguageVersion.V_3) { + Report.FeatureIsNotAvailable (GetLocation ($5), "optional parameter"); + } + + Parameter.Modifier mod = (Parameter.Modifier) $2; + if (mod != Parameter.Modifier.NONE) { + switch (mod) { + case Parameter.Modifier.REF: + case Parameter.Modifier.OUT: + Report.Error (1741, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter", + Parameter.GetModifierSignature (mod)); + break; + + case Parameter.Modifier.This: + Report.Error (1743, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter", + Parameter.GetModifierSignature (mod)); + break; + default: + throw new NotImplementedException (mod.ToString ()); + } + + mod = Parameter.Modifier.NONE; + } + + if ((valid_param_mod & ParameterModifierType.DefaultValue) == 0) + Report.Error (1065, GetLocation ($5), "Optional parameter is not valid in this context"); + + var lt = (Tokenizer.LocatedToken) $4; + $$ = new Parameter ((FullNamedExpression) $3, lt.Value, mod, (Attributes) $1, lt.Location); + lbag.AddLocation ($$, GetLocation ($5)); + + if ($7 != null) + ((Parameter) $$).DefaultValue = (Expression) $7; + } ; opt_parameter_modifier @@ -1576,22 +1661,22 @@ parameter_modifiers parameter_modifier : REF { - if (parameter_modifiers_not_allowed) - Error_ParameterModifierNotValid ("ref", (Location)$1); + if ((valid_param_mod & ParameterModifierType.Ref) == 0) + Error_ParameterModifierNotValid ("ref", GetLocation ($1)); $$ = Parameter.Modifier.REF; } | OUT { - if (parameter_modifiers_not_allowed) - Error_ParameterModifierNotValid ("out", (Location)$1); + if ((valid_param_mod & ParameterModifierType.Out) == 0) + Error_ParameterModifierNotValid ("out", GetLocation ($1)); $$ = Parameter.Modifier.OUT; } | THIS { - if (parameter_modifiers_not_allowed) - Error_ParameterModifierNotValid ("this", (Location)$1); + if ((valid_param_mod & ParameterModifierType.This) == 0) + Error_ParameterModifierNotValid ("this", GetLocation ($1)); if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "extension methods"); @@ -1602,11 +1687,19 @@ parameter_modifier parameter_array : opt_attributes params_modifier type IDENTIFIER - { - LocatedToken lt = (LocatedToken) $4; + { + var lt = (Tokenizer.LocatedToken) $4; $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location); } - | opt_attributes params_modifier type error { + | opt_attributes params_modifier type IDENTIFIER ASSIGN constant_expression + { + Report.Error (1751, GetLocation ($2), "Cannot specify a default value for a parameter array"); + + var lt = (Tokenizer.LocatedToken) $4; + $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location); + } + | opt_attributes params_modifier type error + { CheckIdentifierToken (yyToken, GetLocation ($4)); $$ = null; } @@ -1615,29 +1708,29 @@ parameter_array params_modifier : PARAMS { - if (params_modifiers_not_allowed) - Report.Error (1670, ((Location) $1), "The `params' modifier is not allowed in current context"); + if ((valid_param_mod & ParameterModifierType.Params) == 0) + Report.Error (1670, (GetLocation ($1)), "The `params' modifier is not allowed in current context"); } | PARAMS parameter_modifier { Parameter.Modifier mod = (Parameter.Modifier)$2; if ((mod & Parameter.Modifier.This) != 0) { - Report.Error (1104, (Location)$1, "The parameter modifiers `this' and `params' cannot be used altogether"); + Report.Error (1104, GetLocation ($1), "The parameter modifiers `this' and `params' cannot be used altogether"); } else { - Report.Error (1611, (Location)$1, "The params parameter cannot be declared as ref or out"); + Report.Error (1611, GetLocation ($1), "The params parameter cannot be declared as ref or out"); } } | PARAMS params_modifier { - Error_DuplicateParameterModifier ((Location)$1, Parameter.Modifier.PARAMS); + Error_DuplicateParameterModifier (GetLocation ($1), Parameter.Modifier.PARAMS); } ; arglist_modifier : ARGLIST { - if (!arglist_allowed) - Report.Error (1669, (Location) $1, "__arglist is not valid in this context"); + if ((valid_param_mod & ParameterModifierType.Arglist) == 0) + Report.Error (1669, GetLocation ($1), "__arglist is not valid in this context"); } ; @@ -1650,86 +1743,95 @@ property_declaration if (RootContext.Documentation != null) tmpComment = Lexer.consume_doc_comment (); } - OPEN_BRACE + OPEN_BRACE { - implicit_value_parameter_type = (FullNamedExpression) $3; + current_property = new Property (current_class, (FullNamedExpression) $3, (Modifiers) $2, + (MemberName) $4, (Attributes) $1); + + if (current_property.TypeExpression.Type == TypeManager.void_type) + Report.Error (547, GetLocation ($3), "`{0}': property or indexer cannot have void type", current_property.GetSignatureForError ()); + + current_container.AddProperty ((Property)current_property); + lbag.AddMember (current_property, mod_locations, GetLocation ($6)); + lexer.PropertyParsing = true; } accessor_declarations { lexer.PropertyParsing = false; - has_get = has_set = false; + + if (RootContext.Documentation != null) + current_property.DocComment = ConsumeStoredComment (); } CLOSE_BRACE - { - Property prop; - Accessors accessors = (Accessors) $8; - Accessor get_block = accessors != null ? accessors.get_or_add : null; - Accessor set_block = accessors != null ? accessors.set_or_remove : null; - bool order = accessors != null ? accessors.declared_in_reverse : false; - - MemberName name = (MemberName) $4; - FullNamedExpression ptype = (FullNamedExpression) $3; + { + lbag.AppendToMember (current_property, GetLocation ($10)); + current_property = null; + } + ; - prop = new Property (current_class, ptype, (int) $2, - name, (Attributes) $1, get_block, set_block, order, current_block); - if (ptype == TypeManager.system_void_expr) - Report.Error (547, name.Location, "`{0}': property or indexer cannot have void type", prop.GetSignatureForError ()); +indexer_declaration + : opt_attributes opt_modifiers + member_type indexer_declaration_name OPEN_BRACKET + { + valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue; + } + opt_formal_parameter_list CLOSE_BRACKET OPEN_BRACE + { + valid_param_mod = 0; + + Indexer indexer = new Indexer (current_class, (FullNamedExpression) $3, + (MemberName)$4, (Modifiers) $2, (ParametersCompiled) $7, (Attributes) $1); - if (accessors == null) - Report.Error (548, prop.Location, "`{0}': property or indexer must have at least one accessor", prop.GetSignatureForError ()); + current_property = indexer; - if (current_container.Kind == Kind.Interface) { - if (prop.Get.Block != null) - Report.Error (531, prop.Location, "`{0}.get': interface members cannot have a definition", prop.GetSignatureForError ()); + current_container.AddIndexer (indexer); + lbag.AddMember (current_property, mod_locations, GetLocation ($5), GetLocation ($8), GetLocation ($9)); + + if (indexer.TypeExpression.Type == TypeManager.void_type) + Report.Error (620, GetLocation ($3), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ()); - if (prop.Set.Block != null) - Report.Error (531, prop.Location, "`{0}.set': interface members cannot have a definition", prop.GetSignatureForError ()); + if (indexer.Parameters.IsEmpty) { + Report.Error (1551, GetLocation ($5), "Indexers must have at least one parameter"); } - current_container.AddProperty (prop); - implicit_value_parameter_type = null; + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + lexer.PropertyParsing = true; + } + accessor_declarations + { + lexer.PropertyParsing = false; + } + CLOSE_BRACE + { if (RootContext.Documentation != null) - prop.DocComment = ConsumeStoredComment (); - + current_property.DocComment = ConsumeStoredComment (); + + lbag.AppendToMember (current_property, GetLocation ($12)); + current_property = null; } ; + accessor_declarations : get_accessor_declaration - { - $$ = new Accessors ((Accessor) $1, null); - } | get_accessor_declaration accessor_declarations - { - Accessors accessors = (Accessors) $2; - accessors.get_or_add = (Accessor) $1; - $$ = accessors; - } | set_accessor_declaration - { - $$ = new Accessors (null, (Accessor) $1); - } | set_accessor_declaration accessor_declarations - { - Accessors accessors = (Accessors) $2; - accessors.set_or_remove = (Accessor) $1; - accessors.declared_in_reverse = true; - $$ = accessors; - } | error { if (yyToken == Token.CLOSE_BRACE) { - $$ = null; + Report.Error (548, lexer.Location, "`{0}': property or indexer must have at least one accessor", current_property.GetSignatureForError ()); } else { if (yyToken == Token.SEMICOLON) Report.Error (1597, lexer.Location, "Semicolon after method or accessor block is not valid"); else Report.Error (1014, GetLocation ($1), "A get or set accessor expected"); - - $$ = new Accessors (null, null); } } ; @@ -1737,65 +1839,91 @@ accessor_declarations get_accessor_declaration : opt_attributes opt_modifiers GET { - // If this is not the case, then current_local_parameters has already - // been set in indexer_declaration - if (parsing_indexer == false) - current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; - else - current_local_parameters = indexer_parameters; + if ($2 != ModifierNone && RootContext.Version == LanguageVersion.ISO_1) { + Report.FeatureIsNotAvailable (GetLocation ($2), "access modifiers on properties"); + } + + if (current_property.Get != null) { + Report.Error (1007, GetLocation ($3), "Property accessor already defined"); + } + + if (current_property is Indexer) { + current_property.Get = new Indexer.GetIndexerMethod (current_property, (Modifiers) $2, ((Indexer)current_property).ParameterInfo.Clone (), + (Attributes) $1, GetLocation ($3)); + } else { + current_property.Get = new Property.GetMethod (current_property, + (Modifiers) $2, (Attributes) $1, GetLocation ($3)); + } + + current_local_parameters = current_property.Get.ParameterInfo; + lbag.AddMember (current_property.Get, mod_locations); lexer.PropertyParsing = false; } accessor_body { - if (has_get) { - Report.Error (1007, GetLocation ($3), "Property accessor already defined"); - break; + if ($5 != null) { + current_property.Get.Block = (ToplevelBlock) $5; + + if (current_container.Kind == MemberKind.Interface) { + Report.Error (531, current_property.Get.Block.StartLocation, + "`{0}': interface members cannot have a definition", current_property.Get.GetSignatureForError ()); + } } - Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, current_local_parameters, (Location) $3); - 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; - - $$ = accessor; } ; set_accessor_declaration : opt_attributes opt_modifiers SET { - Parameter implicit_value_parameter = new Parameter ( - implicit_value_parameter_type, "value", - Parameter.Modifier.NONE, null, (Location) $3); - - if (!parsing_indexer) { - current_local_parameters = new ParametersCompiled (new Parameter [] { implicit_value_parameter }); + if ($2 != ModifierNone && RootContext.Version == LanguageVersion.ISO_1) { + Report.FeatureIsNotAvailable (GetLocation ($2), "access modifiers on properties"); + } + + if (current_property.Set != null) { + Report.Error (1007, GetLocation ($3), "Property accessor already defined"); + } + + if (current_property is Indexer) { + current_property.Set = new Indexer.SetIndexerMethod (current_property, (Modifiers) $2, + ParametersCompiled.MergeGenerated (compiler, + ((Indexer)current_property).ParameterInfo, true, new Parameter ( + current_property.TypeExpression, "value", Parameter.Modifier.NONE, null, GetLocation ($3)), + null), + (Attributes) $1, GetLocation ($3)); } else { - current_local_parameters = ParametersCompiled.MergeGenerated ( - indexer_parameters, true, implicit_value_parameter, null); + current_property.Set = new Property.SetMethod (current_property, (Modifiers) $2, + ParametersCompiled.CreateImplicitParameter (current_property.TypeExpression, GetLocation ($3)), + (Attributes) $1, GetLocation ($3)); } + current_local_parameters = current_property.Set.ParameterInfo; + lbag.AddMember (current_property.Set, mod_locations); lexer.PropertyParsing = false; } accessor_body { - if (has_set) { - Report.Error (1007, GetLocation ($3), "Property accessor already defined"); - break; + if ($5 != null) { + current_property.Set.Block = (ToplevelBlock) $5; + + if (current_container.Kind == MemberKind.Interface) { + Report.Error (531, current_property.Set.Block.StartLocation, + "`{0}': interface members cannot have a definition", current_property.Set.GetSignatureForError ()); + } } - Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, current_local_parameters, (Location) $3); - has_set = true; + current_local_parameters = null; lexer.PropertyParsing = true; if (RootContext.Documentation != null && Lexer.doc_state == XmlCommentState.Error) Lexer.doc_state = XmlCommentState.NotAllowed; - - $$ = accessor; } ; @@ -1803,11 +1931,12 @@ accessor_body : block | SEMICOLON { + // TODO: lbag $$ = null; } | error { - Error_SyntaxError (1043, yyToken); + Error_SyntaxError (1043, yyToken, "Invalid accessor body"); $$ = null; } ; @@ -1823,21 +1952,22 @@ interface_declaration type_declaration_name { MemberName name = MakeName ((MemberName) $6); - push_current_class (new Interface (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3); + push_current_class (new Interface (current_namespace, current_class, name, (Modifiers) $2, (Attributes) $1), $3); + lbag.AddMember (current_class, mod_locations, GetLocation ($4)); } opt_class_base opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; - current_class.SetParameterInfo ((ArrayList) $9); + current_class.SetParameterInfo ((List) $9); if (RootContext.Documentation != null) { current_container.DocComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } } - interface_body + OPEN_BRACE opt_interface_member_declarations CLOSE_BRACE { --lexer.parsing_declaration; if (RootContext.Documentation != null) @@ -1845,6 +1975,7 @@ interface_declaration } opt_semicolon { + lbag.AppendToMember (current_class, GetLocation ($11), GetLocation ($13)); $$ = pop_current_class (); } | opt_attributes opt_modifiers opt_partial INTERFACE error { @@ -1852,12 +1983,6 @@ interface_declaration } ; -interface_body - : OPEN_BRACE - opt_interface_member_declarations - CLOSE_BRACE - ; - opt_interface_member_declarations : /* empty */ | interface_member_declarations @@ -1906,7 +2031,7 @@ operator_declaration OperatorDeclaration decl = (OperatorDeclaration) $3; Operator op = new Operator ( - current_class, decl.optype, decl.ret_type, (int) $2, + current_class, decl.optype, decl.ret_type, (Modifiers) $2, current_local_parameters, (ToplevelBlock) $5, (Attributes) $1, decl.location); @@ -1918,6 +2043,7 @@ operator_declaration // Note again, checking is done in semantic analysis current_container.AddOperator (op); + lbag.AddMember (op, mod_locations, lbag.GetLocations (decl)); current_local_parameters = null; } ; @@ -1931,21 +2057,21 @@ operator_type : type_expression_or_array | VOID { - Report.Error (590, lexer.Location, "User-defined operators cannot return void"); - $$ = TypeManager.system_void_expr; + Report.Error (590, GetLocation ($1), "User-defined operators cannot return void"); + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; operator_declarator : operator_type OPERATOR overloadable_operator OPEN_PARENS { - params_modifiers_not_allowed = true; + valid_param_mod = ParameterModifierType.DefaultValue; } - opt_parameter_list_no_mod CLOSE_PARENS + opt_formal_parameter_list CLOSE_PARENS { - params_modifiers_not_allowed = false; + valid_param_mod = 0; - Location loc = (Location) $2; + Location loc = GetLocation ($2); Operator.OpType op = (Operator.OpType) $3; current_local_parameters = (ParametersCompiled)$6; @@ -1979,6 +2105,7 @@ operator_declarator } $$ = new OperatorDeclaration (op, (FullNamedExpression) $1, loc); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3), GetLocation ($4), GetLocation ($7)); } | conversion_operator_declarator ; @@ -2014,13 +2141,13 @@ overloadable_operator conversion_operator_declarator : IMPLICIT OPERATOR type OPEN_PARENS { - params_modifiers_not_allowed = true; + valid_param_mod = ParameterModifierType.DefaultValue; } - opt_parameter_list_no_mod CLOSE_PARENS + opt_formal_parameter_list CLOSE_PARENS { - params_modifiers_not_allowed = false; + valid_param_mod = 0; - Location loc = (Location) $2; + Location loc = GetLocation ($2); current_local_parameters = (ParametersCompiled)$6; if (RootContext.Documentation != null) { @@ -2029,16 +2156,17 @@ conversion_operator_declarator } $$ = new OperatorDeclaration (Operator.OpType.Implicit, (FullNamedExpression) $3, loc); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7)); } | EXPLICIT OPERATOR type OPEN_PARENS { - params_modifiers_not_allowed = true; + valid_param_mod = ParameterModifierType.DefaultValue; } - opt_parameter_list_no_mod CLOSE_PARENS + opt_formal_parameter_list CLOSE_PARENS { - params_modifiers_not_allowed = false; + valid_param_mod = 0; - Location loc = (Location) $2; + Location loc = GetLocation ($2); current_local_parameters = (ParametersCompiled)$6; if (RootContext.Documentation != null) { @@ -2047,15 +2175,18 @@ conversion_operator_declarator } $$ = new OperatorDeclaration (Operator.OpType.Explicit, (FullNamedExpression) $3, loc); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7)); } | IMPLICIT error { Error_SyntaxError (yyToken); + current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; $$ = new OperatorDeclaration (Operator.OpType.Implicit, null, GetLocation ($1)); } | EXPLICIT error { Error_SyntaxError (yyToken); + current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; $$ = new OperatorDeclaration (Operator.OpType.Explicit, null, GetLocation ($1)); } ; @@ -2087,9 +2218,12 @@ constructor_declarator tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } + + valid_param_mod = ParameterModifierType.All; } OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { + valid_param_mod = 0; current_local_parameters = (ParametersCompiled) $6; // @@ -2100,8 +2234,8 @@ constructor_declarator } opt_constructor_initializer { - LocatedToken lt = (LocatedToken) $3; - int mods = (int) $2; + var lt = (Tokenizer.LocatedToken) $3; + var mods = (Modifiers) $2; ConstructorInitializer ci = (ConstructorInitializer) $9; Constructor c = new Constructor (current_class, lt.Value, mods, @@ -2110,7 +2244,7 @@ constructor_declarator if (lt.Value != current_container.MemberName.Name) { Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type"); } else if ((mods & Modifiers.STATIC) != 0) { - if ((mods & Modifiers.Accessibility) != 0){ + if ((mods & Modifiers.AccessibilityMask) != 0){ Report.Error (515, c.Location, "`{0}': static constructor cannot have an access modifier", c.GetSignatureForError ()); @@ -2123,6 +2257,7 @@ constructor_declarator } } + lbag.AddMember (c, mod_locations, GetLocation ($5), GetLocation ($7)); $$ = c; } ; @@ -2145,7 +2280,8 @@ constructor_initializer opt_argument_list CLOSE_PARENS { --lexer.parsing_block; - $$ = new ConstructorBaseInitializer ((ArrayList) $5, (Location) $2); + $$ = new ConstructorBaseInitializer ((Arguments) $5, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6)); } | COLON THIS OPEN_PARENS { @@ -2154,7 +2290,8 @@ constructor_initializer opt_argument_list CLOSE_PARENS { --lexer.parsing_block; - $$ = new ConstructorThisInitializer ((ArrayList) $5, (Location) $2); + $$ = new ConstructorThisInitializer ((Arguments) $5, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6)); } | COLON error { Report.Error (1018, GetLocation ($1), "Keyword `this' or `base' expected"); @@ -2174,20 +2311,21 @@ destructor_declaration } IDENTIFIER OPEN_PARENS CLOSE_PARENS method_body { - LocatedToken lt = (LocatedToken) $5; + var lt = (Tokenizer.LocatedToken) $5; if (lt.Value != current_container.MemberName.Name){ Report.Error (574, lt.Location, "Name of destructor must match name of class"); - } else if (current_container.Kind != Kind.Class){ + } else if (current_container.Kind != MemberKind.Class){ Report.Error (575, lt.Location, "Only class types can contain destructor"); - } else { - Destructor d = new Destructor (current_class, (int) $2, - ParametersCompiled.EmptyReadOnlyParameters, (Attributes) $1, lt.Location); - if (RootContext.Documentation != null) - d.DocComment = ConsumeStoredComment (); - - d.Block = (ToplevelBlock) $8; - current_container.AddMethod (d); } + + Destructor d = new Destructor (current_class, (Modifiers) $2, + ParametersCompiled.EmptyReadOnlyParameters, (Attributes) $1, lt.Location); + if (RootContext.Documentation != null) + d.DocComment = ConsumeStoredComment (); + + d.Block = (ToplevelBlock) $8; + current_container.AddMethod (d); + lbag.AddMember (d, mod_locations, GetLocation ($3), GetLocation ($6), GetLocation ($7)); current_local_parameters = null; } @@ -2196,339 +2334,309 @@ destructor_declaration event_declaration : opt_attributes opt_modifiers - EVENT type variable_declarators SEMICOLON + EVENT type member_declaration_name { - current_array_type = null; - foreach (VariableMemberDeclaration var in (ArrayList) $5) { - - EventField e = new EventField ( - current_class, (FullNamedExpression) $4, (int) $2, var.MemberName, (Attributes) $1); - - if (var.expression_or_array_initializer != null) { - if (current_container.Kind == Kind.Interface) { - Report.Error (68, e.Location, "`{0}': event in interface cannot have initializer", e.GetSignatureForError ()); - } - - e.Initializer = var.expression_or_array_initializer; - } - - if (var.MemberName.Left != null) { - Report.Error (71, e.Location, - "`{0}': An explicit interface implementation of an event must use property syntax", - e.GetSignatureForError ()); - } - - current_container.AddEvent (e); - - if (RootContext.Documentation != null) { - e.DocComment = Lexer.consume_doc_comment (); - Lexer.doc_state = XmlCommentState.Allowed; - } + current_event_field = new EventField (current_class, (FullNamedExpression) $4, (Modifiers) $2, (MemberName) $5, (Attributes) $1); + current_container.AddEvent (current_event_field); + + if (current_event_field.MemberName.Left != null) { + Report.Error (71, current_event_field.Location, "`{0}': An explicit interface implementation of an event must use property syntax", + current_event_field.GetSignatureForError ()); } + + $$ = current_event_field; + } + opt_event_initializer + opt_event_declarators + SEMICOLON + { + if (RootContext.Documentation != null) { + current_event_field.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + + lbag.AddMember (current_event_field, mod_locations, GetLocation ($3), GetLocation ($9)); + current_event_field = null; } | opt_attributes opt_modifiers EVENT type member_declaration_name OPEN_BRACE { - implicit_value_parameter_type = (FullNamedExpression) $4; - current_local_parameters = new ParametersCompiled ( - new Parameter (implicit_value_parameter_type, "value", - Parameter.Modifier.NONE, null, GetLocation ($3))); - + current_event = new EventProperty (current_class, (FullNamedExpression) $4, (Modifiers) $2, (MemberName) $5, (Attributes) $1); + current_container.AddEvent (current_event); + lbag.AddMember (current_event, mod_locations, GetLocation ($3), GetLocation ($6)); + lexer.EventParsing = true; } event_accessor_declarations { - lexer.EventParsing = false; + if (current_container.Kind == MemberKind.Interface) + Report.Error (69, GetLocation ($6), "Event in interface cannot have add or remove accessors"); + + lexer.EventParsing = false; } CLOSE_BRACE { - MemberName name = (MemberName) $5; - - if (current_container.Kind == Kind.Interface) { - Report.Error (69, (Location) $3, "Event in interface cannot have add or remove accessors"); - } - - if ($8 == null){ - Report.Error (65, (Location) $3, "`{0}.{1}': event property must have both add and remove accessors", - current_container.Name, name.GetSignatureForError ()); - $$ = null; - } else { - Accessors accessors = (Accessors) $8; - - if (accessors.get_or_add == null || accessors.set_or_remove == null) - // CS0073 is already reported, so no CS0065 here. - $$ = null; - else { - Event e = new EventProperty ( - current_class, (FullNamedExpression) $4, (int) $2, name, - (Attributes) $1, accessors.get_or_add, accessors.set_or_remove); - if (RootContext.Documentation != null) { - e.DocComment = Lexer.consume_doc_comment (); - Lexer.doc_state = XmlCommentState.Allowed; - } - - current_container.AddEvent (e); - implicit_value_parameter_type = null; - } + if (RootContext.Documentation != null) { + current_event.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; } + + lbag.AppendToMember (current_event, GetLocation ($9)); + current_event = null; current_local_parameters = null; } - | opt_attributes opt_modifiers EVENT type member_declaration_name error + ; + +opt_event_initializer + : /* empty */ + | ASSIGN { - MemberName mn = (MemberName) $5; - if (mn.Left != null) - Report.Error (71, mn.Location, "An explicit interface implementation of an event must use property syntax"); - - if (RootContext.Documentation != null) - Lexer.doc_state = XmlCommentState.Allowed; - - Error_SyntaxError (yyToken); - $$ = null; + ++lexer.parsing_block; + } + event_variable_initializer + { + --lexer.parsing_block; + current_event_field.Initializer = (Expression) $3; } ; - -event_accessor_declarations - : add_accessor_declaration remove_accessor_declaration + +opt_event_declarators + : /* empty */ + | event_declarators + ; + +event_declarators + : event_declarator + { + current_event_field.AddDeclarator ((FieldDeclarator) $1); + } + | event_declarators event_declarator { - $$ = new Accessors ((Accessor) $1, (Accessor) $2); + current_event_field.AddDeclarator ((FieldDeclarator) $2); } + ; + +event_declarator + : COMMA IDENTIFIER + { + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null); + lbag.AddLocation ($$, GetLocation ($1)); + } + | COMMA IDENTIFIER ASSIGN + { + ++lexer.parsing_block; + } + event_variable_initializer + { + --lexer.parsing_block; + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); + } + ; + +event_variable_initializer + : { + if (current_container.Kind == MemberKind.Interface) { + Report.Error (68, lexer.Location, "`{0}': event in interface cannot have an initializer", + current_event_field.GetSignatureForError ()); + } + + if ((current_event_field.ModFlags & Modifiers.ABSTRACT) != 0) { + Report.Error (74, lexer.Location, "`{0}': abstract event cannot have an initializer", + current_event_field.GetSignatureForError ()); + } + } + variable_initializer + { + $$ = $2; + } + ; + +event_accessor_declarations + : add_accessor_declaration remove_accessor_declaration | remove_accessor_declaration add_accessor_declaration + | add_accessor_declaration + { + Report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors", + current_event.GetSignatureForError ()); + } + | remove_accessor_declaration { - Accessors accessors = new Accessors ((Accessor) $2, (Accessor) $1); - accessors.declared_in_reverse = true; - $$ = accessors; + Report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors", + current_event.GetSignatureForError ()); } - | add_accessor_declaration { $$ = null; } - | remove_accessor_declaration { $$ = null; } | error { Report.Error (1055, GetLocation ($1), "An add or remove accessor expected"); $$ = null; } - | { $$ = null; } ; add_accessor_declaration - : opt_attributes ADD + : opt_attributes opt_modifiers ADD { - lexer.EventParsing = false; + if ($2 != ModifierNone) { + Report.Error (1609, GetLocation ($2), "Modifiers cannot be placed on event accessor declarations"); + } + + current_event.Add = new EventProperty.AddDelegateMethod (current_event, (Attributes) $1, GetLocation ($3)); + current_local_parameters = current_event.Add.ParameterInfo; + + lbag.AddMember (current_event.Add, mod_locations); + lexer.EventParsing = false; } - block + event_accessor_block { - Accessor accessor = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, null, (Location) $2); lexer.EventParsing = true; - $$ = accessor; - } - | opt_attributes ADD error { - Report.Error (73, (Location) $2, "An add or remove accessor must have a body"); - $$ = null; - } - | opt_attributes modifiers ADD { - Report.Error (1609, (Location) $3, "Modifiers cannot be placed on event accessor declarations"); - $$ = null; + + current_event.Add.Block = (ToplevelBlock) $5; + + if (current_container.Kind == MemberKind.Interface) { + Report.Error (531, current_event.Add.Block.StartLocation, + "`{0}': interface members cannot have a definition", current_event.Add.GetSignatureForError ()); + } + + current_local_parameters = null; } ; - + remove_accessor_declaration - : opt_attributes REMOVE + : opt_attributes opt_modifiers REMOVE { - lexer.EventParsing = false; + if ($2 != ModifierNone) { + Report.Error (1609, GetLocation ($2), "Modifiers cannot be placed on event accessor declarations"); + } + + current_event.Remove = new EventProperty.RemoveDelegateMethod (current_event, (Attributes) $1, GetLocation ($3)); + current_local_parameters = current_event.Remove.ParameterInfo; + + lbag.AddMember (current_event.Remove, mod_locations); + lexer.EventParsing = false; } - block + event_accessor_block { - $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, null, (Location) $2); lexer.EventParsing = true; - } - | opt_attributes REMOVE error { - Report.Error (73, (Location) $2, "An add or remove accessor must have a body"); - $$ = null; - } - | opt_attributes modifiers REMOVE { - Report.Error (1609, (Location) $3, "Modifiers cannot be placed on event accessor declarations"); - $$ = null; - } - ; - -indexer_declaration - : opt_attributes opt_modifiers - member_type indexer_declaration_name OPEN_BRACKET opt_parameter_list_no_mod CLOSE_BRACKET - OPEN_BRACE - { - implicit_value_parameter_type = (FullNamedExpression) $3; - indexer_parameters = (ParametersCompiled) $6; + + current_event.Remove.Block = (ToplevelBlock) $5; - if (indexer_parameters.IsEmpty) - Report.Error (1551, GetLocation ($5), "Indexers must have at least one parameter"); - - if (RootContext.Documentation != null) { - tmpComment = Lexer.consume_doc_comment (); - Lexer.doc_state = XmlCommentState.Allowed; + if (current_container.Kind == MemberKind.Interface) { + Report.Error (531, current_event.Remove.Block.StartLocation, + "`{0}': interface members cannot have a definition", current_event.Remove.GetSignatureForError ()); } - - lexer.PropertyParsing = true; - parsing_indexer = true; + current_local_parameters = null; } - accessor_declarations - { - lexer.PropertyParsing = false; - has_get = has_set = false; - parsing_indexer = false; - } - CLOSE_BRACE - { - Accessors accessors = (Accessors) $10; - Accessor get_block = accessors != null ? accessors.get_or_add : null; - Accessor set_block = accessors != null ? accessors.set_or_remove : null; - bool order = accessors != null ? accessors.declared_in_reverse : false; - - Indexer indexer = new Indexer (current_class, (FullNamedExpression) $3, - (MemberName)$4, (int) $2, (ParametersCompiled) $6, (Attributes) $1, - get_block, set_block, order); - - if ($3 == TypeManager.system_void_expr) - Report.Error (620, GetLocation ($3), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ()); - - if (accessors == null) - Report.Error (548, indexer.Location, "`{0}': property or indexer must have at least one accessor", indexer.GetSignatureForError ()); - - if (current_container.Kind == Kind.Interface) { - if (indexer.Get.Block != null) - Report.Error (531, indexer.Location, "`{0}.get': interface members cannot have a definition", indexer.GetSignatureForError ()); - - if (indexer.Set.Block != null) - Report.Error (531, indexer.Location, "`{0}.set': interface members cannot have a definition", indexer.GetSignatureForError ()); - } - - if (RootContext.Documentation != null) - indexer.DocComment = ConsumeStoredComment (); + ; - current_container.AddIndexer (indexer); - - current_local_parameters = null; - implicit_value_parameter_type = null; - indexer_parameters = null; +event_accessor_block + : opt_semicolon + { + Report.Error (73, lexer.Location, "An add or remove accessor must have a body"); + $$ = null; } + | block; ; enum_declaration : opt_attributes opt_modifiers ENUM type_declaration_name - opt_enum_base { + opt_enum_base + { if (RootContext.Documentation != null) enumTypeComment = Lexer.consume_doc_comment (); } - enum_body - opt_semicolon + OPEN_BRACE { + if (RootContext.Documentation != null) + Lexer.doc_state = XmlCommentState.Allowed; + MemberName name = (MemberName) $4; if (name.IsGeneric) { Report.Error (1675, name.Location, "Enums cannot have type parameters"); } - - name = MakeName (name); - Enum e = new Enum (current_namespace, current_class, (TypeExpr) $5, (int) $2, - name, (Attributes) $1); + push_current_class (new Enum (current_namespace, current_class, (TypeExpression) $5, (Modifiers) $2, MakeName (name), (Attributes) $1), null); + } + opt_enum_member_declarations + { + // here will be evaluated after CLOSE_BLACE is consumed. if (RootContext.Documentation != null) - e.DocComment = enumTypeComment; - - - EnumMember em = null; - foreach (VariableDeclaration ev in (ArrayList) $7) { - em = new EnumMember ( - e, em, ev.identifier, (Expression) ev.expression_or_array_initializer, - ev.OptAttributes, ev.Location); + Lexer.doc_state = XmlCommentState.Allowed; + } + CLOSE_BRACE opt_semicolon + { + if (RootContext.Documentation != null) + current_class.DocComment = enumTypeComment; + + --lexer.parsing_declaration; // if (RootContext.Documentation != null) - em.DocComment = ev.DocComment; - - e.AddEnumMember (em); - } - if (RootContext.EvalMode) - undo.AddTypeContainer (current_container, e); - - current_container.AddTypeContainer (e); - - $$ = e; +// em.DocComment = ev.DocComment; + lbag.AddMember (current_class, mod_locations, GetLocation ($3), GetLocation ($7), GetLocation ($11)); + $$ = pop_current_class (); } ; opt_enum_base - : /* empty */ { $$ = TypeManager.system_int32_expr; } + : /* empty */ | COLON type { - if ($2 != TypeManager.system_int32_expr && $2 != TypeManager.system_uint32_expr && - $2 != TypeManager.system_int64_expr && $2 != TypeManager.system_uint64_expr && - $2 != TypeManager.system_int16_expr && $2 != TypeManager.system_uint16_expr && - $2 != TypeManager.system_byte_expr && $2 != TypeManager.system_sbyte_expr) - Enum.Error_1008 (GetLocation ($2)); - - $$ = $2; + var te = $2 as TypeExpression; + if (te == null || + (te.Type != TypeManager.int32_type && te.Type != TypeManager.uint32_type && + te.Type != TypeManager.int64_type && te.Type != TypeManager.uint64_type && + te.Type != TypeManager.short_type && te.Type != TypeManager.ushort_type && + te.Type != TypeManager.byte_type && te.Type != TypeManager.sbyte_type)) { + Enum.Error_1008 (GetLocation ($2), Report); + $$ = null; + } else { + $$ = $2; + } } | COLON error { - Error_TypeExpected (lexer.Location); + Error_TypeExpected (GetLocation ($1)); + $$ = null; } ; -enum_body - : OPEN_BRACE - { - 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 +opt_enum_member_declarations + : /* empty */ + | enum_member_declarations + | enum_member_declarations COMMA { - $$ = $3; + lbag.AddLocation ($1, GetLocation ($2)); } ; -opt_enum_member_declarations - : /* empty */ { $$ = new ArrayList (4); } - | enum_member_declarations opt_comma { $$ = $1; } - ; - enum_member_declarations - : enum_member_declaration - { - ArrayList l = new ArrayList (4); - - l.Add ($1); - $$ = l; - } + : enum_member_declaration | enum_member_declarations COMMA enum_member_declaration { - ArrayList l = (ArrayList) $1; - - l.Add ($3); - - $$ = l; + lbag.AddLocation ($1, GetLocation ($2)); + $$ = $3; } ; enum_member_declaration - : opt_attributes IDENTIFIER + : opt_attributes IDENTIFIER { - VariableDeclaration vd = new VariableDeclaration ( - (LocatedToken) $2, null, (Attributes) $1); + var lt = (Tokenizer.LocatedToken) $2; + var em = new EnumMember ((Enum) current_class, new MemberName (lt.Value, lt.Location), (Attributes) $1); + ((Enum) current_class).AddEnumMember (em); if (RootContext.Documentation != null) { - vd.DocComment = Lexer.consume_doc_comment (); + em.DocComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } - $$ = vd; + $$ = em; } | opt_attributes IDENTIFIER { @@ -2540,14 +2648,17 @@ enum_member_declaration } ASSIGN constant_expression { - --lexer.parsing_block; - VariableDeclaration vd = new VariableDeclaration ( - (LocatedToken) $2, $5, (Attributes) $1); - + --lexer.parsing_block; + + var lt = (Tokenizer.LocatedToken) $2; + var em = new EnumMember ((Enum) current_class, new MemberName (lt.Value, lt.Location), (Attributes) $1); + em.Initializer = new ConstInitializer (em, (Expression) $5, GetLocation ($4)); + ((Enum) current_class).AddEnumMember (em); + if (RootContext.Documentation != null) - vd.DocComment = ConsumeStoredComment (); + em.DocComment = ConsumeStoredComment (); - $$ = vd; + $$ = em; } ; @@ -2556,13 +2667,19 @@ delegate_declaration opt_modifiers DELEGATE member_type type_declaration_name - OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + OPEN_PARENS + { + valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue; + } + opt_formal_parameter_list CLOSE_PARENS { + valid_param_mod = 0; + MemberName name = MakeName ((MemberName) $5); - ParametersCompiled p = (ParametersCompiled) $7; + ParametersCompiled p = (ParametersCompiled) $8; Delegate del = new Delegate (current_namespace, current_class, (FullNamedExpression) $4, - (int) $2, name, p, (Attributes) $1); + (Modifiers) $2, name, p, (Attributes) $1); if (RootContext.Documentation != null) { del.DocComment = Lexer.consume_doc_comment (); @@ -2579,7 +2696,9 @@ delegate_declaration } SEMICOLON { - current_delegate.SetParameterInfo ((ArrayList) $10); + current_delegate.SetParameterInfo ((List) $11); + lbag.AddMember (current_delegate, mod_locations, GetLocation ($3), GetLocation ($6), GetLocation ($9), GetLocation ($13)); + $$ = current_delegate; current_delegate = null; @@ -2593,10 +2712,12 @@ opt_nullable } | INTERR_NULLABLE { - if (RootContext.Version < LanguageVersion.ISO_2) - Report.FeatureIsNotAvailable (lexer.Location, "nullable types"); + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (GetLocation ($1), "nullable types"); + else if (RootContext.Version < LanguageVersion.ISO_2) + Report.FeatureIsNotAvailable (GetLocation ($1), "nullable types"); - $$ = this; + $$ = ComposedTypeSpecifier.CreateNullable (GetLocation ($1)); } ; @@ -2604,8 +2725,8 @@ namespace_or_type_name : member_name | qualified_alias_member IDENTIFIER opt_type_argument_list { - LocatedToken lt1 = (LocatedToken) $1; - LocatedToken lt2 = (LocatedToken) $2; + var lt1 = (Tokenizer.LocatedToken) $1; + var lt2 = (Tokenizer.LocatedToken) $2; $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); } @@ -2615,15 +2736,16 @@ member_name : type_name | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } ; type_name : IDENTIFIER opt_type_argument_list { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; $$ = new MemberName (lt.Value, (TypeArguments)$2, lt.Location); } ; @@ -2635,7 +2757,9 @@ opt_type_argument_list : /* empty */ { $$ = null; } | OP_GENERICS_LT type_arguments OP_GENERICS_GT { - if (RootContext.Version < LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (GetLocation ($1), "generics"); + else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "generics"); $$ = $2; @@ -2673,7 +2797,7 @@ type_declaration_name opt_type_parameter_list { lexer.parsing_generic_declaration = false; - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; $$ = new MemberName (lt.Value, (TypeArguments)$3, lt.Location); } ; @@ -2693,7 +2817,7 @@ method_declaration_name | explicit_interface IDENTIFIER opt_type_parameter_list { lexer.parsing_generic_declaration = false; - LocatedToken lt = (LocatedToken) $2; + var lt = (Tokenizer.LocatedToken) $2; $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $3, lt.Location); } ; @@ -2714,20 +2838,23 @@ indexer_declaration_name explicit_interface : IDENTIFIER opt_type_argument_list DOT { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location); + lbag.AddLocation ($$, GetLocation ($3)); } | qualified_alias_member IDENTIFIER opt_type_argument_list DOT { - LocatedToken lt1 = (LocatedToken) $1; - LocatedToken lt2 = (LocatedToken) $2; + var lt1 = (Tokenizer.LocatedToken) $1; + var lt2 = (Tokenizer.LocatedToken) $2; $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); + lbag.AddLocation ($$, GetLocation ($4)); } | explicit_interface IDENTIFIER opt_type_argument_list DOT { - LocatedToken lt = (LocatedToken) $2; + var lt = (Tokenizer.LocatedToken) $2; $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $3, lt.Location); + lbag.AddLocation ($$, GetLocation ($4)); } ; @@ -2735,10 +2862,13 @@ opt_type_parameter_list : /* empty */ { $$ = null; } | OP_GENERICS_LT_DECL type_parameters OP_GENERICS_GT { - if (RootContext.Version < LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (GetLocation ($1), "generics"); + else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "generics"); $$ = $2; + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } ; @@ -2754,14 +2884,15 @@ type_parameters TypeArguments type_args = (TypeArguments) $1; type_args.Add ((FullNamedExpression)$3); $$ = type_args; + lbag.AddLocation ($3, GetLocation ($3)); } ; type_parameter : opt_attributes opt_type_parameter_variance IDENTIFIER { - LocatedToken lt = (LocatedToken)$3; - $$ = new TypeParameterName (lt.Value, (Attributes)$1, (Variance)$2, lt.Location); + var lt = (Tokenizer.LocatedToken)$3; + $$ = new TypeParameterName (lt.Value, (Attributes)$1, (Variance) $2, lt.Location); } | error { @@ -2781,7 +2912,7 @@ type_and_void : type_expression_or_array | VOID { - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2791,7 +2922,7 @@ member_type lexer.parsing_generic_declaration = true; } ; - + // // A type which does not allow `void' to be used // @@ -2799,8 +2930,8 @@ type : type_expression_or_array | VOID { - Expression.Error_VoidInvalidInTheContext (lexer.Location); - $$ = TypeManager.system_void_expr; + Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report); + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2808,17 +2939,25 @@ simple_type : type_expression | VOID { - Expression.Error_VoidInvalidInTheContext (lexer.Location); - $$ = TypeManager.system_void_expr; + Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report); + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } - ; + ; + +parameter_type + : type_expression_or_array + | VOID + { + Report.Error (1536, GetLocation ($1), "Invalid parameter type `void'"); + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); + } + ; type_expression_or_array : type_expression | type_expression rank_specifiers { - string rank_specifiers = (string) $2; - $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, rank_specifiers); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } ; @@ -2828,11 +2967,10 @@ type_expression MemberName name = (MemberName) $1; if ($2 != null) { - $$ = new ComposedCast (name.GetTypeExpression (), "?", lexer.Location); + $$ = new ComposedCast (name.GetTypeExpression (), (ComposedTypeSpecifier) $2); } else { - if (name.Left == null && name.Name == "var" && - (RootContext.Version > LanguageVersion.ISO_2 || RootContext.Version == LanguageVersion.Default_MCS)) - $$ = current_array_type = new VarExpr (name.Location); + if (name.Left == null && name.Name == "var") + $$ = new VarExpr (name.Location); else $$ = name.GetTypeExpression (); } @@ -2840,7 +2978,7 @@ type_expression | builtin_types opt_nullable { if ($2 != null) - $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } | type_expression STAR { @@ -2849,25 +2987,25 @@ type_expression // can't perform checks during this phase - we do it during // semantic analysis. // - $$ = new ComposedCast ((FullNamedExpression) $1, "*", Lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } | VOID STAR { - $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1); + $$ = new ComposedCast (new TypeExpression (TypeManager.void_type, GetLocation ($1)), ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } ; type_list : base_type_name { - ArrayList types = new ArrayList (2); - types.Add ($1); + var types = new List (2); + types.Add ((FullNamedExpression) $1); $$ = types; } | type_list COMMA base_type_name { - ArrayList types = (ArrayList) $1; - types.Add ($3); + var types = (List) $1; + types.Add ((FullNamedExpression) $3); $$ = types; } ; @@ -2875,13 +3013,15 @@ type_list base_type_name : type { - if ($1 is ComposedCast) + if ($1 is ComposedCast) { Report.Error (1521, GetLocation ($1), "Invalid base type `{0}'", ((ComposedCast)$1).GetSignatureForError ()); + } $$ = $1; } | error { Error_TypeExpected (lexer.Location); + $$ = null; } ; @@ -2890,33 +3030,25 @@ base_type_name * simple types, but we need this to reuse it easily in variable_type */ builtin_types - : OBJECT { $$ = TypeManager.system_object_expr; } - | STRING { $$ = TypeManager.system_string_expr; } - | BOOL { $$ = TypeManager.system_boolean_expr; } - | DECIMAL { $$ = TypeManager.system_decimal_expr; } - | FLOAT { $$ = TypeManager.system_single_expr; } - | DOUBLE { $$ = TypeManager.system_double_expr; } + : OBJECT { $$ = new TypeExpression (TypeManager.object_type, GetLocation ($1)); } + | STRING { $$ = new TypeExpression (TypeManager.string_type, GetLocation ($1)); } + | BOOL { $$ = new TypeExpression (TypeManager.bool_type, GetLocation ($1)); } + | DECIMAL { $$ = new TypeExpression (TypeManager.decimal_type, GetLocation ($1)); } + | FLOAT { $$ = new TypeExpression (TypeManager.float_type, GetLocation ($1)); } + | DOUBLE { $$ = new TypeExpression (TypeManager.double_type, GetLocation ($1)); } | integral_type ; integral_type - : SBYTE { $$ = TypeManager.system_sbyte_expr; } - | BYTE { $$ = TypeManager.system_byte_expr; } - | SHORT { $$ = TypeManager.system_int16_expr; } - | USHORT { $$ = TypeManager.system_uint16_expr; } - | INT { $$ = TypeManager.system_int32_expr; } - | UINT { $$ = TypeManager.system_uint32_expr; } - | LONG { $$ = TypeManager.system_int64_expr; } - | ULONG { $$ = TypeManager.system_uint64_expr; } - | CHAR { $$ = TypeManager.system_char_expr; } - ; - -predefined_type - : builtin_types - | VOID - { - $$ = TypeManager.system_void_expr; - } + : SBYTE { $$ = new TypeExpression (TypeManager.sbyte_type, GetLocation ($1)); } + | BYTE { $$ = new TypeExpression (TypeManager.byte_type, GetLocation ($1)); } + | SHORT { $$ = new TypeExpression (TypeManager.short_type, GetLocation ($1)); } + | USHORT { $$ = new TypeExpression (TypeManager.ushort_type, GetLocation ($1)); } + | INT { $$ = new TypeExpression (TypeManager.int32_type, GetLocation ($1)); } + | UINT { $$ = new TypeExpression (TypeManager.uint32_type, GetLocation ($1)); } + | LONG { $$ = new TypeExpression (TypeManager.int64_type, GetLocation ($1)); } + | ULONG { $$ = new TypeExpression (TypeManager.uint64_type, GetLocation ($1)); } + | CHAR { $$ = new TypeExpression (TypeManager.char_type, GetLocation ($1)); } ; // @@ -2933,11 +3065,11 @@ primary_expression_no_array_creation : literal | IDENTIFIER opt_type_argument_list { - LocatedToken lt = (LocatedToken) $1; - $$ = new SimpleName (MemberName.MakeName (lt.Value, (TypeArguments)$2), (TypeArguments)$2, lt.Location); + var lt = (Tokenizer.LocatedToken) $1; + $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location); } | IDENTIFIER GENERATE_COMPLETION { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location); } | parenthesized_expression @@ -2961,39 +3093,13 @@ primary_expression_no_array_creation literal : boolean_literal - | integer_literal - | real_literal - | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value, lexer.Location); } - | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value, lexer.Location); } - | NULL { $$ = new NullLiteral (lexer.Location); } - ; - -real_literal - : LITERAL_FLOAT { $$ = new FloatLiteral ((float) lexer.Value, lexer.Location); } - | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value, lexer.Location); } - | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value, lexer.Location); } - ; - -integer_literal - : LITERAL_INTEGER { - object v = lexer.Value; - - if (v is int){ - $$ = new IntLiteral ((int) v, lexer.Location); - } else if (v is uint) - $$ = new UIntLiteral ((UInt32) v, lexer.Location); - else if (v is long) - $$ = new LongLiteral ((Int64) v, lexer.Location); - else if (v is ulong) - $$ = new ULongLiteral ((UInt64) v, lexer.Location); - else - Console.WriteLine ("OOPS. Unexpected result from scanner"); - } + | LITERAL + | NULL { $$ = new NullLiteral (GetLocation ($1)); } ; boolean_literal - : TRUE { $$ = new BoolLiteral (true, lexer.Location); } - | FALSE { $$ = new BoolLiteral (false, lexer.Location); } + : TRUE { $$ = new BoolLiteral (true, GetLocation ($1)); } + | FALSE { $$ = new BoolLiteral (false, GetLocation ($1)); } ; @@ -3005,13 +3111,23 @@ boolean_literal open_parens_any : OPEN_PARENS | OPEN_PARENS_CAST - | OPEN_PARENS_LAMBDA ; +// +// Use this production to accept closing parenthesis or +// performing completion +// +close_parens + : CLOSE_PARENS + | COMPLETE_COMPLETION + ; + + parenthesized_expression : OPEN_PARENS expression CLOSE_PARENS { $$ = new ParenthesizedExpression ((Expression) $2); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } | OPEN_PARENS expression COMPLETE_COMPLETION { @@ -3022,19 +3138,20 @@ parenthesized_expression member_access : primary_expression DOT IDENTIFIER opt_type_argument_list { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } - | predefined_type DOT IDENTIFIER opt_type_argument_list + | builtin_types DOT IDENTIFIER opt_type_argument_list { - LocatedToken lt = (LocatedToken) $3; - // TODO: Location is wrong as some predefined types doesn't hold a location + var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } | qualified_alias_member IDENTIFIER opt_type_argument_list { - LocatedToken lt1 = (LocatedToken) $1; - LocatedToken lt2 = (LocatedToken) $2; + var lt1 = (Tokenizer.LocatedToken) $1; + var lt2 = (Tokenizer.LocatedToken) $2; $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); } @@ -3042,24 +3159,24 @@ member_access $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3)); } | primary_expression DOT IDENTIFIER GENERATE_COMPLETION { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); } - | predefined_type DOT GENERATE_COMPLETION + | builtin_types DOT GENERATE_COMPLETION { - // TODO: Location is wrong as some predefined types doesn't hold a location $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location); } - | predefined_type DOT IDENTIFIER GENERATE_COMPLETION { - LocatedToken lt = (LocatedToken) $3; + | builtin_types DOT IDENTIFIER GENERATE_COMPLETION { + var lt = (Tokenizer.LocatedToken) $3; $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); } ; invocation_expression - : primary_expression open_parens_any opt_argument_list CLOSE_PARENS + : primary_expression open_parens_any opt_argument_list close_parens { - $$ = new Invocation ((Expression) $1, (ArrayList) $3); + $$ = new Invocation ((Expression) $1, (Arguments) $3); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3069,16 +3186,20 @@ opt_object_or_collection_initializer ; object_or_collection_initializer - : OPEN_BRACE opt_member_initializer_list CLOSE_BRACE + : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion { - if ($2 == null) - $$ = CollectionOrObjectInitializers.Empty; - else - $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1)); + if ($2 == null) { + $$ = CollectionOrObjectInitializers.Empty; + // TODO: lbag + } else { + $$ = new CollectionOrObjectInitializers ((List) $2, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); + } } | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE { - $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1)); + $$ = new CollectionOrObjectInitializers ((List) $2, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4)); } ; @@ -3093,35 +3214,51 @@ opt_member_initializer_list member_initializer_list : member_initializer { - ArrayList a = new ArrayList (); - a.Add ($1); + var a = new List (); + a.Add ((Expression) $1); $$ = a; } | member_initializer_list COMMA member_initializer { - ArrayList a = (ArrayList)$1; - a.Add ($3); + var a = (List)$1; + a.Add ((Expression) $3); $$ = a; } + | member_initializer_list error { + Error_SyntaxError (yyToken); + $$ = $1; + } ; member_initializer : IDENTIFIER ASSIGN initializer_value { - LocatedToken lt = $1 as LocatedToken; + var lt = (Tokenizer.LocatedToken) $1; $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } - | non_assignment_expression + | GENERATE_COMPLETION { - $$ = new CollectionElementInitializer ((Expression)$1); + $$ = new CompletionElementInitializer (null, GetLocation ($1)); + } + | non_assignment_expression opt_COMPLETE_COMPLETION { + CompletionSimpleName csn = $1 as CompletionSimpleName; + if (csn == null) + $$ = new CollectionElementInitializer ((Expression)$1); + else + $$ = new CompletionElementInitializer (csn.Prefix, csn.Location); } | OPEN_BRACE expression_list CLOSE_BRACE { - $$ = new CollectionElementInitializer ((ArrayList)$2, GetLocation ($1)); + if ($2 == null) + $$ = null; + else + $$ = new CollectionElementInitializer ((List)$2, GetLocation ($1)); } | OPEN_BRACE CLOSE_BRACE { Report.Error (1920, GetLocation ($1), "An element initializer cannot be empty"); + $$ = null; } ; @@ -3136,24 +3273,41 @@ opt_argument_list ; argument_list - : argument + : argument_or_named_argument { - ArrayList list = new ArrayList (4); - list.Add ($1); + Arguments list = new Arguments (4); + list.Add ((Argument) $1); $$ = list; } | argument_list COMMA argument { - ArrayList list = (ArrayList) $1; - list.Add ($3); + Arguments list = (Arguments) $1; + if (list [list.Count - 1] is NamedArgument) + Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]); + + list.Add ((Argument) $3); + $$ = list; + } + | argument_list COMMA named_argument + { + Arguments list = (Arguments) $1; + NamedArgument a = (NamedArgument) $3; + for (int i = 0; i < list.Count; ++i) { + NamedArgument na = list [i] as NamedArgument; + if (na != null && na.Name == a.Name) + Report.Error (1740, na.Location, "Named argument `{0}' specified multiple times", + na.Name); + } + + list.Add (a); $$ = list; } | argument_list COMMA { Report.Error (839, GetLocation ($2), "An argument is missing"); - $$ = null; + $$ = $1; } - | COMMA argument + | COMMA error { Report.Error (839, GetLocation ($1), "An argument is missing"); $$ = null; @@ -3163,200 +3317,220 @@ argument_list argument : expression { - $$ = new Argument ((Expression) $1, Argument.AType.Expression); + $$ = new Argument ((Expression) $1); } | non_simple_argument - { - $$ = $1; - } + ; + +argument_or_named_argument + : argument + | named_argument ; non_simple_argument : REF variable_reference { $$ = new Argument ((Expression) $2, Argument.AType.Ref); + lbag.AddLocation ($$, GetLocation ($1)); } | OUT variable_reference { $$ = new Argument ((Expression) $2, Argument.AType.Out); + lbag.AddLocation ($$, GetLocation ($1)); } - | ARGLIST open_parens_any argument_list CLOSE_PARENS + | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS { - ArrayList list = (ArrayList) $3; - Argument[] args = new Argument [list.Count]; - list.CopyTo (args, 0); - - Expression expr = new Arglist (args, (Location) $1); - $$ = new Argument (expr, Argument.AType.Expression); + $$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1))); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } - | ARGLIST open_parens_any CLOSE_PARENS + | ARGLIST OPEN_PARENS CLOSE_PARENS { - $$ = new Argument (new Arglist ((Location) $1), Argument.AType.Expression); + $$ = new Argument (new Arglist (GetLocation ($1))); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3)); } | ARGLIST { - $$ = new Argument (new ArglistAccess ((Location) $1), Argument.AType.ArgList); + $$ = new Argument (new ArglistAccess (GetLocation ($1))); } ; variable_reference - : expression { note ("section 5.4"); $$ = $1; } + : expression ; element_access - : primary_expression_no_array_creation OPEN_BRACKET expression_list CLOSE_BRACKET - { - $$ = new ElementAccess ((Expression) $1, (ArrayList) $3); - } - | array_creation_expression OPEN_BRACKET expression_list CLOSE_BRACKET - { - // LAMESPEC: Not allowed according to specification - $$ = new ElementAccess ((Expression) $1, (ArrayList) $3); - } - | primary_expression_no_array_creation rank_specifiers + : primary_expression OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET { - // So the super-trick is that primary_expression - // can only be either a SimpleName or a MemberAccess. - // The MemberAccess case arises when you have a fully qualified type-name like : - // Foo.Bar.Blah i; - // SimpleName is when you have - // Blah i; - - Expression expr = (Expression) $1; - if (expr is ComposedCast){ - $$ = new ComposedCast ((ComposedCast)expr, (string) $2); - } else if (expr is ATypeNameExpression){ - // - // So we extract the string corresponding to the SimpleName - // or MemberAccess - // - $$ = new ComposedCast ((ATypeNameExpression)expr, (string) $2); - } else { - Error_ExpectingTypeName (expr); - $$ = TypeManager.system_object_expr; - } - - current_array_type = (FullNamedExpression)$$; + $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); } ; expression_list : expression { - ArrayList list = new ArrayList (4); - list.Add ($1); + var list = new List (4); + list.Add ((Expression) $1); $$ = list; } | expression_list COMMA expression { - ArrayList list = (ArrayList) $1; - list.Add ($3); + var list = (List) $1; + list.Add ((Expression) $3); $$ = list; } + | expression_list error { + Error_SyntaxError (yyToken); + $$ = $1; + } + ; + +expression_list_arguments + : expression_list_argument + { + Arguments args = new Arguments (4); + args.Add ((Argument) $1); + $$ = args; + } + | expression_list_arguments COMMA expression_list_argument + { + Arguments args = (Arguments) $1; + args.Add ((Argument) $3); + $$ = args; + } + ; + +expression_list_argument + : expression + { + $$ = new Argument ((Expression) $1); + } + | named_argument ; this_access : THIS { - $$ = new This (current_block, (Location) $1); + $$ = new This (GetLocation ($1)); } ; base_access : BASE DOT IDENTIFIER opt_type_argument_list { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; $$ = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2)); } - | BASE OPEN_BRACKET expression_list CLOSE_BRACKET + | BASE OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET { - $$ = new BaseIndexerAccess ((ArrayList) $3, (Location) $1); + $$ = new BaseIndexerAccess ((Arguments) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } - | BASE error { - Report.Error (175, (Location) $1, "Use of keyword `base' is not valid in this context"); - $$ = null; + | BASE OPEN_BRACKET error + { + Error_SyntaxError (yyToken); + $$ = new BaseAccess (null, GetLocation ($1)); } ; post_increment_expression : primary_expression OP_INC { - $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1); + $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1, GetLocation ($2)); } ; post_decrement_expression : primary_expression OP_DEC { - $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1); + $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1, GetLocation ($2)); } ; - + object_or_delegate_creation_expression - : new_expr_start open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer + : NEW new_expr_type open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer { - if ($5 != null) { + if ($6 != null) { if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "object initializers"); - $$ = new NewInitialize ((Expression) $1, (ArrayList) $3, (CollectionOrObjectInitializers) $5, GetLocation ($1)); + $$ = new NewInitialize ((FullNamedExpression) $2, (Arguments) $4, (CollectionOrObjectInitializers) $6, GetLocation ($1)); + } else { + $$ = new New ((FullNamedExpression) $2, (Arguments) $4, GetLocation ($1)); } - else - $$ = new New ((Expression) $1, (ArrayList) $3, GetLocation ($1)); + + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5)); } - | new_expr_start object_or_collection_initializer + | NEW new_expr_type object_or_collection_initializer { if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "collection initializers"); - $$ = new NewInitialize ((Expression) $1, null, (CollectionOrObjectInitializers) $2, GetLocation ($1)); + $$ = new NewInitialize ((FullNamedExpression) $2, null, (CollectionOrObjectInitializers) $3, GetLocation ($1)); } ; array_creation_expression - : new_expr_start OPEN_BRACKET expression_list CLOSE_BRACKET - opt_rank_specifier // shift/reduce on OPEN_BRACE + : NEW new_expr_type OPEN_BRACKET_EXPR expression_list CLOSE_BRACKET + opt_rank_specifier opt_array_initializer { - $$ = new ArrayCreation ((FullNamedExpression) $1, (ArrayList) $3, (string) $5, (ArrayList) $6, GetLocation ($1)); + $$ = new ArrayCreation ((FullNamedExpression) $2, (List) $4, + new ComposedTypeSpecifier (((List) $4).Count, GetLocation ($3)) { + Next = (ComposedTypeSpecifier) $6 + }, (ArrayInitializer) $7, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5)); } - | new_expr_start rank_specifiers opt_array_initializer + | NEW new_expr_type rank_specifiers opt_array_initializer { - if ($3 == null) + if ($4 == null) Report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer"); - $$ = new ArrayCreation ((FullNamedExpression) $1, (string) $2, (ArrayList) $3, GetLocation ($1)); + $$ = new ArrayCreation ((FullNamedExpression) $2, (ComposedTypeSpecifier) $3, (ArrayInitializer) $4, GetLocation ($1)); } | NEW rank_specifiers array_initializer { - $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayList) $3, GetLocation ($1)); + if (RootContext.Version <= LanguageVersion.ISO_2) + Report.FeatureIsNotAvailable (GetLocation ($1), "implicitly typed arrays"); + + $$ = new ImplicitlyTypedArrayCreation ((ComposedTypeSpecifier) $2, (ArrayInitializer) $3, GetLocation ($1)); } - | new_expr_start error + | NEW new_expr_type OPEN_BRACKET CLOSE_BRACKET OPEN_BRACKET_EXPR error CLOSE_BRACKET { - Report.Error (1526, GetLocation ($1), "A new expression requires () or [] after type"); - $$ = null; + Report.Error (178, GetLocation ($6), "Invalid rank specifier, expecting `,' or `]'"); + $$ = new ArrayCreation ((FullNamedExpression) $2, null, GetLocation ($1)); + } + | NEW new_expr_type error + { + Error_SyntaxError (1526, yyToken, "Unexpected symbol"); + $$ = new ArrayCreation ((FullNamedExpression) $2, null, GetLocation ($1)); } ; -new_expr_start - : NEW - { +new_expr_type + : { ++lexer.parsing_type; } simple_type { --lexer.parsing_type; - $$ = $3; + $$ = $2; } ; anonymous_type_expression : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE { - if (RootContext.Version <= LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (GetLocation ($1), "anonymous types"); + else if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "anonymous types"); - $$ = new AnonymousTypeDeclaration ((ArrayList) $3, current_container, GetLocation ($1)); + $$ = new NewAnonymousType ((List) $3, current_container, GetLocation ($1)); + + // TODO: lbag comma location + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3373,14 +3547,14 @@ anonymous_type_parameters_opt anonymous_type_parameters : anonymous_type_parameter { - ArrayList a = new ArrayList (4); - a.Add ($1); + var a = new List (4); + a.Add ((AnonymousTypeParameter) $1); $$ = a; } | anonymous_type_parameters COMMA anonymous_type_parameter { - ArrayList a = (ArrayList) $1; - a.Add ($3); + var a = (List) $1; + a.Add ((AnonymousTypeParameter) $3); $$ = a; } ; @@ -3388,20 +3562,21 @@ anonymous_type_parameters anonymous_type_parameter : IDENTIFIER ASSIGN variable_initializer { - LocatedToken lt = (LocatedToken)$1; + var lt = (Tokenizer.LocatedToken)$1; $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } | IDENTIFIER { - LocatedToken lt = (LocatedToken)$1; + var lt = (Tokenizer.LocatedToken)$1; $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location), lt.Value, lt.Location); } | BASE DOT IDENTIFIER opt_type_argument_list { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; BaseAccess ba = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location); - $$ = new AnonymousTypeParameter (ba, lt.Value, lt.Location); + $$ = new AnonymousTypeParameter (ba, lt.Value, lt.Location); } | member_access { @@ -3410,36 +3585,30 @@ anonymous_type_parameter } | error { - Report.Error (746, lexer.Location, "Invalid anonymous type member declarator. " + - "Anonymous type members must be a member assignment, simple name or member access expression"); + Report.Error (746, lexer.Location, + "Invalid anonymous type member declarator. Anonymous type members must be a member assignment, simple name or member access expression"); + $$ = null; } ; opt_rank_specifier : /* empty */ { - $$ = ""; + $$ = null; } | rank_specifiers - { - $$ = $1; - } ; - -opt_rank_specifier_or_nullable - : opt_nullable - { - if ($1 != null) - $$ = "?"; - else - $$ = string.Empty; - } + +opt_rank_specifier_or_nullable + : opt_nullable | opt_nullable rank_specifiers { - if ($1 != null) - $$ = "?" + (string) $2; - else + if ($1 != null) { + ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2; + $$ = $1; + } else { $$ = $2; + } } ; @@ -3447,34 +3616,30 @@ rank_specifiers : rank_specifier | rank_specifier rank_specifiers { - $$ = (string) $2 + (string) $1; + ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2; + $$ = $1; } ; rank_specifier : OPEN_BRACKET CLOSE_BRACKET { - $$ = "[]"; + $$ = ComposedTypeSpecifier.CreateArrayDimension (1, GetLocation ($1)); } | OPEN_BRACKET dim_separators CLOSE_BRACKET { - $$ = "[" + (string) $2 + "]"; - } - | OPEN_BRACKET error CLOSE_BRACKET - { - ArrayCreation.Error_IncorrectArrayInitializer (GetLocation ($1)); - $$ = "[]"; + $$ = ComposedTypeSpecifier.CreateArrayDimension ((int)$2, GetLocation ($1)); } ; dim_separators : COMMA { - $$ = ","; + $$ = 2; } | dim_separators COMMA { - $$ = (string) $1 + ","; + $$ = ((int) $1) + 1; } ; @@ -3492,50 +3657,46 @@ opt_array_initializer array_initializer : OPEN_BRACE CLOSE_BRACE { - ArrayList list = new ArrayList (4); - $$ = list; + $$ = new ArrayInitializer (0, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2)); } | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE { - $$ = (ArrayList) $2; + $$ = new ArrayInitializer ((List) $2, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } ; variable_initializer_list : variable_initializer { - ArrayList list = new ArrayList (4); - list.Add ($1); + var list = new List (4); + list.Add ((Expression) $1); $$ = list; } | variable_initializer_list COMMA variable_initializer { - ArrayList list = (ArrayList) $1; - list.Add ($3); + var list = (List) $1; + list.Add ((Expression) $3); $$ = list; } | error { Error_SyntaxError (yyToken); - $$ = new ArrayList (); + $$ = new List (); } ; typeof_expression : TYPEOF { - pushed_current_array_type = current_array_type; lexer.TypeOfParsing = true; } open_parens_any typeof_type_expression CLOSE_PARENS { lexer.TypeOfParsing = false; - Expression type = (Expression)$4; - if (type == TypeManager.system_void_expr) - $$ = new TypeOfVoid ((Location) $1); - else - $$ = new TypeOf (type, (Location) $1); - current_array_type = pushed_current_array_type; + $$ = new TypeOf ((FullNamedExpression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5)); } ; @@ -3552,43 +3713,45 @@ typeof_type_expression unbound_type_name : IDENTIFIER generic_dimension { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; - $$ = new SimpleName (MemberName.MakeName (lt.Value, (int)$2), lt.Location); + $$ = new SimpleName (lt.Value, (int) $2, lt.Location); } | qualified_alias_member IDENTIFIER generic_dimension { - LocatedToken lt1 = (LocatedToken) $1; - LocatedToken lt2 = (LocatedToken) $2; + var lt1 = (Tokenizer.LocatedToken) $1; + var lt2 = (Tokenizer.LocatedToken) $2; - $$ = new QualifiedAliasMember (lt1.Value, MemberName.MakeName (lt2.Value, (int) $3), lt1.Location); + $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location); } | unbound_type_name DOT IDENTIFIER { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location); } | unbound_type_name DOT IDENTIFIER generic_dimension { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; - $$ = new MemberAccess ((Expression) $1, MemberName.MakeName (lt.Value, (int) $4), lt.Location); + $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location); } | namespace_or_type_name DOT IDENTIFIER generic_dimension { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; MemberName name = (MemberName) $1; - $$ = new MemberAccess (name.GetTypeExpression (), MemberName.MakeName (lt.Value, (int) $4), lt.Location); + $$ = new MemberAccess (name.GetTypeExpression (), lt.Value, (int) $4, lt.Location); } ; generic_dimension : GENERIC_DIMENSION { - if (RootContext.Version < LanguageVersion.ISO_2) - Report.FeatureIsNotAvailable (lexer.Location, "generics"); + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (GetLocation ($1), "generics"); + else if (RootContext.Version < LanguageVersion.ISO_2) + Report.FeatureIsNotAvailable (GetLocation ($1), "generics"); $$ = $1; } @@ -3597,7 +3760,7 @@ generic_dimension qualified_alias_member : IDENTIFIER DOUBLE_COLON { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; if (RootContext.Version == LanguageVersion.ISO_1) Report.FeatureIsNotAvailable (lt.Location, "namespace alias qualifier"); @@ -3606,40 +3769,41 @@ qualified_alias_member ; sizeof_expression - : SIZEOF open_parens_any type CLOSE_PARENS { - $$ = new SizeOf ((Expression) $3, (Location) $1); + : SIZEOF open_parens_any type CLOSE_PARENS + { + $$ = new SizeOf ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; checked_expression : CHECKED open_parens_any expression CLOSE_PARENS { - $$ = new CheckedExpr ((Expression) $3, (Location) $1); + $$ = new CheckedExpr ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; unchecked_expression : UNCHECKED open_parens_any expression CLOSE_PARENS { - $$ = new UnCheckedExpr ((Expression) $3, (Location) $1); + $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; pointer_member_access : primary_expression OP_PTR IDENTIFIER { - Expression deref; - LocatedToken lt = (LocatedToken) $3; - - deref = new Indirection ((Expression) $1, lt.Location); - $$ = new MemberAccess (deref, lt.Value); + var lt = (Tokenizer.LocatedToken) $3; + $$ = new MemberAccess (new Indirection ((Expression) $1, GetLocation ($2)), lt.Value, lt.Location); } ; anonymous_method_expression : DELEGATE opt_anonymous_method_signature { - start_anonymous (false, (ParametersCompiled) $2, (Location) $1); + start_anonymous (false, (ParametersCompiled) $2, GetLocation ($1)); } block { @@ -3658,11 +3822,11 @@ opt_anonymous_method_signature anonymous_method_signature : OPEN_PARENS { - params_modifiers_not_allowed = true; + valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; } opt_formal_parameter_list CLOSE_PARENS { - params_modifiers_not_allowed = false; + valid_param_mod = 0; $$ = $3; } ; @@ -3671,9 +3835,10 @@ default_value_expression : DEFAULT open_parens_any type CLOSE_PARENS { if (RootContext.Version < LanguageVersion.ISO_2) - Report.FeatureIsNotAvailable (lexer.Location, "default value expression"); + Report.FeatureIsNotAvailable (GetLocation ($1), "default value expression"); $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3681,11 +3846,11 @@ unary_expression : primary_expression | BANG prefixed_unary_expression { - $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2); + $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, GetLocation ($1)); } | TILDE prefixed_unary_expression { - $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2); + $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1)); } | cast_expression ; @@ -3694,10 +3859,12 @@ cast_expression : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression { $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } - | OPEN_PARENS predefined_type CLOSE_PARENS prefixed_unary_expression + | OPEN_PARENS builtin_types CLOSE_PARENS prefixed_unary_expression { $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } ; @@ -3709,19 +3876,19 @@ prefixed_unary_expression : unary_expression | PLUS prefixed_unary_expression { - $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2); + $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1)); } | MINUS prefixed_unary_expression { - $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2); + $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1)); } | OP_INC prefixed_unary_expression { - $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2); + $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2, GetLocation ($1)); } | OP_DEC prefixed_unary_expression { - $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2); + $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2, GetLocation ($1)); } | STAR prefixed_unary_expression { @@ -3729,7 +3896,7 @@ prefixed_unary_expression } | BITWISE_AND prefixed_unary_expression { - $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2); + $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1)); } ; @@ -3738,17 +3905,17 @@ multiplicative_expression | multiplicative_expression STAR prefixed_unary_expression { $$ = new Binary (Binary.Operator.Multiply, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } | multiplicative_expression DIV prefixed_unary_expression { $$ = new Binary (Binary.Operator.Division, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } | multiplicative_expression PERCENT prefixed_unary_expression { $$ = new Binary (Binary.Operator.Modulus, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3757,24 +3924,24 @@ additive_expression | additive_expression PLUS multiplicative_expression { $$ = new Binary (Binary.Operator.Addition, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } | additive_expression MINUS multiplicative_expression { - $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3); + $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2)); } | parenthesized_expression MINUS multiplicative_expression { // Shift/Reduce conflict - $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3); + $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2)); } | additive_expression AS type { - $$ = new As ((Expression) $1, (Expression) $3, (Location) $2); + $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2)); } | additive_expression IS type { - $$ = new Is ((Expression) $1, (Expression) $3, (Location) $2); + $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3783,12 +3950,12 @@ shift_expression | shift_expression OP_SHIFT_LEFT additive_expression { $$ = new Binary (Binary.Operator.LeftShift, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } | shift_expression OP_SHIFT_RIGHT additive_expression { $$ = new Binary (Binary.Operator.RightShift, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3797,22 +3964,22 @@ relational_expression | relational_expression OP_LT shift_expression { $$ = new Binary (Binary.Operator.LessThan, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } | relational_expression OP_GT shift_expression { $$ = new Binary (Binary.Operator.GreaterThan, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } | relational_expression OP_LE shift_expression { $$ = new Binary (Binary.Operator.LessThanOrEqual, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } | relational_expression OP_GE shift_expression { $$ = new Binary (Binary.Operator.GreaterThanOrEqual, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3821,12 +3988,12 @@ equality_expression | equality_expression OP_EQ relational_expression { $$ = new Binary (Binary.Operator.Equality, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } | equality_expression OP_NE relational_expression { $$ = new Binary (Binary.Operator.Inequality, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3835,7 +4002,7 @@ and_expression | and_expression BITWISE_AND equality_expression { $$ = new Binary (Binary.Operator.BitwiseAnd, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3844,7 +4011,7 @@ exclusive_or_expression | exclusive_or_expression CARRET and_expression { $$ = new Binary (Binary.Operator.ExclusiveOr, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3853,7 +4020,7 @@ inclusive_or_expression | inclusive_or_expression BITWISE_OR exclusive_or_expression { $$ = new Binary (Binary.Operator.BitwiseOr, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3862,7 +4029,7 @@ conditional_and_expression | conditional_and_expression OP_AND inclusive_or_expression { $$ = new Binary (Binary.Operator.LogicalAnd, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3871,7 +4038,7 @@ conditional_or_expression | conditional_or_expression OP_OR conditional_and_expression { $$ = new Binary (Binary.Operator.LogicalOr, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3882,7 +4049,7 @@ null_coalescing_expression if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator"); - $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, lexer.Location); + $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3890,78 +4057,79 @@ conditional_expression : null_coalescing_expression | null_coalescing_expression INTERR expression COLON expression { - $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5); + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); } ; assignment_expression : prefixed_unary_expression ASSIGN expression { - $$ = new SimpleAssign ((Expression) $1, (Expression) $3); + $$ = new SimpleAssign ((Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_MULT_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.Multiply, (Expression) $1, (Expression) $3); + Binary.Operator.Multiply, (Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_DIV_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.Division, (Expression) $1, (Expression) $3); + Binary.Operator.Division, (Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_MOD_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.Modulus, (Expression) $1, (Expression) $3); + Binary.Operator.Modulus, (Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_ADD_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.Addition, (Expression) $1, (Expression) $3); + Binary.Operator.Addition, (Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_SUB_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.Subtraction, (Expression) $1, (Expression) $3); + Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.LeftShift, (Expression) $1, (Expression) $3); + Binary.Operator.LeftShift, (Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.RightShift, (Expression) $1, (Expression) $3); + Binary.Operator.RightShift, (Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_AND_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3); + Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_OR_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3); + Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3, GetLocation ($2)); } | prefixed_unary_expression OP_XOR_ASSIGN expression { $$ = new CompoundAssign ( - Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3); + Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3, GetLocation ($2)); } ; lambda_parameter_list : lambda_parameter { - ArrayList pars = new ArrayList (4); - pars.Add ($1); + var pars = new List (4); + pars.Add ((Parameter) $1); $$ = pars; } | lambda_parameter_list COMMA lambda_parameter { - ArrayList pars = (ArrayList) $1; + var pars = (List) $1; Parameter p = (Parameter)$3; if (pars[0].GetType () != p.GetType ()) { Report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly"); @@ -3973,21 +4141,21 @@ lambda_parameter_list ; lambda_parameter - : parameter_modifier type IDENTIFIER + : parameter_modifier parameter_type IDENTIFIER { - LocatedToken lt = (LocatedToken) $3; + var lt = (Tokenizer.LocatedToken) $3; $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location); } - | type IDENTIFIER + | parameter_type IDENTIFIER { - LocatedToken lt = (LocatedToken) $2; + var lt = (Tokenizer.LocatedToken) $2; $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location); } | IDENTIFIER { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; $$ = new ImplicitLambdaParameter (lt.Value, lt.Location); } ; @@ -3995,8 +4163,8 @@ lambda_parameter opt_lambda_parameter_list : /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; } | lambda_parameter_list { - ArrayList pars_list = (ArrayList) $1; - $$ = new ParametersCompiled ((Parameter[])pars_list.ToArray (typeof (Parameter))); + var pars_list = (List) $1; + $$ = new ParametersCompiled (compiler, pars_list.ToArray ()); } ; @@ -4018,21 +4186,31 @@ lambda_expression_body lambda_expression : IDENTIFIER ARROW { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); - start_anonymous (true, new ParametersCompiled (p), GetLocation ($1)); + start_anonymous (true, new ParametersCompiled (compiler, p), GetLocation ($1)); } lambda_expression_body { $$ = end_anonymous ((ToplevelBlock) $4); + lbag.AddLocation ($$, GetLocation ($2)); + } + | OPEN_PARENS_LAMBDA + { + if (RootContext.Version <= LanguageVersion.ISO_2) + Report.FeatureIsNotAvailable (GetLocation ($1), "lambda expressions"); + + valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out; } - | OPEN_PARENS_LAMBDA opt_lambda_parameter_list CLOSE_PARENS ARROW + opt_lambda_parameter_list CLOSE_PARENS ARROW { - start_anonymous (true, (ParametersCompiled) $2, GetLocation ($1)); + valid_param_mod = 0; + start_anonymous (true, (ParametersCompiled) $3, GetLocation ($1)); } lambda_expression_body { - $$ = end_anonymous ((ToplevelBlock) $6); + $$ = end_anonymous ((ToplevelBlock) $7); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4)); } ; @@ -4044,7 +4222,7 @@ expression non_assignment_expression : conditional_expression | lambda_expression - | query_expression + | query_expression ; constant_expression @@ -4053,6 +4231,9 @@ constant_expression boolean_expression : expression + { + $$ = new BooleanExpression ((Expression) $1); + } ; // @@ -4069,28 +4250,30 @@ class_declaration type_declaration_name { MemberName name = MakeName ((MemberName) $6); - push_current_class (new Class (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3); + push_current_class (new Class (current_namespace, current_class, name, (Modifiers) $2, (Attributes) $1), $3); } opt_class_base opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; - current_class.SetParameterInfo ((ArrayList) $9); + current_class.SetParameterInfo ((List) $9); + lbag.AddMember (current_class, mod_locations, GetLocation ($4)); if (RootContext.Documentation != null) { current_container.DocComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } } - class_body + OPEN_BRACE opt_class_member_declarations CLOSE_BRACE { - --lexer.parsing_declaration; + --lexer.parsing_declaration; if (RootContext.Documentation != null) Lexer.doc_state = XmlCommentState.Allowed; } opt_semicolon { + lbag.AppendToMember (current_class, GetLocation ($11), GetLocation ($13), GetLocation ($15)); $$ = pop_current_class (); } ; @@ -4103,7 +4286,11 @@ opt_partial ; opt_modifiers - : /* empty */ { $$ = (int) 0; } + : /* empty */ + { + mod_locations = null; + $$ = ModifierNone; + } | modifiers ; @@ -4111,14 +4298,19 @@ modifiers : modifier | modifiers modifier { - int m1 = (int) $1; - int m2 = (int) $2; + var m1 = (Modifiers) $1; + var m2 = (Modifiers) $2; if ((m1 & m2) != 0) { - Location l = lexer.Location; - Report.Error (1004, l, "Duplicate `{0}' modifier", Modifiers.Name (m2)); + Report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length, + "Duplicate `{0}' modifier", ModifiersExtensions.Name (m2)); + } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 && + ((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) { + Report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length, + "More than one protection modifier specified"); } - $$ = (int) (m1 | m2); + + $$ = m1 | m2; } ; @@ -4126,53 +4318,113 @@ modifier : NEW { $$ = Modifiers.NEW; + StoreModifierLocation ($$, GetLocation ($1)); + if (current_container == RootContext.ToplevelTypes) - Report.Error (1530, lexer.Location, "Keyword `new' is not allowed on namespace elements"); - } - | PUBLIC { $$ = Modifiers.PUBLIC; } - | PROTECTED { $$ = Modifiers.PROTECTED; } - | INTERNAL { $$ = Modifiers.INTERNAL; } - | PRIVATE { $$ = Modifiers.PRIVATE; } - | ABSTRACT { $$ = Modifiers.ABSTRACT; } - | SEALED { $$ = Modifiers.SEALED; } - | STATIC { $$ = Modifiers.STATIC; } - | READONLY { $$ = Modifiers.READONLY; } - | VIRTUAL { $$ = Modifiers.VIRTUAL; } - | OVERRIDE { $$ = Modifiers.OVERRIDE; } - | EXTERN { $$ = Modifiers.EXTERN; } - | VOLATILE { $$ = Modifiers.VOLATILE; } - | UNSAFE { $$ = Modifiers.UNSAFE; } + Report.Error (1530, GetLocation ($1), "Keyword `new' is not allowed on namespace elements"); + } + | PUBLIC + { + $$ = Modifiers.PUBLIC; + StoreModifierLocation ($$, GetLocation ($1)); + } + | PROTECTED + { + $$ = Modifiers.PROTECTED; + StoreModifierLocation ($$, GetLocation ($1)); + } + | INTERNAL + { + $$ = Modifiers.INTERNAL; + StoreModifierLocation ($$, GetLocation ($1)); + } + | PRIVATE + { + $$ = Modifiers.PRIVATE; + StoreModifierLocation ($$, GetLocation ($1)); + } + | ABSTRACT + { + $$ = Modifiers.ABSTRACT; + StoreModifierLocation ($$, GetLocation ($1)); + } + | SEALED + { + $$ = Modifiers.SEALED; + StoreModifierLocation ($$, GetLocation ($1)); + } + | STATIC + { + $$ = Modifiers.STATIC; + StoreModifierLocation ($$, GetLocation ($1)); + } + | READONLY + { + $$ = Modifiers.READONLY; + StoreModifierLocation ($$, GetLocation ($1)); + } + | VIRTUAL + { + $$ = Modifiers.VIRTUAL; + StoreModifierLocation ($$, GetLocation ($1)); + } + | OVERRIDE + { + $$ = Modifiers.OVERRIDE; + StoreModifierLocation ($$, GetLocation ($1)); + } + | EXTERN + { + $$ = Modifiers.EXTERN; + StoreModifierLocation ($$, GetLocation ($1)); + } + | VOLATILE + { + $$ = Modifiers.VOLATILE; + StoreModifierLocation ($$, GetLocation ($1)); + } + | UNSAFE + { + $$ = Modifiers.UNSAFE; + StoreModifierLocation ($$, GetLocation ($1)); + if (!RootContext.Unsafe) + Error_UnsafeCodeNotAllowed (GetLocation ($1)); + } ; opt_class_base : /* empty */ - | class_base - ; - -class_base - : COLON type_list { current_container.AddBasesForPart (current_class, (ArrayList) $2); } + | COLON type_list + { + current_container.AddBasesForPart (current_class, (List) $2); + } ; opt_type_parameter_constraints_clauses : /* empty */ { $$ = null; } | type_parameter_constraints_clauses - { $$ = $1; } + { + $$ = $1; + } ; type_parameter_constraints_clauses - : type_parameter_constraints_clause { - ArrayList constraints = new ArrayList (1); - constraints.Add ($1); + : type_parameter_constraints_clause + { + var constraints = new List (1); + constraints.Add ((Constraints) $1); $$ = constraints; } - | type_parameter_constraints_clauses type_parameter_constraints_clause { - ArrayList constraints = (ArrayList) $1; + | type_parameter_constraints_clauses type_parameter_constraints_clause + { + var constraints = (List) $1; Constraints new_constraint = (Constraints)$2; foreach (Constraints c in constraints) { - if (new_constraint.TypeParameter == c.TypeParameter) { - Report.Error (409, new_constraint.Location, "A constraint clause has already been specified for type parameter `{0}'", - new_constraint.TypeParameter); + if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) { + Report.Error (409, new_constraint.Location, + "A constraint clause has already been specified for type parameter `{0}'", + new_constraint.TypeParameter.Value); } } @@ -4182,36 +4434,65 @@ type_parameter_constraints_clauses ; type_parameter_constraints_clause - : WHERE IDENTIFIER COLON type_parameter_constraints { - LocatedToken lt = (LocatedToken) $2; - $$ = new Constraints (lt.Value, (ArrayList) $4, lt.Location); + : WHERE IDENTIFIER COLON type_parameter_constraints + { + var lt = (Tokenizer.LocatedToken) $2; + $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List) $4, GetLocation ($1)); } ; type_parameter_constraints - : type_parameter_constraint { - ArrayList constraints = new ArrayList (1); - constraints.Add ($1); + : type_parameter_constraint + { + var constraints = new List (1); + constraints.Add ((FullNamedExpression) $1); $$ = constraints; } - | type_parameter_constraints COMMA type_parameter_constraint { - ArrayList constraints = (ArrayList) $1; + | type_parameter_constraints COMMA type_parameter_constraint + { + var constraints = (List) $1; + var prev = constraints [constraints.Count - 1] as SpecialContraintExpr; + if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) { + Report.Error (401, GetLocation ($2), "The `new()' constraint must be the last constraint specified"); + } + + prev = $3 as SpecialContraintExpr; + if (prev != null) { + if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) { + Report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified"); + } else { + prev = constraints [0] as SpecialContraintExpr; + if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) { + Report.Error (451, GetLocation ($3), "The `new()' constraint cannot be used with the `struct' constraint"); + } + } + } - constraints.Add ($3); + constraints.Add ((FullNamedExpression) $3); $$ = constraints; } ; type_parameter_constraint : type - | NEW OPEN_PARENS CLOSE_PARENS { - $$ = SpecialConstraint.Constructor; + { + if ($1 is ComposedCast) + Report.Error (706, GetLocation ($1), "Invalid constraint type `{0}'", ((ComposedCast)$1).GetSignatureForError ()); + + $$ = $1; + } + | NEW OPEN_PARENS CLOSE_PARENS + { + $$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3)); } - | CLASS { - $$ = SpecialConstraint.ReferenceType; + | CLASS + { + $$ = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation ($1)); } - | STRUCT { - $$ = SpecialConstraint.ValueType; + | STRUCT + { + $$ = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation ($1)); } ; @@ -4222,8 +4503,11 @@ opt_type_parameter_variance } | type_parameter_variance { - if (RootContext.Version < LanguageVersion.Future) - Report.FeatureIsNotAvailable (lexer.Location, "generic variance"); + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "generic type variance"); + else if (RootContext.Version <= LanguageVersion.V_3) + Report.FeatureIsNotAvailable (lexer.Location, "generic type variance"); + $$ = $1; } ; @@ -4256,19 +4540,19 @@ block : OPEN_BRACE { ++lexer.parsing_block; - start_block ((Location) $1); + start_block (GetLocation ($1)); } opt_statement_list block_end { $$ = $4; - } + } ; block_end : CLOSE_BRACE { --lexer.parsing_block; - $$ = end_block ((Location) $1); + $$ = end_block (GetLocation ($1)); } | COMPLETE_COMPLETION { @@ -4287,7 +4571,7 @@ block_prepared opt_statement_list CLOSE_BRACE { --lexer.parsing_block; - $$ = end_block ((Location) $4); + $$ = end_block (GetLocation ($4)); } ; @@ -4345,7 +4629,7 @@ interactive_statement valid_declaration_statement : block | empty_statement - | expression_statement + | expression_statement | selection_statement | iteration_statement | jump_statement @@ -4391,14 +4675,14 @@ embedded_statement empty_statement : SEMICOLON { - $$ = EmptyStatement.Value; + $$ = new EmptyStatement (GetLocation ($1)); } ; labeled_statement : IDENTIFIER COLON { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location); if (current_block.AddLabel (labeled)) @@ -4410,22 +4694,18 @@ labeled_statement declaration_statement : local_variable_declaration SEMICOLON { - current_array_type = null; if ($1 != null){ - DictionaryEntry de = (DictionaryEntry) $1; - Expression e = (Expression) de.Key; - - $$ = declare_local_variables (e, (ArrayList) de.Value, e.Location); + var de = (Tuple>) $1; + $$ = declare_local_variables (de.Item1, de.Item2, de.Item1.Location); } } | local_constant_declaration SEMICOLON { - current_array_type = null; if ($1 != null){ - DictionaryEntry de = (DictionaryEntry) $1; + var de = (Tuple>) $1; - $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value); + $$ = declare_local_constants (de.Item1, de.Item2); } } ; @@ -4439,8 +4719,6 @@ declaration_statement variable_type : primary_expression_no_array_creation opt_rank_specifier_or_nullable { - // FIXME: Do something smart here regarding the composition of the type. - // Ok, the above "primary_expression" is there to get rid of // both reduce/reduce and shift/reduces in the grammar, it should // really just be "type_name". If you use type_name, a reduce/reduce @@ -4456,41 +4734,30 @@ variable_type // Blah i; Expression expr = (Expression) $1; - string rank_or_nullable = (string) $2; - - if (expr is ComposedCast){ - $$ = new ComposedCast ((ComposedCast)expr, rank_or_nullable); - } else if (expr is ATypeNameExpression){ - // - // So we extract the string corresponding to the SimpleName - // or MemberAccess - // - if (rank_or_nullable.Length == 0) { - SimpleName sn = expr as SimpleName; - if (sn != null && sn.Name == "var" && - (RootContext.Version > LanguageVersion.ISO_2 || RootContext.Version == LanguageVersion.Default_MCS)) - $$ = current_array_type = new VarExpr (sn.Location); - else - $$ = $1; - } else { - $$ = new ComposedCast ((ATypeNameExpression)expr, rank_or_nullable); - } + if ($2 == null) { + SimpleName sn = expr as SimpleName; + if (sn != null && sn.Name == "var") + $$ = new VarExpr (sn.Location); + else + $$ = $1; + } else if (expr is ATypeNameExpression) { + $$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2); } else { Error_ExpectingTypeName (expr); - $$ = TypeManager.system_object_expr; + $$ = null; } } | builtin_types opt_rank_specifier_or_nullable { - if ((string) $2 == "") + if ($2 == null) $$ = $1; else - $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, (string) $2, lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } | VOID opt_rank_specifier { - Expression.Error_VoidInvalidInTheContext (lexer.Location); - $$ = TypeManager.system_void_expr; + Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report); + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -4500,7 +4767,7 @@ local_variable_pointer_type ATypeNameExpression expr = $1 as ATypeNameExpression; if (expr != null) { - $$ = new ComposedCast (expr, "*"); + $$ = new ComposedCast (expr, ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } else { Error_ExpectingTypeName ((Expression)$1); $$ = expr; @@ -4508,15 +4775,15 @@ local_variable_pointer_type } | builtin_types STAR { - $$ = new ComposedCast ((FullNamedExpression) $1, "*", GetLocation ($1)); + $$ = new ComposedCast ((FullNamedExpression) $1, ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } | VOID STAR { - $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1); + $$ = new ComposedCast (new TypeExpression (TypeManager.void_type, GetLocation ($1)), ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } | local_variable_pointer_type STAR { - $$ = new ComposedCast ((FullNamedExpression) $1, "*"); + $$ = new ComposedCast ((FullNamedExpression) $1, ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } ; @@ -4525,12 +4792,10 @@ local_variable_type | local_variable_pointer_type opt_rank_specifier { if ($1 != null){ - string rank = (string)$2; - - if (rank == "") + if ($2 == null) $$ = $1; else - $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, rank); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } else { $$ = null; } @@ -4542,27 +4807,64 @@ local_variable_declaration { if ($1 != null) { VarExpr ve = $1 as VarExpr; - if (ve != null) - ve.VariableInitializer = (ArrayList)$2; + if (ve != null) { + if (!((VariableDeclaration) ((List)$2) [0]).HasInitializer) + ve.VariableInitializersCount = 0; + else + ve.VariableInitializersCount = ((List)$2).Count; + } - $$ = new DictionaryEntry ($1, $2); + $$ = new Tuple> ((FullNamedExpression) $1, (List) $2); } else $$ = null; } ; local_constant_declaration - : CONST variable_type constant_declarators + : CONST variable_type local_constant_declarators { if ($2 != null) - $$ = new DictionaryEntry ($2, $3); + $$ = new Tuple> ((FullNamedExpression) $2, (List) $3); else $$ = null; } ; + +local_constant_declarators + : local_constant_declarator + { + variables_bucket.Clear (); + if ($1 != null) + variables_bucket.Add ($1); + $$ = variables_bucket; + } + | local_constant_declarators COMMA local_constant_declarator + { + if ($3 != null) { + var constants = (List) $1; + constants.Add ($3); + } + } + ; + +local_constant_declarator + : IDENTIFIER ASSIGN constant_initializer_expr + { + $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, (Expression) $3); + } + | IDENTIFIER error + { + Report.Error (145, GetLocation ($1), "A const field requires a value to be provided"); + $$ = null; + } + ; expression_statement - : statement_expression SEMICOLON { $$ = $1; } + : statement_expression SEMICOLON + { + $$ = $1; + lbag.AddStatement ($$, GetLocation ($2)); + } | statement_expression COMPLETE_COMPLETION { $$ = $1; } ; @@ -4580,7 +4882,7 @@ statement_expression { ExpressionStatement s = $1 as ExpressionStatement; if (s == null) { - ((Expression) $1).Error_InvalidExpressionStatement (); + Expression.Error_InvalidExpressionStatement (Report, GetLocation ($1)); s = EmptyExpressionStatement.Instance; } @@ -4605,7 +4907,7 @@ interactive_statement_expression | error { Error_SyntaxError (yyToken); - $$ = null; + $$ = new EmptyStatement (GetLocation ($1)); } ; @@ -4618,27 +4920,22 @@ if_statement : IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement { - Location l = (Location) $1; - - $$ = new If ((Expression) $3, (Statement) $5, l); - - // FIXME: location for warning should be loc property of $5. - if ($5 == EmptyStatement.Value) - Report.Warning (642, 3, l, "Possible mistaken empty statement"); - + if ($5 is EmptyStatement) + Report.Warning (642, 3, GetLocation ($5), "Possible mistaken empty statement"); + + $$ = new If ((BooleanExpression) $3, (Statement) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } | IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement ELSE embedded_statement { - Location l = (Location) $1; - - $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7, l); - - // FIXME: location for warning should be loc property of $5 and $7. - if ($5 == EmptyStatement.Value) - Report.Warning (642, 3, l, "Possible mistaken empty statement"); - if ($7 == EmptyStatement.Value) - Report.Warning (642, 3, l, "Possible mistaken empty statement"); + $$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6)); + + if ($5 is EmptyStatement) + Report.Warning (642, 3, GetLocation ($5), "Possible mistaken empty statement"); + if ($7 is EmptyStatement) + Report.Warning (642, 3, GetLocation ($7), "Possible mistaken empty statement"); } ; @@ -4646,31 +4943,24 @@ switch_statement : SWITCH open_parens_any { if (switch_stack == null) - switch_stack = new Stack (2); + switch_stack = new Stack (2); switch_stack.Push (current_block); } expression CLOSE_PARENS - switch_block + OPEN_BRACE opt_switch_sections CLOSE_BRACE { - $$ = new Switch ((Expression) $4, (ArrayList) $6, (Location) $1); + $$ = new Switch ((Expression) $4, (List) $7, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($5), GetLocation ($6), GetLocation ($8)); + current_block = (Block) switch_stack.Pop (); } ; -switch_block - : OPEN_BRACE - opt_switch_sections - CLOSE_BRACE - { - $$ = $2; - } - ; - opt_switch_sections : /* empty */ - { - Report.Warning (1522, 1, lexer.Location, "Empty switch block"); - $$ = new ArrayList (); + { + Report.Warning (1522, 1, lexer.Location, "Empty switch block"); + $$ = new List (); } | switch_sections ; @@ -4678,16 +4968,16 @@ opt_switch_sections switch_sections : switch_section { - ArrayList sections = new ArrayList (4); + var sections = new List (4); - sections.Add ($1); + sections.Add ((SwitchSection) $1); $$ = sections; } | switch_sections switch_section { - ArrayList sections = (ArrayList) $1; + var sections = (List) $1; - sections.Add ($2); + sections.Add ((SwitchSection) $2); $$ = sections; } ; @@ -4699,22 +4989,22 @@ switch_section } statement_list { - $$ = new SwitchSection ((ArrayList) $1, current_block.Explicit); + $$ = new SwitchSection ((List) $1, current_block.Explicit); } ; switch_labels : switch_label { - ArrayList labels = new ArrayList (4); + var labels = new List (4); - labels.Add ($1); + labels.Add ((SwitchLabel) $1); $$ = labels; } | switch_labels switch_label { - ArrayList labels = (ArrayList) ($1); - labels.Add ($2); + var labels = (List) ($1); + labels.Add ((SwitchLabel) $2); $$ = labels; } @@ -4723,11 +5013,12 @@ switch_labels switch_label : CASE constant_expression COLON { - $$ = new SwitchLabel ((Expression) $2, (Location) $1); + $$ = new SwitchLabel ((Expression) $2, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } | DEFAULT_COLON { - $$ = new SwitchLabel (null, (Location) $1); + $$ = new SwitchLabel (null, GetLocation ($1)); } ; @@ -4741,8 +5032,8 @@ iteration_statement while_statement : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement { - Location l = (Location) $1; - $$ = new While ((Expression) $3, (Statement) $5, l); + $$ = new While ((BooleanExpression) $3, (Statement) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -4750,9 +5041,8 @@ do_statement : DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON { - Location l = (Location) $1; - - $$ = new Do ((Statement) $2, (Expression) $5, l); + $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7)); } ; @@ -4763,13 +5053,12 @@ for_statement start_block (l); Block assign_block = current_block; - if ($3 is DictionaryEntry){ - DictionaryEntry de = (DictionaryEntry) $3; + if ($3 is Tuple>){ + var de = (Tuple>) $3; - Expression type = (Expression) de.Key; - ArrayList var_declarators = (ArrayList) de.Value; + var type = de.Item1; - foreach (VariableDeclaration decl in var_declarators){ + foreach (VariableDeclaration decl in de.Item2){ LocalInfo vi; @@ -4777,7 +5066,7 @@ for_statement if (vi == null) continue; - Expression expr = decl.expression_or_array_initializer; + Expression expr = decl.GetInitializer (type); LocalVariableReference var; var = new LocalVariableReference (assign_block, decl.identifier, l); @@ -4800,18 +5089,17 @@ for_statement opt_for_iterator CLOSE_PARENS embedded_statement { - Location l = (Location) $1; - - For f = new For ((Statement) $5, (Expression) $6, (Statement) $8, (Statement) $10, l); - + For f = new For ((Statement) $5, (BooleanExpression) $6, (Statement) $8, (Statement) $10, GetLocation ($1)); current_block.AddStatement (f); + + lbag.AddStatement (f, GetLocation ($2), GetLocation ($4), GetLocation ($7), GetLocation ($9)); $$ = end_block (lexer.Location); } ; opt_for_initializer - : /* empty */ { $$ = EmptyStatement.Value; } + : /* empty */ { $$ = new EmptyStatement (lexer.Location); } | for_initializer ; @@ -4826,7 +5114,7 @@ opt_for_condition ; opt_for_iterator - : /* empty */ { $$ = EmptyStatement.Value; } + : /* empty */ { $$ = new EmptyStatement (lexer.Location); } | for_iterator ; @@ -4835,28 +5123,24 @@ for_iterator ; statement_expression_list - : statement_expression - { - // CHANGE: was `null' - Statement s = (Statement) $1; - Block b = new Block (current_block, s.loc, lexer.Location); - - b.AddStatement (s); - $$ = b; - } + : statement_expression | statement_expression_list COMMA statement_expression { - Block b = (Block) $1; - - b.AddStatement ((Statement) $3); - $$ = $1; + var sl = $1 as StatementList; + if (sl == null) + sl = new StatementList ((Statement) $1, (Statement) $3); + else + sl.Add ((Statement) $3); + + lbag.AddStatement (sl, GetLocation ($2)); + $$ = sl; } ; foreach_statement : FOREACH open_parens_any type IN expression CLOSE_PARENS { - Report.Error (230, (Location) $1, "Type and identifier are both required in a foreach statement"); + Report.Error (230, GetLocation ($1), "Type and identifier are both required in a foreach statement"); $$ = null; } | FOREACH open_parens_any type IDENTIFIER IN @@ -4865,7 +5149,7 @@ foreach_statement start_block (lexer.Location); Block foreach_block = current_block; - LocatedToken lt = (LocatedToken) $4; + var lt = (Tokenizer.LocatedToken) $4; Location l = lt.Location; LocalInfo vi = foreach_block.AddVariable ((Expression) $3, lt.Value, l); if (vi != null) { @@ -4882,11 +5166,10 @@ foreach_statement } embedded_statement { - LocalVariableReference v = (LocalVariableReference) $8; - Location l = (Location) $1; - - if (v != null) { - Foreach f = new Foreach ((Expression) $3, v, (Expression) $6, (Statement) $9, l); + if ($8 != null) { + Foreach f = new Foreach ((Expression) $3, (LocalVariableReference) $8, (Expression) $6, (Statement) $9, GetLocation ($1)); + lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7)); + current_block.AddStatement (f); } @@ -4906,83 +5189,84 @@ jump_statement break_statement : BREAK SEMICOLON { - $$ = new Break ((Location) $1); + $$ = new Break (GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2)); } ; continue_statement : CONTINUE SEMICOLON { - $$ = new Continue ((Location) $1); + $$ = new Continue (GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2)); } ; goto_statement : GOTO IDENTIFIER SEMICOLON { - LocatedToken lt = (LocatedToken) $2; + var lt = (Tokenizer.LocatedToken) $2; $$ = new Goto (lt.Value, lt.Location); + lbag.AddStatement ($$, GetLocation ($1), GetLocation ($3)); } | GOTO CASE constant_expression SEMICOLON { - $$ = new GotoCase ((Expression) $3, (Location) $1); + $$ = new GotoCase ((Expression) $3, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } | GOTO DEFAULT SEMICOLON { - $$ = new GotoDefault ((Location) $1); + $$ = new GotoDefault (GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3)); } ; return_statement : RETURN opt_expression SEMICOLON { - $$ = new Return ((Expression) $2, (Location) $1); + $$ = new Return ((Expression) $2, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($3)); } ; throw_statement : THROW opt_expression SEMICOLON { - $$ = new Throw ((Expression) $2, (Location) $1); + $$ = new Throw ((Expression) $2, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($3)); } ; yield_statement - : IDENTIFIER RETURN expression SEMICOLON + : IDENTIFIER RETURN opt_expression SEMICOLON { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; string s = lt.Value; if (s != "yield"){ Report.Error (1003, lt.Location, "; expected"); - $$ = null; - } - if (RootContext.Version == LanguageVersion.ISO_1){ - Report.FeatureIsNotAvailable (lt.Location, "yield statement"); - $$ = null; + } else if ($3 == null) { + Report.Error (1627, GetLocation ($4), "Expression expected after yield return"); + } else if (RootContext.Version == LanguageVersion.ISO_1){ + Report.FeatureIsNotAvailable (lt.Location, "iterators"); } + current_block.Toplevel.IsIterator = true; - $$ = new Yield ((Expression) $3, lt.Location); - } - | IDENTIFIER RETURN SEMICOLON - { - Report.Error (1627, (Location) $2, "Expression expected after yield return"); - $$ = null; + $$ = new Yield ((Expression) $3, lt.Location); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } | IDENTIFIER BREAK SEMICOLON { - LocatedToken lt = (LocatedToken) $1; + var lt = (Tokenizer.LocatedToken) $1; string s = lt.Value; if (s != "yield"){ Report.Error (1003, lt.Location, "; expected"); - $$ = null; - } - if (RootContext.Version == LanguageVersion.ISO_1){ - Report.FeatureIsNotAvailable (lt.Location, "yield statement"); - $$ = null; + } else if (RootContext.Version == LanguageVersion.ISO_1){ + Report.FeatureIsNotAvailable (lt.Location, "iterators"); } current_block.Toplevel.IsIterator = true; $$ = new YieldBreak (lt.Location); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3)); } ; @@ -4994,19 +5278,21 @@ opt_expression try_statement : TRY block catch_clauses { - $$ = new TryCatch ((Block) $2, (ArrayList) $3, (Location) $1, false); + $$ = new TryCatch ((Block) $2, (List) $3, GetLocation ($1), false); } | TRY block FINALLY block { - $$ = new TryFinally ((Statement) $2, (Block) $4, (Location) $1); + $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($3)); } | TRY block catch_clauses FINALLY block { - $$ = new TryFinally (new TryCatch ((Block) $2, (ArrayList) $3, (Location) $1, true), (Block) $5, (Location) $1); + $$ = new TryFinally (new TryCatch ((Block) $2, (List) $3, GetLocation ($1), true), (Block) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($4)); } | TRY block error { - Report.Error (1524, (Location) $1, "Expected catch or finally"); + Report.Error (1524, GetLocation ($1), "Expected catch or finally"); $$ = null; } ; @@ -5014,16 +5300,25 @@ try_statement catch_clauses : catch_clause { - ArrayList l = new ArrayList (4); + var l = new List (2); - l.Add ($1); + l.Add ((Catch) $1); $$ = l; } | catch_clauses catch_clause { - ArrayList l = (ArrayList) $1; - - l.Add ($2); + var l = (List) $1; + + Catch c = (Catch) $2; + if (l [0].IsGeneral) { + Report.Error (1017, c.loc, "Try statement already has an empty catch block"); + } else { + if (c.IsGeneral) + l.Insert (0, c); + else + l.Add (c); + } + $$ = l; } ; @@ -5036,20 +5331,17 @@ opt_identifier catch_clause : CATCH opt_catch_args { - Expression type = null; - if ($2 != null) { - DictionaryEntry cc = (DictionaryEntry) $2; - type = (Expression) cc.Key; - LocatedToken lt = (LocatedToken) cc.Value; + var cc = (Tuple) $2; + var lt = cc.Item2; if (lt != null){ - ArrayList one = new ArrayList (4); + List one = new List (1); one.Add (new VariableDeclaration (lt, null)); start_block (lexer.Location); - current_block = declare_local_variables (type, one, lt.Location); + current_block = declare_local_variables (cc.Item1, one, lt.Location); } } } block { @@ -5058,9 +5350,9 @@ catch_clause Block var_block = null; if ($2 != null){ - DictionaryEntry cc = (DictionaryEntry) $2; - type = (Expression) cc.Key; - LocatedToken lt = (LocatedToken) cc.Value; + var cc = (Tuple) $2; + type = cc.Item1; + var lt = cc.Item2; if (lt != null){ id = lt.Value; @@ -5069,6 +5361,8 @@ catch_clause } $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc); + lbag.AddLocation ($$, GetLocation ($1)); + lbag.AppendTo ($$, lbag.GetLocations ($2)); } ; @@ -5080,34 +5374,37 @@ opt_catch_args catch_args : open_parens_any type opt_identifier CLOSE_PARENS { - $$ = new DictionaryEntry ($2, $3); + $$ = new Tuple ((FullNamedExpression)$2, (Tokenizer.LocatedToken) $3); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($4)); } | open_parens_any CLOSE_PARENS { Report.Error (1015, GetLocation ($1), "A type that derives from `System.Exception', `object', or `string' expected"); + $$ = null; } ; checked_statement : CHECKED block { - $$ = new Checked ((Block) $2); + $$ = new Checked ((Block) $2, GetLocation ($1)); } ; unchecked_statement : UNCHECKED block { - $$ = new Unchecked ((Block) $2); + $$ = new Unchecked ((Block) $2, GetLocation ($1)); } ; unsafe_statement - : UNSAFE + : UNSAFE { - RootContext.CheckUnsafeOption ((Location) $1); + if (!RootContext.Unsafe) + Error_UnsafeCodeNotAllowed (GetLocation ($1)); } block { - $$ = new Unsafe ((Block) $3); + $$ = new Unsafe ((Block) $3, GetLocation ($1)); } ; @@ -5116,32 +5413,23 @@ fixed_statement type_and_void fixed_pointer_declarators CLOSE_PARENS { - ArrayList list = (ArrayList) $4; - Expression type = (Expression) $3; - Location l = (Location) $1; - int top = list.Count; - start_block (lexer.Location); - - for (int i = 0; i < top; i++){ - Pair p = (Pair) list [i]; - LocalInfo v; - - v = current_block.AddVariable (type, (string) p.First, l); - if (v == null) - continue; - - v.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed); - v.Pinned = true; - p.First = v; - list [i] = p; - } } embedded_statement { - Location l = (Location) $1; + Expression type = (Expression) $3; + var list = (List>) $4; + Fixed f = new Fixed (type, + list.ConvertAll (i => { + var v = new KeyValuePair (current_block.AddVariable (type, i.Key.Value, i.Key.Location), i.Value); + if (v.Key != null) { + v.Key.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed); + v.Key.Pinned = true; + } + return v; + }), (Statement) $7, GetLocation ($1)); - Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l); + lbag.AddStatement (f, GetLocation ($2), GetLocation ($5)); current_block.AddStatement (f); @@ -5151,16 +5439,16 @@ fixed_statement fixed_pointer_declarators : fixed_pointer_declarator { - ArrayList declarators = new ArrayList (4); + var declarators = new List> (2); if ($1 != null) - declarators.Add ($1); + declarators.Add ((KeyValuePair)$1); $$ = declarators; } | fixed_pointer_declarators COMMA fixed_pointer_declarator { - ArrayList declarators = (ArrayList) $1; + var declarators = (List>) $1; if ($3 != null) - declarators.Add ($3); + declarators.Add ((KeyValuePair)$3); $$ = declarators; } ; @@ -5168,25 +5456,21 @@ fixed_pointer_declarators fixed_pointer_declarator : IDENTIFIER ASSIGN expression { - LocatedToken lt = (LocatedToken) $1; - // FIXME: keep location - $$ = new Pair (lt.Value, $3); + var lt = (Tokenizer.LocatedToken) $1; + $$ = new KeyValuePair (lt, (Expression) $3); } | IDENTIFIER { - Report.Error (210, ((LocatedToken) $1).Location, "You must provide an initializer in a fixed or using statement declaration"); + Report.Error (210, ((Tokenizer.LocatedToken) $1).Location, "You must provide an initializer in a fixed or using statement declaration"); $$ = null; } ; lock_statement - : LOCK open_parens_any expression CLOSE_PARENS - { - // - } - embedded_statement + : LOCK open_parens_any expression CLOSE_PARENS embedded_statement { - $$ = new Lock ((Expression) $3, (Statement) $6, (Location) $1); + $$ = new Lock ((Expression) $3, (Statement) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -5196,21 +5480,20 @@ using_statement start_block (lexer.Location); Block assign_block = current_block; - DictionaryEntry de = (DictionaryEntry) $3; - Location l = (Location) $1; + var de = (Tuple>) $3; + Location l = GetLocation ($1); - Expression type = (Expression) de.Key; - ArrayList var_declarators = (ArrayList) de.Value; + var vars = new Stack> (); - Stack vars = new Stack (); + lbag.AddStatement (assign_block, GetLocation ($1), GetLocation ($2), GetLocation ($4)); - foreach (VariableDeclaration decl in var_declarators) { - LocalInfo vi = current_block.AddVariable (type, decl.identifier, decl.Location); + foreach (VariableDeclaration decl in de.Item2) { + LocalInfo vi = current_block.AddVariable (de.Item1, decl.identifier, decl.Location); if (vi == null) continue; vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Using); - Expression expr = decl.expression_or_array_initializer; + Expression expr = decl.GetInitializer (de.Item1); if (expr == null) { Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration"); continue; @@ -5223,7 +5506,7 @@ using_statement // This is so that it is not a warning on using variables vi.Used = true; - vars.Push (new DictionaryEntry (var, expr)); + vars.Push (new Tuple (var, expr)); // Assign a = new SimpleAssign (var, expr, decl.Location); // assign_block.AddStatement (new StatementExpression (a)); @@ -5236,12 +5519,12 @@ using_statement embedded_statement { Statement stmt = (Statement) $6; - Stack vars = (Stack) $5; - Location l = (Location) $1; + var vars = (Stack>) $5; + Location l = GetLocation ($1); while (vars.Count > 0) { - DictionaryEntry de = (DictionaryEntry) vars.Pop (); - stmt = new Using ((Expression) de.Key, (Expression) de.Value, stmt, l); + var de = vars.Pop (); + stmt = new Using (de.Item1, de.Item2, stmt, l); } current_block.AddStatement (stmt); $$ = end_block (lexer.Location); @@ -5252,7 +5535,9 @@ using_statement } embedded_statement { - current_block.AddStatement (new UsingTemporary ((Expression) $3, (Statement) $6, (Location) $1)); + UsingTemporary usingTemporary = new UsingTemporary ((Expression) $3, (Statement) $6, GetLocation ($1)); + lbag.AddStatement (usingTemporary, GetLocation ($2), GetLocation ($4)); + current_block.AddStatement (usingTemporary); $$ = end_block (lexer.Location); } ; @@ -5261,7 +5546,7 @@ using_statement // LINQ query_expression - : first_from_clause query_body + : first_from_clause query_body { lexer.query_parsing = false; @@ -5283,69 +5568,102 @@ query_expression current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; } + + // Bubble up COMPLETE_COMPLETION productions + | first_from_clause COMPLETE_COMPLETION { + lexer.query_parsing = false; + $$ = $1; + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + } + | nested_from_clause COMPLETE_COMPLETION { + $$ = $1; + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + } ; first_from_clause : FROM_FIRST IDENTIFIER IN expression { - $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4)); - current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + + var lt = (Tokenizer.LocatedToken) $2; + $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1))); } | FROM_FIRST type IDENTIFIER IN expression { - $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5)); - current_block = new Linq.QueryBlock (current_block, (LocatedToken) $3, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + + var lt = (Tokenizer.LocatedToken) $3; + $$ = new Linq.QueryExpression ( + new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + } + ); } ; nested_from_clause : FROM IDENTIFIER IN expression { - $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4)); - current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + + var lt = (Tokenizer.LocatedToken) $2; + $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1))); } | FROM type IDENTIFIER IN expression { - $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5)); - current_block = new Linq.QueryBlock (current_block, (LocatedToken) $3, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + + var lt = (Tokenizer.LocatedToken) $3; + $$ = new Linq.QueryExpression ( + new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + } + ); } ; from_clause : FROM IDENTIFIER IN { - current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression { - LocatedToken lt = (LocatedToken) $2; - $$ = new Linq.SelectMany (current_block.Toplevel, lt, (Expression)$5); + var lt = (Tokenizer.LocatedToken) $2; + var sn = new SimpleMemberName (lt.Value, lt.Location); + $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$5, GetLocation ($1)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); } | FROM type IDENTIFIER IN { - current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression { - LocatedToken lt = (LocatedToken) $3; - FullNamedExpression type = (FullNamedExpression)$2; - - $$ = new Linq.SelectMany (current_block.Toplevel, lt, new Linq.Cast (type, (FullNamedExpression)$6)); + var lt = (Tokenizer.LocatedToken) $3; + var sn = new SimpleMemberName (lt.Value, lt.Location); + + $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$6, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + }; current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); } ; query_body - : opt_query_body_clauses select_or_group_clause opt_query_continuation + : opt_query_body_clauses select_or_group_clause opt_query_continuation { Linq.AQueryClause head = (Linq.AQueryClause)$2; @@ -5360,16 +5678,17 @@ query_body $$ = head; } + | opt_query_body_clauses COMPLETE_COMPLETION ; select_or_group_clause : SELECT { - current_block = new Linq.QueryBlock (current_block, lexer.Location); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression { - $$ = new Linq.Select (current_block.Toplevel, (Expression)$3, GetLocation ($1)); + $$ = new Linq.Select ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; @@ -5377,21 +5696,21 @@ select_or_group_clause | GROUP { if (linq_clause_blocks == null) - linq_clause_blocks = new Stack (); + linq_clause_blocks = new Stack (); - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock)current_block); } expression { current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (current_block, lexer.Location); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } BY expression { - $$ = new Linq.GroupBy (current_block.Toplevel, (Expression)$3, (ToplevelBlock) linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1)); + $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; @@ -5414,7 +5733,7 @@ query_body_clauses query_body_clause : from_clause - | let_clause + | let_clause | where_clause | join_clause | orderby_clause @@ -5423,28 +5742,29 @@ query_body_clause let_clause : LET IDENTIFIER ASSIGN { - current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression { - LocatedToken lt = (LocatedToken) $2; - $$ = new Linq.Let (current_block.Toplevel, current_container, lt, (Expression)$5); + var lt = (Tokenizer.LocatedToken) $2; + var sn = new SimpleMemberName (lt.Value, lt.Location); + $$ = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)$5, GetLocation ($1)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); } ; where_clause : WHERE { - current_block = new Linq.QueryBlock (current_block, lexer.Location); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } boolean_expression { - $$ = new Linq.Where (current_block.Toplevel, (Expression)$3, GetLocation ($1)); + $$ = new Linq.Where ((Linq.QueryBlock)current_block, (BooleanExpression)$3, GetLocation ($1)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; @@ -5455,18 +5775,18 @@ join_clause : JOIN IDENTIFIER IN { if (linq_clause_blocks == null) - linq_clause_blocks = new Stack (); + linq_clause_blocks = new Stack (); - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } expression ON { current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } expression EQUALS { @@ -5474,46 +5794,47 @@ join_clause current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, lexer.Location); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression opt_join_into { - LocatedToken lt = (LocatedToken) $2; + var lt = (Tokenizer.LocatedToken) $2; + var sn = new SimpleMemberName (lt.Value, lt.Location); + SimpleMemberName sn2 = null; - ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop (); - ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop (); + var outer_selector = linq_clause_blocks.Pop (); + var block = linq_clause_blocks.Pop (); if ($12 == null) { - $$ = new Linq.Join (block, lt, (Expression)$5, outer_selector, current_block.Toplevel, GetLocation ($1)); + $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)); } else { - $$ = new Linq.GroupJoin (block, lt, (Expression)$5, outer_selector, current_block.Toplevel, - (LocatedToken) $12, GetLocation ($1)); + var lt2 = (Tokenizer.LocatedToken) $12; + sn2 = new SimpleMemberName (lt2.Value, lt2.Location); + $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, + sn2, GetLocation ($1)); } current_block.AddStatement (new ContextualReturn ((Expression) $11)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - if ($12 == null) - ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); - else - ((Linq.QueryBlock)current_block).AddTransparentParameter ((LocatedToken) $12); + ((Linq.QueryBlock)current_block).AddRangeVariable (sn2 ?? sn); } | JOIN type IDENTIFIER IN { if (linq_clause_blocks == null) - linq_clause_blocks = new Stack (); + linq_clause_blocks = new Stack (); - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } expression ON { current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } expression EQUALS { @@ -5521,30 +5842,33 @@ join_clause current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (current_block, (LocatedToken) $3, lexer.Location); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression opt_join_into { - LocatedToken lt = (LocatedToken) $3; - ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop (); - ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop (); + var lt = (Tokenizer.LocatedToken) $3; + var sn = new SimpleMemberName (lt.Value, lt.Location); + SimpleMemberName sn2 = null; + var outer_selector = linq_clause_blocks.Pop (); + var block = linq_clause_blocks.Pop (); - Linq.Cast cast = new Linq.Cast ((FullNamedExpression)$2, (Expression)$6); if ($13 == null) { - $$ = new Linq.Join (block, lt, cast, outer_selector, current_block.Toplevel, GetLocation ($1)); + $$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + }; } else { - $$ = new Linq.GroupJoin (block, lt, cast, outer_selector, current_block.Toplevel, - (LocatedToken) $13, GetLocation ($1)); + var lt2 = (Tokenizer.LocatedToken) $13; + sn2 = new SimpleMemberName (lt2.Value, lt2.Location); + $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, sn2, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + }; } current_block.AddStatement (new ContextualReturn ((Expression) $12)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - if ($13 == null) - ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); - else - ((Linq.QueryBlock)current_block).AddTransparentParameter ((LocatedToken) $13); + ((Linq.QueryBlock)current_block).AddRangeVariable (sn2 ?? sn); } ; @@ -5559,7 +5883,7 @@ opt_join_into orderby_clause : ORDERBY { - current_block = new Linq.QueryBlock (current_block, lexer.Location); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } orderings { @@ -5577,7 +5901,7 @@ orderings current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (current_block, lexer.Location); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } orderings_then_by { @@ -5593,11 +5917,11 @@ orderings_then_by current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (current_block, lexer.Location); + current_block = new Linq.QueryBlock (compiler, (Linq.QueryBlock) current_block, lexer.Location); } then_by { - ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$3; + ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$4; $$ = $1; } ; @@ -5605,30 +5929,30 @@ orderings_then_by order_by : expression { - $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1); + $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1); } | expression ASCENDING { - $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1); + $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1); } | expression DESCENDING { - $$ = new Linq.OrderByDescending (current_block.Toplevel, (Expression)$1); + $$ = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)$1); } ; then_by : expression { - $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); + $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1); } | expression ASCENDING { - $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); + $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1); } | expression DESCENDING { - $$ = new Linq.ThenByDescending (current_block.Toplevel, (Expression)$1); + $$ = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)$1); } ; @@ -5643,12 +5967,21 @@ opt_query_continuation current_block.SetEndLocation (GetLocation ($1)); current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); - current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, GetLocation ($1)); + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } query_body { - $$ = new Linq.QueryExpression (current_block, (Linq.AQueryClause)$4); + var current_block = linq_clause_blocks.Pop (); + var lt = (Tokenizer.LocatedToken) $2; + $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) { + next = (Linq.AQueryClause)$4 + }; } ; @@ -5674,20 +6007,20 @@ interactive_parsing push_current_class (new Class (current_namespace, current_class, new MemberName ("Class" + class_count++), Modifiers.PUBLIC, null), null); - ArrayList baseclass_list = new ArrayList (); + var baseclass_list = new List (); baseclass_list.Add (new TypeExpression (Evaluator.InteractiveBaseClass, lexer.Location)); current_container.AddBasesForPart (current_class, baseclass_list); // (ref object retval) Parameter [] mpar = new Parameter [1]; - mpar [0] = new Parameter (TypeManager.system_object_expr, "$retval", Parameter.Modifier.REF, null, Location.Null); + mpar [0] = new Parameter (new TypeExpression (TypeManager.object_type, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null); - ParametersCompiled pars = new ParametersCompiled (mpar); + ParametersCompiled pars = new ParametersCompiled (compiler, mpar); current_local_parameters = pars; Method method = new Method ( current_class, null, // generic - TypeManager.system_void_expr, + new TypeExpression (TypeManager.void_type, Location.Null), Modifiers.PUBLIC | Modifiers.STATIC, new MemberName ("Host"), pars, @@ -5726,49 +6059,38 @@ opt_COMPLETE_COMPLETION : /* nothing */ | COMPLETE_COMPLETION ; + +close_brace_or_complete_completion + : CLOSE_BRACE + | COMPLETE_COMPLETION + ; %% // // A class used to pass around variable declarations and constants // -public class VariableDeclaration { +class VariableDeclaration { public string identifier; - public Expression expression_or_array_initializer; + Expression initializer; public Location Location; - public Attributes OptAttributes; - public string DocComment; - public VariableDeclaration (LocatedToken lt, object eoai, Attributes opt_attrs) + public VariableDeclaration (Tokenizer.LocatedToken lt, Expression initializer) { this.identifier = lt.Value; - if (eoai is ArrayList) { - this.expression_or_array_initializer = new ArrayCreation (CSharpParser.current_array_type, "", (ArrayList)eoai, lt.Location); - } else { - this.expression_or_array_initializer = (Expression)eoai; - } + this.initializer = initializer; this.Location = lt.Location; - this.OptAttributes = opt_attrs; } - public VariableDeclaration (LocatedToken lt, object eoai) : this (lt, eoai, null) + public Expression GetInitializer (FullNamedExpression type) { + if (initializer is ArrayInitializer) + return new ArrayCreation (type, (ArrayInitializer)initializer); + + return initializer; } -} -class VariableMemberDeclaration -{ - public readonly MemberName MemberName; - public Expression expression_or_array_initializer; - - public VariableMemberDeclaration (MemberName mn, object initializer) - { - MemberName = mn; - - if (initializer is ArrayList) { - this.expression_or_array_initializer = new ArrayCreation (CSharpParser.current_array_type, "", (ArrayList)initializer, mn.Location); - } else { - this.expression_or_array_initializer = (Expression)initializer; - } + public bool HasInitializer { + get { return initializer != null; } } } @@ -5794,27 +6116,37 @@ void Error_ExpectingTypeName (Expression expr) if (expr is Invocation){ Report.Error (1002, expr.Location, "Expecting `;'"); } else { - expr.Error_InvalidExpressionStatement (); + Expression.Error_InvalidExpressionStatement (Report, expr.Location); } } -static void Error_ParameterModifierNotValid (string modifier, Location loc) +void Error_ParameterModifierNotValid (string modifier, Location loc) { Report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context", modifier); } -static void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod) +void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod) { Report.Error (1107, loc, "Duplicate parameter modifier `{0}'", Parameter.GetModifierSignature (mod)); } -static void Error_TypeExpected (Location loc) +void Error_TypeExpected (Location loc) { Report.Error (1031, loc, "Type expected"); } +void Error_UnsafeCodeNotAllowed (Location loc) +{ + Report.Error (227, loc, "Unsafe code requires the `unsafe' command line option to be specified"); +} + +void Error_NamedArgumentExpected (NamedArgument a) +{ + Report.Error (1738, a.Location, "Named arguments must appear after the positional arguments"); +} + void push_current_class (TypeContainer tc, object partial_token) { if (RootContext.EvalMode){ @@ -5860,10 +6192,21 @@ MakeName (MemberName class_name) } } -Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc) +[System.Diagnostics.Conditional ("FULL_AST")] +void StoreModifierLocation (object token, Location loc) +{ + if (lbag == null) + return; + + if (mod_locations == null) + mod_locations = new List> (); + + mod_locations.Add (Tuple.Create ((Modifiers) token, loc)); +} + +Block declare_local_variables (FullNamedExpression type, List variable_declarators, Location loc) { Block implicit_block; - ArrayList inits = null; // // If we are doing interactive editing, we want variable declarations @@ -5887,13 +6230,17 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators, foreach (VariableDeclaration decl in variable_declarators){ // We can not use the super-handy f.Initializer, because // multiple lines would force code to be executed out of sync - if (decl.expression_or_array_initializer != null){ + var init = decl.GetInitializer (type); + if (init != null){ string id = "$" + decl.identifier; - current_block.AddVariable (type, id, decl.Location); + LocalInfo vi = current_block.AddVariable (type, id, decl.Location); + + // Avoid warning about this variable not being used. + vi.Used = true; LocalVariableReference var; - var = new LocalVariableReferenceWithClassSideEffect (current_container, decl.identifier, current_block, id, decl.Location); - Assign assign = new SimpleAssign (var, decl.expression_or_array_initializer, decl.Location); + var = new LocalVariableReferenceWithClassSideEffect (current_container, decl.identifier, current_block, id, vi, decl.Location); + Assign assign = new SimpleAssign (var, init, decl.Location); current_block.AddStatement (new StatementExpression (assign)); assign = new SimpleAssign (new SimpleName (decl.identifier, decl.Location), var); current_block.AddStatement (new StatementExpression (assign)); @@ -5934,33 +6281,22 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators, foreach (VariableDeclaration decl in variable_declarators){ if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) { - if (decl.expression_or_array_initializer != null){ - if (inits == null) - inits = new ArrayList (4); - inits.Add (decl); - } - } - } - - if (inits == null) - return implicit_block; - - foreach (VariableDeclaration decl in inits){ - Assign assign; - Expression expr = decl.expression_or_array_initializer; - - LocalVariableReference var; - var = new LocalVariableReference (implicit_block, decl.identifier, loc); + if (decl.HasInitializer){ + Assign assign; + + var lvr = new LocalVariableReference (implicit_block, decl.identifier, loc); - assign = new SimpleAssign (var, expr, decl.Location); + assign = new SimpleAssign (lvr, decl.GetInitializer (type), decl.Location); - implicit_block.AddStatement (new StatementExpression (assign)); + implicit_block.AddStatement (new StatementExpression (assign)); + } + } } return implicit_block; } -Block declare_local_constants (Expression type, ArrayList declarators) +Block declare_local_constants (FullNamedExpression type, List declarators) { Block implicit_block; @@ -5970,7 +6306,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, decl.Location); + implicit_block.AddConstant (type, decl.identifier, decl.GetInitializer (type), decl.Location); } return implicit_block; @@ -6010,11 +6346,6 @@ void syntax_error (Location l, string msg) Report.Error (1003, l, "Syntax error, " + msg); } -void note (string s) -{ - // Used to put annotations -} - Tokenizer lexer; public Tokenizer Lexer { @@ -6025,49 +6356,55 @@ public Tokenizer Lexer { static CSharpParser () { - oob_stack = new Stack (); + oob_stack = new Stack (); } -public CSharpParser (SeekableStreamReader reader, CompilationUnit file) +public CSharpParser (SeekableStreamReader reader, CompilationUnit file, CompilerContext ctx) { if (RootContext.EvalMode) undo = new Undo (); this.file = file; + this.compiler = ctx; current_namespace = new NamespaceEntry (null, file, null); current_class = current_namespace.SlaveDeclSpace; current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes oob_stack.Clear (); - lexer = new Tokenizer (reader, file); + lexer = new Tokenizer (reader, file, ctx); + + use_global_stacks = true; } public void parse () { eof_token = Token.EOF; - + Tokenizer.LocatedToken.Initialize (); + try { if (yacc_verbose_flag > 1) yyparse (lexer, new yydebug.yyDebugSimple ()); else yyparse (lexer); + + Tokenizer tokenizer = lexer as Tokenizer; + tokenizer.cleanup (); } catch (Exception e){ if (e is yyParser.yyUnexpectedEof) UnexpectedEOF = true; - else if (yacc_verbose_flag > 0) - Console.WriteLine (e); + if (e is yyParser.yyException) Report.Error (-25, lexer.Location, "Parsing error"); + else if (yacc_verbose_flag > 0) + throw; // Used by compiler-tester to test internal errors else - Report.Error (-32, lexer.Location, "Internal compiler error during parsing, Run with -v for details"); + Report.Error (589, lexer.Location, "Internal compiler error during parsing"); } - Tokenizer tokenizer = lexer as Tokenizer; - tokenizer.cleanup (); if (RootContext.ToplevelTypes.NamespaceEntry != null) throw new InternalErrorException ("who set it?"); } -static void CheckToken (int error, int yyToken, string msg, Location loc) +void CheckToken (int error, int yyToken, string msg, Location loc) { if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD) Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, GetTokenName (yyToken)); @@ -6090,21 +6427,34 @@ string ConsumeStoredComment () Location GetLocation (object obj) { - if (obj is MemberCore) - return ((MemberCore) obj).Location; + if (obj is Tokenizer.LocatedToken) + return ((Tokenizer.LocatedToken) obj).Location; if (obj is MemberName) return ((MemberName) obj).Location; - if (obj is LocatedToken) - return ((LocatedToken) obj).Location; - if (obj is Location) - return (Location) obj; + + if (obj is Expression) + return ((Expression) obj).Location; + return lexer.Location; } +Report Report { + get { return compiler.Report; } +} + +public LocationsBag LocationsBag { + get { + return lbag; + } + set { + lbag = value; + } +} + void start_block (Location loc) { if (current_block == null || parsing_anonymous_method) { - current_block = new ToplevelBlock (current_block, current_local_parameters, current_generic_method, loc); + current_block = new ToplevelBlock (compiler, current_block, current_local_parameters, loc); parsing_anonymous_method = false; } else { current_block = new ExplicitBlock (current_block, loc, Location.Null); @@ -6166,10 +6516,10 @@ public NamespaceEntry CurrentNamespace { void Error_SyntaxError (int token) { - Error_SyntaxError (0, token); + Error_SyntaxError (0, token, "Unexpected symbol"); } -void Error_SyntaxError (int error_code, int token) +void Error_SyntaxError (int error_code, int token, string msg) { string symbol = GetSymbolName (token); string expecting = GetExpecting (); @@ -6181,17 +6531,16 @@ void Error_SyntaxError (int error_code, int token) error_code = 1525; } - if (expecting != null) - Report.Error (error_code, lexer.Location, "Unexpected symbol `{0}', expecting {1}", - symbol, expecting); + if (string.IsNullOrEmpty (expecting)) + Report.Error (error_code, lexer.Location, "{1} `{0}'", symbol, msg); else - Report.Error (error_code, lexer.Location, "Unexpected symbol `{0}'", symbol); + Report.Error (error_code, lexer.Location, "{2} `{0}', expecting {1}", symbol, expecting, msg); } string GetExpecting () { int [] tokens = yyExpectingTokens (yyExpectingState); - ArrayList names = new ArrayList (tokens.Length); + var names = new List (tokens.Length); bool has_type = false; bool has_identifier = false; for (int i = 0; i < tokens.Length; i++){ @@ -6230,7 +6579,7 @@ string GetExpecting () sb.Append ("or "); sb.Append ('`'); sb.Append (names [i]); - sb.Append (last ? "'" : "', "); + sb.Append (last ? "'" : count < 3 ? "' " : "', "); } return sb.ToString (); } @@ -6239,15 +6588,10 @@ string GetExpecting () string GetSymbolName (int token) { switch (token){ - case Token.LITERAL_FLOAT: - case Token.LITERAL_INTEGER: - case Token.LITERAL_DOUBLE: - case Token.LITERAL_DECIMAL: - case Token.LITERAL_CHARACTER: - case Token.LITERAL_STRING: - return lexer.Value.ToString (); + case Token.LITERAL: + return ((Constant)lexer.Value).GetValue ().ToString (); case Token.IDENTIFIER: - return ((LocatedToken)lexer.Value).Value; + return ((Tokenizer.LocatedToken)lexer.Value).Value; case Token.BOOL: return "bool"; @@ -6486,7 +6830,7 @@ static string GetTokenName (int token) case Token.WHILE: return "while"; case Token.ARGLIST: - return "arglist"; + return "__arglist"; case Token.PARTIAL: return "partial"; case Token.ARROW: @@ -6525,6 +6869,7 @@ static string GetTokenName (int token) case Token.CLOSE_BRACE: return "}"; case Token.OPEN_BRACKET: + case Token.OPEN_BRACKET_EXPR: return "["; case Token.CLOSE_BRACKET: return "]"; @@ -6613,12 +6958,7 @@ static string GetTokenName (int token) return "?"; case Token.DOUBLE_COLON: return "::"; - case Token.LITERAL_FLOAT: - case Token.LITERAL_INTEGER: - case Token.LITERAL_DOUBLE: - case Token.LITERAL_DECIMAL: - case Token.LITERAL_CHARACTER: - case Token.LITERAL_STRING: + case Token.LITERAL: return "value"; case Token.IDENTIFIER: return "identifier";