diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 525e50ebbe616e8b61d74bf3662901f9e26b525e..5638b9a969a572d9ca5f12ad47f4c6800f7ae998 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -428,7 +428,7 @@ private NamespaceDeclarationSyntax ParseNamespaceDeclaration() Debug.Assert(this.CurrentToken.Kind == SyntaxKind.NamespaceKeyword); var namespaceToken = this.EatToken(SyntaxKind.NamespaceKeyword); - if (IsScript || IsInteractive) + if (IsScriptOrInteractive) { namespaceToken = this.AddError(namespaceToken, ErrorCode.ERR_NamespaceNotAllowedInScript); } @@ -592,7 +592,7 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil Debug.Assert(!IsInAsync); bool isGlobal = openBrace == null; - bool isGlobalScript = isGlobal && this.IsScript; + bool isGlobalScript = isGlobal && this.IsScriptOrInteractive; var saveTerm = _termState; _termState |= TerminatorState.IsNamespaceMemberStartOrStop; @@ -629,7 +629,7 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil var token = this.EatToken(); token = this.AddError(token, - IsScript ? ErrorCode.ERR_GlobalDefinitionOrStatementExpected : ErrorCode.ERR_EOFExpected); + IsScriptOrInteractive ? ErrorCode.ERR_GlobalDefinitionOrStatementExpected : ErrorCode.ERR_EOFExpected); this.AddSkippedNamespaceText(ref openBrace, ref body, ref initialBadNodes, token); reportUnexpectedToken = true; @@ -738,7 +738,7 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil if (reportUnexpectedToken && !skippedToken.ContainsDiagnostics) { skippedToken = this.AddError(skippedToken, - IsScript ? ErrorCode.ERR_GlobalDefinitionOrStatementExpected : ErrorCode.ERR_EOFExpected); + IsScriptOrInteractive ? ErrorCode.ERR_GlobalDefinitionOrStatementExpected : ErrorCode.ERR_EOFExpected); // do not report the error multiple times for subsequent tokens: reportUnexpectedToken = false; @@ -2230,7 +2230,7 @@ private MemberDeclarationSyntax ParseMemberDeclarationOrStatement(SyntaxKind par cancellationToken.ThrowIfCancellationRequested(); - bool isGlobalScript = parentKind == SyntaxKind.CompilationUnit && this.IsScript; + bool isGlobalScript = parentKind == SyntaxKind.CompilationUnit && this.IsScriptOrInteractive; bool acceptStatement = isGlobalScript; // don't reuse members if they were previously declared under a different type keyword kind @@ -2498,7 +2498,7 @@ private MemberDeclarationSyntax ParseMemberDeclarationOrStatement(SyntaxKind par return incompleteMember; } else if (parentKind == SyntaxKind.NamespaceDeclaration || - parentKind == SyntaxKind.CompilationUnit && !IsScript) + parentKind == SyntaxKind.CompilationUnit && !IsScriptOrInteractive) { return this.AddErrorToLastToken(incompleteMember, ErrorCode.ERR_NamespaceUnexpected); } @@ -4520,7 +4520,7 @@ private void ParseVariableDeclarators(TypeSyntax type, VariableFlags flags, Sepa // the reported errors should take into consideration whether or not one expects them in the current context. bool variableDeclarationsExpected = parentKind != SyntaxKind.NamespaceDeclaration && - (parentKind != SyntaxKind.CompilationUnit || IsScript); + (parentKind != SyntaxKind.CompilationUnit || IsScriptOrInteractive); ParseVariableDeclarators(type, flags, variables, variableDeclarationsExpected); } @@ -8231,7 +8231,7 @@ private static bool IsExpectedAssignmentOperator(SyntaxKind kind) private bool IsPossibleAwaitExpressionStatement() { - return (this.IsInteractive || this.IsInAsync) && this.CurrentToken.ContextualKind == SyntaxKind.AwaitKeyword; + return (this.IsScriptOrInteractive || this.IsInAsync) && this.CurrentToken.ContextualKind == SyntaxKind.AwaitKeyword; } private bool IsAwaitExpression() diff --git a/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs b/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs index b9464cd55948e2174e26b245a794bb8e9bcd7543..4a4223e85c47f738a2587d60ad925c2c692fb076 100644 --- a/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/SyntaxParser.cs @@ -191,11 +191,11 @@ public bool IsInteractive } /// - /// Script - global statements and member declarations allowed, but not expressions. + /// Script or interactive - global statements, member declarations, and expressions allowed. /// - public bool IsScript + public bool IsScriptOrInteractive { - get { return Options.Kind != SourceCodeKind.Regular; } + get { return (Options.Kind == SourceCodeKind.Script) || (Options.Kind == SourceCodeKind.Interactive); } } protected LexerMode Mode diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs index 531f8413bfd7475b3042744f673e2bd139223e9b..c308dff5e078745b381f1ef14fe196d45b87abf8 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs @@ -3605,7 +3605,6 @@ public static Task GetValue() CompileAndVerify(comp.WithOptions(TestOptions.ReleaseExe), expectedOutput: "0"); } - [Fact] public void AwaitInScriptExpression() { @@ -3615,6 +3614,15 @@ public void AwaitInScriptExpression() compilation.VerifyDiagnostics(); } + [Fact] + public void AwaitInScriptGlobalStatement() + { + var source = +@"await System.Threading.Tasks.Task.FromResult(4);"; + var compilation = CreateCompilationWithMscorlib45(source, parseOptions: TestOptions.Script, options: TestOptions.DebugExe); + compilation.VerifyDiagnostics(); + } + [Fact] public void AwaitInScriptDeclaration() { @@ -3641,6 +3649,16 @@ public void AwaitInInteractiveExpression() s1.VerifyDiagnostics(); } + [Fact] + public void AwaitInInteractiveGlobalStatement() + { + var references = new[] { MscorlibRef_v4_0_30316_17626, SystemCoreRef }; + var source0 = +@"await System.Threading.Tasks.Task.FromResult(5);"; + var s0 = CSharpCompilation.CreateSubmission("s0.dll", SyntaxFactory.ParseSyntaxTree(source0, options: TestOptions.Interactive), references); + s0.VerifyDiagnostics(); + } + [Fact] public void AwaitInInteractiveDeclaration() { @@ -3731,7 +3749,6 @@ static void M(int input) } catch (Exception) { - } } } @@ -3775,24 +3792,24 @@ public void SwitchOnAwaitedValueString() using System; class Program +{ + static void Main() { - static void Main() - { - M(0).Wait(); - } + M(0).Wait(); + } - static async Task M(int input) + static async Task M(int input) + { + var value = ""q""; + switch (value) { - var value = ""q""; - switch (value) - { - case ""a"": - return; - case ""b"": - return; - } + case ""a"": + return; + case ""b"": + return; } } +} "; var comp = CreateCompilation(source, options: TestOptions.DebugExe); CompileAndVerify(comp);