X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcs-parser.jay;h=de1b01e4a858e557b95348750e627bb6e5ad27dc;hb=cc39d7ebf1bfa8fafd6adc3a9fda354672579d1c;hp=cac7c02e07b63971737ebfb15273edc414f4bb0d;hpb=5cb362639b832eba53adefd2fde22393971545c6;p=mono.git diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index cac7c02e07b..de1b01e4a85 100644 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -41,20 +41,27 @@ namespace Mono.CSharp 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 /// them. /// Block current_block; + + BlockVariableDeclaration current_variable; Delegate current_delegate; - GenericMethod current_generic_method; AnonymousMethodExpression current_anonymous_method; /// @@ -66,20 +73,6 @@ 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; - - /// - /// Used to determine if we are parsing the get/set pair - /// of an indexer or a property - /// - bool parsing_indexer; - bool parsing_anonymous_method; /// @@ -87,11 +80,6 @@ namespace Mono.CSharp /// static Stack oob_stack; - /// - /// Switch stack. - /// - Stack switch_stack; - /// /// Controls the verbosity of the errors produced by the parser /// @@ -120,7 +108,6 @@ namespace Mono.CSharp /// assembly and module attribute definitions are enabled bool global_attrs_enabled = true; - bool has_get, has_set; ParameterModifierType valid_param_mod; @@ -135,7 +122,7 @@ namespace Mono.CSharp // public Undo undo; - Stack linq_clause_blocks; + Stack linq_clause_blocks; // A counter to create new class names in interactive mode static int class_count; @@ -148,7 +135,12 @@ namespace Mono.CSharp // 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 @@ -259,11 +251,6 @@ namespace Mono.CSharp %token INTERR_NULLABLE %token EXTERN_ALIAS -/* Generics <,> tokens */ -%token OP_GENERICS_LT -%token OP_GENERICS_LT_DECL -%token OP_GENERICS_GT - /* C# keywords which are not really keywords */ %token GET %token SET @@ -323,6 +310,11 @@ namespace Mono.CSharp %token OP_PTR %token OP_COALESCING +/* Generics <,> tokens */ +%token OP_GENERICS_LT +%token OP_GENERICS_LT_DECL +%token OP_GENERICS_GT + %token LITERAL %token IDENTIFIER @@ -330,6 +322,7 @@ namespace Mono.CSharp %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 @@ -450,8 +443,9 @@ using_alias_directive var lt = (Tokenizer.LocatedToken) $2; current_namespace.AddUsingAlias (lt.Value, (MemberName) $4, GetLocation ($1)); } - | USING error { - CheckIdentifierToken (yyToken, GetLocation ($2)); + | USING error + { + Error_SyntaxError (yyToken); $$ = null; } ; @@ -477,7 +471,7 @@ namespace_declaration Report.Error(1671, name.Location, "A namespace declaration cannot have modifiers or attributes"); } - current_namespace = new NamespaceEntry ( + current_namespace = new NamespaceEntry (compiler, current_namespace, file, name.GetName ()); current_class = current_namespace.SlaveDeclSpace; current_container = current_class.PartialContainer; @@ -503,7 +497,7 @@ qualified_identifier } | error { - syntax_error (lexer.Location, "`.' expected"); + Error_SyntaxError (yyToken); $$ = new MemberName ("", lexer.Location); } ; @@ -548,7 +542,6 @@ namespace_body_body { Report.Error (1518, lexer.Location, "Expected `class', `delegate', `enum', `interface', or `struct'"); } - CLOSE_BRACE | opt_extern_alias_directives opt_using_directives opt_namespace_member_declarations @@ -787,9 +780,9 @@ attribute 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, - expr, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location)); + expr, arguments, mname.Location, lexer.IsEscapedIdentifier (mname)); else - $$ = new Attribute (current_attr_target, expr, arguments, mname.Location, lexer.IsEscapedIdentifier (mname.Location)); + $$ = new Attribute (current_attr_target, expr, arguments, mname.Location, lexer.IsEscapedIdentifier (mname)); } ; @@ -854,10 +847,15 @@ positional_or_named_argument ; named_attribute_argument - : IDENTIFIER ASSIGN expression + : IDENTIFIER ASSIGN + { + ++lexer.parsing_block; + } + expression { + --lexer.parsing_block; var lt = (Tokenizer.LocatedToken) $1; - $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $3); + $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4); } ; @@ -887,10 +885,6 @@ opt_named_modifier } ; -class_body - : OPEN_BRACE opt_class_member_declarations CLOSE_BRACE - ; - opt_class_member_declarations : /* empty */ | class_member_declarations @@ -933,7 +927,7 @@ 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 @@ -944,6 +938,8 @@ struct_declaration if (RootContext.Documentation != null) current_container.DocComment = Lexer.consume_doc_comment (); + + lbag.AddMember (current_class, mod_locations, GetLocation ($4)); } struct_body { @@ -953,10 +949,12 @@ struct_declaration } opt_semicolon { + lbag.AppendToMember (current_class, GetLocation ($13)); $$ = pop_current_class (); } - | opt_attributes opt_modifiers opt_partial STRUCT error { - CheckIdentifierToken (yyToken, GetLocation ($5)); + | opt_attributes opt_modifiers opt_partial STRUCT error + { + Error_SyntaxError (yyToken); } ; @@ -967,6 +965,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 @@ -996,73 +997,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 (List) $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, - constant.GetInitializer ((FullNamedExpression) $4), 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 { - variables_bucket.Clear (); - if ($1 != null) - variables_bucket.Add ($1); - $$ = variables_bucket; + current_field.AddDeclarator ((FieldDeclarator) $1); } - | constant_declarators COMMA constant_declarator + | constant_declarators constant_declarator { - if ($3 != null) { - var constants = (List) $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 ((Tokenizer.LocatedToken) $1, (Expression) $4); + ++lexer.parsing_block; } - | IDENTIFIER + constant_initializer_expr { - // A const field requires a value to be provided - Report.Error (145, GetLocation ($1), "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 ; @@ -1070,189 +1077,171 @@ 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; - - foreach (VariableMemberDeclaration var in (List) $4){ - Field field = new Field (current_class, type, mod, var.MemberName, (Attributes) $1); - - field.Initializer = var.GetInitializer (type); - - 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; + if (RootContext.Version < LanguageVersion.ISO_2) + Report.FeatureIsNotAvailable (GetLocation ($3), "fixed size buffers"); - foreach (VariableDeclaration var in (List) $5) { - FixedField field = new FixedField (current_class, type, mod, var.identifier, - var.GetInitializer (type), (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 - { - Report.Error (1641, GetLocation ($4), "A fixed size buffer field must have the array size specifier after the field name"); - } - ; - -fixed_variable_declarators - : fixed_variable_declarator - { - var decl = new List (2); - decl.Add ((VariableDeclaration)$1); - $$ = decl; - } - | fixed_variable_declarators COMMA fixed_variable_declarator + FIXED simple_type error + SEMICOLON { - var decls = (List) $1; - decls.Add ((VariableDeclaration)$3); - $$ = $1; + Report.Error (1641, GetLocation ($5), "A fixed size buffer field must have the array size specifier after the field name"); } ; - -fixed_variable_declarator - : IDENTIFIER OPEN_BRACKET expression CLOSE_BRACKET + +opt_field_initializer + : /* empty */ + | ASSIGN { - $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, (Expression) $3); + ++lexer.parsing_block; + current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; + start_block (GetLocation ($1)); } - | IDENTIFIER OPEN_BRACKET CLOSE_BRACKET + variable_initializer { - Report.Error (443, lexer.Location, "Value or constant expected"); - $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, null); + --lexer.parsing_block; + current_field.Initializer = (Expression) $3; + end_block (lexer.Location); + current_local_parameters = null; } ; +opt_field_declarators + : /* empty */ + | field_declarators + ; -local_variable_declarators - : local_variable_declarator +field_declarators + : field_declarator { - variables_bucket.Clear (); - if ($1 != null) - variables_bucket.Add ($1); - $$ = variables_bucket; + current_field.AddDeclarator ((FieldDeclarator) $1); } - | local_variable_declarators COMMA local_variable_declarator + | field_declarators field_declarator { - var decls = (List) $1; - decls.Add ($3); - $$ = $1; + current_field.AddDeclarator ((FieldDeclarator) $2); } ; -local_variable_declarator - : IDENTIFIER ASSIGN local_variable_initializer +field_declarator + : COMMA IDENTIFIER { - $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, (Expression) $3); + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null); + lbag.AddLocation ($$, GetLocation ($1)); } - | IDENTIFIER + | COMMA IDENTIFIER ASSIGN { - $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, null); + ++lexer.parsing_block; } - | IDENTIFIER variable_bad_array + variable_initializer { - $$ = null; + --lexer.parsing_block; + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } - ; + ; -local_variable_initializer - : expression - | array_initializer - | STACKALLOC simple_type OPEN_BRACKET expression CLOSE_BRACKET - { - $$ = new StackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1)); - } - | ARGLIST +opt_fixed_field_declarators + : /* empty */ + | fixed_field_declarators + ; + +fixed_field_declarators + : fixed_field_declarator { - $$ = new ArglistAccess (GetLocation ($1)); + current_field.AddDeclarator ((FieldDeclarator) $1); } - | STACKALLOC simple_type + | fixed_field_declarators fixed_field_declarator { - Report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type"); - $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1)); + current_field.AddDeclarator ((FieldDeclarator) $2); } ; - -variable_declarators - : variable_declarator - { - variables_bucket.Clear (); - if ($1 != null) - variables_bucket.Add ($1); - $$ = variables_bucket; - } - | variable_declarators COMMA variable_declarator + +fixed_field_declarator + : COMMA IDENTIFIER fixed_field_size { - var decls = (List) $1; - decls.Add ($3); - $$ = $1; + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3); + lbag.AddLocation ($$, GetLocation ($1)); } ; -variable_declarator - : member_declaration_name ASSIGN - { - ++lexer.parsing_block; - lexer.parsing_generic_declaration = false; - } - variable_initializer +fixed_field_size + : OPEN_BRACKET { - --lexer.parsing_block; - $$ = new VariableMemberDeclaration ((MemberName) $1, (Expression) $4); + ++lexer.parsing_block; } - | member_declaration_name + expression CLOSE_BRACKET { - lexer.parsing_generic_declaration = false; - $$ = new VariableMemberDeclaration ((MemberName) $1, null); + --lexer.parsing_block; + $$ = new ConstInitializer (current_field, (Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($4)); } - | member_declaration_name variable_bad_array + | OPEN_BRACKET error { - lexer.parsing_generic_declaration = false; + Report.Error (443, lexer.Location, "Value or constant expected"); $$ = null; - } - ; - -variable_bad_array - : OPEN_BRACKET 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"); - } + } ; variable_initializer : expression | array_initializer + | error + { + // It has to be here for the parent to safely restore artificial block + Error_SyntaxError (yyToken); + $$ = null; + } ; method_declaration @@ -1266,11 +1255,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) @@ -1297,28 +1285,30 @@ method_header 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 ((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 @@ -1349,15 +1339,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 ((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) { @@ -1373,14 +1364,15 @@ method_header 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 @@ -1390,9 +1382,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; @@ -1416,29 +1408,29 @@ opt_formal_parameter_list formal_parameter_list : fixed_parameters - { + { var pars_list = (List) $1; - $$ = new ParametersCompiled (compiler, pars_list.ToArray ()); + $$ = new ParametersCompiled (pars_list.ToArray ()); } | fixed_parameters COMMA parameter_array { var pars_list = (List) $1; pars_list.Add ((Parameter) $3); - $$ = new ParametersCompiled (compiler, pars_list.ToArray ()); + $$ = new ParametersCompiled (pars_list.ToArray ()); } | fixed_parameters COMMA arglist_modifier { var pars_list = (List) $1; pars_list.Add (new ArglistParameter (GetLocation ($3))); - $$ = new ParametersCompiled (compiler, pars_list.ToArray (), true); + $$ = new ParametersCompiled (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"); - $$ = new ParametersCompiled (compiler, new Parameter[] { (Parameter) $1 } ); + $$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } ); } | fixed_parameters COMMA parameter_array COMMA error { @@ -1448,13 +1440,13 @@ formal_parameter_list var pars_list = (List) $1; pars_list.Add (new ArglistParameter (GetLocation ($3))); - $$ = new ParametersCompiled (compiler, pars_list.ToArray (), true); + $$ = new ParametersCompiled (pars_list.ToArray (), true); } | arglist_modifier COMMA error { 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); + $$ = new ParametersCompiled (new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true); } | fixed_parameters COMMA ARGLIST COMMA error { @@ -1463,15 +1455,20 @@ formal_parameter_list var pars_list = (List) $1; pars_list.Add (new ArglistParameter (GetLocation ($3))); - $$ = new ParametersCompiled (compiler, pars_list.ToArray (), true); + $$ = new ParametersCompiled (pars_list.ToArray (), true); } | parameter_array { - $$ = new ParametersCompiled (compiler, new Parameter[] { (Parameter) $1 } ); + $$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } ); } | arglist_modifier { - $$ = new ParametersCompiled (compiler, new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true); + $$ = new ParametersCompiled (new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true); + } + | error + { + Error_SyntaxError (yyToken); + $$ = ParametersCompiled.EmptyReadOnlyParameters; } ; @@ -1497,7 +1494,10 @@ fixed_parameters default_parameter_used |= p.HasDefaultValue; pars.Add (p); + + lbag.AddLocation (p, GetLocation ($2)); } + $$ = $1; } ; @@ -1525,8 +1525,8 @@ fixed_parameter parameter_type error { + Error_SyntaxError (yyToken); Location l = GetLocation ($4); - CheckIdentifierToken (yyToken, l); $$ = new Parameter ((FullNamedExpression) $3, "NeedSomeGeneratorHere", (Parameter.Modifier) $2, (Attributes) $1, l); } | opt_attributes @@ -1534,8 +1534,12 @@ fixed_parameter parameter_type IDENTIFIER ASSIGN + { + ++lexer.parsing_block; + } constant_expression { + --lexer.parsing_block; if (RootContext.Version <= LanguageVersion.V_3) { Report.FeatureIsNotAvailable (GetLocation ($5), "optional parameter"); } @@ -1561,12 +1565,14 @@ fixed_parameter } if ((valid_param_mod & ParameterModifierType.DefaultValue) == 0) - Report.Error (1065, GetLocation ($6), "Optional parameter is not valid in this context"); + 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); - if ($6 != null) - ((Parameter) $$).DefaultValue = (Expression) $6; + lbag.AddLocation ($$, GetLocation ($5)); + + if ($7 != null) + ((Parameter) $$).DefaultValue = (Expression) $7; } ; @@ -1643,8 +1649,9 @@ 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)); + | opt_attributes params_modifier type error + { + Error_SyntaxError (yyToken); $$ = null; } ; @@ -1687,86 +1694,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); } } ; @@ -1774,65 +1790,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, GetLocation ($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, GetLocation ($3)); - - if (!parsing_indexer) { - current_local_parameters = new ParametersCompiled (compiler, 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 (compiler, - 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, GetLocation ($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; } ; @@ -1840,6 +1882,7 @@ accessor_body : block | SEMICOLON { + // TODO: lbag $$ = null; } | error @@ -1860,7 +1903,8 @@ 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 @@ -1874,7 +1918,7 @@ interface_declaration Lexer.doc_state = XmlCommentState.Allowed; } } - interface_body + OPEN_BRACE opt_interface_member_declarations CLOSE_BRACE { --lexer.parsing_declaration; if (RootContext.Documentation != null) @@ -1882,19 +1926,15 @@ interface_declaration } opt_semicolon { + lbag.AppendToMember (current_class, GetLocation ($11), GetLocation ($13)); $$ = pop_current_class (); } - | opt_attributes opt_modifiers opt_partial INTERFACE error { - CheckIdentifierToken (yyToken, GetLocation ($5)); + | opt_attributes opt_modifiers opt_partial INTERFACE error + { + Error_SyntaxError (yyToken); } ; -interface_body - : OPEN_BRACE - opt_interface_member_declarations - CLOSE_BRACE - ; - opt_interface_member_declarations : /* empty */ | interface_member_declarations @@ -1938,23 +1978,24 @@ operator_declaration } operator_body { - if ($3 == null) - break; - OperatorDeclaration decl = (OperatorDeclaration) $3; - Operator op = new Operator ( - current_class, decl.optype, decl.ret_type, (int) $2, - current_local_parameters, - (ToplevelBlock) $5, (Attributes) $1, decl.location); + if (decl != null) { + Operator op = new Operator ( + current_class, decl.optype, decl.ret_type, (Modifiers) $2, + current_local_parameters, + (ToplevelBlock) $5, (Attributes) $1, decl.location); - if (RootContext.Documentation != null) { - op.DocComment = tmpComment; - Lexer.doc_state = XmlCommentState.Allowed; - } + if (RootContext.Documentation != null) { + op.DocComment = tmpComment; + Lexer.doc_state = XmlCommentState.Allowed; + } - // Note again, checking is done in semantic analysis - current_container.AddOperator (op); + // Note again, checking is done in semantic analysis + current_container.AddOperator (op); + lbag.AddMember (op, mod_locations, lbag.GetLocations (decl)); + } + current_local_parameters = null; } ; @@ -1969,7 +2010,7 @@ operator_type | VOID { Report.Error (590, GetLocation ($1), "User-defined operators cannot return void"); - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2016,6 +2057,7 @@ operator_declarator } $$ = new OperatorDeclaration (op, (FullNamedExpression) $1, loc); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3), GetLocation ($4), GetLocation ($7)); } | conversion_operator_declarator ; @@ -2066,6 +2108,7 @@ 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 { @@ -2084,6 +2127,7 @@ conversion_operator_declarator } $$ = new OperatorDeclaration (Operator.OpType.Explicit, (FullNamedExpression) $3, loc); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7)); } | IMPLICIT error { @@ -2143,7 +2187,7 @@ constructor_declarator opt_constructor_initializer { var lt = (Tokenizer.LocatedToken) $3; - int mods = (int) $2; + var mods = (Modifiers) $2; ConstructorInitializer ci = (ConstructorInitializer) $9; Constructor c = new Constructor (current_class, lt.Value, mods, @@ -2152,7 +2196,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 ()); @@ -2165,6 +2209,7 @@ constructor_declarator } } + lbag.AddMember (c, mod_locations, GetLocation ($5), GetLocation ($7)); $$ = c; } ; @@ -2188,6 +2233,7 @@ constructor_initializer { --lexer.parsing_block; $$ = new ConstructorBaseInitializer ((Arguments) $5, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6)); } | COLON THIS OPEN_PARENS { @@ -2197,6 +2243,7 @@ constructor_initializer { --lexer.parsing_block; $$ = 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"); @@ -2219,17 +2266,18 @@ destructor_declaration 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; } @@ -2238,343 +2286,309 @@ destructor_declaration event_declaration : opt_attributes opt_modifiers - EVENT type variable_declarators SEMICOLON + EVENT type member_declaration_name { - foreach (VariableMemberDeclaration var in (List) $5) { - - EventField e = new EventField ( - current_class, (FullNamedExpression) $4, (int) $2, var.MemberName, (Attributes) $1); - - e.Initializer = var.GetInitializer ((FullNamedExpression) $4); - if (current_container.Kind == Kind.Interface && e.Initializer != null) { - Report.Error (68, e.Location, "`{0}': event in interface cannot have initializer", e.GetSignatureForError ()); - } - - 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 (compiler, - 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, GetLocation ($3), "Event in interface cannot have add or remove accessors"); - $8 = new Accessors (null, null); - } else if ($8 == null) { - Report.Error (65, GetLocation ($3), "`{0}.{1}': event property must have both add and remove accessors", - current_container.GetSignatureForError (), name.GetSignatureForError ()); - $8 = new Accessors (null, null); + if (RootContext.Documentation != null) { + current_event.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; } - 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; - } + 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 + { + ++lexer.parsing_block; + } + event_variable_initializer { - 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; + 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 { - $$ = new Accessors ((Accessor) $1, (Accessor) $2); + current_event_field.AddDeclarator ((FieldDeclarator) $1); } - | remove_accessor_declaration add_accessor_declaration + | event_declarators event_declarator { - Accessors accessors = new Accessors ((Accessor) $2, (Accessor) $1); - accessors.declared_in_reverse = true; - $$ = accessors; - } - | add_accessor_declaration { $$ = null; } - | remove_accessor_declaration { $$ = null; } - | error - { - Report.Error (1055, GetLocation ($1), "An add or remove accessor expected"); - $$ = null; + current_event_field.AddDeclarator ((FieldDeclarator) $2); } - | { $$ = null; } ; - -add_accessor_declaration - : opt_attributes ADD + +event_declarator + : COMMA IDENTIFIER { - lexer.EventParsing = false; + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null); + lbag.AddLocation ($$, GetLocation ($1)); } - block + | COMMA IDENTIFIER ASSIGN { - Accessor accessor = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, null, GetLocation ($2)); - lexer.EventParsing = true; - $$ = accessor; - } - | opt_attributes ADD error { - Report.Error (73, GetLocation ($2), "An add or remove accessor must have a body"); - $$ = null; + ++lexer.parsing_block; } - | opt_attributes modifiers ADD { - Report.Error (1609, GetLocation ($3), "Modifiers cannot be placed on event accessor declarations"); - $$ = null; + 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)); } ; - -remove_accessor_declaration - : opt_attributes REMOVE - { - lexer.EventParsing = false; + +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 ()); + } } - block + variable_initializer { - $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, null, GetLocation ($2)); - lexer.EventParsing = true; - } - | opt_attributes REMOVE error { - Report.Error (73, GetLocation ($2), "An add or remove accessor must have a body"); - $$ = null; + $$ = $2; } - | opt_attributes modifiers REMOVE { - Report.Error (1609, GetLocation ($3), "Modifiers cannot be placed on event accessor declarations"); + ; + +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 + { + Report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors", + current_event.GetSignatureForError ()); + } + | error + { + Report.Error (1055, GetLocation ($1), "An add or remove accessor expected"); $$ = null; } ; -indexer_declaration - : opt_attributes opt_modifiers - member_type indexer_declaration_name OPEN_BRACKET +add_accessor_declaration + : opt_attributes opt_modifiers ADD { - valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue; + 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; } - opt_formal_parameter_list CLOSE_BRACKET - OPEN_BRACE + event_accessor_block { - valid_param_mod = 0; - implicit_value_parameter_type = (FullNamedExpression) $3; - indexer_parameters = (ParametersCompiled) $7; + lexer.EventParsing = true; + + current_event.Add.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.Add.Block.StartLocation, + "`{0}': interface members cannot have a definition", current_event.Add.GetSignatureForError ()); } - - lexer.PropertyParsing = true; - parsing_indexer = true; + current_local_parameters = null; } - accessor_declarations + ; + +remove_accessor_declaration + : opt_attributes opt_modifiers REMOVE { - lexer.PropertyParsing = false; - has_get = has_set = false; - parsing_indexer = false; - } - CLOSE_BRACE - { - Accessors accessors = (Accessors) $11; - 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) $7, (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 ($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; - if (indexer.Set.Block != null) - Report.Error (531, indexer.Location, "`{0}.set': interface members cannot have a definition", indexer.GetSignatureForError ()); + lbag.AddMember (current_event.Remove, mod_locations); + lexer.EventParsing = false; + } + event_accessor_block + { + lexer.EventParsing = true; + + current_event.Remove.Block = (ToplevelBlock) $5; + + 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 ()); } - - 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 (IList) $7) { - em = new EnumMember ( - e, em, ev.identifier, ev.GetInitializer ((FullNamedExpression) $5), - 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; - } | 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) { + 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); - $2 = TypeManager.system_int32_expr; + $$ = null; + } else { + $$ = $2; } - - $$ = $2; } | COLON error { - Error_TypeExpected (lexer.Location); - $$ = TypeManager.system_int32_expr; + 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 VariableDeclaration [0]; } - | enum_member_declarations opt_comma { $$ = $1; } - ; - enum_member_declarations - : enum_member_declaration - { - var l = new List (4); - l.Add ((VariableDeclaration) $1); - $$ = l; - } + : enum_member_declaration | enum_member_declarations COMMA enum_member_declaration { - var l = (List) $1; - l.Add ((VariableDeclaration) $3); - $$ = l; + lbag.AddLocation ($1, GetLocation ($2)); + $$ = $3; } ; enum_member_declaration - : opt_attributes IDENTIFIER + : opt_attributes IDENTIFIER { - VariableDeclaration vd = new VariableDeclaration ( - (Tokenizer.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 { @@ -2586,14 +2600,17 @@ enum_member_declaration } ASSIGN constant_expression { - --lexer.parsing_block; - VariableDeclaration vd = new VariableDeclaration ( - (Tokenizer.LocatedToken) $2, (Expression) $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; } ; @@ -2614,7 +2631,7 @@ delegate_declaration 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 (); @@ -2632,6 +2649,8 @@ delegate_declaration SEMICOLON { current_delegate.SetParameterInfo ((List) $11); + lbag.AddMember (current_delegate, mod_locations, GetLocation ($3), GetLocation ($6), GetLocation ($9), GetLocation ($13)); + $$ = current_delegate; current_delegate = null; @@ -2640,9 +2659,6 @@ delegate_declaration opt_nullable : /* empty */ - { - $$ = null; - } | INTERR_NULLABLE { if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) @@ -2650,7 +2666,7 @@ opt_nullable else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "nullable types"); - $$ = this; + $$ = ComposedTypeSpecifier.CreateNullable (GetLocation ($1)); } ; @@ -2671,6 +2687,7 @@ member_name { var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } ; @@ -2686,7 +2703,7 @@ type_name // Generics arguments (any type, without attributes) // opt_type_argument_list - : /* empty */ { $$ = null; } + : /* empty */ | OP_GENERICS_LT type_arguments OP_GENERICS_GT { if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) @@ -2730,7 +2747,7 @@ type_declaration_name { lexer.parsing_generic_declaration = false; var lt = (Tokenizer.LocatedToken) $1; - $$ = new MemberName (lt.Value, (TypeArguments)$3, lt.Location); + $$ = new MemberName (lt.Value, (TypeArguments)$3, lt.Location); } ; @@ -2772,6 +2789,7 @@ explicit_interface { 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 { @@ -2779,16 +2797,18 @@ explicit_interface 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 { var lt = (Tokenizer.LocatedToken) $2; $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $3, lt.Location); + lbag.AddLocation ($$, GetLocation ($4)); } ; opt_type_parameter_list - : /* empty */ { $$ = null; } + : /* empty */ | OP_GENERICS_LT_DECL type_parameters OP_GENERICS_GT { if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) @@ -2797,6 +2817,7 @@ opt_type_parameter_list Report.FeatureIsNotAvailable (GetLocation ($1), "generics"); $$ = $2; + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } ; @@ -2812,6 +2833,7 @@ type_parameters TypeArguments type_args = (TypeArguments) $1; type_args.Add ((FullNamedExpression)$3); $$ = type_args; + lbag.AddLocation ($3, GetLocation ($3)); } ; @@ -2839,7 +2861,7 @@ type_and_void : type_expression_or_array | VOID { - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2849,7 +2871,7 @@ member_type lexer.parsing_generic_declaration = true; } ; - + // // A type which does not allow `void' to be used // @@ -2858,7 +2880,7 @@ type | VOID { Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report); - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2867,7 +2889,7 @@ simple_type | VOID { Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report); - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2876,7 +2898,7 @@ parameter_type | VOID { Report.Error (1536, GetLocation ($1), "Invalid parameter type `void'"); - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2884,8 +2906,7 @@ type_expression_or_array : type_expression | type_expression rank_specifiers { - string rank_specifiers = (string) $2; - $$ = new ComposedCast ((FullNamedExpression) $1, rank_specifiers); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } ; @@ -2895,7 +2916,7 @@ 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") $$ = new VarExpr (name.Location); @@ -2903,24 +2924,23 @@ type_expression $$ = name.GetTypeExpression (); } } + | namespace_or_type_name pointer_stars + { + $$ = new ComposedCast (((MemberName) $1).GetTypeExpression (), (ComposedTypeSpecifier) $2); + } | builtin_types opt_nullable { if ($2 != null) - $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } - | type_expression STAR + | builtin_types pointer_stars { - // - // Note that here only unmanaged types are allowed but we - // can't perform checks during this phase - we do it during - // semantic analysis. - // - $$ = new ComposedCast ((FullNamedExpression) $1, "*", Lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } - | VOID STAR + | VOID pointer_stars { - $$ = new ComposedCast (TypeManager.system_void_expr, "*", GetLocation ($1)); - } + $$ = new ComposedCast (new TypeExpression (TypeManager.void_type, GetLocation ($1)), (ComposedTypeSpecifier) $2); + } ; type_list @@ -2941,8 +2961,9 @@ 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 @@ -2957,33 +2978,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)); } ; // @@ -2992,24 +3005,11 @@ predefined_type primary_expression - : primary_expression_no_array_creation + : primary_expression_or_type + | literal | array_creation_expression - ; - -primary_expression_no_array_creation - : literal - | IDENTIFIER opt_type_argument_list - { - var lt = (Tokenizer.LocatedToken) $1; - $$ = new SimpleName (MemberName.MakeName (lt.Value, (TypeArguments)$2), (TypeArguments)$2, lt.Location); - } - | IDENTIFIER GENERATE_COMPLETION { - var lt = (Tokenizer.LocatedToken) $1; - $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location); - } | parenthesized_expression | default_value_expression - | member_access | invocation_expression | element_access | this_access @@ -3026,6 +3026,19 @@ primary_expression_no_array_creation | anonymous_method_expression ; +primary_expression_or_type + : IDENTIFIER opt_type_argument_list + { + var lt = (Tokenizer.LocatedToken) $1; + $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location); + } + | IDENTIFIER GENERATE_COMPLETION { + var lt = (Tokenizer.LocatedToken) $1; + $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location); + } + | member_access + ; + literal : boolean_literal | LITERAL @@ -3046,13 +3059,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 { @@ -3065,12 +3088,19 @@ member_access { 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 { var lt = (Tokenizer.LocatedToken) $3; - // TODO: Location is wrong as some predefined types doesn't hold a location $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); + } + | BASE DOT IDENTIFIER opt_type_argument_list + { + var lt = (Tokenizer.LocatedToken) $3; + $$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } | qualified_alias_member IDENTIFIER opt_type_argument_list { @@ -3086,21 +3116,21 @@ member_access 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 { + | 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, (Arguments) $3); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3112,14 +3142,18 @@ opt_object_or_collection_initializer object_or_collection_initializer : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion { - if ($2 == null) + if ($2 == null) { $$ = CollectionOrObjectInitializers.Empty; - else + // TODO: lbag + } else { $$ = new CollectionOrObjectInitializers ((List) $2, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); + } } | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE { $$ = new CollectionOrObjectInitializers ((List) $2, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4)); } ; @@ -3144,6 +3178,10 @@ member_initializer_list a.Add ((Expression) $3); $$ = a; } + | member_initializer_list error { + Error_SyntaxError (yyToken); + $$ = $1; + } ; member_initializer @@ -3151,6 +3189,7 @@ member_initializer { var lt = (Tokenizer.LocatedToken) $1; $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } | GENERATE_COMPLETION { @@ -3165,7 +3204,10 @@ member_initializer } | OPEN_BRACE expression_list CLOSE_BRACE { - $$ = new CollectionElementInitializer ((List)$2, GetLocation ($1)); + if ($2 == null) + $$ = null; + else + $$ = new CollectionElementInitializer ((List)$2, GetLocation ($1)); } | OPEN_BRACE CLOSE_BRACE { @@ -3217,9 +3259,9 @@ argument_list | argument_list COMMA { Report.Error (839, GetLocation ($2), "An argument is missing"); - $$ = null; + $$ = $1; } - | COMMA argument_or_named_argument + | COMMA error { Report.Error (839, GetLocation ($1), "An argument is missing"); $$ = null; @@ -3243,23 +3285,23 @@ 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 { $$ = 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 (GetLocation ($1))); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3)); } - | ARGLIST - { - $$ = new Argument (new ArglistAccess (GetLocation ($1))); - } ; variable_reference @@ -3267,37 +3309,10 @@ variable_reference ; element_access - : primary_expression_no_array_creation OPEN_BRACKET expression_list_arguments CLOSE_BRACKET - { - $$ = new ElementAccess ((Expression) $1, (Arguments) $3); - } - | array_creation_expression OPEN_BRACKET expression_list_arguments CLOSE_BRACKET - { - // LAMESPEC: Not allowed according to specification - $$ = new ElementAccess ((Expression) $1, (Arguments) $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; - } + $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); } ; @@ -3314,6 +3329,10 @@ expression_list list.Add ((Expression) $3); $$ = list; } + | expression_list error { + Error_SyntaxError (yyToken); + $$ = $1; + } ; expression_list_arguments @@ -3342,99 +3361,105 @@ expression_list_argument this_access : THIS { - $$ = new This (current_block, GetLocation ($1)); + $$ = new This (GetLocation ($1)); } ; base_access - : BASE DOT IDENTIFIER opt_type_argument_list - { - var lt = (Tokenizer.LocatedToken) $3; - $$ = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location); - } - | BASE OPEN_BRACKET expression_list_arguments CLOSE_BRACKET + : BASE OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET { - $$ = new BaseIndexerAccess ((Arguments) $3, GetLocation ($1)); + $$ = new ElementAccess (new BaseThis (GetLocation ($1)), (Arguments) $3, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); } - | BASE error + | BASE OPEN_BRACKET error { Error_SyntaxError (yyToken); - $$ = new BaseAccess (null, GetLocation ($2)); + $$ = new ElementAccess (null, null, GetLocation ($2)); } ; 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, (Arguments) $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, (Arguments) $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, (List) $3, (string) $5, (ArrayInitializer) $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, (ArrayInitializer) $3, GetLocation ($1)); + $$ = new ArrayCreation ((FullNamedExpression) $2, (ComposedTypeSpecifier) $3, (ArrayInitializer) $4, GetLocation ($1)); } | NEW rank_specifiers array_initializer { if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "implicitly typed arrays"); - $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayInitializer) $3, GetLocation ($1)); + $$ = new ImplicitlyTypedArrayCreation ((ComposedTypeSpecifier) $2, (ArrayInitializer) $3, GetLocation ($1)); + } + | NEW new_expr_type OPEN_BRACKET CLOSE_BRACKET OPEN_BRACKET_EXPR error CLOSE_BRACKET + { + Report.Error (178, GetLocation ($6), "Invalid rank specifier, expecting `,' or `]'"); + $$ = new ArrayCreation ((FullNamedExpression) $2, null, GetLocation ($1)); } - | new_expr_start error + | NEW new_expr_type error { - Report.Error (1526, GetLocation ($1), "A new expression requires () or [] after type"); - $$ = new ArrayCreation ((FullNamedExpression) $1, "[]", null, GetLocation ($1)); + 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; } ; @@ -3447,6 +3472,9 @@ anonymous_type_expression Report.FeatureIsNotAvailable (GetLocation ($1), "anonymous types"); $$ = new NewAnonymousType ((List) $3, current_container, GetLocation ($1)); + + // TODO: lbag comma location + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3480,6 +3508,7 @@ anonymous_type_parameter { var lt = (Tokenizer.LocatedToken)$1; $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } | IDENTIFIER { @@ -3487,12 +3516,6 @@ anonymous_type_parameter $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location), lt.Value, lt.Location); } - | BASE DOT IDENTIFIER opt_type_argument_list - { - var lt = (Tokenizer.LocatedToken) $3; - BaseAccess ba = new BaseAccess (lt.Value, (TypeArguments) $4, lt.Location); - $$ = new AnonymousTypeParameter (ba, lt.Value, lt.Location); - } | member_access { MemberAccess ma = (MemberAccess) $1; @@ -3508,64 +3531,37 @@ anonymous_type_parameter opt_rank_specifier : /* empty */ - { - $$ = ""; - } | rank_specifiers - { - $$ = $1; - } - ; - -opt_rank_specifier_or_nullable - : opt_nullable - { - if ($1 != null) - $$ = "?"; - else - $$ = string.Empty; - } - | opt_nullable rank_specifiers - { - if ($1 != null) - $$ = "?" + (string) $2; - else - $$ = $2; - } ; 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 - { - Error_SyntaxError (178, yyToken, "Invalid rank specifier"); - $$ = "[]"; + $$ = ComposedTypeSpecifier.CreateArrayDimension ((int)$2, GetLocation ($1)); } ; dim_separators : COMMA { - $$ = ","; + $$ = 2; } | dim_separators COMMA { - $$ = (string) $1 + ","; + $$ = ((int) $1) + 1; } ; @@ -3583,11 +3579,17 @@ opt_array_initializer array_initializer : OPEN_BRACE CLOSE_BRACE { - $$ = new ArrayInitializer (0, GetLocation ($1)); + var ai = new ArrayInitializer (0, GetLocation ($1)); + ai.VariableDeclaration = current_variable; + lbag.AddLocation (ai, GetLocation ($2)); + $$ = ai; } | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE { - $$ = new ArrayInitializer ((List) $2, GetLocation ($1)); + var ai = new ArrayInitializer ((List) $2, GetLocation ($1)); + ai.VariableDeclaration = current_variable; + lbag.AddLocation (ai, GetLocation ($3)); + $$ = ai; } ; @@ -3604,11 +3606,6 @@ variable_initializer_list list.Add ((Expression) $3); $$ = list; } - | error - { - Error_SyntaxError (yyToken); - $$ = new List (); - } ; typeof_expression @@ -3619,11 +3616,8 @@ typeof_expression open_parens_any typeof_type_expression CLOSE_PARENS { lexer.TypeOfParsing = false; - Expression type = (Expression)$4; - if (type == TypeManager.system_void_expr) - $$ = new TypeOfVoid (GetLocation ($1)); - else - $$ = new TypeOf (type, GetLocation ($1)); + $$ = new TypeOf ((FullNamedExpression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5)); } ; @@ -3642,14 +3636,14 @@ unbound_type_name { 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 { 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 { @@ -3661,14 +3655,16 @@ unbound_type_name { 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 { - var lt = (Tokenizer.LocatedToken) $3; - MemberName name = (MemberName) $1; + var te = ((MemberName) $1).GetTypeExpression (); + if (te.HasTypeArguments) + Error_TypeExpected (GetLocation ($4)); - $$ = new MemberAccess (name.GetTypeExpression (), MemberName.MakeName (lt.Value, (int) $4), lt.Location); + var lt = (Tokenizer.LocatedToken) $3; + $$ = new MemberAccess (te, lt.Value, (int) $4, lt.Location); } ; @@ -3696,8 +3692,10 @@ qualified_alias_member ; sizeof_expression - : SIZEOF open_parens_any type CLOSE_PARENS { + : SIZEOF open_parens_any type CLOSE_PARENS + { $$ = new SizeOf ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3705,6 +3703,7 @@ checked_expression : CHECKED open_parens_any expression CLOSE_PARENS { $$ = new CheckedExpr ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3712,17 +3711,15 @@ unchecked_expression : UNCHECKED open_parens_any expression CLOSE_PARENS { $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; pointer_member_access : primary_expression OP_PTR IDENTIFIER { - Expression deref; var lt = (Tokenizer.LocatedToken) $3; - - deref = new Indirection ((Expression) $1, lt.Location); - $$ = new MemberAccess (deref, lt.Value); + $$ = new MemberAccess (new Indirection ((Expression) $1, GetLocation ($2)), lt.Value, lt.Location); } ; @@ -3733,8 +3730,8 @@ anonymous_method_expression } block { - $$ = end_anonymous ((ToplevelBlock) $4); - } + $$ = end_anonymous ((ParametersBlock) $4); + } ; opt_anonymous_method_signature @@ -3764,6 +3761,7 @@ default_value_expression Report.FeatureIsNotAvailable (GetLocation ($1), "default value expression"); $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3771,23 +3769,20 @@ 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 ; cast_expression - : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression - { - $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); - } - | OPEN_PARENS predefined_type CLOSE_PARENS prefixed_unary_expression + : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression { $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } ; @@ -3799,19 +3794,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 { @@ -3819,7 +3814,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)); } ; @@ -3828,17 +3823,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)); } ; @@ -3847,16 +3842,16 @@ 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 { @@ -3873,12 +3868,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)); } ; @@ -3887,22 +3882,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)); } ; @@ -3911,12 +3906,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)); } ; @@ -3925,7 +3920,7 @@ and_expression | and_expression BITWISE_AND equality_expression { $$ = new Binary (Binary.Operator.BitwiseAnd, - (Expression) $1, (Expression) $3); + (Expression) $1, (Expression) $3, GetLocation ($2)); } ; @@ -3934,7 +3929,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)); } ; @@ -3943,7 +3938,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)); } ; @@ -3952,7 +3947,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)); } ; @@ -3961,7 +3956,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)); } ; @@ -3980,64 +3975,65 @@ conditional_expression : null_coalescing_expression | null_coalescing_expression INTERR expression COLON expression { - $$ = new Conditional (new BooleanExpression ((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)); } ; @@ -4086,7 +4082,7 @@ opt_lambda_parameter_list : /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; } | lambda_parameter_list { var pars_list = (List) $1; - $$ = new ParametersCompiled (compiler, pars_list.ToArray ()); + $$ = new ParametersCompiled (pars_list.ToArray ()); } ; @@ -4100,7 +4096,8 @@ lambda_expression_body b.AddStatement (new ContextualReturn ((Expression) $2)); $$ = b; } - | block { + | block + { $$ = $1; } ; @@ -4110,14 +4107,18 @@ lambda_expression { var lt = (Tokenizer.LocatedToken) $1; Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); - start_anonymous (true, new ParametersCompiled (compiler, p), GetLocation ($1)); + start_anonymous (true, new ParametersCompiled (p), GetLocation ($1)); } lambda_expression_body { - $$ = end_anonymous ((ToplevelBlock) $4); + $$ = end_anonymous ((ParametersBlock) $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; } opt_lambda_parameter_list CLOSE_PARENS ARROW @@ -4127,19 +4128,24 @@ lambda_expression } lambda_expression_body { - $$ = end_anonymous ((ToplevelBlock) $7); + $$ = end_anonymous ((ParametersBlock) $7); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4)); } ; expression : assignment_expression - | non_assignment_expression + | non_assignment_expression ; non_assignment_expression : conditional_expression | lambda_expression | query_expression + | ARGLIST + { + $$ = new ArglistAccess (GetLocation ($1)); + } ; constant_expression @@ -4167,7 +4173,7 @@ 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 @@ -4175,20 +4181,22 @@ class_declaration lexer.ConstraintsParsing = false; 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 (); } ; @@ -4201,7 +4209,11 @@ opt_partial ; opt_modifiers - : /* empty */ { $$ = (int) 0; } + : /* empty */ + { + mod_locations = null; + $$ = ModifierNone; + } | modifiers ; @@ -4209,14 +4221,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; } ; @@ -4224,56 +4241,113 @@ modifier : NEW { $$ = Modifiers.NEW; + StoreModifierLocation ($$, GetLocation ($1)); + if (current_container == RootContext.ToplevelTypes) Report.Error (1530, GetLocation ($1), "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; } + | 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 + | COLON type_list { current_container.AddBasesForPart (current_class, (List) $2); } ; opt_type_parameter_constraints_clauses - : /* empty */ { $$ = null; } + : /* empty */ | type_parameter_constraints_clauses - { $$ = $1; } + { + $$ = $1; + } ; type_parameter_constraints_clauses - : type_parameter_constraints_clause { + : type_parameter_constraints_clause + { var constraints = new List (1); constraints.Add ((Constraints) $1); $$ = constraints; } - | type_parameter_constraints_clauses type_parameter_constraints_clause { + | 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); } } @@ -4283,36 +4357,65 @@ type_parameter_constraints_clauses ; type_parameter_constraints_clause - : WHERE IDENTIFIER COLON type_parameter_constraints { + : WHERE IDENTIFIER COLON type_parameter_constraints + { var lt = (Tokenizer.LocatedToken) $2; - $$ = new Constraints (lt.Value, (List) $4, lt.Location); + $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List) $4, GetLocation ($1)); } ; type_parameter_constraints - : type_parameter_constraint { - var constraints = new List (1); - constraints.Add ($1); + : type_parameter_constraint + { + var constraints = new List (1); + constraints.Add ((FullNamedExpression) $1); $$ = constraints; } - | type_parameter_constraints COMMA type_parameter_constraint { - var constraints = (List) $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)); } ; @@ -4406,18 +4509,20 @@ statement_list ; statement - : declaration_statement + : block_variable_declaration { - if ($1 != null && (Block) $1 != current_block){ - current_block.AddStatement ((Statement) $1); - current_block = (Block) $1; - } + current_block.AddStatement ((Statement) $1); } | valid_declaration_statement { current_block.AddStatement ((Statement) $1); } | labeled_statement + | error + { + Error_SyntaxError (yyToken); + $$ = null; + } ; // @@ -4432,12 +4537,9 @@ interactive_statement_list ; interactive_statement - : declaration_statement + : block_variable_declaration { - if ($1 != null && (Block) $1 != current_block){ - current_block.AddStatement ((Statement) $1); - current_block = (Block) $1; - } + current_block.AddStatement ((Statement) $1); } | interactive_valid_declaration_statement { @@ -4449,7 +4551,7 @@ interactive_statement valid_declaration_statement : block | empty_statement - | expression_statement + | expression_statement | selection_statement | iteration_statement | jump_statement @@ -4480,7 +4582,7 @@ interactive_valid_declaration_statement embedded_statement : valid_declaration_statement - | declaration_statement + | block_variable_declaration { Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement"); $$ = null; @@ -4490,12 +4592,17 @@ embedded_statement Report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement"); $$ = null; } + | error + { + Error_SyntaxError (yyToken); + $$ = new EmptyStatement (GetLocation ($1)); + } ; empty_statement : SEMICOLON { - $$ = EmptyStatement.Value; + $$ = new EmptyStatement (GetLocation ($1)); } ; @@ -4503,30 +4610,22 @@ labeled_statement : IDENTIFIER COLON { var lt = (Tokenizer.LocatedToken) $1; - LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location); + LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location); - if (current_block.AddLabel (labeled)) - current_block.AddStatement (labeled); + current_block.AddLabel (labeled); + current_block.AddStatement (labeled); } statement ; -declaration_statement - : local_variable_declaration SEMICOLON - { - if ($1 != null){ - var de = (Tuple>) $1; - $$ = declare_local_variables (de.Item1, de.Item2, de.Item1.Location); - } - } - - | local_constant_declaration SEMICOLON +variable_type + : variable_type_simple + | variable_type_simple rank_specifiers { - if ($1 != null){ - var de = (Tuple>) $1; - - $$ = declare_local_constants (de.Item1, de.Item2); - } + if ($1 is VarExpr) + $1 = new SimpleName ("var", ((VarExpr) $1).Location); + + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } ; @@ -4536,11 +4635,9 @@ declaration_statement * > expressions to prevent reduce/reduce errors in the grammar. * > The expressions are converted into types during semantic analysis. */ -variable_type - : primary_expression_no_array_creation opt_rank_specifier_or_nullable +variable_type_simple + : primary_expression_or_type opt_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 @@ -4556,116 +4653,199 @@ 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") - $$ = 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; + } + } + | primary_expression_or_type pointer_stars + { + ATypeNameExpression expr = $1 as ATypeNameExpression; + + if (expr != null) { + $$ = new ComposedCast (expr, (ComposedTypeSpecifier) $2); + } else { + Error_ExpectingTypeName ((Expression)$1); + $$ = expr; } } - | builtin_types opt_rank_specifier_or_nullable + | builtin_types opt_nullable { - if ((string) $2 == "") + if ($2 == null) $$ = $1; else - $$ = new ComposedCast ((FullNamedExpression) $1, (string) $2, lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } - | VOID opt_rank_specifier + | builtin_types pointer_stars + { + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); + } + | VOID pointer_stars + { + $$ = new ComposedCast (new TypeExpression (TypeManager.void_type, GetLocation ($1)), (ComposedTypeSpecifier) $2); + } + | VOID { Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report); - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; + +pointer_stars + : pointer_star + | pointer_star pointer_stars + { + ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2; + $$ = $1; + } + ; -local_variable_pointer_type - : primary_expression_no_array_creation STAR +pointer_star + : STAR { - ATypeNameExpression expr = $1 as ATypeNameExpression; + $$ = ComposedTypeSpecifier.CreatePointer (GetLocation ($1)); + } + ; - if (expr != null) { - $$ = new ComposedCast (expr, "*"); - } else { - Error_ExpectingTypeName ((Expression)$1); - $$ = expr; - } +block_variable_declaration + : variable_type IDENTIFIER + { + var lt = (Tokenizer.LocatedToken) $2; + var li = new LocalVariable (current_block, lt.Value, lt.Location); + current_block.AddLocalName (li); + current_variable = new BlockVariableDeclaration ((FullNamedExpression) $1, li); } - | builtin_types STAR + opt_local_variable_initializer opt_variable_declarators SEMICOLON { - $$ = new ComposedCast ((FullNamedExpression) $1, "*", GetLocation ($1)); + $$ = current_variable; + current_variable = null; + lbag.AddLocation ($$, GetLocation ($6)); } - | VOID STAR + | CONST variable_type IDENTIFIER { - $$ = new ComposedCast (TypeManager.system_void_expr, "*", GetLocation ($1)); + var lt = (Tokenizer.LocatedToken) $3; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location); + current_block.AddLocalName (li); + current_variable = new BlockConstantDeclaration ((FullNamedExpression) $2, li); } - | local_variable_pointer_type STAR + const_variable_initializer opt_const_declarators SEMICOLON { - $$ = new ComposedCast ((FullNamedExpression) $1, "*"); + $$ = current_variable; + current_variable = null; + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($7)); } ; -local_variable_type - : variable_type - | local_variable_pointer_type opt_rank_specifier +opt_local_variable_initializer + : /* empty */ + | ASSIGN block_variable_initializer { - if ($1 != null){ - string rank = (string)$2; - - if (rank == "") - $$ = $1; - else - $$ = new ComposedCast ((FullNamedExpression) $1, rank); + current_variable.Initializer = (Expression) $2; + // TODO: lbag + } + | error + { + if (yyToken == Token.OPEN_BRACKET_EXPR) { + Report.Error (650, lexer.Location, + "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type"); } else { - $$ = null; + Error_SyntaxError (yyToken); } } ; -local_variable_declaration - : local_variable_type local_variable_declarators +opt_variable_declarators + : /* empty */ + | variable_declarators + ; + +variable_declarators + : variable_declarator + | variable_declarators variable_declarator + ; + +variable_declarator + : COMMA IDENTIFIER { - if ($1 != null) { - VarExpr ve = $1 as VarExpr; - if (ve != null) { - if (!((VariableDeclaration) ((List)$2) [0]).HasInitializer) - ve.VariableInitializersCount = 0; - else - ve.VariableInitializersCount = ((List)$2).Count; - } - - $$ = new Tuple> ((FullNamedExpression) $1, (List) $2); - } else - $$ = null; + var lt = (Tokenizer.LocatedToken) $2; + var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location); + var d = new BlockVariableDeclaration.Declarator (li, null); + current_variable.AddDeclarator (d); + current_block.AddLocalName (li); + lbag.AddLocation (d, GetLocation ($1)); } - ; - -local_constant_declaration - : CONST variable_type constant_declarators + | COMMA IDENTIFIER ASSIGN block_variable_initializer { - if ($2 != null) - $$ = new Tuple> ((FullNamedExpression) $2, (List) $3); - else - $$ = null; + var lt = (Tokenizer.LocatedToken) $2; + var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location); + var d = new BlockVariableDeclaration.Declarator (li, (Expression) $4); + current_variable.AddDeclarator (d); + current_block.AddLocalName (li); + lbag.AddLocation (d, GetLocation ($1), GetLocation ($3)); + } + ; + +const_variable_initializer + : /* empty */ + { + Report.Error (145, lexer.Location, "A const field requires a value to be provided"); + } + | ASSIGN constant_initializer_expr + { + current_variable.Initializer = (Expression) $2; + } + ; + +opt_const_declarators + : /* empty */ + | const_declarators + ; + +const_declarators + : const_declarator + | const_declarators const_declarator + ; + +const_declarator + : COMMA IDENTIFIER ASSIGN constant_initializer_expr + { + var lt = (Tokenizer.LocatedToken) $2; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location); + var d = new BlockVariableDeclaration.Declarator (li, (Expression) $4); + current_variable.AddDeclarator (d); + current_block.AddLocalName (li); + lbag.AddLocation (d, GetLocation ($1), GetLocation ($3)); + } + ; + +block_variable_initializer + : variable_initializer + | STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET + { + $$ = new StackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5)); + } + | STACKALLOC simple_type + { + Report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type"); + $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1)); } ; expression_statement - : statement_expression SEMICOLON { $$ = $1; } + : statement_expression SEMICOLON + { + $$ = $1; + lbag.AddStatement ($$, GetLocation ($2)); + } | statement_expression COMPLETE_COMPLETION { $$ = $1; } ; @@ -4689,11 +4869,6 @@ statement_expression $$ = new StatementExpression (s); } - | error - { - Error_SyntaxError (yyToken); - $$ = null; - } ; interactive_statement_expression @@ -4708,7 +4883,7 @@ interactive_statement_expression | error { Error_SyntaxError (yyToken); - $$ = EmptyStatement.Value; + $$ = new EmptyStatement (GetLocation ($1)); } ; @@ -4721,58 +4896,42 @@ if_statement : IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement { - Location l = GetLocation ($1); - - $$ = new If ((BooleanExpression) $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) + Warning_EmptyStatement (GetLocation ($5)); + + $$ = 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 = GetLocation ($1); - - $$ = new If ((BooleanExpression) $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) + Warning_EmptyStatement (GetLocation ($5)); + if ($7 is EmptyStatement) + Warning_EmptyStatement (GetLocation ($7)); } ; switch_statement - : SWITCH open_parens_any - { - if (switch_stack == null) - switch_stack = new Stack (2); - switch_stack.Push (current_block); - } - expression CLOSE_PARENS - switch_block + : SWITCH open_parens_any expression CLOSE_PARENS OPEN_BRACE { - $$ = new Switch ((Expression) $4, (List) $6, GetLocation ($1)); - current_block = (Block) switch_stack.Pop (); + start_block (GetLocation ($5)); } - ; - -switch_block - : OPEN_BRACE - opt_switch_sections - CLOSE_BRACE + opt_switch_sections CLOSE_BRACE { - $$ = $2; + $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, (List) $7, GetLocation ($1)); + end_block (GetLocation ($8)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } ; opt_switch_sections : /* empty */ - { - Report.Warning (1522, 1, lexer.Location, "Empty switch block"); + { + Report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); $$ = new List (); } | switch_sections @@ -4793,6 +4952,11 @@ switch_sections sections.Add ((SwitchSection) $2); $$ = sections; } + | error + { + Error_SyntaxError (yyToken); + $$ = new List (); + } ; switch_section @@ -4802,7 +4966,7 @@ switch_section } statement_list { - $$ = new SwitchSection ((List) $1, current_block.Explicit); + $$ = new SwitchSection ((List) $1, current_block); } ; @@ -4827,6 +4991,7 @@ switch_label : CASE constant_expression COLON { $$ = new SwitchLabel ((Expression) $2, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } | DEFAULT_COLON { @@ -4844,8 +5009,11 @@ iteration_statement while_statement : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement { - Location l = GetLocation ($1); - $$ = new While ((BooleanExpression) $3, (Statement) $5, l); + if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation ($5)); + + $$ = new While ((BooleanExpression) $3, (Statement) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -4853,72 +5021,52 @@ do_statement : DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON { - Location l = GetLocation ($1); - - $$ = new Do ((Statement) $2, (BooleanExpression) $5, l); + $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7)); } ; for_statement - : FOR open_parens_any opt_for_initializer SEMICOLON + : FOR open_parens_any { - Location l = lexer.Location; - start_block (l); - Block assign_block = current_block; - - if ($3 is Tuple>){ - var de = (Tuple>) $3; - - var type = de.Item1; - - foreach (VariableDeclaration decl in de.Item2){ - - LocalInfo vi; - - vi = current_block.AddVariable (type, decl.identifier, decl.Location); - if (vi == null) - continue; - - Expression expr = decl.GetInitializer (type); - - LocalVariableReference var; - var = new LocalVariableReference (assign_block, decl.identifier, l); - - if (expr != null) { - Assign a = new SimpleAssign (var, expr, decl.Location); - - assign_block.AddStatement (new StatementExpression (a)); - } - } - - // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal. - // This can be referred to as $5 below. - $$ = null; - } else { - $$ = $3; - } - } + start_block (GetLocation ($2)); + current_block.IsCompilerGenerated = true; + } + opt_for_initializer SEMICOLON opt_for_condition SEMICOLON opt_for_iterator CLOSE_PARENS embedded_statement { - Location l = GetLocation ($1); - - For f = new For ((Statement) $5, (BooleanExpression) $6, (Statement) $8, (Statement) $10, l); - + if ($10 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation ($10)); + + For f = new For ((Statement) $4, (BooleanExpression) $6, (Statement) $8, (Statement) $10, GetLocation ($1)); current_block.AddStatement (f); + + lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7), GetLocation ($9)); - $$ = end_block (lexer.Location); + $$ = end_block (GetLocation ($5)); } ; opt_for_initializer - : /* empty */ { $$ = EmptyStatement.Value; } + : /* empty */ { $$ = new EmptyStatement (lexer.Location); } | for_initializer ; for_initializer - : local_variable_declaration + : variable_type IDENTIFIER + { + var lt = (Tokenizer.LocatedToken) $2; + var li = new LocalVariable (current_block, lt.Value, lt.Location); + current_block.AddLocalName (li); + current_variable = new BlockVariableDeclaration ((FullNamedExpression) $1, li); + } + opt_local_variable_initializer opt_variable_declarators + { + $$ = current_variable; + current_variable = null; + } | statement_expression_list ; @@ -4928,7 +5076,7 @@ opt_for_condition ; opt_for_iterator - : /* empty */ { $$ = EmptyStatement.Value; } + : /* empty */ { $$ = new EmptyStatement (lexer.Location); } | for_iterator ; @@ -4937,21 +5085,19 @@ 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); + lbag.AddStatement (sl, GetLocation ($2)); + } else { + sl.Add ((Statement) $3); + lbag.AppendTo (sl, GetLocation ($2)); + } + + $$ = sl; } ; @@ -4961,38 +5107,26 @@ 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 - expression CLOSE_PARENS + | FOREACH open_parens_any type IDENTIFIER IN expression CLOSE_PARENS { - start_block (lexer.Location); - Block foreach_block = current_block; - + start_block (GetLocation ($2)); + current_block.IsCompilerGenerated = true; + var lt = (Tokenizer.LocatedToken) $4; - Location l = lt.Location; - LocalInfo vi = foreach_block.AddVariable ((Expression) $3, lt.Value, l); - if (vi != null) { - vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Foreach); - - // Get a writable reference to this read-only variable. - // - // Note that the $$ here refers to the value of _this_ code block, - // not the value of the LHS non-terminal. This can be referred to as $8 below. - $$ = new LocalVariableReference (foreach_block, lt.Value, l, vi, false); - } else { - $$ = null; - } - } - embedded_statement - { - LocalVariableReference v = (LocalVariableReference) $8; - Location l = GetLocation ($1); - - if (v != null) { - Foreach f = new Foreach ((Expression) $3, v, (Expression) $6, (Statement) $9, l); - current_block.AddStatement (f); - } - - $$ = end_block (lexer.Location); + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location); + current_block.AddLocalName (li); + $$ = li; + } + embedded_statement + { + if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation ($9)); + + Foreach f = new Foreach ((Expression) $3, (LocalVariable) $8, (Expression) $6, (Statement) $9, GetLocation ($1)); + current_block.AddStatement (f); + + lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7)); + $$ = end_block (GetLocation ($7)); } ; @@ -5009,6 +5143,7 @@ break_statement : BREAK SEMICOLON { $$ = new Break (GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2)); } ; @@ -5016,6 +5151,7 @@ continue_statement : CONTINUE SEMICOLON { $$ = new Continue (GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2)); } ; @@ -5024,14 +5160,17 @@ goto_statement { 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, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } | GOTO DEFAULT SEMICOLON { $$ = new GotoDefault (GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3)); } ; @@ -5039,6 +5178,7 @@ return_statement : RETURN opt_expression SEMICOLON { $$ = new Return ((Expression) $2, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($3)); } ; @@ -5046,29 +5186,26 @@ throw_statement : THROW opt_expression SEMICOLON { $$ = new Throw ((Expression) $2, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($3)); } ; yield_statement - : IDENTIFIER RETURN expression SEMICOLON + : IDENTIFIER RETURN opt_expression SEMICOLON { 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, GetLocation ($2), "Expression expected after yield return"); - $$ = null; + + current_block.ParametersBlock.TopBlock.IsIterator = true; + $$ = new Yield ((Expression) $3, lt.Location); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } | IDENTIFIER BREAK SEMICOLON { @@ -5076,15 +5213,13 @@ yield_statement 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; + current_block.ParametersBlock.TopBlock.IsIterator = true; $$ = new YieldBreak (lt.Location); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3)); } ; @@ -5101,10 +5236,12 @@ try_statement | TRY block FINALLY block { $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($3)); } | TRY block catch_clauses FINALLY block { $$ = new TryFinally (new TryCatch ((Block) $2, (List) $3, GetLocation ($1), true), (Block) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($4)); } | TRY block error { @@ -5140,222 +5277,160 @@ catch_clauses ; opt_identifier - : /* empty */ { $$ = null; } + : /* empty */ | IDENTIFIER ; catch_clause - : CATCH opt_catch_args + : CATCH block { - if ($2 != null) { - var cc = (Tuple) $2; - var lt = cc.Item2; - - if (lt != null){ - List one = new List (1); - - one.Add (new VariableDeclaration (lt, null)); + $$ = new Catch ((Block) $2, GetLocation ($1)); + } + | CATCH open_parens_any type opt_identifier CLOSE_PARENS + { + start_block (GetLocation ($2)); + var c = new Catch (current_block, GetLocation ($1)); + c.TypeExpression = (FullNamedExpression) $3; - start_block (lexer.Location); - current_block = declare_local_variables (cc.Item1, one, lt.Location); - } - } - } block { - Expression type = null; - string id = null; - Block var_block = null; - - if ($2 != null){ - var cc = (Tuple) $2; - type = cc.Item1; - var lt = cc.Item2; - - if (lt != null){ - id = lt.Value; - var_block = end_block (lexer.Location); - } + if ($4 != null) { + var lt = (Tokenizer.LocatedToken) $4; + c.Variable = new LocalVariable (current_block, lt.Value, lt.Location); + current_block.AddLocalName (c.Variable); } - - $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc); + + lbag.AddLocation (c, GetLocation ($2), GetLocation ($5)); + $$ = c; } - ; - -opt_catch_args - : /* empty */ { $$ = null; } - | catch_args - ; - -catch_args - : open_parens_any type opt_identifier CLOSE_PARENS + block_prepared { - $$ = new Tuple ((FullNamedExpression)$2, (Tokenizer.LocatedToken) $3); + $$ = $6; } - | open_parens_any CLOSE_PARENS + | CATCH open_parens_any error { - Report.Error (1015, GetLocation ($1), "A type that derives from `System.Exception', `object', or `string' expected"); - $$ = null; + if (yyToken == Token.CLOSE_PARENS) { + Report.Error (1015, lexer.Location, + "A type that derives from `System.Exception', `object', or `string' expected"); + } else { + Error_SyntaxError (yyToken); + } + + $$ = new Catch (null, GetLocation ($1)); } ; 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 (GetLocation ($1), Report); + if (!RootContext.Unsafe) + Error_UnsafeCodeNotAllowed (GetLocation ($1)); } block { - $$ = new Unsafe ((Block) $3); - } - ; - -fixed_statement - : FIXED open_parens_any - type_and_void fixed_pointer_declarators - CLOSE_PARENS - { - start_block (lexer.Location); - } - embedded_statement - { - 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)); - - current_block.AddStatement (f); - - $$ = end_block (lexer.Location); + $$ = new Unsafe ((Block) $3, GetLocation ($1)); } ; -fixed_pointer_declarators - : fixed_pointer_declarator { - var declarators = new List> (2); - if ($1 != null) - declarators.Add ((KeyValuePair)$1); - $$ = declarators; - } - | fixed_pointer_declarators COMMA fixed_pointer_declarator +lock_statement + : LOCK open_parens_any expression CLOSE_PARENS embedded_statement { - var declarators = (List>) $1; - if ($3 != null) - declarators.Add ((KeyValuePair)$3); - $$ = declarators; + if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation ($5)); + + $$ = new Lock ((Expression) $3, (Statement) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } ; -fixed_pointer_declarator - : IDENTIFIER ASSIGN expression +fixed_statement + : FIXED open_parens_any variable_type IDENTIFIER { - var lt = (Tokenizer.LocatedToken) $1; - $$ = new KeyValuePair (lt, (Expression) $3); + start_block (GetLocation ($2)); + + var lt = (Tokenizer.LocatedToken) $4; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.FixedVariable | LocalVariable.Flags.Used, lt.Location); + current_block.AddLocalName (li); + current_variable = new Fixed.VariableDeclaration ((FullNamedExpression) $3, li); } - | IDENTIFIER + using_or_fixed_variable_initializer opt_variable_declarators CLOSE_PARENS { - Report.Error (210, ((Tokenizer.LocatedToken) $1).Location, "You must provide an initializer in a fixed or using statement declaration"); - $$ = null; + $$ = current_variable; + current_variable = null; } - ; - -lock_statement - : LOCK open_parens_any expression CLOSE_PARENS - { - // - } embedded_statement { - $$ = new Lock ((Expression) $3, (Statement) $6, GetLocation ($1)); + if ($10 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation ($10)); + + Fixed f = new Fixed ((Fixed.VariableDeclaration) $9, (Statement) $10, GetLocation ($1)); + current_block.AddStatement (f); + $$ = end_block (GetLocation ($8)); } ; using_statement - : USING open_parens_any local_variable_declaration CLOSE_PARENS + : USING open_parens_any variable_type IDENTIFIER { - start_block (lexer.Location); - Block assign_block = current_block; - - var de = (Tuple>) $3; - Location l = GetLocation ($1); - - var vars = new Stack> (); - - 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.GetInitializer (de.Item1); - if (expr == null) { - Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration"); - continue; - } - LocalVariableReference var; - - // Get a writable reference to this read-only variable. - var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false); - - // This is so that it is not a warning on using variables - vi.Used = true; - - vars.Push (new Tuple (var, expr)); - - // Assign a = new SimpleAssign (var, expr, decl.Location); - // assign_block.AddStatement (new StatementExpression (a)); - } - - // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal. - // It can be referred to as $5 below. - $$ = vars; + start_block (GetLocation ($2)); + + var lt = (Tokenizer.LocatedToken) $4; + var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.UsingVariable | LocalVariable.Flags.Used, lt.Location); + current_block.AddLocalName (li); + current_variable = new Using.VariableDeclaration ((FullNamedExpression) $3, li); + } + using_or_fixed_variable_initializer opt_variable_declarators CLOSE_PARENS + { + $$ = current_variable; + current_variable = null; } embedded_statement { - Statement stmt = (Statement) $6; - var vars = (Stack>) $5; - Location l = GetLocation ($1); - - while (vars.Count > 0) { - var de = vars.Pop (); - stmt = new Using (de.Item1, de.Item2, stmt, l); - } - current_block.AddStatement (stmt); - $$ = end_block (lexer.Location); + if ($10 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation ($10)); + + Using u = new Using ((Using.VariableDeclaration) $9, (Statement) $10, GetLocation ($1)); + current_block.AddStatement (u); + $$ = end_block (GetLocation ($8)); } - | USING open_parens_any expression CLOSE_PARENS + | USING open_parens_any expression CLOSE_PARENS embedded_statement { - start_block (lexer.Location); + if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE) + Warning_EmptyStatement (GetLocation ($5)); + + Using u = new Using ((Expression) $3, (Statement) $5, GetLocation ($1)); + lbag.AddStatement (u, GetLocation ($2), GetLocation ($4)); + $$ = u; } - embedded_statement + ; + +using_or_fixed_variable_initializer + : /* empty */ { - current_block.AddStatement (new UsingTemporary ((Expression) $3, (Statement) $6, GetLocation ($1))); - $$ = end_block (lexer.Location); + Report.Error (210, lexer.Location, "You must provide an initializer in a fixed or using statement declaration"); } - ; + | ASSIGN variable_initializer + { + current_variable.Initializer = (Expression) $2; + $$ = current_variable; + } + ; // LINQ query_expression - : first_from_clause query_body + : first_from_clause query_body { lexer.query_parsing = false; @@ -5377,76 +5452,106 @@ 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 (compiler, current_block, lexer.Location); + var lt = (Tokenizer.LocatedToken) $2; - current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)); + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1))); } | FROM_FIRST type IDENTIFIER IN expression { + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + var lt = (Tokenizer.LocatedToken) $3; - $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5)); - current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)); + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + $$ = new Linq.QueryExpression ( + new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, 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 (compiler, current_block, lexer.Location); + var lt = (Tokenizer.LocatedToken) $2; - current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)); + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1))); } | FROM type IDENTIFIER IN expression { - $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + var lt = (Tokenizer.LocatedToken) $3; - current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)); + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + $$ = new Linq.QueryExpression ( + new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + } + ); } ; from_clause : FROM IDENTIFIER IN { - current_block = new Linq.QueryBlock (compiler, current_block, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression { var lt = (Tokenizer.LocatedToken) $2; - var sn = new SimpleMemberName (lt.Value, lt.Location); - $$ = new Linq.SelectMany (current_block.Toplevel, sn, (Expression)$5); + var sn = new Linq.RangeVariable (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 (compiler, sn); + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); } | FROM type IDENTIFIER IN { - current_block = new Linq.QueryBlock (compiler, current_block, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression { var lt = (Tokenizer.LocatedToken) $3; - var sn = new SimpleMemberName (lt.Value, lt.Location); + var sn = new Linq.RangeVariable (lt.Value, lt.Location); - FullNamedExpression type = (FullNamedExpression)$2; - - $$ = new Linq.SelectMany (current_block.Toplevel, sn, new Linq.Cast (type, (FullNamedExpression)$6)); + $$ = 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 (compiler, sn); + ((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; @@ -5461,6 +5566,7 @@ query_body $$ = head; } + | opt_query_body_clauses COMPLETE_COMPLETION ; select_or_group_clause @@ -5470,7 +5576,7 @@ select_or_group_clause } 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; @@ -5478,10 +5584,10 @@ 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 (compiler, current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + linq_clause_blocks.Push ((Linq.QueryBlock)current_block); } expression { @@ -5492,7 +5598,7 @@ select_or_group_clause } 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; @@ -5515,7 +5621,7 @@ query_body_clauses query_body_clause : from_clause - | let_clause + | let_clause | where_clause | join_clause | orderby_clause @@ -5524,18 +5630,18 @@ query_body_clause let_clause : LET IDENTIFIER ASSIGN { - current_block = new Linq.QueryBlock (compiler, current_block, GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression { var lt = (Tokenizer.LocatedToken) $2; - var sn = new SimpleMemberName (lt.Value, lt.Location); - $$ = new Linq.Let (current_block.Toplevel, current_container, sn, (Expression)$5); + var sn = new Linq.RangeVariable (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 (compiler, sn); + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); } ; @@ -5546,7 +5652,7 @@ where_clause } boolean_expression { - $$ = new Linq.Where (current_block.Toplevel, (BooleanExpression)$3, GetLocation ($1)); + $$ = new Linq.Where ((Linq.QueryBlock)current_block, (BooleanExpression)$3, GetLocation ($1)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; @@ -5557,10 +5663,10 @@ 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 (compiler, current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } expression ON { @@ -5568,7 +5674,7 @@ join_clause current_block = current_block.Parent; current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } expression EQUALS { @@ -5576,43 +5682,51 @@ join_clause current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - var lt = (Tokenizer.LocatedToken) $2; - current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), lexer.Location); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression opt_join_into { - 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 (); + current_block.AddStatement (new ContextualReturn ((Expression) $11)); + current_block.SetEndLocation (lexer.Location); + + var outer_selector = linq_clause_blocks.Pop (); + var block = linq_clause_blocks.Pop (); + var lt = (Tokenizer.LocatedToken) $2; + var sn = new Linq.RangeVariable (lt.Value, lt.Location); + Linq.RangeVariable into; + if ($12 == null) { - $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, current_block.Toplevel, GetLocation ($1)); + into = sn; + $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)); } else { - var lt2 = (Tokenizer.LocatedToken) $12; - sn2 = new SimpleMemberName (lt2.Value, lt2.Location); - $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, current_block.Toplevel, - sn2, GetLocation ($1)); + // + // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions + // + var parent = block.Parent; + while (parent is Linq.QueryBlock) { + parent = parent.Parent; + } + current_block.Parent = parent; + + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); + + lt = (Tokenizer.LocatedToken) $12; + into = new Linq.RangeVariable (lt.Value, lt.Location); + + $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1)); } - current_block.AddStatement (new ContextualReturn ((Expression) $11)); - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; - - if (sn2 == null) - ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn); - else - ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn2); + current_block = block.Parent; + ((Linq.QueryBlock)current_block).AddRangeVariable (into); } | JOIN type IDENTIFIER IN { if (linq_clause_blocks == null) - linq_clause_blocks = new Stack (); + linq_clause_blocks = new Stack (); current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } expression ON { @@ -5620,7 +5734,7 @@ join_clause current_block = current_block.Parent; current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } expression EQUALS { @@ -5628,35 +5742,47 @@ join_clause current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - var lt = (Tokenizer.LocatedToken) $3; - current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), lexer.Location); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); } expression opt_join_into { + current_block.AddStatement (new ContextualReturn ((Expression) $12)); + current_block.SetEndLocation (lexer.Location); + + var outer_selector = linq_clause_blocks.Pop (); + var block = linq_clause_blocks.Pop (); + var lt = (Tokenizer.LocatedToken) $3; - 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 sn = new Linq.RangeVariable (lt.Value, lt.Location); + Linq.RangeVariable into; - Linq.Cast cast = new Linq.Cast ((FullNamedExpression)$2, (Expression)$6); if ($13 == null) { - $$ = new Linq.Join (block, sn, cast, outer_selector, current_block.Toplevel, GetLocation ($1)); + into = sn; + $$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + }; } else { - var lt2 = (Tokenizer.LocatedToken) $13; - sn2 = new SimpleMemberName (lt2.Value, lt2.Location); - $$ = new Linq.GroupJoin (block, sn, cast, outer_selector, current_block.Toplevel, - sn2, GetLocation ($1)); - } + // + // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions + // + var parent = block.Parent; + while (parent is Linq.QueryBlock) { + parent = parent.Parent; + } + current_block.Parent = parent; - current_block.AddStatement (new ContextualReturn ((Expression) $12)); - current_block.SetEndLocation (lexer.Location); - current_block = current_block.Parent; + ((Linq.QueryBlock)current_block).AddRangeVariable (sn); + + lt = (Tokenizer.LocatedToken) $13; + into = new Linq.RangeVariable (lt.Value, lt.Location); // TODO: - if (sn2 == null) - ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn); - else - ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn2); + $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + }; + } + + current_block = block.Parent; + ((Linq.QueryBlock)current_block).AddRangeVariable (into); } ; @@ -5705,11 +5831,11 @@ orderings_then_by current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (compiler, 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; } ; @@ -5717,30 +5843,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); } ; @@ -5755,14 +5881,22 @@ opt_query_continuation current_block.SetEndLocation (GetLocation ($1)); current_block = current_block.Parent; - - var lt = (Tokenizer.LocatedToken) $2; + + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); - current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), 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; + var rv = new Linq.RangeVariable (lt.Value, lt.Location); + $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, rv, GetLocation ($1)) { + next = (Linq.AQueryClause)$4 + }; } ; @@ -5781,7 +5915,7 @@ opt_query_continuation interactive_parsing : EVAL_STATEMENT_PARSER EOF - | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives + | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives opt_COMPLETE_COMPLETION | EVAL_STATEMENT_PARSER { Evaluator.LoadAliases (current_namespace); @@ -5794,14 +5928,14 @@ interactive_parsing // (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 (compiler, mpar); + ParametersCompiled pars = new ParametersCompiled (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, @@ -5847,67 +5981,10 @@ close_brace_or_complete_completion ; %% -// -// A class used to pass around variable declarations and constants -// -class VariableDeclaration { - public string identifier; - Expression initializer; - public Location Location; - public Attributes OptAttributes; - public string DocComment; - - public VariableDeclaration (Tokenizer.LocatedToken lt, Expression initializer, Attributes opt_attrs) - { - this.identifier = lt.Value; - this.initializer = initializer; - this.Location = lt.Location; - this.OptAttributes = opt_attrs; - } - - public VariableDeclaration (Tokenizer.LocatedToken lt, Expression initializer) - : this (lt, initializer, null) - { - } - - public Expression GetInitializer (FullNamedExpression type) - { - if (initializer is ArrayInitializer) - return new ArrayCreation (type, "", (ArrayInitializer)initializer, Location); - - return initializer; - } - - public bool HasInitializer { - get { return initializer != null; } - } -} - -class VariableMemberDeclaration -{ - public readonly MemberName MemberName; - Expression initializer; - - public VariableMemberDeclaration (MemberName mn, Expression initializer) - { - MemberName = mn; - this.initializer = initializer; - } - - public Expression GetInitializer (FullNamedExpression type) - { - if (initializer is ArrayInitializer) - return new ArrayCreation (type, "", (ArrayInitializer)initializer, MemberName.Location); - - return initializer; - } -} - - // // A class used to hold info about an operator declarator // -struct OperatorDeclaration { +class OperatorDeclaration { public readonly Operator.OpType optype; public readonly FullNamedExpression ret_type; public readonly Location location; @@ -5946,6 +6023,16 @@ 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 Warning_EmptyStatement (Location loc) +{ + Report.Warning (642, 3, loc, "Possible mistaken empty statement"); +} + void Error_NamedArgumentExpected (NamedArgument a) { Report.Error (1738, a.Location, "Named arguments must appear after the positional arguments"); @@ -5996,112 +6083,16 @@ MakeName (MemberName class_name) } } -Block declare_local_variables (FullNamedExpression type, List variable_declarators, Location loc) -{ - Block implicit_block; - - // - // If we are doing interactive editing, we want variable declarations - // that are in the top block to be added instead to the class as - // static variables - // - if (RootContext.StatementMode){ - bool hoist = true; - - for (Block b = current_block; b != null; b = b.Parent){ - if (b is ExplicitBlock && !(b is ToplevelBlock)){ - // There has been an explicit block, we cant add to the class - hoist = false; - break; - } - } - if (hoist){ - // - // We can use "current_block" since we know there are no explicit blocks - // - 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 - var init = decl.GetInitializer (type); - if (init != null){ - string id = "$" + decl.identifier; - 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, 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)); - } else { - Field f = new Field (current_container, (FullNamedExpression) type, Modifiers.PUBLIC | Modifiers.STATIC, - new MemberName (decl.identifier, loc), null); - current_container.AddField (f); - - // Register the field to be visible later as a global variable - Evaluator.QueueField (f); - } - } - - return current_block; - } - } - - // - // We use the `Used' property to check whether statements - // have been added to the current block. If so, we need - // to create another block to contain the new declaration - // otherwise, as an optimization, we use the same block to - // add the declaration. - // - // FIXME: A further optimization is to check if the statements - // that were added were added as part of the initialization - // below. In which case, no other statements have been executed - // and we might be able to reduce the number of blocks for - // situations like this: - // - // int j = 1; int k = j + 1; - // - if (current_block.Used) - implicit_block = new Block (current_block, loc, lexer.Location); - else - implicit_block = current_block; - - foreach (VariableDeclaration decl in variable_declarators){ - - if (implicit_block.AddVariable (type, decl.identifier, decl.Location) != null) { - if (decl.HasInitializer){ - Assign assign; - - var lvr = new LocalVariableReference (implicit_block, decl.identifier, loc); - - assign = new SimpleAssign (lvr, decl.GetInitializer (type), decl.Location); - - implicit_block.AddStatement (new StatementExpression (assign)); - } - } - } - - return implicit_block; -} - -Block declare_local_constants (FullNamedExpression type, List declarators) +[System.Diagnostics.Conditional ("FULL_AST")] +void StoreModifierLocation (object token, Location loc) { - Block implicit_block; + if (lbag == null) + return; - if (current_block.Used) - implicit_block = new Block (current_block); - else - implicit_block = current_block; + if (mod_locations == null) + mod_locations = new List> (); - foreach (VariableDeclaration decl in declarators){ - implicit_block.AddConstant (type, decl.identifier, decl.GetInitializer (type), decl.Location); - } - - return implicit_block; + mod_locations.Add (Tuple.Create ((Modifiers) token, loc)); } string CheckAttributeTarget (string a, Location l) @@ -6158,7 +6149,7 @@ public CSharpParser (SeekableStreamReader reader, CompilationUnit file, Compiler this.file = file; this.compiler = ctx; - current_namespace = new NamespaceEntry (null, file, null); + current_namespace = new NamespaceEntry (ctx, null, file, null); current_class = current_namespace.SlaveDeclSpace; current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes oob_stack.Clear (); @@ -6181,15 +6172,21 @@ public void parse () Tokenizer tokenizer = lexer as Tokenizer; tokenizer.cleanup (); } catch (Exception e){ - if (e is yyParser.yyUnexpectedEof) + if (e is yyParser.yyUnexpectedEof) { + Error_SyntaxError (yyToken); UnexpectedEOF = true; - - if (e is yyParser.yyException) + return; + } + + 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 + } else { + // Used by compiler-tester to test internal errors + if (yacc_verbose_flag > 0) + throw; + Report.Error (589, lexer.Location, "Internal compiler error during parsing"); + } } if (RootContext.ToplevelTypes.NamespaceEntry != null) @@ -6204,11 +6201,6 @@ void CheckToken (int error, int yyToken, string msg, Location loc) Report.Error (error, loc, msg); } -void CheckIdentifierToken (int yyToken, Location loc) -{ - CheckToken (1041, yyToken, "Identifier expected", loc); -} - string ConsumeStoredComment () { string s = tmpComment; @@ -6219,10 +6211,17 @@ string ConsumeStoredComment () Location GetLocation (object obj) { - if (obj is Tokenizer.LocatedToken) - return ((Tokenizer.LocatedToken) obj).Location; - if (obj is MemberName) - return ((MemberName) obj).Location; + var lt = obj as Tokenizer.LocatedToken; + if (lt != null) + return lt.Location; + + var mn = obj as MemberName; + if (mn != null) + return mn.Location; + + var expr = obj as Expression; + if (expr != null) + return expr.Location; return lexer.Location; } @@ -6231,10 +6230,21 @@ 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 (compiler, current_block, current_local_parameters, current_generic_method, loc); + if (current_block == null) { + current_block = new ToplevelBlock (compiler, current_local_parameters, loc); + } else if (parsing_anonymous_method) { + current_block = new ParametersBlock (current_block, current_local_parameters, loc); parsing_anonymous_method = false; } else { current_block = new ExplicitBlock (current_block, loc, Location.Null); @@ -6250,8 +6260,7 @@ end_block (Location loc) return retval; } -void -start_anonymous (bool lambda, ParametersCompiled parameters, Location loc) +void start_anonymous (bool lambda, ParametersCompiled parameters, Location loc) { if (RootContext.Version == LanguageVersion.ISO_1){ Report.FeatureIsNotAvailable (loc, "anonymous methods"); @@ -6259,6 +6268,7 @@ start_anonymous (bool lambda, ParametersCompiled parameters, Location loc) oob_stack.Push (current_anonymous_method); oob_stack.Push (current_local_parameters); + oob_stack.Push (current_variable); current_local_parameters = parameters; @@ -6274,13 +6284,14 @@ start_anonymous (bool lambda, ParametersCompiled parameters, Location loc) * Completes the anonymous method processing, if lambda_expr is null, this * means that we have a Statement instead of an Expression embedded */ -AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block) +AnonymousMethodExpression end_anonymous (ParametersBlock anon_block) { AnonymousMethodExpression retval; current_anonymous_method.Block = anon_block; retval = current_anonymous_method; + current_variable = (BlockVariableDeclaration) oob_stack.Pop (); current_local_parameters = (ParametersCompiled) oob_stack.Pop (); current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop (); @@ -6293,7 +6304,6 @@ public NamespaceEntry CurrentNamespace { } } - void Error_SyntaxError (int token) { Error_SyntaxError (0, token, "Unexpected symbol"); @@ -6301,21 +6311,34 @@ void Error_SyntaxError (int token) void Error_SyntaxError (int error_code, int token, string msg) { + // An error message has been reported by tokenizer + if (token == Token.ERROR) + return; + string symbol = GetSymbolName (token); string expecting = GetExpecting (); + var loc = lexer.Location - symbol.Length; if (error_code == 0) { - if (expecting == "`)'") + if (expecting == "`identifier'") { + if (token > Token.FIRST_KEYWORD && token < Token.LAST_KEYWORD) { + Report.Error (1041, loc, "Identifier expected, `{0}' is a keyword", symbol); + return; + } + + error_code = 1001; + expecting = "identifier"; + } else if (expecting == "`)'") { error_code = 1026; - else + } else { error_code = 1525; + } } - if (expecting != null) - Report.Error (error_code, lexer.Location, "{2} `{0}', expecting {1}", - symbol, expecting, msg); + if (string.IsNullOrEmpty (expecting)) + Report.Error (error_code, loc, "{1} `{0}'", symbol, msg); else - Report.Error (error_code, lexer.Location, "{1} `{0}'", symbol, msg); + Report.Error (error_code, loc, "{2} `{0}', expecting {1}", symbol, expecting, msg); } string GetExpecting () @@ -6650,6 +6673,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 "]"; @@ -6743,11 +6767,13 @@ static string GetTokenName (int token) case Token.IDENTIFIER: return "identifier"; + case Token.EOF: + return "end-of-file"; + // All of these are internal. case Token.NONE: case Token.ERROR: case Token.FIRST_KEYWORD: - case Token.EOF: case Token.EVAL_COMPILATION_UNIT_PARSER: case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER: case Token.EVAL_STATEMENT_PARSER: