X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcs-parser.jay;h=b30fc6224fb72f9df45ced19615d85b20bd2c59c;hb=0c2bb8157f43826a57c39b863a1d67e3aef1b7b2;hp=c9655baecdfa6ac123c23c4f6a20621d5b11e974;hpb=f0fd85c7ed07266f3fe941adcc7079ff829b3170;p=mono.git diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index c9655baecdf..b30fc6224fb 100644 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -55,7 +55,7 @@ namespace Mono.CSharp // FIXME: This is very ugly and it's very hard to reset it correctly // on all places, especially when some parameters are autogenerated. - Parameters current_local_parameters; + ParametersCompiled current_local_parameters; /// /// Using during property parsing to describe the implicit @@ -63,7 +63,7 @@ namespace Mono.CSharp /// methods (properties and indexers). /// FullNamedExpression implicit_value_parameter_type; - Parameters indexer_parameters; + ParametersCompiled indexer_parameters; /// /// Hack to help create non-typed array initializer @@ -119,9 +119,9 @@ namespace Mono.CSharp bool global_attrs_enabled = true; bool has_get, has_set; bool parameter_modifiers_not_allowed; - bool params_modifiers_not_allowed; + bool complex_parameters_modifiers_not_allowed; bool arglist_allowed; - + bool default_parameter_used; /// When using the interactive parser, this holds the /// resulting expression @@ -131,6 +131,9 @@ namespace Mono.CSharp // Keeps track of global data changes to undo on parser error // public Undo undo; + + // Stack + Stack linq_clause_blocks; // A counter to create new class names in interactive mode static int class_count; @@ -228,8 +231,8 @@ namespace Mono.CSharp %token ARGLIST %token PARTIAL %token ARROW -%token QUERY_FIRST_TOKEN %token FROM +%token FROM_FIRST %token JOIN %token ON %token EQUALS @@ -241,8 +244,13 @@ namespace Mono.CSharp %token ASCENDING %token DESCENDING %token INTO -%token QUERY_LAST_TOKEN %token INTERR_NULLABLE +%token EXTERN_ALIAS + +/* Generics <,> tokens */ +%token OP_GENERICS_LT +%token OP_GENERICS_LT_DECL +%token OP_GENERICS_GT /* C# keywords which are not really keywords */ %token GET @@ -257,6 +265,7 @@ namespace Mono.CSharp %token CLOSE_BRACKET %token OPEN_PARENS %token CLOSE_PARENS + %token DOT %token COMMA %token COLON @@ -268,10 +277,7 @@ namespace Mono.CSharp %token BANG %token ASSIGN %token OP_LT -%token OP_GENERICS_LT -%token OP_GENERICS_LT_DECL %token OP_GT -%token OP_GENERICS_GT %token BITWISE_AND %token BITWISE_OR %token STAR @@ -279,7 +285,6 @@ namespace Mono.CSharp %token DIV %token CARRET %token INTERR -%token EXTERN_ALIAS /* C# multi-character operators. */ %token DOUBLE_COLON @@ -316,11 +321,7 @@ namespace Mono.CSharp %token IDENTIFIER %token OPEN_PARENS_LAMBDA -%token CLOSE_PARENS_CAST -%token CLOSE_PARENS_NO_CAST -%token CLOSE_PARENS_OPEN_PARENS -%token CLOSE_PARENS_MINUS -%token DEFAULT_OPEN_PARENS +%token OPEN_PARENS_CAST %token GENERIC_DIMENSION %token DEFAULT_COLON @@ -329,11 +330,25 @@ namespace Mono.CSharp %token EVAL_COMPILATION_UNIT_PARSER %token EVAL_USING_DECLARATIONS_UNIT_PARSER +// +// This token is generated to trigger the completion engine at this point +// +%token GENERATE_COMPLETION + +// +// This token is return repeatedly after the first GENERATE_COMPLETION +// token is produced and before the final EOF +// +%token COMPLETE_COMPLETION + /* Add precedence rules to solve dangling else s/r conflict */ -%nonassoc LOWPREC %nonassoc IF %nonassoc ELSE + +/* Define the operator tokens and their precedences */ %right ASSIGN +%right OP_COALESCING +%right INTERR %left OP_OR %left OP_AND %left BITWISE_OR @@ -346,7 +361,6 @@ namespace Mono.CSharp %left OPEN_PARENS %left OPEN_BRACKET OPEN_BRACE %left DOT -%nonassoc HIGHPREC %start compilation_unit %% @@ -356,7 +370,7 @@ compilation_unit | outer_declarations global_attributes opt_EOF | global_attributes opt_EOF | opt_EOF /* allow empty files */ - | interactive_parsing opt_EOF + | interactive_parsing { Lexer.CompleteOnEOF = false; } opt_EOF ; opt_EOF @@ -640,7 +654,7 @@ attribute_sections if (global_attrs_enabled) { if (current_attr_target == "module") { - CodeGen.Module.AddAttributes (sect); + current_container.Module.AddAttributes (sect); $$ = null; } else if (current_attr_target != null && current_attr_target.Length > 0) { CodeGen.Assembly.AddAttributes (sect); @@ -671,7 +685,7 @@ attribute_sections if (global_attrs_enabled) { if (current_attr_target == "module") { - CodeGen.Module.AddAttributes (sect); + current_container.Module.AddAttributes (sect); $$ = null; } else if (current_attr_target == "assembly") { CodeGen.Assembly.AddAttributes (sect); @@ -898,6 +912,7 @@ class_member_declaration Report.Error (1519, lexer.Location, "Unexpected symbol `{0}' in class, struct, or interface member declaration", GetSymbolName (yyToken)); $$ = null; + lexer.parsing_generic_declaration = false; } ; @@ -1278,7 +1293,7 @@ method_header lexer.ConstraintsParsing = false; arglist_allowed = false; MemberName name = (MemberName) $4; - current_local_parameters = (Parameters) $7; + current_local_parameters = (ParametersCompiled) $7; if ($10 != null && name.TypeArguments == null) Report.Error (80, lexer.Location, @@ -1308,18 +1323,23 @@ method_header opt_modifiers PARTIAL VOID method_declaration_name - OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + OPEN_PARENS + { + arglist_allowed = true; + } + opt_formal_parameter_list CLOSE_PARENS { lexer.ConstraintsParsing = true; } opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; + arglist_allowed = false; MemberName name = (MemberName) $5; - current_local_parameters = (Parameters) $7; + current_local_parameters = (ParametersCompiled) $8; - if ($9 != null && name.TypeArguments == null) + if ($10 != null && name.TypeArguments == null) Report.Error (80, lexer.Location, "Constraints are not allowed on non-generic declarations"); @@ -1329,7 +1349,7 @@ method_header generic = new GenericMethod (current_namespace, current_class, name, TypeManager.system_void_expr, current_local_parameters); - generic.SetParameterInfo ((ArrayList) $10); + generic.SetParameterInfo ((ArrayList) $11); } int modifiers = (int) $2; @@ -1348,7 +1368,7 @@ method_header Report.Error (751, name.Location, "A partial method must be declared within a " + "partial class or partial struct"); } - + modifiers |= Modifiers.PARTIAL | Modifiers.PRIVATE; method = new Method (current_class, generic, TypeManager.system_void_expr, @@ -1371,9 +1391,9 @@ method_header "Member modifier `{0}' must precede the member type and name", Modifiers.Name ((int) $4)); Method method = new Method (current_class, null, TypeManager.system_void_expr, - 0, name, (Parameters) $7, (Attributes) $1); + 0, name, (ParametersCompiled) $7, (Attributes) $1); - current_local_parameters = (Parameters) $7; + current_local_parameters = (ParametersCompiled) $7; if (RootContext.Documentation != null) method.DocComment = Lexer.consume_doc_comment (); @@ -1388,12 +1408,12 @@ method_body ; opt_formal_parameter_list - : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; } + : /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; } | formal_parameter_list ; opt_parameter_list_no_mod - : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; } + : /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; } | { parameter_modifiers_not_allowed = true; @@ -1406,14 +1426,14 @@ opt_parameter_list_no_mod ; formal_parameter_list - : fixed_parameters + : fixed_parameters { ArrayList pars_list = (ArrayList) $1; Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars); + $$ = new ParametersCompiled (pars); } | fixed_parameters COMMA parameter_array { @@ -1423,7 +1443,7 @@ formal_parameter_list Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars); + $$ = new ParametersCompiled (pars); } | fixed_parameters COMMA arglist_modifier { @@ -1433,7 +1453,7 @@ formal_parameter_list Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars, true); + $$ = new ParametersCompiled (pars, true); } | parameter_array COMMA error { @@ -1459,11 +1479,11 @@ formal_parameter_list } | parameter_array { - $$ = new Parameters (new Parameter[] { (Parameter) $1 } ); + $$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } ); } | arglist_modifier { - $$ = new Parameters (new Parameter [] { new ArglistParameter ((Location) $1) }, true); + $$ = new ParametersCompiled (new Parameter [] { new ArglistParameter ((Location) $1) }, true); } ; @@ -1471,17 +1491,23 @@ fixed_parameters : fixed_parameter { ArrayList pars = new ArrayList (4); - - pars.Add ($1); + Parameter p = (Parameter) $1; + pars.Add (p); + + default_parameter_used = p.HasDefaultValue; $$ = pars; } | fixed_parameters COMMA fixed_parameter { ArrayList pars = (ArrayList) $1; - Parameter p = (Parameter)$3; + Parameter p = (Parameter) $3; if (p != null) { if (p.HasExtensionMethodModifier) Report.Error (1100, p.Location, "The parameter modifier `this' can only be used on the first parameter"); + else if (!p.HasDefaultValue && default_parameter_used) + Report.Error (1737, p.Location, "Optional parameter cannot precede required parameters"); + + default_parameter_used |= p.HasDefaultValue; pars.Add (p); } $$ = $1; @@ -1509,16 +1535,11 @@ fixed_parameter | opt_attributes opt_parameter_modifier type + error { - Report.Error (1001, GetLocation ($3), "Identifier expected"); - $$ = new Parameter ((FullNamedExpression) $3, "NeedSomeGeneratorHere", (Parameter.Modifier) $2, (Attributes) $1, lexer.Location); - } - | opt_attributes - opt_parameter_modifier - type - error { - CheckIdentifierToken (yyToken, GetLocation ($4)); - $$ = null; + Location l = GetLocation ($4); + CheckIdentifierToken (yyToken, l); + $$ = new Parameter ((FullNamedExpression) $3, "NeedSomeGeneratorHere", (Parameter.Modifier) $2, (Attributes) $1, l); } | opt_attributes opt_parameter_modifier @@ -1526,11 +1547,39 @@ fixed_parameter IDENTIFIER ASSIGN constant_expression - { + { + if (RootContext.Version <= LanguageVersion.V_3) { + Report.FeatureIsNotAvailable (GetLocation ($5), "optional parameter"); + } + + Parameter.Modifier mod = (Parameter.Modifier) $2; + if (mod != Parameter.Modifier.NONE) { + switch (mod) { + case Parameter.Modifier.REF: + case Parameter.Modifier.OUT: + Report.Error (1741, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter", + Parameter.GetModifierSignature (mod)); + break; + + case Parameter.Modifier.This: + Report.Error (1743, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter", + Parameter.GetModifierSignature (mod)); + break; + default: + throw new NotImplementedException (mod.ToString ()); + } + + mod = Parameter.Modifier.NONE; + } + + if (complex_parameters_modifiers_not_allowed) + Report.Error (1065, GetLocation ($6), "Optional parameter is not valid in this context"); + LocatedToken lt = (LocatedToken) $4; - Report.Error (241, lt.Location, "Default parameter specifiers are not permitted"); - $$ = null; - } + $$ = new Parameter ((FullNamedExpression) $3, lt.Value, mod, (Attributes) $1, lt.Location); + if ($6 != null) + ((Parameter) $$).DefaultValue = (Expression) $6; + } ; opt_parameter_modifier @@ -1595,10 +1644,17 @@ parameter_modifier parameter_array : opt_attributes params_modifier type IDENTIFIER - { + { LocatedToken lt = (LocatedToken) $4; $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location); } + | opt_attributes params_modifier type IDENTIFIER ASSIGN constant_expression + { + Report.Error (1751, GetLocation ($2), "Cannot specify a default value for a parameter array"); + + LocatedToken lt = (LocatedToken) $4; + $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location); + } | opt_attributes params_modifier type error { CheckIdentifierToken (yyToken, GetLocation ($4)); $$ = null; @@ -1608,7 +1664,7 @@ parameter_array params_modifier : PARAMS { - if (params_modifiers_not_allowed) + if (complex_parameters_modifiers_not_allowed) Report.Error (1670, ((Location) $1), "The `params' modifier is not allowed in current context"); } | PARAMS parameter_modifier @@ -1733,7 +1789,7 @@ get_accessor_declaration // If this is not the case, then current_local_parameters has already // been set in indexer_declaration if (parsing_indexer == false) - current_local_parameters = null; + current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; else current_local_parameters = indexer_parameters; lexer.PropertyParsing = false; @@ -1741,7 +1797,7 @@ get_accessor_declaration accessor_body { if (has_get) { - Report.Error (1007, (Location) $3, "Property accessor already defined"); + Report.Error (1007, GetLocation ($3), "Property accessor already defined"); break; } Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, current_local_parameters, (Location) $3); @@ -1765,9 +1821,9 @@ set_accessor_declaration Parameter.Modifier.NONE, null, (Location) $3); if (!parsing_indexer) { - current_local_parameters = new Parameters (new Parameter [] { implicit_value_parameter }); + current_local_parameters = new ParametersCompiled (new Parameter [] { implicit_value_parameter }); } else { - current_local_parameters = Parameters.MergeGenerated ( + current_local_parameters = ParametersCompiled.MergeGenerated ( indexer_parameters, true, implicit_value_parameter, null); } @@ -1776,7 +1832,7 @@ set_accessor_declaration accessor_body { if (has_set) { - Report.Error (1007, ((LocatedToken) $3).Location, "Property accessor already defined"); + Report.Error (1007, GetLocation ($3), "Property accessor already defined"); break; } Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, current_local_parameters, (Location) $3); @@ -1932,15 +1988,15 @@ operator_type operator_declarator : operator_type OPERATOR overloadable_operator OPEN_PARENS { - params_modifiers_not_allowed = true; + complex_parameters_modifiers_not_allowed = true; } opt_parameter_list_no_mod CLOSE_PARENS { - params_modifiers_not_allowed = false; + complex_parameters_modifiers_not_allowed = false; Location loc = (Location) $2; Operator.OpType op = (Operator.OpType) $3; - current_local_parameters = (Parameters)$6; + current_local_parameters = (ParametersCompiled)$6; int p_count = current_local_parameters.Count; if (p_count == 1) { @@ -2007,14 +2063,14 @@ overloadable_operator conversion_operator_declarator : IMPLICIT OPERATOR type OPEN_PARENS { - params_modifiers_not_allowed = true; + complex_parameters_modifiers_not_allowed = true; } opt_parameter_list_no_mod CLOSE_PARENS { - params_modifiers_not_allowed = false; + complex_parameters_modifiers_not_allowed = false; Location loc = (Location) $2; - current_local_parameters = (Parameters)$6; + current_local_parameters = (ParametersCompiled)$6; if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); @@ -2025,14 +2081,14 @@ conversion_operator_declarator } | EXPLICIT OPERATOR type OPEN_PARENS { - params_modifiers_not_allowed = true; + complex_parameters_modifiers_not_allowed = true; } opt_parameter_list_no_mod CLOSE_PARENS { - params_modifiers_not_allowed = false; + complex_parameters_modifiers_not_allowed = false; Location loc = (Location) $2; - current_local_parameters = (Parameters)$6; + current_local_parameters = (ParametersCompiled)$6; if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); @@ -2043,11 +2099,13 @@ conversion_operator_declarator } | IMPLICIT error { - syntax_error ((Location) $1, "'operator' expected"); + Error_SyntaxError (yyToken); + $$ = new OperatorDeclaration (Operator.OpType.Implicit, null, GetLocation ($1)); } | EXPLICIT error { - syntax_error ((Location) $1, "'operator' expected"); + Error_SyntaxError (yyToken); + $$ = new OperatorDeclaration (Operator.OpType.Explicit, null, GetLocation ($1)); } ; @@ -2078,10 +2136,12 @@ constructor_declarator tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } + arglist_allowed = true; } OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { - current_local_parameters = (Parameters) $6; + arglist_allowed = false; + current_local_parameters = (ParametersCompiled) $6; // // start block here, so possible anonymous methods inside @@ -2148,7 +2208,7 @@ constructor_initializer $$ = new ConstructorThisInitializer ((ArrayList) $5, (Location) $2); } | COLON error { - Report.Error (1018, (Location) $1, "Keyword this or base expected"); + Report.Error (1018, GetLocation ($1), "Keyword `this' or `base' expected"); $$ = null; } ; @@ -2160,8 +2220,10 @@ destructor_declaration tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; } + + current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; } - IDENTIFIER OPEN_PARENS CLOSE_PARENS block + IDENTIFIER OPEN_PARENS CLOSE_PARENS method_body { LocatedToken lt = (LocatedToken) $5; if (lt.Value != current_container.MemberName.Name){ @@ -2169,15 +2231,16 @@ destructor_declaration } else if (current_container.Kind != Kind.Class){ Report.Error (575, lt.Location, "Only class types can contain destructor"); } else { - Method d = new Destructor ( - current_class, TypeManager.system_void_expr, (int) $2, "Finalize", - Parameters.EmptyReadOnlyParameters, (Attributes) $1, lt.Location); + Destructor d = new Destructor (current_class, (int) $2, + ParametersCompiled.EmptyReadOnlyParameters, (Attributes) $1, lt.Location); if (RootContext.Documentation != null) d.DocComment = ConsumeStoredComment (); d.Block = (ToplevelBlock) $8; current_container.AddMethod (d); } + + current_local_parameters = null; } ; @@ -2220,7 +2283,7 @@ event_declaration OPEN_BRACE { implicit_value_parameter_type = (FullNamedExpression) $4; - current_local_parameters = new Parameters ( + current_local_parameters = new ParametersCompiled ( new Parameter (implicit_value_parameter_type, "value", Parameter.Modifier.NONE, null, GetLocation ($3))); @@ -2345,10 +2408,15 @@ indexer_declaration OPEN_BRACE { implicit_value_parameter_type = (FullNamedExpression) $3; - indexer_parameters = (Parameters) $6; + indexer_parameters = (ParametersCompiled) $6; - if (indexer_parameters.IsEmpty) + if (indexer_parameters.IsEmpty) { Report.Error (1551, GetLocation ($5), "Indexers must have at least one parameter"); + } else if (indexer_parameters.Count == 1) { + Parameter p = indexer_parameters [0]; + if (p.HasDefaultValue) + p.Warning_UselessOptionalParameter (); + } if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); @@ -2373,7 +2441,7 @@ indexer_declaration bool order = accessors != null ? accessors.declared_in_reverse : false; Indexer indexer = new Indexer (current_class, (FullNamedExpression) $3, - (MemberName)$4, (int) $2, (Parameters) $6, (Attributes) $1, + (MemberName)$4, (int) $2, (ParametersCompiled) $6, (Attributes) $1, get_block, set_block, order); if ($3 == TypeManager.system_void_expr) @@ -2520,6 +2588,7 @@ enum_member_declaration } | opt_attributes IDENTIFIER { + ++lexer.parsing_block; if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; @@ -2527,6 +2596,7 @@ enum_member_declaration } ASSIGN constant_expression { + --lexer.parsing_block; VariableDeclaration vd = new VariableDeclaration ( (LocatedToken) $2, $5, (Attributes) $1); @@ -2545,7 +2615,7 @@ delegate_declaration OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { MemberName name = MakeName ((MemberName) $5); - Parameters p = (Parameters) $7; + ParametersCompiled p = (ParametersCompiled) $7; Delegate del = new Delegate (current_namespace, current_class, (FullNamedExpression) $4, (int) $2, name, p, (Attributes) $1); @@ -2579,7 +2649,9 @@ opt_nullable } | INTERR_NULLABLE { - if (RootContext.Version < LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "nullable types"); + else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (lexer.Location, "nullable types"); $$ = this; @@ -2621,7 +2693,9 @@ opt_type_argument_list : /* empty */ { $$ = null; } | OP_GENERICS_LT type_arguments OP_GENERICS_GT { - if (RootContext.Version < LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "generics"); + else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "generics"); $$ = $2; @@ -2629,21 +2703,21 @@ opt_type_argument_list | OP_GENERICS_LT error { Error_TypeExpected (lexer.Location); - $$ = new TypeArguments (lexer.Location); + $$ = new TypeArguments (); } ; type_arguments : type { - TypeArguments type_args = new TypeArguments (lexer.Location); - type_args.Add ((Expression) $1); + TypeArguments type_args = new TypeArguments (); + type_args.Add ((FullNamedExpression) $1); $$ = type_args; } | type_arguments COMMA type { TypeArguments type_args = (TypeArguments) $1; - type_args.Add ((Expression) $3); + type_args.Add ((FullNamedExpression) $3); $$ = type_args; } ; @@ -2721,7 +2795,9 @@ opt_type_parameter_list : /* empty */ { $$ = null; } | OP_GENERICS_LT_DECL type_parameters OP_GENERICS_GT { - if (RootContext.Version < LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "generics"); + else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "generics"); $$ = $2; @@ -2731,23 +2807,23 @@ opt_type_parameter_list type_parameters : type_parameter { - TypeArguments type_args = new TypeArguments (lexer.Location); - type_args.Add ((Expression)$1); + TypeArguments type_args = new TypeArguments (); + type_args.Add ((FullNamedExpression)$1); $$ = type_args; } | type_parameters COMMA type_parameter { TypeArguments type_args = (TypeArguments) $1; - type_args.Add ((Expression)$3); + type_args.Add ((FullNamedExpression)$3); $$ = type_args; } ; type_parameter - : opt_attributes IDENTIFIER + : opt_attributes opt_type_parameter_variance IDENTIFIER { - LocatedToken lt = (LocatedToken)$2; - $$ = new TypeParameterName (lt.Value, (Attributes)$1, lt.Location); + LocatedToken lt = (LocatedToken)$3; + $$ = new TypeParameterName (lt.Value, (Attributes)$1, (Variance) $2, lt.Location); } | error { @@ -2816,8 +2892,7 @@ type_expression if ($2 != null) { $$ = new ComposedCast (name.GetTypeExpression (), "?", lexer.Location); } else { - if (name.Left == null && name.Name == "var" && - (RootContext.Version > LanguageVersion.ISO_2 || RootContext.Version == LanguageVersion.Default_MCS)) + if (name.Left == null && name.Name == "var" && RootContext.Version > LanguageVersion.ISO_2) $$ = current_array_type = new VarExpr (name.Location); else $$ = name.GetTypeExpression (); @@ -2843,44 +2918,6 @@ type_expression } ; -non_expression_type - : builtin_types opt_nullable - { - if ($2 != null) - $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location); - } - | VOID - { - $$ = TypeManager.system_void_expr; - } - | non_expression_type rank_specifiers - { - Location loc = GetLocation ($1); - if (loc.IsNull) - loc = lexer.Location; - $$ = new ComposedCast ((FullNamedExpression) $1, (string) $2, loc); - } - | non_expression_type STAR - { - Location loc = GetLocation ($1); - if (loc.IsNull) - loc = lexer.Location; - $$ = new ComposedCast ((FullNamedExpression) $1, "*", loc); - } - // - // We need this because the parser will happily go and reduce IDENTIFIER STAR - // through this different path - // - | multiplicative_expression STAR - { - FullNamedExpression e = $1 as FullNamedExpression; - if (e != null) - $$ = new ComposedCast (e, "*"); - else - Error_TypeExpected (GetLocation ($1)); - } - ; - type_list : base_type_name { @@ -2911,7 +2948,7 @@ base_type_name /* * replaces all the productions for isolating the various - * simple types, but we need this to reuse it easily in local_variable_type + * simple types, but we need this to reuse it easily in variable_type */ builtin_types : OBJECT { $$ = TypeManager.system_object_expr; } @@ -2960,6 +2997,10 @@ primary_expression_no_array_creation LocatedToken lt = (LocatedToken) $1; $$ = new SimpleName (MemberName.MakeName (lt.Value, (TypeArguments)$2), (TypeArguments)$2, lt.Location); } + | IDENTIFIER GENERATE_COMPLETION { + LocatedToken lt = (LocatedToken) $1; + $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location); + } | parenthesized_expression | default_value_expression | member_access @@ -3016,36 +3057,29 @@ boolean_literal | FALSE { $$ = new BoolLiteral (false, lexer.Location); } ; -parenthesized_expression_0 - : OPEN_PARENS expression CLOSE_PARENS - { - $$ = $2; - lexer.Deambiguate_CloseParens ($$); - // After this, the next token returned is one of - // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST (CLOSE_PARENS), CLOSE_PARENS_OPEN_PARENS - // or CLOSE_PARENS_MINUS. - } - | OPEN_PARENS expression error { CheckToken (1026, yyToken, "Expecting ')'", lexer.Location); } + +// +// Here is the trick, tokenizer may think that parens is a special but +// parser is interested in open parens only, so we merge them. +// Consider: if (a)foo (); +// +open_parens_any + : OPEN_PARENS + | OPEN_PARENS_CAST + | OPEN_PARENS_LAMBDA ; parenthesized_expression - : parenthesized_expression_0 CLOSE_PARENS_NO_CAST - { - $$ = $1; - } - | parenthesized_expression_0 CLOSE_PARENS + : OPEN_PARENS expression CLOSE_PARENS { - $$ = $1; + $$ = new ParenthesizedExpression ((Expression) $2); } - | parenthesized_expression_0 CLOSE_PARENS_MINUS + | OPEN_PARENS expression COMPLETE_COMPLETION { - // If a parenthesized expression is followed by a minus, we need to wrap - // the expression inside a ParenthesizedExpression for the CS0075 check - // in Binary.DoResolve(). - $$ = new ParenthesizedExpression ((Expression) $1); + $$ = new ParenthesizedExpression ((Expression) $2); } ; - + member_access : primary_expression DOT IDENTIFIER opt_type_argument_list { @@ -3065,32 +3099,28 @@ member_access $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); } - ; - -invocation_expression - : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS - { - $$ = new Invocation ((Expression) $1, (ArrayList) $3); + | primary_expression DOT GENERATE_COMPLETION { + $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3)); } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS - { - $$ = new Invocation ((Expression) $1, new ArrayList ()); - } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression - { - $$ = new InvocationOrCast ((Expression) $1, (Expression) $3); + | primary_expression DOT IDENTIFIER GENERATE_COMPLETION { + LocatedToken lt = (LocatedToken) $3; + $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS non_simple_argument CLOSE_PARENS + | predefined_type DOT GENERATE_COMPLETION { - ArrayList args = new ArrayList (1); - args.Add ($4); - $$ = new Invocation ((Expression) $1, args); + // TODO: Location is wrong as some predefined types doesn't hold a location + $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location); } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS argument_list COMMA argument CLOSE_PARENS + | predefined_type DOT IDENTIFIER GENERATE_COMPLETION { + LocatedToken lt = (LocatedToken) $3; + $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); + } + ; + +invocation_expression + : primary_expression open_parens_any opt_argument_list CLOSE_PARENS { - ArrayList args = ((ArrayList) $4); - args.Add ($6); - $$ = new Invocation ((Expression) $1, args); + $$ = new Invocation ((Expression) $1, (ArrayList) $3); } ; @@ -3100,12 +3130,12 @@ opt_object_or_collection_initializer ; object_or_collection_initializer - : OPEN_BRACE opt_member_initializer_list CLOSE_BRACE + : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion { if ($2 == null) - $$ = CollectionOrObjectInitializers.Empty; + $$ = CollectionOrObjectInitializers.Empty; else - $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1)); + $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1)); } | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE { @@ -3122,7 +3152,7 @@ opt_member_initializer_list ; member_initializer_list - : member_initializer + : member_initializer { ArrayList a = new ArrayList (); a.Add ($1); @@ -3142,9 +3172,16 @@ member_initializer LocatedToken lt = $1 as LocatedToken; $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); } - | non_assignment_expression + | GENERATE_COMPLETION { - $$ = new CollectionElementInitializer ((Expression)$1); + $$ = new CompletionElementInitializer (null, GetLocation ($1)); + } + | non_assignment_expression opt_COMPLETE_COMPLETION { + CompletionSimpleName csn = $1 as CompletionSimpleName; + if (csn == null) + $$ = new CollectionElementInitializer ((Expression)$1); + else + $$ = new CompletionElementInitializer (csn.Prefix, csn.Location); } | OPEN_BRACE expression_list CLOSE_BRACE { @@ -3211,7 +3248,7 @@ non_simple_argument { $$ = new Argument ((Expression) $2, Argument.AType.Out); } - | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS + | ARGLIST open_parens_any argument_list CLOSE_PARENS { ArrayList list = (ArrayList) $3; Argument[] args = new Argument [list.Count]; @@ -3220,7 +3257,7 @@ non_simple_argument Expression expr = new Arglist (args, (Location) $1); $$ = new Argument (expr, Argument.AType.Expression); } - | ARGLIST OPEN_PARENS CLOSE_PARENS + | ARGLIST open_parens_any CLOSE_PARENS { $$ = new Argument (new Arglist ((Location) $1), Argument.AType.Expression); } @@ -3312,70 +3349,81 @@ base_access post_increment_expression : primary_expression OP_INC { - $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, - (Expression) $1, (Location) $2); + $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1); } ; post_decrement_expression : primary_expression OP_DEC { - $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, - (Expression) $1, (Location) $2); + $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1); } ; object_or_delegate_creation_expression - : NEW simple_type OPEN_PARENS opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer + : new_expr_start open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer { - if ($6 != null) { + if ($5 != null) { if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "object initializers"); - $$ = new NewInitialize ((Expression) $2, (ArrayList) $4, (CollectionOrObjectInitializers) $6, (Location) $1); + $$ = new NewInitialize ((Expression) $1, (ArrayList) $3, (CollectionOrObjectInitializers) $5, GetLocation ($1)); } else - $$ = new New ((Expression) $2, (ArrayList) $4, (Location) $1); + $$ = new New ((Expression) $1, (ArrayList) $3, GetLocation ($1)); } - | NEW simple_type object_or_collection_initializer + | new_expr_start object_or_collection_initializer { if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "collection initializers"); - $$ = new NewInitialize ((Expression) $2, null, (CollectionOrObjectInitializers) $3, (Location) $1); + $$ = new NewInitialize ((Expression) $1, null, (CollectionOrObjectInitializers) $2, GetLocation ($1)); } ; - array_creation_expression - : NEW simple_type OPEN_BRACKET expression_list CLOSE_BRACKET + : new_expr_start OPEN_BRACKET expression_list CLOSE_BRACKET opt_rank_specifier // shift/reduce on OPEN_BRACE opt_array_initializer { - $$ = new ArrayCreation ((FullNamedExpression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, (Location) $1); + $$ = new ArrayCreation ((FullNamedExpression) $1, (ArrayList) $3, (string) $5, (ArrayList) $6, GetLocation ($1)); } - | NEW simple_type rank_specifiers opt_array_initializer + | new_expr_start rank_specifiers opt_array_initializer { - if ($4 == null) + if ($3 == null) Report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer"); - $$ = new ArrayCreation ((FullNamedExpression) $2, (string) $3, (ArrayList) $4, (Location) $1); + $$ = new ArrayCreation ((FullNamedExpression) $1, (string) $2, (ArrayList) $3, GetLocation ($1)); } | NEW rank_specifiers array_initializer { - $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayList) $3, (Location) $1); + $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayList) $3, GetLocation ($1)); } - | NEW simple_type error + | new_expr_start error { - Report.Error (1526, (Location) $1, "A new expression requires () or [] after type"); + Report.Error (1526, GetLocation ($1), "A new expression requires () or [] after type"); $$ = null; } ; +new_expr_start + : NEW + { + ++lexer.parsing_type; + } + simple_type + { + --lexer.parsing_type; + $$ = $3; + } + ; + anonymous_type_expression : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE { - if (RootContext.Version <= LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "anonymous types"); + else if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "anonymous types"); $$ = new AnonymousTypeDeclaration ((ArrayList) $3, current_container, GetLocation ($1)); @@ -3549,7 +3597,7 @@ typeof_expression pushed_current_array_type = current_array_type; lexer.TypeOfParsing = true; } - OPEN_PARENS typeof_type_expression CLOSE_PARENS + open_parens_any typeof_type_expression CLOSE_PARENS { lexer.TypeOfParsing = false; Expression type = (Expression)$4; @@ -3563,13 +3611,7 @@ typeof_expression typeof_type_expression : type_and_void - { - $$ = $1; - } | unbound_type_name - { - $$ = new UnboundTypeExpression ((MemberName)$1, lexer.Location); - } | error { Error_TypeExpected (lexer.Location); @@ -3581,41 +3623,46 @@ unbound_type_name : IDENTIFIER generic_dimension { LocatedToken lt = (LocatedToken) $1; - TypeArguments ta = (TypeArguments)$2; - $$ = new MemberName (lt.Value, ta, lt.Location); + $$ = new SimpleName (MemberName.MakeName (lt.Value, (int)$2), lt.Location); } | qualified_alias_member IDENTIFIER generic_dimension { LocatedToken lt1 = (LocatedToken) $1; LocatedToken lt2 = (LocatedToken) $2; - TypeArguments ta = (TypeArguments)$3; - $$ = new MemberName (new MemberName (lt1.Value, lt1.Location), lt2.Value, ta, lt2.Location); + $$ = new QualifiedAliasMember (lt1.Value, MemberName.MakeName (lt2.Value, (int) $3), lt1.Location); + } + | unbound_type_name DOT IDENTIFIER + { + LocatedToken lt = (LocatedToken) $3; + + $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location); } | unbound_type_name DOT IDENTIFIER generic_dimension { LocatedToken lt = (LocatedToken) $3; - TypeArguments ta = (TypeArguments)$4; - $$ = new MemberName ((MemberName)$1, lt.Value, ta, lt.Location); + $$ = new MemberAccess ((Expression) $1, MemberName.MakeName (lt.Value, (int) $4), lt.Location); } | namespace_or_type_name DOT IDENTIFIER generic_dimension { LocatedToken lt = (LocatedToken) $3; - TypeArguments ta = (TypeArguments)$4; - - $$ = new MemberName ((MemberName)$1, lt.Value, ta, lt.Location); + MemberName name = (MemberName) $1; + + $$ = new MemberAccess (name.GetTypeExpression (), MemberName.MakeName (lt.Value, (int) $4), lt.Location); } ; - + generic_dimension : GENERIC_DIMENSION { - if (RootContext.Version < LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "generics"); + else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (lexer.Location, "generics"); - $$ = new TypeArguments ((int)$1, lexer.Location); + $$ = $1; } ; @@ -3631,20 +3678,20 @@ qualified_alias_member ; sizeof_expression - : SIZEOF OPEN_PARENS type CLOSE_PARENS { + : SIZEOF open_parens_any type CLOSE_PARENS { $$ = new SizeOf ((Expression) $3, (Location) $1); } ; checked_expression - : CHECKED OPEN_PARENS expression CLOSE_PARENS + : CHECKED open_parens_any expression CLOSE_PARENS { $$ = new CheckedExpr ((Expression) $3, (Location) $1); } ; unchecked_expression - : UNCHECKED OPEN_PARENS expression CLOSE_PARENS + : UNCHECKED open_parens_any expression CLOSE_PARENS { $$ = new UnCheckedExpr ((Expression) $3, (Location) $1); } @@ -3664,38 +3711,41 @@ pointer_member_access anonymous_method_expression : DELEGATE opt_anonymous_method_signature { - start_anonymous (false, (Parameters) $2, (Location) $1); + start_anonymous (false, (ParametersCompiled) $2, (Location) $1); } block { - $$ = end_anonymous ((ToplevelBlock) $4, (Location) $1); + $$ = end_anonymous ((ToplevelBlock) $4); } ; opt_anonymous_method_signature - : /* empty */ { $$ = null; } + : + { + $$ = ParametersCompiled.Undefined; + } | anonymous_method_signature ; anonymous_method_signature : OPEN_PARENS { - params_modifiers_not_allowed = true; + complex_parameters_modifiers_not_allowed = true; } opt_formal_parameter_list CLOSE_PARENS { - params_modifiers_not_allowed = false; + complex_parameters_modifiers_not_allowed = false; $$ = $3; } ; default_value_expression - : DEFAULT_OPEN_PARENS type CLOSE_PARENS + : DEFAULT open_parens_any type CLOSE_PARENS { if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (lexer.Location, "default value expression"); - $$ = new DefaultValueExpression ((Expression) $2, lexer.Location); + $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1)); } ; @@ -3703,39 +3753,23 @@ unary_expression : primary_expression | BANG prefixed_unary_expression { - $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2); } | TILDE prefixed_unary_expression { - $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2); } | cast_expression ; -cast_list - : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression - { - $$ = new Cast ((Expression) $1, (Expression) $3); - } - | parenthesized_expression_0 CLOSE_PARENS_NO_CAST default_value_expression +cast_expression + : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression { - $$ = new Cast ((Expression) $1, (Expression) $3); + $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression - { - $$ = new Cast ((Expression) $1, (Expression) $3); - } - ; - -cast_expression - : cast_list - | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression + | OPEN_PARENS predefined_type CLOSE_PARENS prefixed_unary_expression { - if ($2 == TypeManager.system_void_expr) - Expression.Error_VoidInvalidInTheContext (GetLocation ($2)); - - // TODO: wrong location - $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location); + $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); } ; @@ -3747,29 +3781,27 @@ prefixed_unary_expression : unary_expression | PLUS prefixed_unary_expression { - $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2); } | MINUS prefixed_unary_expression { - $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2); } | OP_INC prefixed_unary_expression { - $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, - (Expression) $2, (Location) $1); + $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2); } | OP_DEC prefixed_unary_expression { - $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, - (Expression) $2, (Location) $1); + $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2); } | STAR prefixed_unary_expression { - $$ = new Indirection ((Expression) $2, (Location) $1); + $$ = new Indirection ((Expression) $2, GetLocation ($1)); } | BITWISE_AND prefixed_unary_expression { - $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2); } ; @@ -3801,9 +3833,13 @@ additive_expression } | additive_expression MINUS multiplicative_expression { - $$ = new Binary (Binary.Operator.Subtraction, - (Expression) $1, (Expression) $3); + $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3); } + | parenthesized_expression MINUS multiplicative_expression + { + // Shift/Reduce conflict + $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3); + } | additive_expression AS type { $$ = new As ((Expression) $1, (Expression) $3, (Location) $2); @@ -3910,29 +3946,23 @@ conditional_or_expression (Expression) $1, (Expression) $3); } ; - -conditional_expression + +null_coalescing_expression : conditional_or_expression - | conditional_or_expression INTERR expression COLON expression - { - $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5); - } - | conditional_or_expression OP_COALESCING expression + | conditional_or_expression OP_COALESCING null_coalescing_expression { if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator"); $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, lexer.Location); } - | primary_expression INTERR_NULLABLE opt_rank_specifier + ; + +conditional_expression + : null_coalescing_expression + | null_coalescing_expression INTERR expression COLON expression { - // - // TODO: Is this the best place to handle `= (foo?)a;' ? - // - if (RootContext.Version < LanguageVersion.ISO_2) - Report.FeatureIsNotAvailable (GetLocation ($1), "nullable types"); - - $$ = new ComposedCast ((FullNamedExpression) $1, "?" + (string)$3, lexer.Location); + $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5); } ; @@ -4035,10 +4065,10 @@ lambda_parameter ; opt_lambda_parameter_list - : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; } + : /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; } | lambda_parameter_list { ArrayList pars_list = (ArrayList) $1; - $$ = new Parameters ((Parameter[])pars_list.ToArray (typeof (Parameter))); + $$ = new ParametersCompiled ((Parameter[])pars_list.ToArray (typeof (Parameter))); } ; @@ -4062,25 +4092,25 @@ lambda_expression { LocatedToken lt = (LocatedToken) $1; Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); - start_anonymous (true, new Parameters (p), (Location) $2); + start_anonymous (true, new ParametersCompiled (p), GetLocation ($1)); } lambda_expression_body { - $$ = end_anonymous ((ToplevelBlock) $4, (Location) $2); + $$ = end_anonymous ((ToplevelBlock) $4); } | OPEN_PARENS_LAMBDA opt_lambda_parameter_list CLOSE_PARENS ARROW { - start_anonymous (true, (Parameters) $2, (Location) $4); + start_anonymous (true, (ParametersCompiled) $2, GetLocation ($1)); } lambda_expression_body { - $$ = end_anonymous ((ToplevelBlock) $6, (Location) $4); + $$ = end_anonymous ((ToplevelBlock) $6); } ; expression - : assignment_expression - | non_assignment_expression + : assignment_expression + | non_assignment_expression ; non_assignment_expression @@ -4257,6 +4287,33 @@ type_parameter_constraint } ; +opt_type_parameter_variance + : /* empty */ + { + $$ = Variance.None; + } + | type_parameter_variance + { + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "generic type variance"); + else if (RootContext.Version <= LanguageVersion.V_3) + Report.FeatureIsNotAvailable (lexer.Location, "generic type variance"); + + $$ = $1; + } + ; + +type_parameter_variance + : OUT + { + $$ = Variance.Covariant; + } + | IN + { + $$ = Variance.Contravariant; + } + ; + // // Statements (8.2) // @@ -4276,13 +4333,26 @@ block ++lexer.parsing_block; start_block ((Location) $1); } - opt_statement_list CLOSE_BRACE + opt_statement_list block_end + { + $$ = $4; + } + ; + +block_end + : CLOSE_BRACE { --lexer.parsing_block; - $$ = end_block ((Location) $4); + $$ = end_block ((Location) $1); + } + | COMPLETE_COMPLETION + { + --lexer.parsing_block; + $$ = end_block (lexer.Location); } ; + block_prepared : OPEN_BRACE { @@ -4441,7 +4511,7 @@ declaration_statement * > expressions to prevent reduce/reduce errors in the grammar. * > The expressions are converted into types during semantic analysis. */ -local_variable_type +variable_type : primary_expression_no_array_creation opt_rank_specifier_or_nullable { // FIXME: Do something smart here regarding the composition of the type. @@ -4472,8 +4542,7 @@ local_variable_type // if (rank_or_nullable.Length == 0) { SimpleName sn = expr as SimpleName; - if (sn != null && sn.Name == "var" && - (RootContext.Version > LanguageVersion.ISO_2 || RootContext.Version == LanguageVersion.Default_MCS)) + if (sn != null && sn.Name == "var" && RootContext.Version > LanguageVersion.ISO_2) $$ = current_array_type = new VarExpr (sn.Location); else $$ = $1; @@ -4513,7 +4582,7 @@ local_variable_pointer_type } | builtin_types STAR { - $$ = new ComposedCast ((FullNamedExpression) $1, "*", lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, "*", GetLocation ($1)); } | VOID STAR { @@ -4525,6 +4594,23 @@ local_variable_pointer_type } ; +local_variable_type + : variable_type + | local_variable_pointer_type opt_rank_specifier + { + if ($1 != null){ + string rank = (string)$2; + + if (rank == "") + $$ = $1; + else + $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, rank); + } else { + $$ = null; + } + } + ; + local_variable_declaration : local_variable_type local_variable_declarators { @@ -4537,23 +4623,10 @@ local_variable_declaration } else $$ = null; } - | local_variable_pointer_type opt_rank_specifier local_variable_declarators - { - if ($1 != null){ - Expression t; - - if ((string) $2 == "") - t = (Expression) $1; - else - t = new ComposedCast ((FullNamedExpression) $1, (string) $2); - $$ = new DictionaryEntry (t, $3); - } else - $$ = null; - } ; local_constant_declaration - : CONST local_variable_type constant_declarators + : CONST variable_type constant_declarators { if ($2 != null) $$ = new DictionaryEntry ($2, $3); @@ -4564,10 +4637,12 @@ local_constant_declaration expression_statement : statement_expression SEMICOLON { $$ = $1; } + | statement_expression COMPLETE_COMPLETION { $$ = $1; } ; interactive_expression_statement : interactive_statement_expression SEMICOLON { $$ = $1; } + | interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; } ; // @@ -4577,17 +4652,13 @@ interactive_expression_statement statement_expression : expression { - Expression expr = (Expression) $1; - ExpressionStatement s; - - s = expr as ExpressionStatement; - + ExpressionStatement s = $1 as ExpressionStatement; if (s == null) { - expr.Error_InvalidExpressionStatement (); - $$ = null; - } else { - $$ = new StatementExpression (s); + ((Expression) $1).Error_InvalidExpressionStatement (); + s = EmptyExpressionStatement.Instance; } + + $$ = new StatementExpression (s); } | error { @@ -4618,7 +4689,7 @@ selection_statement ; if_statement - : IF OPEN_PARENS boolean_expression CLOSE_PARENS + : IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement { Location l = (Location) $1; @@ -4630,7 +4701,7 @@ if_statement Report.Warning (642, 3, l, "Possible mistaken empty statement"); } - | IF OPEN_PARENS boolean_expression CLOSE_PARENS + | IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement ELSE embedded_statement { Location l = (Location) $1; @@ -4646,7 +4717,7 @@ if_statement ; switch_statement - : SWITCH OPEN_PARENS + : SWITCH open_parens_any { if (switch_stack == null) switch_stack = new Stack (2); @@ -4742,7 +4813,7 @@ iteration_statement ; while_statement - : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement + : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement { Location l = (Location) $1; $$ = new While ((Expression) $3, (Statement) $5, l); @@ -4751,7 +4822,7 @@ while_statement do_statement : DO embedded_statement - WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON + WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON { Location l = (Location) $1; @@ -4760,8 +4831,7 @@ do_statement ; for_statement - : FOR OPEN_PARENS - opt_for_initializer SEMICOLON + : FOR open_parens_any opt_for_initializer SEMICOLON { Location l = lexer.Location; start_block (l); @@ -4858,12 +4928,12 @@ statement_expression_list ; foreach_statement - : FOREACH OPEN_PARENS type IN expression CLOSE_PARENS + : FOREACH open_parens_any type IN expression CLOSE_PARENS { Report.Error (230, (Location) $1, "Type and identifier are both required in a foreach statement"); $$ = null; } - | FOREACH OPEN_PARENS type IDENTIFIER IN + | FOREACH open_parens_any type IDENTIFIER IN expression CLOSE_PARENS { start_block (lexer.Location); @@ -5082,11 +5152,11 @@ opt_catch_args ; catch_args - : OPEN_PARENS type opt_identifier CLOSE_PARENS + : open_parens_any type opt_identifier CLOSE_PARENS { $$ = new DictionaryEntry ($2, $3); } - | OPEN_PARENS CLOSE_PARENS + | open_parens_any CLOSE_PARENS { Report.Error (1015, GetLocation ($1), "A type that derives from `System.Exception', `object', or `string' expected"); } @@ -5116,7 +5186,7 @@ unsafe_statement ; fixed_statement - : FIXED OPEN_PARENS + : FIXED open_parens_any type_and_void fixed_pointer_declarators CLOSE_PARENS { @@ -5184,7 +5254,7 @@ fixed_pointer_declarator ; lock_statement - : LOCK OPEN_PARENS expression CLOSE_PARENS + : LOCK open_parens_any expression CLOSE_PARENS { // } @@ -5195,7 +5265,7 @@ lock_statement ; using_statement - : USING OPEN_PARENS local_variable_declaration CLOSE_PARENS + : USING open_parens_any local_variable_declaration CLOSE_PARENS { start_block (lexer.Location); Block assign_block = current_block; @@ -5250,7 +5320,7 @@ using_statement current_block.AddStatement (stmt); $$ = end_block (lexer.Location); } - | USING OPEN_PARENS expression CLOSE_PARENS + | USING open_parens_any expression CLOSE_PARENS { start_block (lexer.Location); } @@ -5265,18 +5335,23 @@ using_statement // LINQ query_expression - : first_from_clause + : first_from_clause query_body { - ++lexer.query_parsing; + lexer.query_parsing = false; + + Linq.AQueryClause from = $1 as Linq.AQueryClause; + + from.Tail.Next = (Linq.AQueryClause)$2; + $$ = from; + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; } - query_body + | nested_from_clause query_body { - if (--lexer.query_parsing == 1) - lexer.query_parsing = 0; - Linq.AQueryClause from = $1 as Linq.AQueryClause; - from.Tail.Next = (Linq.AQueryClause)$3; + from.Tail.Next = (Linq.AQueryClause)$2; $$ = from; current_block.SetEndLocation (lexer.Location); @@ -5285,42 +5360,61 @@ query_expression ; first_from_clause + : FROM_FIRST IDENTIFIER IN expression + { + $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4)); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, GetLocation ($1)); + } + | FROM_FIRST type IDENTIFIER IN expression + { + $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5)); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $3, GetLocation ($1)); + } + ; + +nested_from_clause : FROM IDENTIFIER IN expression { - current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); - LocatedToken lt = (LocatedToken) $2; - - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, lt.Value, lt.Location); - $$ = new Linq.QueryExpression (lt, new Linq.QueryStartClause ((Expression)$4)); + $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4)); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, GetLocation ($1)); } | FROM type IDENTIFIER IN expression { - current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); - LocatedToken lt = (LocatedToken) $3; - - Expression type = (Expression)$2; - current_block.AddVariable (type, lt.Value, lt.Location); - $$ = new Linq.QueryExpression (lt, new Linq.Cast (type, (Expression)$5)); + $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5)); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $3, GetLocation ($1)); } ; from_clause - : FROM IDENTIFIER IN expression + : FROM IDENTIFIER IN + { + current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); + } + expression { LocatedToken lt = (LocatedToken) $2; + $$ = new Linq.SelectMany (current_block.Toplevel, lt, (Expression)$5); - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, - lt.Value, lt.Location); - - $$ = new Linq.SelectMany (lt, (Expression)$4); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); + } + | FROM type IDENTIFIER IN + { + current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); } - | FROM type IDENTIFIER IN expression + expression { LocatedToken lt = (LocatedToken) $3; - - Expression type = (Expression)$2; - current_block.AddVariable (type, lt.Value, lt.Location); - $$ = new Linq.SelectMany (lt, new Linq.Cast (type, (Expression)$5)); + FullNamedExpression type = (FullNamedExpression)$2; + + $$ = new Linq.SelectMany (current_block.Toplevel, lt, new Linq.Cast (type, (FullNamedExpression)$6)); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); } ; @@ -5343,13 +5437,38 @@ query_body ; select_or_group_clause - : SELECT expression + : SELECT + { + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + expression + { + $$ = new Linq.Select (current_block.Toplevel, (Expression)$3, GetLocation ($1)); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + } + | GROUP + { + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); + } + expression { - $$ = new Linq.Select ((Expression)$2, GetLocation ($1)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); } - | GROUP expression BY expression + BY expression { - $$ = new Linq.GroupBy ((Expression)$2, (Expression)$4, GetLocation ($1)); + $$ = new Linq.GroupBy (current_block.Toplevel, (Expression)$3, (ToplevelBlock) linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1)); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; } ; @@ -5376,54 +5495,130 @@ query_body_clause ; let_clause - : LET IDENTIFIER ASSIGN expression + : LET IDENTIFIER ASSIGN + { + current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); + } + expression { LocatedToken lt = (LocatedToken) $2; - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, - lt.Value, lt.Location); - $$ = new Linq.Let (lt, (Expression)$4, GetLocation ($1)); + $$ = new Linq.Let (current_block.Toplevel, current_container, lt, (Expression)$5); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); } ; where_clause - : WHERE boolean_expression + : WHERE { - $$ = new Linq.Where ((Expression)$2, GetLocation ($1)); + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + boolean_expression + { + $$ = new Linq.Where (current_block.Toplevel, (Expression)$3, GetLocation ($1)); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; } ; join_clause - : JOIN IDENTIFIER IN expression ON expression EQUALS expression opt_join_into + : JOIN IDENTIFIER IN + { + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); + } + expression ON + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); + } + expression EQUALS + { + current_block.AddStatement (new ContextualReturn ((Expression) $8)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, lexer.Location); + } + expression opt_join_into { - Location loc = GetLocation ($1); LocatedToken lt = (LocatedToken) $2; - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, - lt.Value, lt.Location); - if ($9 == null) { - $$ = new Linq.Join (lt, (Expression)$4, (Expression)$6, - (Expression)$8, loc); + ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop (); + ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop (); + + if ($12 == null) { + $$ = new Linq.Join (block, lt, (Expression)$5, outer_selector, current_block.Toplevel, GetLocation ($1)); } else { - LocatedToken lt_into = (LocatedToken) $9; - $$ = new Linq.GroupJoin (lt, (Expression)$4, (Expression)$6, - (Expression)$8, lt_into, loc); + $$ = new Linq.GroupJoin (block, lt, (Expression)$5, outer_selector, current_block.Toplevel, + (LocatedToken) $12, GetLocation ($1)); } + + current_block.AddStatement (new ContextualReturn ((Expression) $11)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + if ($12 == null) + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); + else + ((Linq.QueryBlock)current_block).AddTransparentParameter ((LocatedToken) $12); + } + | JOIN type IDENTIFIER IN + { + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); + } + expression ON + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); } - | JOIN type IDENTIFIER IN expression ON expression EQUALS expression opt_join_into + expression EQUALS + { + current_block.AddStatement (new ContextualReturn ((Expression) $9)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $3, lexer.Location); + } + expression opt_join_into { - Location loc = GetLocation ($1); LocatedToken lt = (LocatedToken) $3; - current_block.AddVariable ((Expression)$2, lt.Value, lt.Location); + ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop (); + ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop (); - Linq.Cast cast = new Linq.Cast ((Expression)$2, (Expression)$5); - if ($10 == null) { - $$ = new Linq.Join (lt, cast, (Expression)$7, - (Expression)$9, loc); + Linq.Cast cast = new Linq.Cast ((FullNamedExpression)$2, (Expression)$6); + if ($13 == null) { + $$ = new Linq.Join (block, lt, cast, outer_selector, current_block.Toplevel, GetLocation ($1)); } else { - LocatedToken lt_into = (LocatedToken) $10; - $$ = new Linq.GroupJoin (lt, cast, (Expression)$7, - (Expression)$9, lt_into, loc); + $$ = new Linq.GroupJoin (block, lt, cast, outer_selector, current_block.Toplevel, + (LocatedToken) $13, GetLocation ($1)); } + + current_block.AddStatement (new ContextualReturn ((Expression) $12)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + if ($13 == null) + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); + else + ((Linq.QueryBlock)current_block).AddTransparentParameter ((LocatedToken) $13); } ; @@ -5431,65 +5626,83 @@ opt_join_into : /* empty */ | INTO IDENTIFIER { - $$ = $2; + $$ = $2; } ; orderby_clause - : ORDERBY orderings + : ORDERBY { - $$ = $2; + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + orderings + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + $$ = $3; } ; orderings : order_by - | order_by COMMA orderings_then_by + | order_by COMMA + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + orderings_then_by { - ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$3; + ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$4; $$ = $1; } ; orderings_then_by : then_by - { - $$ = $1; - } - | orderings_then_by COMMA then_by - { + | orderings_then_by COMMA + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + then_by + { ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$3; $$ = $1; - } + } ; order_by : expression { - $$ = new Linq.OrderByAscending ((Expression)$1); + $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1); } | expression ASCENDING { - $$ = new Linq.OrderByAscending ((Expression)$1); + $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1); } | expression DESCENDING { - $$ = new Linq.OrderByDescending ((Expression)$1); + $$ = new Linq.OrderByDescending (current_block.Toplevel, (Expression)$1); } ; then_by : expression { - $$ = new Linq.ThenByAscending ((Expression)$1); + $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); } | expression ASCENDING { - $$ = new Linq.ThenByAscending ((Expression)$1); + $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); } | expression DESCENDING { - $$ = new Linq.ThenByDescending ((Expression)$1); + $$ = new Linq.ThenByDescending (current_block.Toplevel, (Expression)$1); } ; @@ -5504,16 +5717,12 @@ opt_query_continuation current_block.SetEndLocation (GetLocation ($1)); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); - LocatedToken lt = (LocatedToken) $2; - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, - lt.Value, lt.Location); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, GetLocation ($1)); } query_body { - $$ = new Linq.QueryExpression ((LocatedToken) $2, - (Linq.AQueryClause)$4); + $$ = new Linq.QueryExpression (current_block, (Linq.AQueryClause)$4); } ; @@ -5547,7 +5756,7 @@ interactive_parsing Parameter [] mpar = new Parameter [1]; mpar [0] = new Parameter (TypeManager.system_object_expr, "$retval", Parameter.Modifier.REF, null, Location.Null); - Parameters pars = new Parameters (mpar); + ParametersCompiled pars = new ParametersCompiled (mpar); current_local_parameters = pars; Method method = new Method ( current_class, @@ -5562,7 +5771,7 @@ interactive_parsing ++lexer.parsing_block; start_block (lexer.Location); } - interactive_statement_list + interactive_statement_list opt_COMPLETE_COMPLETION { --lexer.parsing_block; Method method = (Method) oob_stack.Pop (); @@ -5586,6 +5795,16 @@ interactive_compilation_unit | global_attributes | /* nothing */ ; + +opt_COMPLETE_COMPLETION + : /* nothing */ + | COMPLETE_COMPLETION + ; + +close_brace_or_complete_completion + : CLOSE_BRACE + | COMPLETE_COMPLETION + ; %% // @@ -5981,16 +6200,20 @@ end_block (Location loc) } void -start_anonymous (bool lambda, Parameters parameters, Location loc) +start_anonymous (bool lambda, ParametersCompiled parameters, Location loc) { + if (RootContext.Version == LanguageVersion.ISO_1){ + Report.FeatureIsNotAvailable (loc, "anonymous methods"); + } + oob_stack.Push (current_anonymous_method); oob_stack.Push (current_local_parameters); current_local_parameters = parameters; current_anonymous_method = lambda - ? new LambdaExpression (parameters, loc) - : new AnonymousMethodExpression (parameters, loc); + ? new LambdaExpression (loc) + : new AnonymousMethodExpression (loc); // Force the next block to be created as a ToplevelBlock parsing_anonymous_method = true; @@ -6000,19 +6223,14 @@ start_anonymous (bool lambda, Parameters parameters, Location loc) * Completes the anonymous method processing, if lambda_expr is null, this * means that we have a Statement instead of an Expression embedded */ -AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block, Location loc) +AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block) { AnonymousMethodExpression retval; - if (RootContext.Version == LanguageVersion.ISO_1){ - Report.FeatureIsNotAvailable (loc, "anonymous methods"); - retval = null; - } else { - current_anonymous_method.Block = anon_block; - retval = current_anonymous_method; - } + current_anonymous_method.Block = anon_block; + retval = current_anonymous_method; - current_local_parameters = (Parameters) oob_stack.Pop (); + current_local_parameters = (ParametersCompiled) oob_stack.Pop (); current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop (); return retval; @@ -6027,15 +6245,23 @@ public NamespaceEntry CurrentNamespace { void Error_SyntaxError (int token) { - Error_SyntaxError (1525, token); + Error_SyntaxError (0, token); } void Error_SyntaxError (int error_code, int token) { string symbol = GetSymbolName (token); string expecting = GetExpecting (); + + if (error_code == 0) { + if (expecting == "`)'") + error_code = 1026; + else + error_code = 1525; + } + if (expecting != null) - Report.Error (error_code, lexer.Location, "Unexpected symbol `{0}', expecting {1}", + Report.Error (error_code, lexer.Location, "Unexpected symbol `{0}', expecting {1}", symbol, expecting); else Report.Error (error_code, lexer.Location, "Unexpected symbol `{0}'", symbol); @@ -6044,10 +6270,7 @@ void Error_SyntaxError (int error_code, int token) string GetExpecting () { int [] tokens = yyExpectingTokens (yyExpectingState); - if (tokens.Length == 1) - return "`" + GetTokenName (tokens [0]) + "'"; - - ArrayList names = new ArrayList (); + ArrayList names = new ArrayList (tokens.Length); bool has_type = false; bool has_identifier = false; for (int i = 0; i < tokens.Length; i++){ @@ -6064,7 +6287,7 @@ string GetExpecting () names.Add (name); } - + // // Too many tokens to enumerate // @@ -6074,6 +6297,9 @@ string GetExpecting () if (has_type && has_identifier) names.Remove ("identifier"); + if (names.Count == 1) + return "`" + GetTokenName (tokens [0]) + "'"; + StringBuilder sb = new StringBuilder (); names.Sort (); int count = names.Count; @@ -6134,6 +6360,74 @@ string GetSymbolName (int token) return "ushort"; case Token.OBJECT: return "object"; + + case Token.PLUS: + return "+"; + case Token.UMINUS: + case Token.MINUS: + return "-"; + case Token.BANG: + return "!"; + case Token.BITWISE_AND: + return "&"; + case Token.BITWISE_OR: + return "|"; + case Token.STAR: + return "*"; + case Token.PERCENT: + return "%"; + case Token.DIV: + return "/"; + case Token.CARRET: + return "^"; + case Token.OP_INC: + return "++"; + case Token.OP_DEC: + return "--"; + case Token.OP_SHIFT_LEFT: + return "<<"; + case Token.OP_SHIFT_RIGHT: + return ">>"; + case Token.OP_LT: + return "<"; + case Token.OP_GT: + return ">"; + case Token.OP_LE: + return "<="; + case Token.OP_GE: + return ">="; + case Token.OP_EQ: + return "=="; + case Token.OP_NE: + return "!="; + case Token.OP_AND: + return "&&"; + case Token.OP_OR: + return "||"; + case Token.OP_PTR: + return "->"; + case Token.OP_COALESCING: + return "??"; + case Token.OP_MULT_ASSIGN: + return "*="; + case Token.OP_DIV_ASSIGN: + return "/="; + case Token.OP_MOD_ASSIGN: + return "%="; + case Token.OP_ADD_ASSIGN: + return "+="; + case Token.OP_SUB_ASSIGN: + return "-="; + case Token.OP_SHIFT_LEFT_ASSIGN: + return "<<="; + case Token.OP_SHIFT_RIGHT_ASSIGN: + return ">>="; + case Token.OP_AND_ASSIGN: + return "&="; + case Token.OP_XOR_ASSIGN: + return "^="; + case Token.OP_OR_ASSIGN: + return "|="; } return GetTokenName (token); @@ -6271,12 +6565,13 @@ static string GetTokenName (int token) case Token.WHILE: return "while"; case Token.ARGLIST: - return "arglist"; + return "__arglist"; case Token.PARTIAL: return "partial"; case Token.ARROW: return "=>"; case Token.FROM: + case Token.FROM_FIRST: return "from"; case Token.JOIN: return "join"; @@ -6312,14 +6607,10 @@ static string GetTokenName (int token) return "["; case Token.CLOSE_BRACKET: return "]"; - case Token.DEFAULT_OPEN_PARENS: + case Token.OPEN_PARENS_CAST: case Token.OPEN_PARENS_LAMBDA: case Token.OPEN_PARENS: return "("; - case Token.CLOSE_PARENS_CAST: - case Token.CLOSE_PARENS_NO_CAST: - case Token.CLOSE_PARENS_OPEN_PARENS: - case Token.CLOSE_PARENS_MINUS: case Token.CLOSE_PARENS: return ")"; case Token.DOT: @@ -6359,8 +6650,6 @@ static string GetTokenName (int token) case Token.OP_OR: case Token.OP_PTR: case Token.OP_COALESCING: - return ""; - case Token.OP_MULT_ASSIGN: case Token.OP_DIV_ASSIGN: case Token.OP_MOD_ASSIGN: @@ -6421,10 +6710,9 @@ static string GetTokenName (int token) case Token.EVAL_COMPILATION_UNIT_PARSER: case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER: case Token.EVAL_STATEMENT_PARSER: - case Token.LOWPREC: - case Token.QUERY_LAST_TOKEN: - case Token.QUERY_FIRST_TOKEN: - case Token.LAST_KEYWORD: + case Token.LAST_KEYWORD: + case Token.GENERATE_COMPLETION: + case Token.COMPLETE_COMPLETION: return ""; // A bit more robust.