2009-06-23 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / cs-parser.jay
index 303dd4a7dd604bcd15cd786fdde7b1db9c23a5c0..e7390c8dfbf638f7c8efb409b77249564ef35c81 100644 (file)
@@ -767,7 +767,7 @@ attribute
          {
                ++lexer.parsing_block;
          }
-        opt_attribute_arguments
+         opt_attribute_arguments
          {
                --lexer.parsing_block;
                MemberName mname = (MemberName) $1;
@@ -807,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
@@ -1323,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 = (ParametersCompiled) $7;
+               current_local_parameters = (ParametersCompiled) $8;
 
-               if ($9 != null && name.TypeArguments == null)
+               if ($10 != null && name.TypeArguments == null)
                        Report.Error (80, lexer.Location,
                                      "Constraints are not allowed on non-generic declarations");
 
@@ -1344,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;
@@ -1363,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,
@@ -1571,7 +1566,9 @@ fixed_parameter
                        Report.Error (1065, GetLocation ($6), "Optional parameter is not valid in this context");
                
                LocatedToken lt = (LocatedToken) $4;
-               $$ = new Parameter ((FullNamedExpression) $3, lt.Value, mod, (Attributes) $1, (Expression) $6, lt.Location);
+               $$ = new Parameter ((FullNamedExpression) $3, lt.Value, mod, (Attributes) $1, lt.Location);
+               if ($6 != null)
+                       ((Parameter) $$).DefaultValue = (Expression) $6;
          }
        ;
 
@@ -2408,9 +2405,7 @@ indexer_declaration
                } else if (indexer_parameters.Count == 1) {
                        Parameter p = indexer_parameters [0];
                        if (p.HasDefaultValue)
-                               Report.Warning (1066, 1, p.Location,
-                                       "The default value specified for optional parameter 'i' will never be used",
-                                       p.Name);
+                               p.Warning_UselessOptionalParameter ();
                }
 
                if (RootContext.Documentation != null) {
@@ -3208,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;
          }
@@ -3226,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
@@ -3249,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
@@ -5863,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 `;'");
@@ -5889,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){
@@ -6084,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 {