X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcs-parser.jay;h=b718931b1fb3e4313fd3c338ba756bd6d03c2a9f;hb=c6b0cc1d23b1cc8b66b748b5edbc700fc886f074;hp=647360860130734dacd28bf473d94265e8ac5d1d;hpb=f02dd3a82e3a9233aa646e3d1d7c005761ae37d1;p=mono.git diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index 64736086013..b718931b1fb 100644 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -41,10 +41,16 @@ 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 @@ -54,7 +60,6 @@ namespace Mono.CSharp Delegate current_delegate; - GenericMethod current_generic_method; AnonymousMethodExpression current_anonymous_method; /// @@ -66,20 +71,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; /// @@ -120,7 +111,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 +125,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; @@ -149,6 +139,12 @@ namespace Mono.CSharp // 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 @@ -330,6 +326,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 @@ -854,10 +851,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 +889,6 @@ opt_named_modifier } ; -class_body - : OPEN_BRACE opt_class_member_declarations CLOSE_BRACE - ; - opt_class_member_declarations : /* empty */ | class_member_declarations @@ -944,6 +942,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,6 +953,7 @@ struct_declaration } opt_semicolon { + lbag.AppendToMember (current_class, GetLocation ($13)); $$ = pop_current_class (); } | opt_attributes opt_modifiers opt_partial STRUCT error { @@ -967,6 +968,9 @@ struct_body Lexer.doc_state = XmlCommentState.Allowed; } opt_struct_member_declarations CLOSE_BRACE + { + lbag.AppendToMember (current_class, GetLocation ($1), GetLocation ($4)); + } ; opt_struct_member_declarations @@ -996,73 +1000,79 @@ struct_member_declaration */ | destructor_declaration ; - + constant_declaration : opt_attributes opt_modifiers - CONST - type - constant_declarators - SEMICOLON + CONST type IDENTIFIER { - var modflags = (Modifiers) $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,90 +1080,156 @@ 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"); - - var mod = (Modifiers) $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; - - var mod = (Modifiers) $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); - - if (RootContext.Version < LanguageVersion.ISO_2) - Report.FeatureIsNotAvailable (GetLocation ($3), "fixed size buffers"); + var lt = (Tokenizer.LocatedToken) $5; + current_field = new FixedField (current_class, (FullNamedExpression) $4, (Modifiers) $2, + new MemberName (lt.Value, lt.Location), (Attributes) $1); + + current_container.AddField (current_field); + } + fixed_field_size opt_fixed_field_declarators SEMICOLON + { + if (RootContext.Documentation != null) { + current_field.DocComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } - if (RootContext.Documentation != null) { - field.DocComment = Lexer.consume_doc_comment (); - Lexer.doc_state = XmlCommentState.Allowed; - } - current_container.AddField (field); - $$ = field; // FIXME: might be better if it points to the top item - } + current_field.Initializer = (ConstInitializer) $7; + lbag.AddMember (current_field, mod_locations, GetLocation ($9)); + $$ = current_field; + current_field = null; } | opt_attributes opt_modifiers - FIXED - member_type - error + FIXED simple_type error + SEMICOLON { - Report.Error (1641, GetLocation ($4), "A fixed size buffer field must have the array size specifier after the field name"); + Report.Error (1641, GetLocation ($5), "A fixed size buffer field must have the array size specifier after the field name"); } ; + +opt_field_initializer + : /* empty */ + | ASSIGN + { + ++lexer.parsing_block; + } + variable_initializer + { + --lexer.parsing_block; + current_field.Initializer = (Expression) $3; + } + ; + +opt_field_declarators + : /* empty */ + | field_declarators + ; + +field_declarators + : field_declarator + { + current_field.AddDeclarator ((FieldDeclarator) $1); + } + | field_declarators field_declarator + { + current_field.AddDeclarator ((FieldDeclarator) $2); + } + ; + +field_declarator + : COMMA IDENTIFIER + { + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null); + lbag.AddLocation ($$, GetLocation ($1)); + } + | COMMA IDENTIFIER ASSIGN + { + ++lexer.parsing_block; + } + variable_initializer + { + --lexer.parsing_block; + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); + } + ; -fixed_variable_declarators - : fixed_variable_declarator +opt_fixed_field_declarators + : /* empty */ + | fixed_field_declarators + ; + +fixed_field_declarators + : fixed_field_declarator { - var decl = new List (2); - decl.Add ((VariableDeclaration)$1); - $$ = decl; - } - | fixed_variable_declarators COMMA fixed_variable_declarator + current_field.AddDeclarator ((FieldDeclarator) $1); + } + | fixed_field_declarators fixed_field_declarator { - var decls = (List) $1; - decls.Add ((VariableDeclaration)$3); - $$ = $1; + current_field.AddDeclarator ((FieldDeclarator) $2); + } + ; + +fixed_field_declarator + : COMMA IDENTIFIER fixed_field_size + { + var lt = (Tokenizer.LocatedToken) $2; + $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3); + lbag.AddLocation ($$, GetLocation ($1)); } ; -fixed_variable_declarator - : IDENTIFIER OPEN_BRACKET expression CLOSE_BRACKET +fixed_field_size + : OPEN_BRACKET { - $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, (Expression) $3); + ++lexer.parsing_block; } - | IDENTIFIER OPEN_BRACKET CLOSE_BRACKET + expression CLOSE_BRACKET { - Report.Error (443, lexer.Location, "Value or constant expected"); - $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, null); + --lexer.parsing_block; + $$ = new ConstInitializer (current_field, (Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($4)); } + | OPEN_BRACKET error + { + Report.Error (443, lexer.Location, "Value or constant expected"); + $$ = null; + } ; @@ -1169,6 +1245,7 @@ local_variable_declarators { var decls = (List) $1; decls.Add ($3); + lbag.AppendTo ($3, GetLocation ($2)); $$ = $1; } ; @@ -1177,6 +1254,7 @@ local_variable_declarator : IDENTIFIER ASSIGN local_variable_initializer { $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, (Expression) $3); + lbag.AddLocation ($$, GetLocation ($2)); } | IDENTIFIER { @@ -1191,9 +1269,10 @@ local_variable_declarator local_variable_initializer : expression | array_initializer - | STACKALLOC simple_type OPEN_BRACKET expression CLOSE_BRACKET + | STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET { $$ = new StackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5)); } | ARGLIST { @@ -1206,47 +1285,8 @@ local_variable_initializer } ; -variable_declarators - : variable_declarator - { - variables_bucket.Clear (); - if ($1 != null) - variables_bucket.Add ($1); - $$ = variables_bucket; - } - | variable_declarators COMMA variable_declarator - { - var decls = (List) $1; - decls.Add ($3); - $$ = $1; - } - ; - -variable_declarator - : member_declaration_name ASSIGN - { - ++lexer.parsing_block; - lexer.parsing_generic_declaration = false; - } - variable_initializer - { - --lexer.parsing_block; - $$ = new VariableMemberDeclaration ((MemberName) $1, (Expression) $4); - } - | member_declaration_name - { - lexer.parsing_generic_declaration = false; - $$ = new VariableMemberDeclaration ((MemberName) $1, null); - } - | member_declaration_name variable_bad_array - { - lexer.parsing_generic_declaration = false; - $$ = null; - } - ; - variable_bad_array - : OPEN_BRACKET opt_expression CLOSE_BRACKET + : OPEN_BRACKET_EXPR opt_expression CLOSE_BRACKET { Report.Error (650, GetLocation ($1), "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. " + "To declare a fixed size buffer field, use the fixed keyword before the field type"); @@ -1273,7 +1313,6 @@ method_declaration 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) @@ -1320,11 +1359,10 @@ method_header method.GetSignatureForError ()); } - current_generic_method = generic; - if (RootContext.Documentation != null) method.DocComment = Lexer.consume_doc_comment (); + lbag.AddMember (method, mod_locations, GetLocation ($5), GetLocation ($8)); $$ = method; } | opt_attributes @@ -1355,7 +1393,8 @@ 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); } @@ -1379,14 +1418,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 @@ -1398,7 +1438,7 @@ method_header Report.Error (1585, name.Location, "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; @@ -1503,7 +1543,10 @@ fixed_parameters default_parameter_used |= p.HasDefaultValue; pars.Add (p); + + lbag.AddLocation (p, GetLocation ($2)); } + $$ = $1; } ; @@ -1540,8 +1583,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"); } @@ -1567,12 +1614,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; } ; @@ -1649,7 +1698,8 @@ parameter_array var lt = (Tokenizer.LocatedToken) $4; $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location); } - | opt_attributes params_modifier type error { + | opt_attributes params_modifier type error + { CheckIdentifierToken (yyToken, GetLocation ($4)); $$ = null; } @@ -1693,86 +1743,95 @@ property_declaration if (RootContext.Documentation != null) tmpComment = Lexer.consume_doc_comment (); } - OPEN_BRACE + OPEN_BRACE { - implicit_value_parameter_type = (FullNamedExpression) $3; + current_property = new Property (current_class, (FullNamedExpression) $3, (Modifiers) $2, + (MemberName) $4, (Attributes) $1); + + if (current_property.TypeExpression.Type == TypeManager.void_type) + Report.Error (547, GetLocation ($3), "`{0}': property or indexer cannot have void type", current_property.GetSignatureForError ()); + + current_container.AddProperty ((Property)current_property); + lbag.AddMember (current_property, mod_locations, GetLocation ($6)); + lexer.PropertyParsing = true; } accessor_declarations { lexer.PropertyParsing = false; - has_get = has_set = false; + + if (RootContext.Documentation != null) + current_property.DocComment = ConsumeStoredComment (); } CLOSE_BRACE - { - Property prop; - Accessors accessors = (Accessors) $8; - Accessor get_block = accessors != null ? accessors.get_or_add : null; - Accessor set_block = accessors != null ? accessors.set_or_remove : null; - bool order = accessors != null ? accessors.declared_in_reverse : false; - - MemberName name = (MemberName) $4; - FullNamedExpression ptype = (FullNamedExpression) $3; + { + lbag.AppendToMember (current_property, GetLocation ($10)); + current_property = null; + } + ; - prop = new Property (current_class, ptype, (Modifiers) $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 == MemberKind.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); } } ; @@ -1780,65 +1839,91 @@ accessor_declarations get_accessor_declaration : opt_attributes opt_modifiers GET { - // If this is not the case, then current_local_parameters has already - // been set in indexer_declaration - if (parsing_indexer == false) - current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; - else - current_local_parameters = indexer_parameters; + if ($2 != ModifierNone && RootContext.Version == LanguageVersion.ISO_1) { + Report.FeatureIsNotAvailable (GetLocation ($2), "access modifiers on properties"); + } + + if (current_property.Get != null) { + Report.Error (1007, GetLocation ($3), "Property accessor already defined"); + } + + if (current_property is Indexer) { + current_property.Get = new Indexer.GetIndexerMethod (current_property, (Modifiers) $2, ((Indexer)current_property).ParameterInfo.Clone (), + (Attributes) $1, GetLocation ($3)); + } else { + current_property.Get = new Property.GetMethod (current_property, + (Modifiers) $2, (Attributes) $1, GetLocation ($3)); + } + + current_local_parameters = current_property.Get.ParameterInfo; + lbag.AddMember (current_property.Get, mod_locations); lexer.PropertyParsing = false; } accessor_body { - if (has_get) { - Report.Error (1007, GetLocation ($3), "Property accessor already defined"); - break; + if ($5 != null) { + current_property.Get.Block = (ToplevelBlock) $5; + + if (current_container.Kind == MemberKind.Interface) { + Report.Error (531, current_property.Get.Block.StartLocation, + "`{0}': interface members cannot have a definition", current_property.Get.GetSignatureForError ()); + } } - Accessor accessor = new Accessor ((ToplevelBlock) $5, (Modifiers) $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, (Modifiers) $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; } ; @@ -1846,6 +1931,7 @@ accessor_body : block | SEMICOLON { + // TODO: lbag $$ = null; } | error @@ -1867,6 +1953,7 @@ interface_declaration { MemberName name = MakeName ((MemberName) $6); 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 @@ -1880,7 +1967,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) @@ -1888,6 +1975,7 @@ interface_declaration } opt_semicolon { + lbag.AppendToMember (current_class, GetLocation ($11), GetLocation ($13)); $$ = pop_current_class (); } | opt_attributes opt_modifiers opt_partial INTERFACE error { @@ -1895,12 +1983,6 @@ interface_declaration } ; -interface_body - : OPEN_BRACE - opt_interface_member_declarations - CLOSE_BRACE - ; - opt_interface_member_declarations : /* empty */ | interface_member_declarations @@ -1961,6 +2043,7 @@ operator_declaration // Note again, checking is done in semantic analysis current_container.AddOperator (op); + lbag.AddMember (op, mod_locations, lbag.GetLocations (decl)); current_local_parameters = null; } ; @@ -1975,7 +2058,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)); } ; @@ -2022,6 +2105,7 @@ operator_declarator } $$ = new OperatorDeclaration (op, (FullNamedExpression) $1, loc); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3), GetLocation ($4), GetLocation ($7)); } | conversion_operator_declarator ; @@ -2072,6 +2156,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 { @@ -2090,6 +2175,7 @@ conversion_operator_declarator } $$ = new OperatorDeclaration (Operator.OpType.Explicit, (FullNamedExpression) $3, loc); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7)); } | IMPLICIT error { @@ -2171,6 +2257,7 @@ constructor_declarator } } + lbag.AddMember (c, mod_locations, GetLocation ($5), GetLocation ($7)); $$ = c; } ; @@ -2194,6 +2281,7 @@ constructor_initializer { --lexer.parsing_block; $$ = new ConstructorBaseInitializer ((Arguments) $5, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6)); } | COLON THIS OPEN_PARENS { @@ -2203,6 +2291,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"); @@ -2227,15 +2316,16 @@ destructor_declaration Report.Error (574, lt.Location, "Name of destructor must match name of 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, (Modifiers) $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; } @@ -2244,343 +2334,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, (Modifiers) $2, var.MemberName, (Attributes) $1); - - e.Initializer = var.GetInitializer ((FullNamedExpression) $4); - if (current_container.Kind == MemberKind.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 == MemberKind.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, (Modifiers) $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, (Modifiers) $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 ($2 != ModifierNone) { + Report.Error (1609, GetLocation ($2), "Modifiers cannot be placed on event accessor declarations"); + } + + current_event.Remove = new EventProperty.RemoveDelegateMethod (current_event, (Attributes) $1, GetLocation ($3)); + current_local_parameters = current_event.Remove.ParameterInfo; + lbag.AddMember (current_event.Remove, mod_locations); + lexer.EventParsing = false; + } + event_accessor_block + { + lexer.EventParsing = true; + + current_event.Remove.Block = (ToplevelBlock) $5; + if (current_container.Kind == MemberKind.Interface) { - if (indexer.Get.Block != null) - Report.Error (531, indexer.Location, "`{0}.get': interface members cannot have a definition", indexer.GetSignatureForError ()); - - if (indexer.Set.Block != null) - Report.Error (531, indexer.Location, "`{0}.set': interface members cannot have a definition", indexer.GetSignatureForError ()); + 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, (Modifiers) $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 (GetLocation ($1)); - $$ = TypeManager.system_int32_expr; + $$ = 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 { @@ -2592,14 +2648,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; } ; @@ -2638,6 +2697,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; @@ -2656,7 +2717,7 @@ opt_nullable else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "nullable types"); - $$ = this; + $$ = ComposedTypeSpecifier.CreateNullable (GetLocation ($1)); } ; @@ -2677,6 +2738,7 @@ member_name { var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } ; @@ -2778,6 +2840,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 { @@ -2785,11 +2848,13 @@ 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)); } ; @@ -2803,6 +2868,7 @@ opt_type_parameter_list Report.FeatureIsNotAvailable (GetLocation ($1), "generics"); $$ = $2; + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } ; @@ -2818,6 +2884,7 @@ type_parameters TypeArguments type_args = (TypeArguments) $1; type_args.Add ((FullNamedExpression)$3); $$ = type_args; + lbag.AddLocation ($3, GetLocation ($3)); } ; @@ -2845,7 +2912,7 @@ type_and_void : type_expression_or_array | VOID { - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2855,7 +2922,7 @@ member_type lexer.parsing_generic_declaration = true; } ; - + // // A type which does not allow `void' to be used // @@ -2864,7 +2931,7 @@ type | VOID { Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report); - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2873,7 +2940,7 @@ simple_type | VOID { Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report); - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2882,7 +2949,7 @@ parameter_type | VOID { Report.Error (1536, GetLocation ($1), "Invalid parameter type `void'"); - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -2890,8 +2957,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); } ; @@ -2901,7 +2967,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); @@ -2912,7 +2978,7 @@ type_expression | builtin_types opt_nullable { if ($2 != null) - $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } | type_expression STAR { @@ -2921,11 +2987,11 @@ type_expression // can't perform checks during this phase - we do it during // semantic analysis. // - $$ = new ComposedCast ((FullNamedExpression) $1, "*", Lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } | VOID STAR { - $$ = new ComposedCast (TypeManager.system_void_expr, "*", GetLocation ($1)); + $$ = new ComposedCast (new TypeExpression (TypeManager.void_type, GetLocation ($1)), ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } ; @@ -2964,25 +3030,25 @@ base_type_name * simple types, but we need this to reuse it easily in variable_type */ builtin_types - : OBJECT { $$ = TypeManager.system_object_expr; } - | STRING { $$ = TypeManager.system_string_expr; } - | BOOL { $$ = TypeManager.system_boolean_expr; } - | DECIMAL { $$ = TypeManager.system_decimal_expr; } - | FLOAT { $$ = TypeManager.system_single_expr; } - | DOUBLE { $$ = TypeManager.system_double_expr; } + : OBJECT { $$ = new TypeExpression (TypeManager.object_type, GetLocation ($1)); } + | STRING { $$ = new TypeExpression (TypeManager.string_type, GetLocation ($1)); } + | BOOL { $$ = new TypeExpression (TypeManager.bool_type, GetLocation ($1)); } + | DECIMAL { $$ = new TypeExpression (TypeManager.decimal_type, GetLocation ($1)); } + | FLOAT { $$ = new TypeExpression (TypeManager.float_type, GetLocation ($1)); } + | DOUBLE { $$ = new TypeExpression (TypeManager.double_type, GetLocation ($1)); } | integral_type ; integral_type - : SBYTE { $$ = TypeManager.system_sbyte_expr; } - | BYTE { $$ = TypeManager.system_byte_expr; } - | SHORT { $$ = TypeManager.system_int16_expr; } - | USHORT { $$ = TypeManager.system_uint16_expr; } - | INT { $$ = TypeManager.system_int32_expr; } - | UINT { $$ = TypeManager.system_uint32_expr; } - | LONG { $$ = TypeManager.system_int64_expr; } - | ULONG { $$ = TypeManager.system_uint64_expr; } - | CHAR { $$ = TypeManager.system_char_expr; } + : 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)); } ; // @@ -3061,6 +3127,7 @@ parenthesized_expression : OPEN_PARENS expression CLOSE_PARENS { $$ = new ParenthesizedExpression ((Expression) $2); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } | OPEN_PARENS expression COMPLETE_COMPLETION { @@ -3073,12 +3140,19 @@ member_access { var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } | 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 { @@ -3096,7 +3170,6 @@ member_access } | 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); } | builtin_types DOT IDENTIFIER GENERATE_COMPLETION { @@ -3109,6 +3182,7 @@ invocation_expression : primary_expression open_parens_any opt_argument_list close_parens { $$ = new Invocation ((Expression) $1, (Arguments) $3); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3120,14 +3194,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)); } ; @@ -3163,6 +3241,7 @@ member_initializer { var lt = (Tokenizer.LocatedToken) $1; $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } | GENERATE_COMPLETION { @@ -3234,10 +3313,10 @@ argument_list Report.Error (839, GetLocation ($2), "An argument is missing"); $$ = $1; } - | COMMA argument_or_named_argument + | COMMA error { Report.Error (839, GetLocation ($1), "An argument is missing"); - $$ = $1; + $$ = null; } ; @@ -3258,18 +3337,22 @@ 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 argument_list CLOSE_PARENS { $$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1))); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } | ARGLIST OPEN_PARENS CLOSE_PARENS { $$ = new Argument (new Arglist (GetLocation ($1))); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3)); } | ARGLIST { @@ -3282,37 +3365,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 + : primary_expression OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET { - // LAMESPEC: Not allowed according to specification - $$ = new ElementAccess ((Expression) $1, (Arguments) $3); - } - | primary_expression_no_array_creation rank_specifiers - { - // 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)); } ; @@ -3361,24 +3417,20 @@ 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)); } ; @@ -3395,65 +3447,75 @@ post_decrement_expression $$ = 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; } ; @@ -3466,6 +3528,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)); } ; @@ -3499,6 +3564,7 @@ anonymous_type_parameter { var lt = (Tokenizer.LocatedToken)$1; $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); } | IDENTIFIER { @@ -3506,12 +3572,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; @@ -3528,28 +3588,21 @@ anonymous_type_parameter opt_rank_specifier : /* empty */ { - $$ = ""; + $$ = null; } | 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 + if ($1 != null) { + ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2; + $$ = $1; + } else { $$ = $2; + } } ; @@ -3557,34 +3610,30 @@ rank_specifiers : rank_specifier | rank_specifier rank_specifiers { - $$ = (string) $1 + (string) $2; + ((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; } ; @@ -3603,10 +3652,12 @@ array_initializer : OPEN_BRACE CLOSE_BRACE { $$ = new ArrayInitializer (0, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2)); } | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE { $$ = new ArrayInitializer ((List) $2, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } ; @@ -3638,11 +3689,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)); } ; @@ -3715,8 +3763,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)); } ; @@ -3724,6 +3774,7 @@ checked_expression : CHECKED open_parens_any expression CLOSE_PARENS { $$ = new CheckedExpr ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3731,17 +3782,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); } ; @@ -3783,6 +3832,7 @@ default_value_expression Report.FeatureIsNotAvailable (GetLocation ($1), "default value expression"); $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -3803,10 +3853,12 @@ cast_expression : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression { $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } | OPEN_PARENS builtin_types CLOSE_PARENS prefixed_unary_expression { $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } ; @@ -3999,64 +4051,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)); } ; @@ -4134,6 +4187,7 @@ lambda_expression lambda_expression_body { $$ = end_anonymous ((ToplevelBlock) $4); + lbag.AddLocation ($$, GetLocation ($2)); } | OPEN_PARENS_LAMBDA { @@ -4150,6 +4204,7 @@ lambda_expression lambda_expression_body { $$ = end_anonymous ((ToplevelBlock) $7); + lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4)); } ; @@ -4197,20 +4252,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 (); } ; @@ -4223,7 +4280,11 @@ opt_partial ; opt_modifiers - : /* empty */ { $$ = (int) 0; } + : /* empty */ + { + mod_locations = null; + $$ = ModifierNone; + } | modifiers ; @@ -4235,9 +4296,14 @@ modifiers var m2 = (Modifiers) $2; if ((m1 & m2) != 0) { - Location l = lexer.Location; - Report.Error (1004, l, "Duplicate `{0}' modifier", ModifiersExtensions.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"); } + $$ = m1 | m2; } ; @@ -4246,31 +4312,83 @@ 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); } @@ -4360,6 +4478,7 @@ type_parameter_constraint | NEW OPEN_PARENS CLOSE_PARENS { $$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3)); } | CLASS { @@ -4504,7 +4623,7 @@ interactive_statement valid_declaration_statement : block | empty_statement - | expression_statement + | expression_statement | selection_statement | iteration_statement | jump_statement @@ -4594,8 +4713,6 @@ declaration_statement variable_type : primary_expression_no_array_creation opt_rank_specifier_or_nullable { - // FIXME: Do something smart here regarding the composition of the type. - // Ok, the above "primary_expression" is there to get rid of // both reduce/reduce and shift/reduces in the grammar, it should // really just be "type_name". If you use type_name, a reduce/reduce @@ -4611,40 +4728,30 @@ variable_type // Blah i; Expression expr = (Expression) $1; - string rank_or_nullable = (string) $2; - - if (expr is ComposedCast){ - $$ = new ComposedCast ((ComposedCast)expr, rank_or_nullable); - } else if (expr is ATypeNameExpression){ - // - // So we extract the string corresponding to the SimpleName - // or MemberAccess - // - if (rank_or_nullable.Length == 0) { - SimpleName sn = expr as SimpleName; - if (sn != null && sn.Name == "var") - $$ = new VarExpr (sn.Location); - else - $$ = $1; - } else { - $$ = new ComposedCast ((ATypeNameExpression)expr, rank_or_nullable); - } + if ($2 == null) { + SimpleName sn = expr as SimpleName; + if (sn != null && sn.Name == "var") + $$ = new VarExpr (sn.Location); + else + $$ = $1; + } else if (expr is ATypeNameExpression) { + $$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2); } else { Error_ExpectingTypeName (expr); - $$ = TypeManager.system_object_expr; + $$ = null; } } | builtin_types opt_rank_specifier_or_nullable { - if ((string) $2 == "") + if ($2 == null) $$ = $1; else - $$ = new ComposedCast ((FullNamedExpression) $1, (string) $2, lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } | VOID opt_rank_specifier { Expression.Error_VoidInvalidInTheContext (GetLocation ($1), Report); - $$ = TypeManager.system_void_expr; + $$ = new TypeExpression (TypeManager.void_type, GetLocation ($1)); } ; @@ -4654,7 +4761,7 @@ local_variable_pointer_type ATypeNameExpression expr = $1 as ATypeNameExpression; if (expr != null) { - $$ = new ComposedCast (expr, "*"); + $$ = new ComposedCast (expr, ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } else { Error_ExpectingTypeName ((Expression)$1); $$ = expr; @@ -4662,15 +4769,15 @@ local_variable_pointer_type } | builtin_types STAR { - $$ = new ComposedCast ((FullNamedExpression) $1, "*", GetLocation ($1)); + $$ = new ComposedCast ((FullNamedExpression) $1, ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } | VOID STAR { - $$ = new ComposedCast (TypeManager.system_void_expr, "*", GetLocation ($1)); + $$ = new ComposedCast (new TypeExpression (TypeManager.void_type, GetLocation ($1)), ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } | local_variable_pointer_type STAR { - $$ = new ComposedCast ((FullNamedExpression) $1, "*"); + $$ = new ComposedCast ((FullNamedExpression) $1, ComposedTypeSpecifier.CreatePointer (GetLocation ($2))); } ; @@ -4679,12 +4786,10 @@ local_variable_type | local_variable_pointer_type opt_rank_specifier { if ($1 != null){ - string rank = (string)$2; - - if (rank == "") + if ($2 == null) $$ = $1; else - $$ = new ComposedCast ((FullNamedExpression) $1, rank); + $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2); } else { $$ = null; } @@ -4710,7 +4815,7 @@ local_variable_declaration ; local_constant_declaration - : CONST variable_type constant_declarators + : CONST variable_type local_constant_declarators { if ($2 != null) $$ = new Tuple> ((FullNamedExpression) $2, (List) $3); @@ -4718,9 +4823,42 @@ local_constant_declaration $$ = null; } ; + +local_constant_declarators + : local_constant_declarator + { + variables_bucket.Clear (); + if ($1 != null) + variables_bucket.Add ($1); + $$ = variables_bucket; + } + | local_constant_declarators COMMA local_constant_declarator + { + if ($3 != null) { + var constants = (List) $1; + constants.Add ($3); + } + } + ; + +local_constant_declarator + : IDENTIFIER ASSIGN constant_initializer_expr + { + $$ = new VariableDeclaration ((Tokenizer.LocatedToken) $1, (Expression) $3); + } + | IDENTIFIER error + { + Report.Error (145, GetLocation ($1), "A const field requires a value to be provided"); + $$ = null; + } + ; expression_statement - : statement_expression SEMICOLON { $$ = $1; } + : statement_expression SEMICOLON + { + $$ = $1; + lbag.AddStatement ($$, GetLocation ($2)); + } | statement_expression COMPLETE_COMPLETION { $$ = $1; } ; @@ -4780,12 +4918,14 @@ if_statement Report.Warning (642, 3, GetLocation ($5), "Possible mistaken empty statement"); $$ = new If ((BooleanExpression) $3, (Statement) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } | IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement ELSE embedded_statement { $$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, GetLocation ($1)); - + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6)); + if ($5 is EmptyStatement) Report.Warning (642, 3, GetLocation ($5), "Possible mistaken empty statement"); if ($7 is EmptyStatement) @@ -4801,26 +4941,19 @@ switch_statement switch_stack.Push (current_block); } expression CLOSE_PARENS - switch_block + OPEN_BRACE opt_switch_sections CLOSE_BRACE { - $$ = new Switch ((Expression) $4, (List) $6, GetLocation ($1)); + $$ = new Switch ((Expression) $4, (List) $7, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($5), GetLocation ($6), GetLocation ($8)); + current_block = (Block) switch_stack.Pop (); } ; -switch_block - : OPEN_BRACE - opt_switch_sections - CLOSE_BRACE - { - $$ = $2; - } - ; - opt_switch_sections : /* empty */ - { - Report.Warning (1522, 1, lexer.Location, "Empty switch block"); + { + Report.Warning (1522, 1, lexer.Location, "Empty switch block"); $$ = new List (); } | switch_sections @@ -4875,6 +5008,7 @@ switch_label : CASE constant_expression COLON { $$ = new SwitchLabel ((Expression) $2, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); } | DEFAULT_COLON { @@ -4892,8 +5026,8 @@ 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); + $$ = new While ((BooleanExpression) $3, (Statement) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -4901,9 +5035,8 @@ 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)); } ; @@ -4950,11 +5083,10 @@ for_statement opt_for_iterator CLOSE_PARENS embedded_statement { - Location l = GetLocation ($1); - - For f = new For ((Statement) $5, (BooleanExpression) $6, (Statement) $8, (Statement) $10, l); - + For f = new For ((Statement) $5, (BooleanExpression) $6, (Statement) $8, (Statement) $10, GetLocation ($1)); current_block.AddStatement (f); + + lbag.AddStatement (f, GetLocation ($2), GetLocation ($4), GetLocation ($7), GetLocation ($9)); $$ = end_block (lexer.Location); } @@ -4985,21 +5117,17 @@ for_iterator ; statement_expression_list - : statement_expression - { - // CHANGE: was `null' - Statement s = (Statement) $1; - Block b = new Block (current_block, s.loc, lexer.Location); - - b.AddStatement (s); - $$ = b; - } + : statement_expression | statement_expression_list COMMA statement_expression { - Block b = (Block) $1; - - b.AddStatement ((Statement) $3); - $$ = $1; + var sl = $1 as StatementList; + if (sl == null) + sl = new StatementList ((Statement) $1, (Statement) $3); + else + sl.Add ((Statement) $3); + + lbag.AddStatement (sl, GetLocation ($2)); + $$ = sl; } ; @@ -5032,11 +5160,10 @@ foreach_statement } 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); + if ($8 != null) { + Foreach f = new Foreach ((Expression) $3, (LocalVariableReference) $8, (Expression) $6, (Statement) $9, GetLocation ($1)); + lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7)); + current_block.AddStatement (f); } @@ -5057,6 +5184,7 @@ break_statement : BREAK SEMICOLON { $$ = new Break (GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2)); } ; @@ -5064,6 +5192,7 @@ continue_statement : CONTINUE SEMICOLON { $$ = new Continue (GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2)); } ; @@ -5072,14 +5201,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)); } ; @@ -5087,6 +5219,7 @@ return_statement : RETURN opt_expression SEMICOLON { $$ = new Return ((Expression) $2, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($3)); } ; @@ -5094,29 +5227,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; + $$ = new Yield ((Expression) $3, lt.Location); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } | IDENTIFIER BREAK SEMICOLON { @@ -5124,15 +5254,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; $$ = new YieldBreak (lt.Location); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3)); } ; @@ -5149,10 +5277,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 { @@ -5225,6 +5355,8 @@ catch_clause } $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc); + lbag.AddLocation ($$, GetLocation ($1)); + lbag.AppendTo ($$, lbag.GetLocations ($2)); } ; @@ -5237,6 +5369,7 @@ catch_args : open_parens_any type opt_identifier CLOSE_PARENS { $$ = new Tuple ((FullNamedExpression)$2, (Tokenizer.LocatedToken) $3); + lbag.AddLocation ($$, GetLocation ($1), GetLocation ($4)); } | open_parens_any CLOSE_PARENS { @@ -5248,23 +5381,24 @@ catch_args 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); + $$ = new Unsafe ((Block) $3, GetLocation ($1)); } ; @@ -5289,6 +5423,8 @@ fixed_statement return v; }), (Statement) $7, GetLocation ($1)); + lbag.AddStatement (f, GetLocation ($2), GetLocation ($5)); + current_block.AddStatement (f); $$ = end_block (lexer.Location); @@ -5325,13 +5461,10 @@ fixed_pointer_declarator ; lock_statement - : LOCK open_parens_any expression CLOSE_PARENS - { - // - } - embedded_statement + : LOCK open_parens_any expression CLOSE_PARENS embedded_statement { - $$ = new Lock ((Expression) $3, (Statement) $6, GetLocation ($1)); + $$ = new Lock ((Expression) $3, (Statement) $5, GetLocation ($1)); + lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } ; @@ -5346,6 +5479,8 @@ using_statement var vars = new Stack> (); + lbag.AddStatement (assign_block, GetLocation ($1), GetLocation ($2), GetLocation ($4)); + foreach (VariableDeclaration decl in de.Item2) { LocalInfo vi = current_block.AddVariable (de.Item1, decl.identifier, decl.Location); if (vi == null) @@ -5394,7 +5529,9 @@ using_statement } embedded_statement { - current_block.AddStatement (new UsingTemporary ((Expression) $3, (Statement) $6, GetLocation ($1))); + UsingTemporary usingTemporary = new UsingTemporary ((Expression) $3, (Statement) $6, GetLocation ($1)); + lbag.AddStatement (usingTemporary, GetLocation ($2), GetLocation ($4)); + current_block.AddStatement (usingTemporary); $$ = end_block (lexer.Location); } ; @@ -5444,66 +5581,78 @@ query_expression first_from_clause : FROM_FIRST IDENTIFIER IN expression { - $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4)); - var lt = (Tokenizer.LocatedToken) $2; - current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + + var lt = (Tokenizer.LocatedToken) $2; + $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1))); } | FROM_FIRST type IDENTIFIER IN expression { + 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)); + $$ = new Linq.QueryExpression ( + new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + } + ); } ; nested_from_clause : FROM IDENTIFIER IN expression { - $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4)); - var lt = (Tokenizer.LocatedToken) $2; - current_block = new Linq.QueryBlock (compiler, current_block, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)); + current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); + + var lt = (Tokenizer.LocatedToken) $2; + $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1))); } | FROM type IDENTIFIER IN expression { - $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5)); + current_block = new Linq.QueryBlock (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)); + $$ = new Linq.QueryExpression ( + new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + } + ); } ; from_clause : FROM IDENTIFIER IN { - current_block = new Linq.QueryBlock (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); + $$ = 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); - 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); } ; @@ -5533,7 +5682,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; @@ -5541,10 +5690,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 { @@ -5555,7 +5704,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; @@ -5587,18 +5736,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); + $$ = 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); } ; @@ -5609,7 +5758,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; @@ -5620,10 +5769,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 { @@ -5631,7 +5780,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 { @@ -5639,8 +5788,7 @@ 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 { @@ -5648,15 +5796,15 @@ join_clause var sn = new SimpleMemberName (lt.Value, lt.Location); SimpleMemberName sn2 = null; - ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop (); - ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop (); + var outer_selector = linq_clause_blocks.Pop (); + var block = linq_clause_blocks.Pop (); if ($12 == null) { - $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, current_block.Toplevel, GetLocation ($1)); + $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)); } else { var lt2 = (Tokenizer.LocatedToken) $12; sn2 = new SimpleMemberName (lt2.Value, lt2.Location); - $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, current_block.Toplevel, + $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, sn2, GetLocation ($1)); } @@ -5664,18 +5812,15 @@ join_clause 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); + ((Linq.QueryBlock)current_block).AddRangeVariable (sn2 ?? sn); } | JOIN type IDENTIFIER IN { if (linq_clause_blocks == null) - linq_clause_blocks = new Stack (); + linq_clause_blocks = new Stack (); current_block = new Linq.QueryBlock (compiler, current_block, lexer.Location); - linq_clause_blocks.Push (current_block); + linq_clause_blocks.Push ((Linq.QueryBlock) current_block); } expression ON { @@ -5683,7 +5828,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 { @@ -5691,35 +5836,33 @@ 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 { 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 outer_selector = linq_clause_blocks.Pop (); + var block = linq_clause_blocks.Pop (); - Linq.Cast cast = new Linq.Cast ((FullNamedExpression)$2, (Expression)$6); if ($13 == null) { - $$ = new Linq.Join (block, sn, cast, outer_selector, current_block.Toplevel, GetLocation ($1)); + $$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + }; } else { 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)); + $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, sn2, GetLocation ($1)) { + IdentifierType = (FullNamedExpression)$2 + }; } current_block.AddStatement (new ContextualReturn ((Expression) $12)); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; - if (sn2 == null) - ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn); - else - ((Linq.QueryBlock)current_block).AddTransparentParameter (compiler, sn2); + ((Linq.QueryBlock)current_block).AddRangeVariable (sn2 ?? sn); } ; @@ -5768,11 +5911,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; } ; @@ -5780,30 +5923,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); } ; @@ -5818,14 +5961,21 @@ 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; + $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1)) { + next = (Linq.AQueryClause)$4 + }; } ; @@ -5857,14 +6007,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); 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, @@ -5917,26 +6067,18 @@ 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) + public VariableDeclaration (Tokenizer.LocatedToken lt, Expression initializer) { 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 new ArrayCreation (type, (ArrayInitializer)initializer); return initializer; } @@ -5946,26 +6088,6 @@ class VariableDeclaration { } } -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 @@ -6009,6 +6131,11 @@ void Error_TypeExpected (Location loc) Report.Error (1031, loc, "Type expected"); } +void Error_UnsafeCodeNotAllowed (Location loc) +{ + Report.Error (227, loc, "Unsafe code requires the `unsafe' command line option to be specified"); +} + void Error_NamedArgumentExpected (NamedArgument a) { Report.Error (1738, a.Location, "Named arguments must appear after the positional arguments"); @@ -6059,6 +6186,18 @@ MakeName (MemberName class_name) } } +[System.Diagnostics.Conditional ("FULL_AST")] +void StoreModifierLocation (object token, Location loc) +{ + if (lbag == null) + return; + + if (mod_locations == null) + mod_locations = new List> (); + + mod_locations.Add (Tuple.Create ((Modifiers) token, loc)); +} + Block declare_local_variables (FullNamedExpression type, List variable_declarators, Location loc) { Block implicit_block; @@ -6287,8 +6426,8 @@ Location GetLocation (object obj) if (obj is MemberName) return ((MemberName) obj).Location; -// if (obj is Expression) -// return ((Expression) obj).Location; + if (obj is Expression) + return ((Expression) obj).Location; return lexer.Location; } @@ -6297,10 +6436,19 @@ 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); + current_block = new ToplevelBlock (compiler, current_block, current_local_parameters, loc); parsing_anonymous_method = false; } else { current_block = new ExplicitBlock (current_block, loc, Location.Null); @@ -6377,11 +6525,10 @@ void Error_SyntaxError (int error_code, int token, string msg) error_code = 1525; } - if (expecting != null) - Report.Error (error_code, lexer.Location, "{2} `{0}', expecting {1}", - symbol, expecting, msg); - else + if (string.IsNullOrEmpty (expecting)) Report.Error (error_code, lexer.Location, "{1} `{0}'", symbol, msg); + else + Report.Error (error_code, lexer.Location, "{2} `{0}', expecting {1}", symbol, expecting, msg); } string GetExpecting () @@ -6716,6 +6863,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 "]";