X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fmcs%2Fcs-parser.jay;h=e7390c8dfbf638f7c8efb409b77249564ef35c81;hb=24b2c4de33c81f823f3da28ccf5a8e12f560820d;hp=82665c5e9d1b92c107b51f89c22c0e58908ec6ab;hpb=fe299b5e94c87f6c6a995863fa05cc4276e200ed;p=mono.git diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index 82665c5e9d1..e7390c8dfbf 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; @@ -229,6 +232,7 @@ namespace Mono.CSharp %token PARTIAL %token ARROW %token FROM +%token FROM_FIRST %token JOIN %token ON %token EQUALS @@ -326,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 @@ -343,7 +361,6 @@ namespace Mono.CSharp %left OPEN_PARENS %left OPEN_BRACKET OPEN_BRACE %left DOT -%nonassoc HIGHPREC %start compilation_unit %% @@ -353,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 @@ -637,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); @@ -668,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); @@ -750,7 +767,7 @@ attribute { ++lexer.parsing_block; } - opt_attribute_arguments + opt_attribute_arguments { --lexer.parsing_block; MemberName mname = (MemberName) $1; @@ -790,78 +807,68 @@ opt_attribute_arguments attribute_arguments - : opt_positional_argument_list + : /* empty */ { $$ = null; } + | positional_or_named_argument { - if ($1 == null) - $$ = null; - else { - $$ = new object [] { $1, null }; - } + ArrayList a = new ArrayList (4); + a.Add ($1); + $$ = new object [] { a, null }; } - | positional_argument_list COMMA named_argument_list + | named_attribute_argument { - $$ = new object[] { $1, $3 }; + ArrayList a = new ArrayList (4); + a.Add ($1); + $$ = new object [] { null, a }; } - | named_argument_list + | attribute_arguments COMMA positional_or_named_argument { - $$ = new object [] { null, $1 }; - } - ; - - -opt_positional_argument_list - : /* empty */ { $$ = null; } - | positional_argument_list - ; - -positional_argument_list - : expression - { - ArrayList args = new ArrayList (4); - args.Add (new Argument ((Expression) $1, Argument.AType.Expression)); - - $$ = args; + object[] o = (object[]) $1; + if (o [1] != null) { + Report.Error (1016, ((Argument) $3).Expr.Location, "Named attribute arguments must appear after the positional arguments"); + o [0] = new ArrayList (4); + } + + ArrayList args = ((ArrayList) o [0]); + if (args.Count > 0 && !($3 is NamedArgument) && args [args.Count - 1] is NamedArgument) + Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]); + + args.Add ($3); } - | positional_argument_list COMMA expression - { - ArrayList args = (ArrayList) $1; - args.Add (new Argument ((Expression) $3, Argument.AType.Expression)); - - $$ = args; - } - ; - -named_argument_list - : named_argument + | attribute_arguments COMMA named_attribute_argument { - ArrayList args = new ArrayList (4); - args.Add ($1); + object[] o = (object[]) $1; + if (o [1] == null) { + o [1] = new ArrayList (4); + } - $$ = args; + ((ArrayList) o [1]).Add ($3); } - | named_argument_list COMMA named_argument - { - ArrayList args = (ArrayList) $1; - args.Add ($3); + ; - $$ = args; - } - | named_argument_list COMMA expression +positional_or_named_argument + : expression { - Report.Error (1016, ((Expression) $3).Location, "Named attribute argument expected"); - $$ = null; + $$ = new Argument ((Expression) $1); } + | named_argument ; -named_argument +named_attribute_argument : IDENTIFIER ASSIGN expression { - // FIXME: keep location - $$ = new DictionaryEntry ( - ((LocatedToken) $1).Value, - new Argument ((Expression) $3, Argument.AType.Expression)); + $$ = new NamedArgument ((LocatedToken) $1, (Expression) $3); } ; + +named_argument + : IDENTIFIER COLON expression + { + if (RootContext.Version <= LanguageVersion.V_3) + Report.FeatureIsNotAvailable (GetLocation ($1), "named argument"); + + $$ = new NamedArgument ((LocatedToken) $1, (Expression) $3); + } + ; class_body @@ -895,6 +902,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; } ; @@ -1275,7 +1283,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, @@ -1305,18 +1313,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"); @@ -1326,7 +1339,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; @@ -1345,7 +1358,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, @@ -1368,9 +1381,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 (); @@ -1385,12 +1398,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; @@ -1403,14 +1416,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 { @@ -1420,7 +1433,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 { @@ -1430,7 +1443,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 { @@ -1456,11 +1469,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); } ; @@ -1468,17 +1481,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; @@ -1506,16 +1525,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 @@ -1523,11 +1537,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 @@ -1592,10 +1634,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; @@ -1605,7 +1654,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 @@ -1730,7 +1779,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; @@ -1762,9 +1811,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); } @@ -1929,15 +1978,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) { @@ -2004,14 +2053,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 (); @@ -2022,14 +2071,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 (); @@ -2077,10 +2126,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 @@ -2147,7 +2198,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; } ; @@ -2159,8 +2210,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){ @@ -2168,15 +2221,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; } ; @@ -2219,7 +2273,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))); @@ -2344,10 +2398,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 (); @@ -2372,7 +2431,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) @@ -2546,7 +2605,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); @@ -2580,7 +2639,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; @@ -2622,7 +2683,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; @@ -2630,21 +2693,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; } ; @@ -2722,7 +2785,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; @@ -2732,23 +2797,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 { @@ -2817,8 +2882,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 (); @@ -2923,6 +2987,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 @@ -2996,6 +3064,10 @@ parenthesized_expression { $$ = new ParenthesizedExpression ((Expression) $2); } + | OPEN_PARENS expression COMPLETE_COMPLETION + { + $$ = new ParenthesizedExpression ((Expression) $2); + } ; member_access @@ -3017,6 +3089,22 @@ member_access $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); } + | primary_expression DOT GENERATE_COMPLETION { + $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3)); + } + | primary_expression DOT IDENTIFIER GENERATE_COMPLETION { + LocatedToken lt = (LocatedToken) $3; + $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); + } + | predefined_type DOT GENERATE_COMPLETION + { + // TODO: Location is wrong as some predefined types doesn't hold a location + $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location); + } + | predefined_type DOT IDENTIFIER GENERATE_COMPLETION { + LocatedToken lt = (LocatedToken) $3; + $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); + } ; invocation_expression @@ -3032,12 +3120,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 { @@ -3054,7 +3142,7 @@ opt_member_initializer_list ; member_initializer_list - : member_initializer + : member_initializer { ArrayList a = new ArrayList (); a.Add ($1); @@ -3074,9 +3162,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 { @@ -3108,6 +3203,9 @@ argument_list | argument_list COMMA argument { ArrayList list = (ArrayList) $1; + if (!($3 is NamedArgument) && list [list.Count - 1] is NamedArgument) + Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]); + list.Add ($3); $$ = list; } @@ -3126,12 +3224,10 @@ argument_list argument : expression { - $$ = new Argument ((Expression) $1, Argument.AType.Expression); + $$ = new Argument ((Expression) $1); } | non_simple_argument - { - $$ = $1; - } + | named_argument ; non_simple_argument @@ -3149,21 +3245,20 @@ non_simple_argument Argument[] args = new Argument [list.Count]; list.CopyTo (args, 0); - Expression expr = new Arglist (args, (Location) $1); - $$ = new Argument (expr, Argument.AType.Expression); + $$ = new Argument (new Arglist (args, (Location) $1)); } | ARGLIST open_parens_any CLOSE_PARENS { - $$ = new Argument (new Arglist ((Location) $1), Argument.AType.Expression); + $$ = new Argument (new Arglist ((Location) $1)); } | ARGLIST { - $$ = new Argument (new ArglistAccess ((Location) $1), Argument.AType.ArgList); + $$ = new Argument (new ArglistAccess ((Location) $1)); } ; variable_reference - : expression { note ("section 5.4"); $$ = $1; } + : expression ; element_access @@ -3256,56 +3351,69 @@ post_decrement_expression ; object_or_delegate_creation_expression - : NEW simple_type open_parens_any 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)); @@ -3493,13 +3601,7 @@ typeof_expression typeof_type_expression : type_and_void - { - $$ = $1; - } | unbound_type_name - { - $$ = new UnboundTypeExpression ((MemberName)$1, lexer.Location); - } | error { Error_TypeExpected (lexer.Location); @@ -3511,41 +3613,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; } ; @@ -3594,7 +3701,7 @@ 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 { @@ -3603,18 +3710,21 @@ anonymous_method_expression ; 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; } ; @@ -3645,11 +3755,11 @@ unary_expression cast_expression : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression { - $$ = new Cast ((Expression) $2, (Expression) $4, GetLocation ($1)); + $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); } | OPEN_PARENS predefined_type CLOSE_PARENS prefixed_unary_expression { - $$ = new Cast ((Expression) $2, (Expression) $4, GetLocation ($1)); + $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); } ; @@ -3826,29 +3936,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); } ; @@ -3951,10 +4055,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))); } ; @@ -3978,7 +4082,7 @@ lambda_expression { LocatedToken lt = (LocatedToken) $1; Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); - start_anonymous (true, new Parameters (p), GetLocation ($1)); + start_anonymous (true, new ParametersCompiled (p), GetLocation ($1)); } lambda_expression_body { @@ -3986,7 +4090,7 @@ lambda_expression } | OPEN_PARENS_LAMBDA opt_lambda_parameter_list CLOSE_PARENS ARROW { - start_anonymous (true, (Parameters) $2, GetLocation ($1)); + start_anonymous (true, (ParametersCompiled) $2, GetLocation ($1)); } lambda_expression_body { @@ -3995,8 +4099,8 @@ lambda_expression ; expression - : assignment_expression - | non_assignment_expression + : assignment_expression + | non_assignment_expression ; non_assignment_expression @@ -4173,6 +4277,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) // @@ -4192,13 +4323,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 { @@ -4388,8 +4532,7 @@ 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; @@ -4484,10 +4627,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; } ; // @@ -4497,13 +4642,10 @@ 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 (); + ((Expression) $1).Error_InvalidExpressionStatement (); + s = EmptyExpressionStatement.Instance; } $$ = new StatementExpression (s); @@ -5183,18 +5325,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); @@ -5203,42 +5350,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); } ; @@ -5261,13 +5427,38 @@ query_body ; select_or_group_clause - : SELECT expression + : SELECT { - $$ = new Linq.Select ((Expression)$2, GetLocation ($1)); + current_block = new Linq.QueryBlock (current_block, lexer.Location); } - | GROUP expression BY expression + expression { - $$ = new Linq.GroupBy ((Expression)$2, (Expression)$4, GetLocation ($1)); + $$ = 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 + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + BY expression + { + $$ = 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; } ; @@ -5294,54 +5485,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); + } + 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); } - | JOIN type IDENTIFIER IN expression ON expression EQUALS expression opt_join_into + 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); } ; @@ -5349,65 +5616,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); } ; @@ -5422,16 +5707,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); } ; @@ -5465,7 +5746,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, @@ -5480,7 +5761,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 (); @@ -5504,6 +5785,16 @@ interactive_compilation_unit | global_attributes | /* nothing */ ; + +opt_COMPLETE_COMPLETION + : /* nothing */ + | COMPLETE_COMPLETION + ; + +close_brace_or_complete_completion + : CLOSE_BRACE + | COMPLETE_COMPLETION + ; %% // @@ -5567,7 +5858,7 @@ struct OperatorDeclaration { } } -void Error_ExpectingTypeName (Expression expr) +static void Error_ExpectingTypeName (Expression expr) { if (expr is Invocation){ Report.Error (1002, expr.Location, "Expecting `;'"); @@ -5593,6 +5884,11 @@ static void Error_TypeExpected (Location loc) Report.Error (1031, loc, "Type expected"); } +static void Error_NamedArgumentExpected (NamedArgument a) +{ + Report.Error (1738, a.Name.Location, "Named arguments must appear after the positional arguments"); +} + void push_current_class (TypeContainer tc, object partial_token) { if (RootContext.EvalMode){ @@ -5788,11 +6084,6 @@ void syntax_error (Location l, string msg) Report.Error (1003, l, "Syntax error, " + msg); } -void note (string s) -{ - // Used to put annotations -} - Tokenizer lexer; public Tokenizer Lexer { @@ -5899,7 +6190,7 @@ 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"); @@ -5911,8 +6202,8 @@ start_anonymous (bool lambda, Parameters parameters, Location loc) 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; @@ -5929,7 +6220,7 @@ AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block) 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; @@ -6264,12 +6555,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"; @@ -6408,8 +6700,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.LAST_KEYWORD: + case Token.LAST_KEYWORD: + case Token.GENERATE_COMPLETION: + case Token.COMPLETE_COMPLETION: return ""; // A bit more robust.