Merge pull request #4195 from lateralusX/jlorenss/win-build-dependency
[mono.git] / mcs / mcs / cs-parser.jay
index 6becc05d0fe6ac64fcb4005dc69b6abdeb3c2920..a9748379086bbde75a62e2c78329576af82f3755 100644 (file)
@@ -257,6 +257,10 @@ namespace Mono.CSharp
 %token MAKEREF
 %token ASYNC
 %token AWAIT
+%token INTERR_OPERATOR
+%token WHEN
+%token INTERPOLATED_STRING
+%token INTERPOLATED_STRING_END
 
 /* C# keywords which are not really keywords */
 %token GET
@@ -396,6 +400,17 @@ outer_declaration
          }
        | opt_extern_alias_directives opt_using_directives attribute_sections
          {
+               Attributes attrs = (Attributes) $3;
+               if (attrs != null) {
+                       foreach (var a in attrs.Attrs) {
+                               if (a.ExplicitTarget == "assembly" || a.ExplicitTarget == "module")
+                                       continue;
+
+                               if (a.ExplicitTarget == null)
+                                       report.Error (-1671, a.Location, "Global attributes must have attribute target specified");
+                       }
+               }
+
                module.AddAttributes ((Attributes) $3, current_namespace);
          }
        | error
@@ -459,25 +474,38 @@ using_directive
        ;
 
 using_namespace
-       : USING namespace_or_type_expr SEMICOLON 
+       : USING opt_static namespace_or_type_expr SEMICOLON
          {
-               var un = new UsingNamespace ((ATypeNameExpression) $2, GetLocation ($1));
-               current_namespace.AddUsing (un);
-               
-               lbag.AddLocation (un, GetLocation ($3));
+               UsingClause uc;
+               if ($2 != null) {
+                       if (lang_version <= LanguageVersion.V_5)
+                               FeatureIsNotAvailable (GetLocation ($2), "using static");
+
+                       uc = new UsingType ((ATypeNameExpression) $3, GetLocation ($1));
+                       lbag.AddLocation (uc, GetLocation ($2), GetLocation ($4));
+               } else {
+                       uc = new UsingNamespace ((ATypeNameExpression) $3, GetLocation ($1));
+                       lbag.AddLocation (uc, GetLocation ($4));
+               }
+
+               current_namespace.AddUsing (uc);
          }
-       | USING IDENTIFIER ASSIGN namespace_or_type_expr SEMICOLON
+       | USING opt_static IDENTIFIER ASSIGN namespace_or_type_expr SEMICOLON
          {
-               var lt = (LocatedToken) $2;
+               var lt = (LocatedToken) $3;
                if (lang_version != LanguageVersion.ISO_1 && lt.Value == "global") {
                        report.Warning (440, 2, lt.Location,
                         "An alias named `global' will not be used when resolving `global::'. The global namespace will be used instead");
                }
 
-               var un = new UsingAliasNamespace (new SimpleMemberName (lt.Value, lt.Location), (ATypeNameExpression) $4, GetLocation ($1));
+               if ($2 != null) {
+                       report.Error (8085, GetLocation ($2), "A `using static' directive cannot be used to declare an alias");
+               }
+
+               var un = new UsingAliasNamespace (new SimpleMemberName (lt.Value, lt.Location), (ATypeNameExpression) $5, GetLocation ($1));
                current_namespace.AddUsing (un);
                
-               lbag.AddLocation (un, GetLocation ($3), GetLocation ($5));
+               lbag.AddLocation (un, GetLocation ($4), GetLocation ($6));
          }
        | USING error
         {
@@ -486,6 +514,11 @@ using_namespace
         }
        ;
 
+opt_static
+       :
+       | STATIC
+       ;
+
 //
 // Strictly speaking, namespaces don't have attributes but
 // we parse global attributes along with namespace declarations and then
@@ -740,7 +773,9 @@ attribute_section_cont
          }
        | error
          {
-               CheckAttributeTarget (yyToken, GetTokenName (yyToken), GetLocation ($1)); 
+               if (CheckAttributeTarget (yyToken, GetTokenName (yyToken), GetLocation ($1)).Length > 0)
+                       Error_SyntaxError (yyToken);
+
                $$ = null;
          }
        ;       
@@ -870,7 +905,7 @@ named_attribute_argument
        ;
        
 named_argument
-       : identifier_inside_body COLON opt_named_modifier expression_or_error
+       : identifier_inside_body COLON opt_named_modifier named_argument_expr
          {
                if (lang_version <= LanguageVersion.V_3)
                        FeatureIsNotAvailable (GetLocation ($1), "named argument");
@@ -883,6 +918,11 @@ named_argument
                lbag.AddLocation ($$, GetLocation($2));
          }
        ;
+
+named_argument_expr
+       : expression_or_error
+//     | declaration_expression
+       ;
        
 opt_named_modifier
        : /* empty */   { $$ = null; }
@@ -923,6 +963,7 @@ class_member_declaration
        | indexer_declaration
        | operator_declaration
        | constructor_declaration
+       | primary_constructor_body
        | destructor_declaration
        | type_declaration
        | attributes_without_members
@@ -936,6 +977,33 @@ class_member_declaration
          }     
        ;
 
+primary_constructor_body
+       : OPEN_BRACE
+         {
+               current_local_parameters = current_type.PrimaryConstructorParameters;
+               if (current_local_parameters == null) {
+                       report.Error (9010, GetLocation ($1), "Primary constructor body is not allowed");
+                       current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
+               }
+
+               ++lexer.parsing_block;
+               start_block (GetLocation ($1));
+         }
+         opt_statement_list block_end
+         {
+               current_local_parameters = null;
+               var t = current_type as ClassOrStruct;
+               if (t != null) {
+                       var b = (ToplevelBlock) $4;
+                       if (t.PrimaryConstructorBlock != null) {
+                               report.Error (8041, b.StartLocation, "Primary constructor already has a body");
+                       } else {
+                               t.PrimaryConstructorBlock = b;
+                       }
+               }
+         }
+       ;
+
 struct_declaration
        : opt_attributes
          opt_modifiers
@@ -1258,7 +1326,7 @@ method_declaration
 
                // Was added earlier in the case of body being eof for full ast
          }
-         method_body
+         method_body_expression_block
          {
                Method method = (Method) $1;
                method.Block = (ToplevelBlock) $3;
@@ -1413,11 +1481,36 @@ method_header
          }
        ;
 
+method_body_expression_block
+       : method_body
+       | expression_block
+       ;
+
 method_body
        : block
        | SEMICOLON             { $$ = null; }
        ;
 
+expression_block
+       : ARROW
+        {
+               if (lang_version < LanguageVersion.V_6) {
+                       FeatureIsNotAvailable (GetLocation ($1), "expression bodied members");
+               }
+
+               ++lexer.parsing_block;
+               start_block (GetLocation ($1));
+        }
+        expression SEMICOLON
+        {
+               lexer.parsing_block = 0;
+               current_block.AddStatement (new ContextualReturn ((Expression) $3));
+               var b = end_block (GetLocation ($4));
+               b.IsCompilerGenerated = true;
+               $$ = b;
+        }
+       ;
+
 opt_formal_parameter_list
        : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
        | formal_parameter_list
@@ -1736,9 +1829,9 @@ property_declaration
          accessor_declarations 
          {
                lexer.PropertyParsing = false;
-               
+
                if (doc_support)
-                       current_property.DocComment = ConsumeStoredComment ();                          
+                       current_property.DocComment = ConsumeStoredComment ();
          }
          CLOSE_BRACE
          {
@@ -1749,6 +1842,40 @@ property_declaration
          {
                current_property = null;
          }
+       | opt_attributes
+         opt_modifiers
+         member_type
+         member_declaration_name
+         {
+               lexer.parsing_generic_declaration = false;
+               if (doc_support)
+                       tmpComment = Lexer.consume_doc_comment ();
+               current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
+         }
+         expression_block
+         {
+               var type = (FullNamedExpression) $3;
+               var property = new Property (current_type, type, (Modifiers) $2,
+                       (MemberName) $4, (Attributes) $1);
+
+               property.Get = new Property.GetMethod (property, Modifiers.COMPILER_GENERATED, null, property.Location);
+               property.Get.Block = (ToplevelBlock) $6;
+
+               if (current_container.Kind == MemberKind.Interface) {
+                       report.Error (531, property.Get.Block.StartLocation,
+                               "`{0}': interface members cannot have a definition", property.GetSignatureForError ());
+               }
+
+               if (type.Type != null && type.Type.Kind == MemberKind.Void)
+                       report.Error (547, GetLocation ($3), "`{0}': property or indexer cannot have void type", property.GetSignatureForError ());
+
+               if (doc_support)
+                       property.DocComment = ConsumeStoredComment ();
+
+               current_type.AddMember (property);
+
+               current_local_parameters = null;
+         }
        ;
 
 opt_property_initializer
@@ -1759,16 +1886,24 @@ opt_property_initializer
                current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
                start_block (GetLocation ($1));
          }
-         expression SEMICOLON
+         property_initializer SEMICOLON
          {
                --lexer.parsing_block;
                ((Property)current_property).Initializer = (Expression) $3;
                lbag.AppendToMember (current_property, GetLocation ($1), GetLocation ($4));
                end_block (GetLocation ($4));
                current_local_parameters = null;
+
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        ;
 
+property_initializer
+       : expression
+       | array_initializer
+       ;
+
 indexer_declaration
        : opt_attributes opt_modifiers
          member_type indexer_declaration_name OPEN_BRACKET
@@ -1799,24 +1934,34 @@ indexer_declaration
                }
 
                lexer.PropertyParsing = true;
+               current_local_parameters = (ParametersCompiled) $7;
          }
-         OPEN_BRACE accessor_declarations 
-         {
-               lexer.PropertyParsing = false;
-         }
-         CLOSE_BRACE
+         indexer_body
          {
+               lexer.PropertyParsing = false;
+               current_local_parameters = null;
+
                if (current_property.AccessorFirst != null && current_property.AccessorFirst.Block == null)
                        ((Indexer) current_property).ParameterInfo.CheckParameters (current_property);
          
                if (doc_support)
                        current_property.DocComment = ConsumeStoredComment ();
                        
-               lbag.AppendToMember (current_property, GetLocation ($10), GetLocation ($13));
                current_property = null;                
          }
        ;
 
+indexer_body
+       : OPEN_BRACE accessor_declarations CLOSE_BRACE
+         {
+               lbag.AppendToMember (current_property, GetLocation ($1), GetLocation ($3));
+         }
+       | expression_block
+         {
+               current_property.Get = new Indexer.GetIndexerMethod (current_property, Modifiers.COMPILER_GENERATED, current_local_parameters, null, current_property.Location);
+               current_property.Get.Block = (ToplevelBlock) $1;
+         }
+       ;
 
 accessor_declarations
        : get_accessor_declaration
@@ -2039,7 +2184,7 @@ operator_declaration
        : opt_attributes opt_modifiers operator_declarator 
          {
          }
-         operator_body
+         method_body_expression_block
          {
                OperatorDeclaration decl = (OperatorDeclaration) $3;
                if (decl != null) {
@@ -2066,11 +2211,6 @@ operator_declaration
          }
        ;
 
-operator_body 
-       : block
-       | SEMICOLON { $$ = null; }
-       ; 
-
 operator_type
        : type_expression_or_array
        | VOID
@@ -2084,6 +2224,8 @@ operator_declarator
        : operator_type OPERATOR overloadable_operator OPEN_PARENS
          {
                valid_param_mod = ParameterModifierType.DefaultValue;
+               if ((Operator.OpType) $3 == Operator.OpType.Is)
+                       valid_param_mod |= ParameterModifierType.Out;
          }
          opt_formal_parameter_list CLOSE_PARENS
          {
@@ -2108,6 +2250,8 @@ operator_declarator
                                report.Error (1535, loc, "Overloaded unary operator `{0}' takes one parameter",
                                        Operator.GetName (op));
                        }
+               } else if (op == Operator.OpType.Is) {
+                       // TODO: Special checks for is operator
                } else {
                        if (p_count == 1) {
                                report.Error (1019, loc, "Overloadable unary operator expected");
@@ -2154,6 +2298,13 @@ overloadable_operator
         | OP_LT { $$ = Operator.OpType.LessThan; }
         | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
         | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
+       | IS
+         {
+               if (lang_version != LanguageVersion.Experimental)
+                       FeatureIsNotAvailable (GetLocation ($1), "is user operator");
+
+               $$ = Operator.OpType.Is;
+         }
        ;
 
 conversion_operator_declarator
@@ -2257,11 +2408,20 @@ constructor_declarator
                if (lt.Value != current_container.MemberName.Name) {
                        report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
                } else if ((mods & Modifiers.STATIC) != 0) {
+                       if (!current_local_parameters.IsEmpty) {
+                               report.Error (132, c.Location, "`{0}': The static constructor must be parameterless",
+                                       c.GetSignatureForError ());
+                       }
+
                        if ((mods & Modifiers.AccessibilityMask) != 0){
                                report.Error (515, c.Location,
                                        "`{0}': static constructor cannot have an access modifier",
                                        c.GetSignatureForError ());
                        }
+               } else {
+                       if (current_type.Kind == MemberKind.Struct && current_local_parameters.IsEmpty) {
+                               report.Error (568, c.Location, "Structs cannot contain explicit parameterless constructors");
+                       }
                }
 
                current_type.AddConstructor (c);
@@ -2659,10 +2819,6 @@ opt_enum_base
        : /* empty */
        | COLON type
         {
-               var te = $2 as TypeExpression;
-               if (te == null || !EnumSpec.IsValidUnderlyingType (te.Type)) {
-                       Enum.Error_1008 (GetLocation ($2), report);
-               }
                $$ = $2;
         }
        | COLON error
@@ -2810,6 +2966,14 @@ namespace_or_type_expr
                $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
                lbag.AddLocation ($$, GetLocation ($2));
          }
+       | qualified_alias_member IDENTIFIER generic_dimension
+         {
+               var lt1 = (LocatedToken) $1;
+               var lt2 = (LocatedToken) $2;
+
+               $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
        ;
 
 member_name
@@ -2820,6 +2984,12 @@ member_name
                $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
                lbag.AddLocation ($$, GetLocation ($2));
          }
+       | namespace_or_type_expr DOT IDENTIFIER generic_dimension
+         {
+               var lt = (LocatedToken) $3;
+               $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
        ;
 
 simple_name_expr
@@ -2828,8 +2998,13 @@ simple_name_expr
                var lt = (LocatedToken) $1;
                $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);
          }
+       | IDENTIFIER generic_dimension
+         {  
+               var lt = (LocatedToken) $1;
+               $$ = new SimpleName (lt.Value, (int) $2, lt.Location);
+         }
        ;
-       
+
 //
 // Generics arguments  (any type, without attributes)
 //
@@ -3004,29 +3179,21 @@ member_type
 //
 type
        : type_expression_or_array
-       | VOID
-         {
-               Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
-               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
-         }     
+       | void_invalid
        ;
        
 simple_type
        : type_expression
-       | VOID
-         {
-               Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
-               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
-         }     
+       | void_invalid
        ;
        
 parameter_type
        : type_expression_or_array
        | VOID
          {
-               report.Error (1536, GetLocation ($1), "Invalid parameter type `void'");
+               report.Error (1536, GetLocation ($1), "Invalid parameter type `void'");
                $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
-         }     
+         }
        ;
 
 type_expression_or_array
@@ -3054,7 +3221,19 @@ type_expression
          {
                $$ = new ComposedCast ((ATypeNameExpression) $1, (ComposedTypeSpecifier) $2);
          }
-       | builtin_types opt_nullable
+       | builtin_type_expression
+       ;
+
+void_invalid
+       : VOID
+         {
+               Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
+               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
+         }
+       ;
+
+builtin_type_expression
+       : builtin_types opt_nullable
          {
                if ($2 != null)
                        $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
@@ -3126,7 +3305,7 @@ integral_type
 
 
 primary_expression
-       : primary_expression_or_type
+       : type_name_expression
        | literal
        | array_creation_expression
        | parenthesized_expression
@@ -3146,14 +3325,11 @@ primary_expression
        | pointer_member_access
        | anonymous_method_expression
        | undocumented_expressions
+       | interpolated_string
        ;
 
-primary_expression_or_type
-       : IDENTIFIER opt_type_argument_list
-         {
-               var lt = (LocatedToken) $1;
-               $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);   
-         }
+type_name_expression
+       : simple_name_expr
        | IDENTIFIER GENERATE_COMPLETION {
                var lt = (LocatedToken) $1;
               $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location);
@@ -3172,6 +3348,77 @@ boolean_literal
        | FALSE                 { $$ = new BoolLiteral (compiler.BuiltinTypes, false, GetLocation ($1)); }
        ;
 
+interpolated_string
+       : INTERPOLATED_STRING interpolations INTERPOLATED_STRING_END
+         {
+               if (lang_version < LanguageVersion.V_6)
+                       FeatureIsNotAvailable (GetLocation ($1), "interpolated strings");
+
+               $$ = new InterpolatedString ((StringLiteral) $1, (List<Expression>) $2, (StringLiteral) $3);
+         }
+       | INTERPOLATED_STRING_END
+         {
+               if (lang_version < LanguageVersion.V_6)
+                       FeatureIsNotAvailable (GetLocation ($1), "interpolated strings");
+
+               $$ = new InterpolatedString ((StringLiteral) $1, null, null);
+         }
+       ;
+
+interpolations
+       : interpolation
+         {
+               var list = new List<Expression> ();
+               list.Add ((InterpolatedStringInsert) $1);
+               $$ = list;
+         }
+       | interpolations INTERPOLATED_STRING interpolation
+         {
+               var list = (List<Expression>) $1;
+               list.Add ((StringLiteral) $2);
+               list.Add ((InterpolatedStringInsert) $3);
+               $$ = list;
+         }
+       ;
+
+interpolation
+       : expression
+         {
+               $$ = new InterpolatedStringInsert ((Expression) $1);
+         }
+       | expression COMMA expression
+         {
+               $$ = new InterpolatedStringInsert ((Expression) $1) {
+                       Alignment = (Expression)$3
+               };
+         }
+       | expression COLON
+         {
+               lexer.parsing_interpolation_format = true;
+         }
+         LITERAL
+         {
+               lexer.parsing_interpolation_format = false;
+
+               $$ = new InterpolatedStringInsert ((Expression) $1) {
+                       Format = (string)$4
+               };
+         }
+       | expression COMMA expression COLON
+         {
+               lexer.parsing_interpolation_format = true;
+         }
+         LITERAL
+         {
+               lexer.parsing_interpolation_format = false;
+
+               $$ = new InterpolatedStringInsert ((Expression) $1) {
+                       Alignment = (Expression)$3,
+                       Format = (string) $6
+               };
+         }
+       ;
+
 
 //
 // Here is the trick, tokenizer may think that parens is a special but
@@ -3204,7 +3451,7 @@ parenthesized_expression
                $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1));
          }
        ;
-       
+
 member_access
        : primary_expression DOT identifier_inside_body opt_type_argument_list
          {
@@ -3212,6 +3459,21 @@ member_access
                $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
                lbag.AddLocation ($$, GetLocation ($2));
          }
+       | primary_expression DOT identifier_inside_body generic_dimension
+         {
+               var lt = (LocatedToken) $3;
+               $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | primary_expression INTERR_OPERATOR DOT identifier_inside_body opt_type_argument_list
+         {
+               if (lang_version < LanguageVersion.V_6)
+                       FeatureIsNotAvailable (GetLocation ($2), "null propagating operator");
+
+               var lt = (LocatedToken) $4;
+               $$ = new ConditionalMemberAccess ((Expression) $1, lt.Value, (TypeArguments) $5, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
+         }
        | builtin_types DOT identifier_inside_body opt_type_argument_list
          {
                var lt = (LocatedToken) $3;
@@ -3238,6 +3500,14 @@ member_access
                $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
                lbag.AddLocation ($$, GetLocation ($2));
          }
+       | qualified_alias_member identifier_inside_body generic_dimension
+         {
+               var lt1 = (LocatedToken) $1;
+               var lt2 = (LocatedToken) $2;
+
+               $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
        | primary_expression DOT GENERATE_COMPLETION {
                $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3));
          }
@@ -3357,7 +3627,15 @@ member_initializer
                else
                        $$ = new CollectionElementInitializer ((List<Expression>)$2, GetLocation ($1));
 
-               lbag.AddLocation ($$, GetLocation ($2));
+               lbag.AddLocation ($$, GetLocation ($3));
+         }
+       | OPEN_BRACKET_EXPR argument_list CLOSE_BRACKET ASSIGN initializer_value
+         {
+               if (lang_version < LanguageVersion.V_6)
+                       FeatureIsNotAvailable (GetLocation ($1), "dictionary initializer");
+
+               $$ = new DictionaryElementInitializer ((Arguments)$2, (Expression) $5, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4));
          }
        | OPEN_BRACE CLOSE_BRACE
          {
@@ -3440,11 +3718,19 @@ non_simple_argument
                $$ = new Argument ((Expression) $2, Argument.AType.Ref);
                lbag.AddLocation ($$, GetLocation ($1));
          }
+       | REF declaration_expression
+         {
+               $$ = new Argument ((Expression) $2, Argument.AType.Ref);
+         }
        | OUT variable_reference 
          { 
                $$ = new Argument ((Expression) $2, Argument.AType.Out);
                lbag.AddLocation ($$, GetLocation ($1));
          }
+       | OUT declaration_expression
+         {
+               $$ = new Argument ((Expression) $2, Argument.AType.Out);
+         }
        | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
          {
                $$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1)));
@@ -3457,6 +3743,48 @@ non_simple_argument
          }       
        ;
 
+declaration_expression
+       : OPEN_PARENS declaration_expression CLOSE_PARENS
+         {
+               $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
+         }
+/*
+       | CHECKED open_parens_any declaration_expression CLOSE_PARENS
+         {
+               $$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | UNCHECKED open_parens_any declaration_expression CLOSE_PARENS
+         {
+               $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }
+*/
+       | variable_type identifier_inside_body
+         {
+               if (lang_version != LanguageVersion.Experimental)
+                       FeatureIsNotAvailable (GetLocation ($1), "declaration expression");
+
+               var lt = (LocatedToken) $2;
+               var lv = new LocalVariable (current_block, lt.Value, lt.Location);
+               current_block.AddLocalName (lv);
+               $$ = new DeclarationExpression ((FullNamedExpression) $1, lv);
+         }
+       | variable_type identifier_inside_body ASSIGN expression
+         {
+               if (lang_version != LanguageVersion.Experimental)
+                       FeatureIsNotAvailable (GetLocation ($1), "declaration expression");
+
+               var lt = (LocatedToken) $2;
+               var lv = new LocalVariable (current_block, lt.Value, lt.Location);
+               current_block.AddLocalName (lv);
+               $$ = new DeclarationExpression ((FullNamedExpression) $1, lv) {
+                       Initializer = (Expression) $4
+               };
+         }
+       ;
+
 variable_reference
        : expression
        ;
@@ -3467,6 +3795,17 @@ element_access
                $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
                lbag.AddLocation ($$, GetLocation ($4));
          }
+       | primary_expression INTERR_OPERATOR OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET  
+         {
+               if (lang_version < LanguageVersion.V_6)
+                       FeatureIsNotAvailable (GetLocation ($2), "null propagating operator");
+
+               $$ = new ElementAccess ((Expression) $1, (Arguments) $4, GetLocation ($3)) {
+                       ConditionalAccess = true
+               };
+
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($5));
+         }
        | primary_expression OPEN_BRACKET_EXPR expression_list_arguments error
          {
                Error_SyntaxError (yyToken);
@@ -3585,7 +3924,10 @@ array_creation_expression
                $$ = new ArrayCreation ((FullNamedExpression) $2, (List<Expression>) $4,
                                new ComposedTypeSpecifier (((List<Expression>) $4).Count, GetLocation ($3)) {
                                        Next = (ComposedTypeSpecifier) $6
-                               }, (ArrayInitializer) $7, GetLocation ($1));
+                               }, (ArrayInitializer) $7, GetLocation ($1)) {
+                       NoEmptyInterpolation = true
+               };
+
                lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
          }
        | NEW new_expr_type rank_specifiers opt_array_initializer
@@ -3593,7 +3935,9 @@ array_creation_expression
                if ($4 == null)
                        report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer");
 
-               $$ = new ArrayCreation ((FullNamedExpression) $2, (ComposedTypeSpecifier) $3, (ArrayInitializer) $4, GetLocation ($1));
+               $$ = new ArrayCreation ((FullNamedExpression) $2, (ComposedTypeSpecifier) $3, (ArrayInitializer) $4, GetLocation ($1)) {
+                       NoEmptyInterpolation = true
+               };
          }
        | NEW rank_specifier array_initializer
          {
@@ -3788,65 +4132,21 @@ variable_initializer_list
        ;
 
 typeof_expression
-       : TYPEOF
-      {
-               lexer.TypeOfParsing = true;
-         }
-         open_parens_any typeof_type_expression CLOSE_PARENS
+       : TYPEOF open_parens_any typeof_type_expression CLOSE_PARENS
          {
-               lexer.TypeOfParsing = false;
-               $$ = new TypeOf ((FullNamedExpression) $4, GetLocation ($1));
-               lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
+               $$ = new TypeOf ((FullNamedExpression) $3, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
          }
        ;
        
 typeof_type_expression
        : type_and_void
-       | unbound_type_name
        | error
         {
                Error_TypeExpected (lexer.Location);
                $$ = null;
         }
        ;
-       
-unbound_type_name
-       : identifier_inside_body generic_dimension
-         {  
-               var lt = (LocatedToken) $1;
-
-               $$ = new SimpleName (lt.Value, (int) $2, lt.Location);
-         }
-       | qualified_alias_member identifier_inside_body generic_dimension
-         {
-               var lt1 = (LocatedToken) $1;
-               var lt2 = (LocatedToken) $2;
-
-               $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
-               lbag.AddLocation ($$, GetLocation ($2));
-         }
-       | unbound_type_name DOT identifier_inside_body
-         {
-               var lt = (LocatedToken) $3;
-               
-               $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);         
-         }
-       | unbound_type_name DOT identifier_inside_body generic_dimension
-         {
-               var lt = (LocatedToken) $3;
-               
-               $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);               
-         }
-       | namespace_or_type_expr DOT identifier_inside_body generic_dimension
-         {
-               var tne = (ATypeNameExpression) $1;
-               if (tne.HasTypeArguments)
-                       Error_TypeExpected (GetLocation ($4));
-
-               var lt = (LocatedToken) $3;
-               $$ = new MemberAccess (tne, lt.Value, (int) $4, lt.Location);           
-         }
-       ;
 
 generic_dimension
        : GENERIC_DIMENSION
@@ -4154,15 +4454,7 @@ additive_expression
                $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
                lbag.AddLocation ($$, GetLocation ($2));
          }
-       | additive_expression AS type
-         {
-               $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
-         }
-       | additive_expression IS type
-         {
-               $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
-         }       
-       | additive_expression PLUS error 
+       | additive_expression PLUS error
          {
                Error_SyntaxError (yyToken);
 
@@ -4176,6 +4468,32 @@ additive_expression
                $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, null);
                lbag.AddLocation ($$, GetLocation ($2));
          }
+       | additive_expression AS type
+         {
+               $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
+         }
+       | additive_expression IS pattern_type_expr opt_identifier
+         {
+               var is_expr = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
+               if ($4 != null) {
+                       if (lang_version != LanguageVersion.Experimental)
+                               FeatureIsNotAvailable (GetLocation ($4), "type pattern matching");
+
+                       var lt = (LocatedToken) $4;
+                       is_expr.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
+                       current_block.AddLocalName (is_expr.Variable);
+               }
+
+               $$ = is_expr;
+         }
+       | additive_expression IS pattern_expr
+         {
+               var is_expr = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
+               if (lang_version != LanguageVersion.Experimental)
+                       FeatureIsNotAvailable (GetLocation ($2), "pattern matching");
+
+               $$ = is_expr;
+         }
        | additive_expression AS error
          {
                Error_SyntaxError (yyToken);
@@ -4200,6 +4518,122 @@ additive_expression
          }
        ;
 
+pattern_type_expr
+       : variable_type
+       ;
+
+pattern_expr
+       : literal
+       | PLUS prefixed_unary_expression
+         {
+               $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
+         }
+       | MINUS prefixed_unary_expression
+         {
+               $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
+         }
+       | sizeof_expression
+       | default_value_expression
+       | OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
+         {
+               $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($3));
+         }
+       | STAR
+         {
+               $$ = new WildcardPattern (GetLocation ($1));
+         }
+       | pattern_expr_invocation
+       | pattern_property
+       ;
+
+pattern_expr_invocation
+       : type_name_expression OPEN_PARENS opt_pattern_list CLOSE_PARENS
+         {
+               $$ = new RecursivePattern ((ATypeNameExpression) $1, (Arguments) $3, GetLocation ($2));
+         }
+       ;
+
+pattern_property
+       : type_name_expression OPEN_BRACE pattern_property_list CLOSE_BRACE
+         {
+               $$ = new PropertyPattern ((ATypeNameExpression) $1, (List<PropertyPatternMember>) $3, GetLocation ($2));
+         }
+       ;
+
+pattern_property_list
+       : pattern_property_entry
+         {
+               var list = new List<PropertyPatternMember> ();
+               list.Add ((PropertyPatternMember) $1);
+               $$ = list;
+         }
+       | pattern_property_list COMMA pattern_property_entry
+         {
+               var list = (List<PropertyPatternMember>) $1;
+               list.Add ((PropertyPatternMember) $3);
+               $$ = list;
+         }
+       ;
+
+pattern_property_entry
+       : identifier_inside_body IS pattern
+         {
+               var lt = (LocatedToken) $1;
+               $$ = new PropertyPatternMember (lt.Value, (Expression) $3, lt.Location);
+         }
+       ;
+
+pattern
+       : pattern_expr
+       | pattern_type_expr opt_identifier
+         {
+               if ($2 != null) {
+                       var lt = (LocatedToken) $2;
+                       var variable = new LocalVariable (current_block, lt.Value, lt.Location);
+                       current_block.AddLocalName (variable);
+               }
+         }
+       ;
+
+opt_pattern_list
+       : /* empty */
+         {
+               $$ = new Arguments (0);
+         }
+       | pattern_list
+       ;
+
+pattern_list
+       : pattern_argument
+         {
+               Arguments args = new Arguments (4);
+               args.Add ((Argument) $1);
+               $$ = args;
+         }
+       | pattern_list COMMA pattern_argument
+         {
+               Arguments args = (Arguments) $1;
+               if (args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
+                       Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
+
+               args.Add ((Argument) $3);
+               $$ = args;
+         }
+       ;
+
+pattern_argument
+       : pattern
+         {
+               $$ = new Argument ((Expression) $1);
+         }
+       | IDENTIFIER COLON pattern
+         {
+               var lt = (LocatedToken) $1;
+               $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $3);
+         }
+       ;
+
 shift_expression
        : additive_expression
        | shift_expression OP_SHIFT_LEFT additive_expression
@@ -4699,7 +5133,7 @@ primary_parameters
                // Cannot use opt_formal_parameter_list because it can be shared instance for empty parameters
                lbag.AppendToMember (current_container, GetLocation ($1), GetLocation ($3));
 
-               if (lang_version < LanguageVersion.V_6)
+               if (lang_version != LanguageVersion.Experimental)
                        FeatureIsNotAvailable (GetLocation ($1), "primary constructor");
          }
        ;
@@ -5256,7 +5690,7 @@ variable_type
  * > The expressions are converted into types during semantic analysis.
  */
 variable_type_simple
-       : primary_expression_or_type opt_nullable
+       : type_name_expression opt_nullable
          { 
                // Ok, the above "primary_expression" is there to get rid of
                // both reduce/reduce and shift/reduces in the grammar, it should
@@ -5272,51 +5706,23 @@ variable_type_simple
                // SimpleName is when you have
                // Blah i;
                
-               Expression expr = (Expression) $1;
+               var expr = (ATypeNameExpression) $1;
                if ($2 == null) {
-                       SimpleName sn = expr as SimpleName;
-                       if (sn != null && sn.Name == "var")
-                               $$ = new VarExpr (sn.Location);
+                       if (expr.Name == "var" && expr is SimpleName)
+                               $$ = new VarExpr (expr.Location);
                        else
                                $$ = $1;
-               } else if (expr is ATypeNameExpression) {
-                       $$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2);
                } else {
-                       Error_ExpectingTypeName (expr);
-                       $$ = null;
-               }
-         }
-       | primary_expression_or_type pointer_stars
-         {
-               ATypeNameExpression expr = $1 as ATypeNameExpression;
-
-               if (expr != null) {
                        $$ = new ComposedCast (expr, (ComposedTypeSpecifier) $2);
-               } else {
-                       Error_ExpectingTypeName ((Expression)$1);
-                       $$ = expr;
                }
          }
-       | builtin_types opt_nullable
-         {
-               if ($2 == null)
-                       $$ = $1;
-               else
-                       $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
-         }
-       | builtin_types pointer_stars
-         {
-               $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
-         }
-       | VOID pointer_stars
-         {
-               $$ = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)), (ComposedTypeSpecifier) $2);
-         }       
-       | VOID
+       | type_name_expression pointer_stars
          {
-               Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
-               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
+               var expr = (ATypeNameExpression) $1;
+               $$ = new ComposedCast (expr, (ComposedTypeSpecifier) $2);
          }
+       | builtin_type_expression
+       | void_invalid
        ;
        
 pointer_stars
@@ -5633,6 +6039,18 @@ switch_label
                Error_SyntaxError (yyToken);
                $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
          }
+/*       
+       | CASE pattern_expr_invocation COLON
+         {
+               if (lang_version != LanguageVersion.Experimental)
+                       FeatureIsNotAvailable (GetLocation ($2), "pattern matching");
+
+               $$ = new SwitchLabel ((Expression) $2, GetLocation ($1)) {
+                       PatternMatching = true
+               };
+               lbag.AddLocation ($$, GetLocation ($3));
+         }
+*/
        | DEFAULT_COLON
          {
                $$ = new SwitchLabel (null, GetLocation ($1));
@@ -6089,8 +6507,9 @@ catch_clause
                
                lbag.AddLocation (c, GetLocation ($2), GetLocation ($5));
                $$ = c;
+               lexer.parsing_catch_when = true;
          }
-         opt_catch_filter block_prepared
+         opt_catch_filter_or_error
          {
                ((Catch) $6).Filter = (CatchFilterExpression) $7;
                $$ = $6;
@@ -6106,35 +6525,36 @@ catch_clause
                
                $$ = new Catch (null, GetLocation ($1));
          }
-       | CATCH open_parens_any type opt_identifier CLOSE_PARENS error
+       ;
+
+opt_catch_filter_or_error
+       : opt_catch_filter block_prepared
          {
+               $$ = $1;
+         }
+       | error
+         {
+               end_block (Location.Null);
                Error_SyntaxError (yyToken);
-
-               // Required otherwise missing block could not be detected because
-               // start_block is run early
-               var c = new Catch (null, GetLocation ($1));
-               c.TypeExpression = (FullNamedExpression) $3;
-
-               if ($4 != null) {
-                       var lt = (LocatedToken) $4;
-                       c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
-               }
-
-               lbag.AddLocation (c, GetLocation ($2), GetLocation ($5));
-
-               $$ = c;
+               $$ = null;
          }
        ;
 
 opt_catch_filter
-       : /* empty */
-       | IF open_parens_any expression CLOSE_PARENS
+       : {
+               lexer.parsing_catch_when = false;
+         }
+       | WHEN
+         {
+               lexer.parsing_catch_when = false;
+         }
+         open_parens_any expression CLOSE_PARENS
          {
                if (lang_version <= LanguageVersion.V_5)
                        FeatureIsNotAvailable (GetLocation ($1), "exception filter");
 
-               $$ = new CatchFilterExpression ((Expression) $3, GetLocation ($1));
-               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+               $$ = new CatchFilterExpression ((Expression) $4, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
          }
        ;
 
@@ -7747,7 +8167,13 @@ static string GetTokenName (int token)
                return ";";
        case Token.TILDE:
                return "~";
-               
+       case Token.WHEN:
+               return "when";
+       case Token.INTERPOLATED_STRING_END:
+               return "}";
+       case Token.INTERPOLATED_STRING:
+               return "${";
+
        case Token.PLUS:
        case Token.UMINUS:
        case Token.MINUS:
@@ -7782,6 +8208,7 @@ static string GetTokenName (int token)
        case Token.OP_AND_ASSIGN:
        case Token.OP_XOR_ASSIGN:
        case Token.OP_OR_ASSIGN:
+       case Token.INTERR_OPERATOR:
                return "<operator>";
 
        case Token.BOOL: