2005-11-07 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / gmcs / cs-parser.jay
index 907d06b395bb4085230ef232acf8286660016c7b..125e65d57e580dac4396a9131bdc8c9a8c23962d 100644 (file)
@@ -315,10 +315,31 @@ outer_declarations
         ;
  
 outer_declaration
-        : using_directive
+       : extern_alias_directive
+        | using_directive 
         | namespace_member_declaration
         ;
-  
+
+extern_alias_directives
+       : extern_alias_directive
+       | extern_alias_directives extern_alias_directive;
+
+extern_alias_directive
+       : EXTERN IDENTIFIER IDENTIFIER SEMICOLON
+         {
+               LocatedToken lt = (LocatedToken) $2;
+               string s = lt.Value;
+               if (s != "alias"){
+                       Report.Error (1003, lt.Location, "'alias' expected");
+               } else if (RootContext.Version == LanguageVersion.ISO_1) {
+                       Report.FeatureIsNotStandardized (lt.Location, "external alias");
+               } else {
+                       lt = (LocatedToken) $3; 
+                       current_namespace.UsingExternalAlias (lt.Value, lt.Location);
+               }
+         }
+       ;
 using_directives
        : using_directive 
        | using_directives using_directive
@@ -343,6 +364,7 @@ using_alias_directive
          {
                LocatedToken lt = (LocatedToken) $2;
                current_namespace.UsingAlias (lt.Value, (MemberName) $4, (Location) $1);
+               current_namespace.UsingFound = true;
          }
        | USING error {
                CheckIdentifierToken (yyToken, GetLocation ($2));
@@ -353,6 +375,7 @@ using_namespace_directive
        : USING namespace_name SEMICOLON 
          {
                current_namespace.Using ((MemberName) $2, (Location) $1);
+               current_namespace.UsingFound = true;
           }
        ;
 
@@ -409,6 +432,7 @@ namespace_body
                if (RootContext.Documentation != null)
                        Lexer.doc_state = XmlCommentState.Allowed;
          }
+         opt_extern_alias_directives
          opt_using_directives
          opt_namespace_member_declarations
          CLOSE_BRACE
@@ -419,6 +443,11 @@ opt_using_directives
        | using_directives
        ;
 
+opt_extern_alias_directives
+       : /* empty */
+       | extern_alias_directives
+       ;
+
 opt_namespace_member_declarations
        : /* empty */
        | namespace_member_declarations
@@ -977,6 +1006,11 @@ fixed_variable_declarator
          {
                $$ = new VariableDeclaration ((LocatedToken) $1, $3);
          }
+       | IDENTIFIER OPEN_BRACKET CLOSE_BRACKET
+         {
+               Report.Error (443, lexer.Location, "Value or constant expected");
+               $$ = new VariableDeclaration ((LocatedToken) $1, null);
+         }
        ;
 
 variable_declarators
@@ -1093,7 +1127,8 @@ method_header
 
                GenericMethod generic = null;
                if (name.TypeArguments != null) {
-                       generic = new GenericMethod (current_namespace, current_class, name);
+                       generic = new GenericMethod (current_namespace, current_class, name,
+                                                    (Expression) $3, (Parameters) $6);
 
                        generic.SetParameterInfo ((ArrayList) $9);
                }
@@ -1128,7 +1163,8 @@ method_header
                Method method;
                GenericMethod generic = null;
                if (name.TypeArguments != null) {
-                       generic = new GenericMethod (current_namespace, current_class, name);
+                       generic = new GenericMethod (current_namespace, current_class, name,
+                                                    TypeManager.system_void_expr, (Parameters) $6);
 
                        generic.SetParameterInfo ((ArrayList) $9);
                }
@@ -1706,7 +1742,8 @@ interface_method_declaration
 
                GenericMethod generic = null;
                if (name.TypeArguments != null) {
-                       generic = new GenericMethod (current_namespace, current_class, name);
+                       generic = new GenericMethod (current_namespace, current_class, name,
+                                                    (Expression) $3, (Parameters) $6);
 
                        generic.SetParameterInfo ((ArrayList) $9);
                }
@@ -1734,7 +1771,8 @@ interface_method_declaration
 
                GenericMethod generic = null;
                if (name.TypeArguments != null) {
-                       generic = new GenericMethod (current_namespace, current_class, name);
+                       generic = new GenericMethod (current_namespace, current_class, name,
+                                                    TypeManager.system_void_expr, (Parameters) $6);
 
                        generic.SetParameterInfo ((ArrayList) $9);
                }
@@ -1752,34 +1790,52 @@ interface_property_declaration
          type IDENTIFIER 
          OPEN_BRACE 
          { lexer.PropertyParsing = true; }
-         interface_accessors 
-         { lexer.PropertyParsing = false; }
+         accessor_declarations 
+         {
+               has_get = has_set = false; 
+               lexer.PropertyParsing = false;
+         }
          CLOSE_BRACE
          {
                LocatedToken lt = (LocatedToken) $4;
                MemberName name = new MemberName (lt.Value, lt.Location);
 
                if ($3 == TypeManager.system_void_expr) {
-                       Report.Error (547, lt.Location, "`{0}': property or indexer cannot have void type", $4);
+                       Report.Error (547, lt.Location, "`{0}': property or indexer cannot have void type", lt.Value);
                        break;
                }
 
+               Property p = null;
                if ($7 == null) {
-                       Property p = new Property (current_class, (Expression) $3, (int) $2, true,
+                       p = new Property (current_class, (Expression) $3, (int) $2, true,
                                   name, (Attributes) $1,
                                   null, null);
 
-                       Report.Error (548, lexer.Location, "`{0}': property or indexer must have at least one accessor", p.GetSignatureForError ());
+                       Report.Error (548, p.Location, "`{0}': property or indexer must have at least one accessor", p.GetSignatureForError ());
                        break;
                }
 
-                InterfaceAccessorInfo pinfo = (InterfaceAccessorInfo) $7;
-
-               $$ = new Property (current_class, (Expression) $3, (int) $2, true,
+               Pair pair = (Pair) $7;
+               p = new Property (current_class, (Expression) $3, (int) $2, true,
                                   name, (Attributes) $1,
-                                  pinfo.Get, pinfo.Set);
+                                  (Accessor)pair.First, (Accessor)pair.Second);
+
+               if (pair.First != null && ((Accessor)(pair.First)).Block != null) {
+                       Report.Error (531, p.Location, "`{0}.get': interface members cannot have a definition", p.GetSignatureForError ());
+                       $$ = null;
+                       break;
+               }
+
+               if (pair.Second != null && ((Accessor)(pair.Second)).Block != null) {
+                       Report.Error (531, p.Location, "`{0}.set': interface members cannot have a definition", p.GetSignatureForError ());
+                       $$ = null;
+                       break;
+               }
+
                if (RootContext.Documentation != null)
-                       ((Property) $$).DocComment = Lexer.consume_doc_comment ();
+                       p.DocComment = Lexer.consume_doc_comment ();
+
+               $$ = p;
          }
        | opt_attributes
          opt_new
@@ -1789,33 +1845,6 @@ interface_property_declaration
          }
        ;
 
-interface_accessors
-       : opt_attributes opt_modifiers GET SEMICOLON    
-         { 
-               $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null, (int) $2, 0, (Location) $3, (Location) $3); 
-         }
-       | opt_attributes opt_modifiers GET OPEN_BRACE
-         {  
-               Report.Error (531, (Location) $3, "`{0}': interface members cannot have a definition", ".get");
-               $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null, (int) $2, 0, (Location) $3, (Location) $3);
-         }
-       | opt_attributes opt_modifiers SET SEMICOLON            
-         { 
-               $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1, 0, (int) $2, (Location) $3, (Location) $3); 
-         }
-       | opt_attributes opt_modifiers GET SEMICOLON opt_attributes opt_modifiers SET SEMICOLON 
-         { 
-               $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $5, (int) $2, (int) $6, (Location) $3, (Location) $7); 
-         }
-       | opt_attributes opt_modifiers SET SEMICOLON opt_attributes opt_modifiers GET SEMICOLON
-         { 
-               $$ = new InterfaceAccessorInfo (true, true, (Attributes) $5, (Attributes) $1, (int) $6, (int) $2, (Location) $3, (Location) $3); 
-         }
-       |
-         {
-               $$ = null;
-         }
-       ;
 
 interface_event_declaration
        : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
@@ -1832,7 +1861,8 @@ interface_event_declaration
                $$ = null;
          }
        | opt_attributes opt_new EVENT type IDENTIFIER ASSIGN  {
-               Report.Error (68, (Location) $3, "`{0}.{1}': event in interface cannot have initializer", current_container.Name, $5);
+               LocatedToken lt = (LocatedToken) $5;
+               Report.Error (68, lt.Location, "`{0}.{1}': event in interface cannot have initializer", current_container.Name, lt.Value);
                $$ = null;
          }
        | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE
@@ -1854,28 +1884,46 @@ interface_indexer_declaration
          OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
          OPEN_BRACE 
          { lexer.PropertyParsing = true; }
-         interface_accessors 
-         { lexer.PropertyParsing = false; }
+         accessor_declarations 
+         { 
+               has_get = has_set = false;
+               lexer.PropertyParsing = false;
+         }
          CLOSE_BRACE
          {
+               Indexer i = null;
                if ($10 == null) {
-                       Indexer i = new Indexer (current_class, (Expression) $3,
+                       i = new Indexer (current_class, (Expression) $3,
                                  new MemberName (TypeContainer.DefaultIndexerName, (Location) $4),
                                  (int) $2, true, (Parameters) $6, (Attributes) $1,
                                  null, null);
 
-                       Report.Error (548, lexer.Location, "`{0}': property or indexer must have at least one accessor", i.GetSignatureForError ());
+                       Report.Error (548, i.Location, "`{0}': property or indexer must have at least one accessor", i.GetSignatureForError ());
                        break;
                }
 
-               InterfaceAccessorInfo info = (InterfaceAccessorInfo) $10;
-
-               $$ = new Indexer (current_class, (Expression) $3,
+               Pair pair = (Pair) $10;
+               i = new Indexer (current_class, (Expression) $3,
                                  new MemberName (TypeContainer.DefaultIndexerName, (Location) $4),
                                  (int) $2, true, (Parameters) $6, (Attributes) $1,
-                                 info.Get, info.Set);
+                                  (Accessor)pair.First, (Accessor)pair.Second);
+
+               if (pair.First != null && ((Accessor)(pair.First)).Block != null) {
+                       Report.Error (531, i.Location, "`{0}.get': interface members cannot have a definition", i.GetSignatureForError ());
+                       $$ = null;
+                       break;
+               }
+
+               if (pair.Second != null && ((Accessor)(pair.Second)).Block != null) {
+                       Report.Error (531, i.Location, "`{0}.set': interface members cannot have a definition", i.GetSignatureForError ());
+                       $$ = null;
+                       break;
+               }
+
                if (RootContext.Documentation != null)
-                       ((Indexer) $$).DocComment = ConsumeStoredComment ();
+                       i.DocComment = ConsumeStoredComment ();
+
+               $$ = i;
          }
        ;
 
@@ -2484,11 +2532,16 @@ enum_declaration
                if (RootContext.Documentation != null)
                        e.DocComment = enumTypeComment;
 
+
+               EnumMember em = null;
                foreach (VariableDeclaration ev in (ArrayList) $8) {
-                       e.AddEnumMember (ev.identifier, 
-                                        (Expression) ev.expression_or_array_initializer,
-                                        ev.Location, ev.OptAttributes,
-                                        ev.DocComment);
+                       em = new EnumMember (e, em, (Expression) ev.expression_or_array_initializer,
+                               new MemberName (ev.identifier, ev.Location), ev.OptAttributes);
+
+//                     if (RootContext.Documentation != null)
+                               em.DocComment = ev.DocComment;
+
+                       e.AddEnumMember (em);
                }
 
                current_container.AddEnum (e);
@@ -2606,7 +2659,7 @@ delegate_declaration
          }
          SEMICOLON
          {
-               current_delegate.SetParameterInfo ((ArrayList) $10);
+               current_delegate.SetParameterInfo ((ArrayList) $11);
                $$ = current_delegate;
 
                current_delegate = null;
@@ -2651,10 +2704,14 @@ opt_type_argument_list
        | OP_GENERICS_LT type_arguments OP_GENERICS_GT
          {
                $$ = $2;
+               if (RootContext.Version == LanguageVersion.ISO_1)
+                       Report.FeatureIsNotStandardized (lexer.Location, "generics");
          }
        | GENERIC_DIMENSION
          {
                $$ = new TypeArguments ((int) $1, lexer.Location);
+               if (RootContext.Version == LanguageVersion.ISO_1)
+                       Report.FeatureIsNotStandardized (lexer.Location, "generics");
          }
        ;
 
@@ -2703,7 +2760,7 @@ pointer_type
                // can't perform checks during this phase - we do it during
                // semantic analysis.
                //
-               $$ = new ComposedCast ((Expression) $1, "*");
+               $$ = new ComposedCast ((Expression) $1, "*", Lexer.Location);
          }
        | VOID STAR
          {
@@ -2719,11 +2776,17 @@ non_expression_type
          }
        | non_expression_type rank_specifier
          {
-               $$ = new ComposedCast ((Expression) $1, (string) $2);
+               Location loc = GetLocation ($1);
+               if (loc.IsNull)
+                       loc = lexer.Location;
+               $$ = new ComposedCast ((Expression) $1, (string) $2, loc);
          }
        | non_expression_type STAR
          {
-               $$ = new ComposedCast ((Expression) $1, "*");
+               Location loc = GetLocation ($1);
+               if (loc.IsNull)
+                       loc = lexer.Location;
+               $$ = new ComposedCast ((Expression) $1, "*", loc);
          }
        | expression rank_specifiers 
          {
@@ -2840,15 +2903,15 @@ literal
        : boolean_literal
        | integer_literal
        | real_literal
-       | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value); }
-       | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value); }
-       | NULL                  { $$ = NullLiteral.Null; }
+       | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value, lexer.Location); }
+       | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value, lexer.Location); } 
+       | NULL                  { $$ = new NullLiteral (lexer.Location); }
        ;
 
 real_literal
-       : LITERAL_FLOAT         { $$ = new FloatLiteral ((float) lexer.Value); }
-       | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value); }
-       | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value); }
+       : LITERAL_FLOAT         { $$ = new FloatLiteral ((float) lexer.Value, lexer.Location); }
+       | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value, lexer.Location); }
+       | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value, lexer.Location); }
        ;
 
 integer_literal
@@ -2856,28 +2919,21 @@ integer_literal
                object v = lexer.Value;
 
                if (v is int){
-                       int i = (int) v;
-
-                       if (i == 0)
-                               $$ = IntLiteral.Zero;
-                       else if (i == 1)
-                               $$ = IntLiteral.One;
-                       else
-                               $$ = new IntLiteral (i);
+                       $$ = new IntLiteral ((int) v, lexer.Location);
                } else if (v is uint)
-                       $$ = new UIntLiteral ((UInt32) v);
+                       $$ = new UIntLiteral ((UInt32) v, lexer.Location);
                else if (v is long)
-                       $$ = new LongLiteral ((Int64) v);
+                       $$ = new LongLiteral ((Int64) v, lexer.Location);
                else if (v is ulong)
-                       $$ = new ULongLiteral ((UInt64) v);
+                       $$ = new ULongLiteral ((UInt64) v, lexer.Location);
                else
                        Console.WriteLine ("OOPS.  Unexpected result from scanner");
          }
        ;
 
 boolean_literal
-       : TRUE                  { $$ = new BoolLiteral (true); }
-       | FALSE                 { $$ = new BoolLiteral (false); }
+       : TRUE                  { $$ = new BoolLiteral (true, lexer.Location); }
+       | FALSE                 { $$ = new BoolLiteral (false, lexer.Location); }
        ;
 
 parenthesized_expression_0
@@ -3426,7 +3482,8 @@ cast_expression
        : cast_list
        | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
          {
-               $$ = new Cast ((Expression) $2, (Expression) $4);
+               // TODO: wrong location
+               $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
          }
        ;
 
@@ -4088,7 +4145,7 @@ local_variable_type
                if ((string) $2 == "")
                        $$ = $1;
                else
-                       $$ = new ComposedCast ((Expression) $1, (string) $2);
+                       $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
          }
         ;
 
@@ -4106,7 +4163,7 @@ local_variable_pointer_type
          }
         | builtin_types STAR
          {
-               $$ = new ComposedCast ((Expression) $1, "*");
+               $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
          }
         | VOID STAR
          {
@@ -4194,7 +4251,8 @@ if_statement
 
                $$ = new If ((Expression) $3, (Statement) $5, l);
 
-               if (RootContext.WarningLevel >= 4){
+               if (RootContext.WarningLevel >= 3){
+                       // FIXME: location for warning should be loc property of $5.
                        if ($5 == EmptyStatement.Value)
                                Report.Warning (642, l, "Possible mistaken empty statement");
                }
@@ -4206,6 +4264,14 @@ if_statement
                Location l = (Location) $1;
 
                $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7, l);
+
+               if (RootContext.WarningLevel >= 3){
+                       // FIXME: location for warning should be loc property of $5 and $7.
+                       if ($5 == EmptyStatement.Value)
+                               Report.Warning (642, l, "Possible mistaken empty statement");
+                       if ($7 == EmptyStatement.Value)
+                               Report.Warning (642, l, "Possible mistaken empty statement");
+               }
          }
        ;
 
@@ -4310,11 +4376,6 @@ while_statement
          {
                Location l = (Location) $1;
                $$ = new While ((Expression) $3, (Statement) $5, l);
-       
-               if (RootContext.WarningLevel >= 4){
-                       if ($5 == EmptyStatement.Value)
-                               Report.Warning (642, l, "Possible mistaken empty statement");
-               }
          }
        ;
 
@@ -4385,11 +4446,6 @@ for_statement
 
                For f = new For ((Statement) $5, (Expression) $6, (Statement) $8, (Statement) $10, l);
 
-               if (RootContext.WarningLevel >= 4){
-                       if ($10 == EmptyStatement.Value)
-                               Report.Warning (642, (Location) $4, "Possible mistaken empty statement");
-               }
-
                current_block.AddStatement (f);
                while (current_block.Implicit)
                        current_block = current_block.Parent;
@@ -4775,11 +4831,6 @@ fixed_statement
 
                Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
 
-               if (RootContext.WarningLevel >= 4){
-                       if ($7 == EmptyStatement.Value)
-                               Report.Warning (642, l, "Possible mistaken empty statement");
-               }
-
                current_block.AddStatement (f);
                while (current_block.Implicit)
                        current_block = current_block.Parent;
@@ -4925,25 +4976,6 @@ public class VariableDeclaration {
        }
 }
 
-/// <summary>
-///  Used to pass around interface property information
-/// </summary>
-public class InterfaceAccessorInfo {
-
-        public readonly Accessor Get, Set;
-
-        public InterfaceAccessorInfo (bool has_get, bool has_set,
-                                      Attributes get_attrs, Attributes set_attrs, int get_mod, int set_mod, Location get_loc, Location set_loc)
-        {
-               if (has_get)
-                       Get = new Accessor (null, get_mod, get_attrs, get_loc);
-               if (has_set)
-                       Set = new Accessor (null, set_mod, set_attrs, set_loc);
-        }
-
-}
-
-
 // <summary>
 //   A class used to hold info about an indexer declarator
 // </summary>
@@ -5011,7 +5043,7 @@ void Error_ExpectingTypeName (Expression expr)
        if (expr is Invocation){
                Report.Error (1002, expr.Location, "Expecting `;'");
        } else {
-               Report.Error (-1, expr.Location, "Invalid Type definition");
+               Report.Error (201, expr.Location, "Only assignment, call, increment, decrement, and new object expressions can be used as a statement");
        }
 }