/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Syntax/Parsing/ParsingErrorRecoveryTests.cs
8 791 строка
406 KB
Jan Jones
Unsafe evolution: make pointers safe regardless of memory safety rules version (#83133)
21 апр 2026, 11:27
Не верифицирован
21 апр 2026, 11:27
fca0128
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public sealed class ParsingErrorRecoveryTests(ITestOutputHelper helper) : ParsingTests(helper) { private new CompilationUnitSyntax ParseTree(string text, CSharpParseOptions options = null) { return SyntaxFactory.ParseCompilationUnit(text, options: options); } [Theory] [InlineData("public")] [InlineData("internal")] [InlineData("protected")] [InlineData("private")] [WorkItem("https://github.com/dotnet/roslyn/pull/74484")] public void AccessibilityModifierErrorRecovery(string accessibility) { var text = $$""" class C { void M() { // bad visibility modifier {{accessibility}} void localFunc() {} } void M2() { typing {{accessibility}} void localFunc() {} } void M3() { // Ambiguous between local func with bad modifier and missing closing // brace on previous method. Parsing currently assumes the latter {{accessibility}} void M4() {} } """; UsingTree(text, // (4,6): error CS1513: } expected // { Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(4, 6), // (8,5): error CS8803: Top-level statements must precede namespace and type declarations. // void M2() Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, """ void M2() { typing """).WithLocation(8, 5), // (10,15): error CS1002: ; expected // typing Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(10, 15), // (10,15): error CS1513: } expected // typing Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(10, 15), // (11,9): error CS0106: The modifier 'internal' is not valid for this item // internal void localFunc() {} Diagnostic(ErrorCode.ERR_BadMemberFlag, $"{accessibility}").WithArguments($"{accessibility}").WithLocation(11, 9), // (12,5): error CS1022: Type or namespace definition, or end-of-file expected // } Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(12, 5), // (14,6): error CS1513: } expected // { Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(14, 6), // (18,5): error CS0106: The modifier 'internal' is not valid for this item // internal void M4() {} Diagnostic(ErrorCode.ERR_BadMemberFlag, $"{accessibility}").WithArguments($"{accessibility}").WithLocation(17, 5), // (19,1): error CS1022: Type or namespace definition, or end-of-file expected // } Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(18, 1)); var accessibilityKind = SyntaxFacts.GetKeywordKind(accessibility); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.MethodDeclaration); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "M"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); M(SyntaxKind.CloseBraceToken); } } N(SyntaxKind.MethodDeclaration); { N(accessibilityKind); N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "localFunc"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.LocalFunctionStatement); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "M2"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "typing"); } M(SyntaxKind.SemicolonToken); } M(SyntaxKind.CloseBraceToken); } } } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.LocalFunctionStatement); { N(accessibilityKind); N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "localFunc"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } } } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.LocalFunctionStatement); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "M3"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); M(SyntaxKind.CloseBraceToken); } } } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.LocalFunctionStatement); { N(accessibilityKind); N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "M4"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void TestGlobalAttributeGarbageAfterLocation() { var text = "[assembly: $"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); } [Fact] public void TestGlobalAttributeUsingAfterLocation() { var text = "[assembly: using n;"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_UsingAfterElements, file.Errors()[2].Code); } [Fact] public void TestGlobalAttributeExternAfterLocation() { var text = "[assembly: extern alias a;"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_ExternAfterElements, file.Errors()[2].Code); } [Fact] public void TestGlobalAttributeNamespaceAfterLocation() { var text = "[assembly: namespace n { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGlobalAttributeClassAfterLocation() { var text = "[assembly: class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGlobalAttributeAttributeAfterLocation() { var text = "[assembly: [assembly: attr]"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGlobalAttributeEOFAfterLocation() { var text = "[assembly: "; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGlobalAttributeGarbageAfterAttribute() { var text = "[assembly: a $"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGlobalAttributeGarbageAfterParameterStart() { var text = "[assembly: a( $"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); } [Fact] public void TestGlobalAttributeGarbageAfterParameter() { var text = "[assembly: a(b $"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); } [Fact] public void TestGlobalAttributeMissingCommaBetweenParameters() { var text = "[assembly: a(b c)"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGlobalAttributeWithGarbageBetweenParameters() { var text = "[assembly: a(b $ c)"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); } [Fact] public void TestGlobalAttributeWithGarbageBetweenAttributes() { var text = "[assembly: a $ b"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(3, file.Errors().Length); file.Errors().Verify( // error CS1056: Unexpected character '$' Diagnostic(ErrorCode.ERR_UnexpectedCharacter).WithArguments("$"), // error CS1003: Syntax error, ',' expected Diagnostic(ErrorCode.ERR_SyntaxError).WithArguments(","), // error CS1003: Syntax error, ']' expected Diagnostic(ErrorCode.ERR_SyntaxError).WithArguments("]") ); } [Fact] public void TestGlobalAttributeWithUsingAfterParameterStart() { var text = "[assembly: a( using n;"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_UsingAfterElements, file.Errors()[2].Code); } [Fact] public void TestGlobalAttributeWithExternAfterParameterStart() { var text = "[assembly: a( extern alias n;"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(0, file.Members.Count); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_ExternAfterElements, file.Errors()[2].Code); } [Fact] public void TestGlobalAttributeWithNamespaceAfterParameterStart() { var text = "[assembly: a( namespace n { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGlobalAttributeWithClassAfterParameterStart() { var text = "[assembly: a( class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.AttributeLists.Count); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGarbageBeforeNamespace() { var text = "$ namespace n { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterNamespace() { var text = "namespace n { } $"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void MultipleSubsequentMisplacedCharactersSingleError1() { var text = "namespace n { } ,,,,,,,,"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_EOFExpected, file.Errors()[0].Code); } [Fact] public void MultipleSubsequentMisplacedCharactersSingleError2() { var text = ",,,, namespace n { } ,,,,"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_EOFExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_EOFExpected, file.Errors()[1].Code); } [Fact] public void TestGarbageInsideNamespace() { var text = "namespace n { $ }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestIncompleteGlobalMembers() { var text = @" asas] extern alias A; asas using System; sadasdasd] [assembly: goo] class C { } [a]fod; [b"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); } [Fact] public void TestAttributeWithGarbageAfterStart() { var text = "[ $"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.IncompleteMember, file.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); } [Fact] public void TestAttributeWithGarbageAfterName() { var text = "[a $"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.IncompleteMember, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestAttributeWithClassAfterBracket() { var text = "[ class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestAttributeWithClassAfterName() { var text = "[a class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestAttributeWithClassAfterParameterStart() { var text = "[a( class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestAttributeWithClassAfterParameter() { var text = "[a(b class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestAttributeWithClassAfterParameterAndComma() { var text = "[a(b, class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); } [Fact] public void TestAttributeWithCommaAfterParameterStart() { var text = "[a(, class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[3].Code); } [Fact] public void TestAttributeWithCommasAfterParameterStart() { var text = "[a(,, class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(5, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[3].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[4].Code); } [Fact] public void TestAttributeWithMissingFirstParameter() { var text = "[a(, b class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); } [Fact] public void TestNamespaceWithGarbage() { var text = "namespace n { $ }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestNamespaceWithUnexpectedKeyword() { var text = "namespace n { int }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_NamespaceUnexpected, file.Errors()[0].Code); } [Fact] public void TestNamespaceWithUnexpectedBracing() { var text = "namespace n { { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_EOFExpected, file.Errors()[0].Code); } [Fact] public void TestGlobalNamespaceWithUnexpectedBracingAtEnd() { var text = "namespace n { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_EOFExpected, file.Errors()[0].Code); } [Fact] public void TestGlobalNamespaceWithUnexpectedBracingAtStart() { var text = "} namespace n { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_EOFExpected, file.Errors()[0].Code); } [Fact] public void TestGlobalNamespaceWithOpenBraceBeforeNamespace() { var text = "{ namespace n { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); } [Fact] public void TestPartialNamespace() { var text = "partial namespace n { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.NamespaceDeclaration, file.Members[0].Kind()); Assert.Equal(0, file.Errors().Length); } [Fact] public void TestClassAfterStartOfBaseTypeList() { var text = "class c : class b { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestClassAfterBaseType() { var text = "class c : t class b { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); } [Fact] public void TestClassAfterBaseTypeAndComma() { var text = "class c : t, class b { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestClassAfterBaseTypesWithMissingComma() { var text = "class c : x y class b { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestGarbageAfterStartOfBaseTypeList() { var text = "class c : $ { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterBaseType() { var text = "class c : t $ { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterBaseTypeAndComma() { var text = "class c : t, $ { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterBaseTypesWithMissingComma() { var text = "class c : x y $ { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestConstraintAfterStartOfBaseTypeList() { var text = "class c<t> : where t : b { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); } [Fact] public void TestConstraintAfterBaseType() { var text = "class c<t> : x where t : b { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(0, file.Errors().Length); } [Fact] public void TestConstraintAfterBaseTypeComma() { var text = "class c<t> : x, where t : b { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); } [Fact] public void TestConstraintAfterBaseTypes() { var text = "class c<t> : x, y where t : b { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(0, file.Errors().Length); } [Fact] public void TestConstraintAfterBaseTypesWithMissingComma() { var text = "class c<t> : x y where t : b { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestOpenBraceAfterStartOfBaseTypeList() { var text = "class c<t> : { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); } [Fact] public void TestOpenBraceAfterBaseType() { var text = "class c<t> : x { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(0, file.Errors().Length); } [Fact] public void TestOpenBraceAfterBaseTypeComma() { var text = "class c<t> : x, { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); } [Fact] public void TestOpenBraceAfterBaseTypes() { var text = "class c<t> : x, y { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(0, file.Errors().Length); } [Fact] public void TestBaseTypesWithMissingComma() { var text = "class c<t> : x y { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestOpenBraceAfterConstraintStart() { var text = "class c<t> where { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[2].Code); } [Fact] public void TestOpenBraceAfterConstraintName() { var text = "class c<t> where t { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[1].Code); } [Fact] public void TestOpenBraceAfterConstraintNameAndColon() { var text = "class c<t> where t : { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); } [Fact] public void TestOpenBraceAfterConstraintNameAndTypeAndComma() { var text = "class c<t> where t : x, { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); } [Fact] public void TestConstraintAfterConstraintStart() { var text = "class c<t> where where t : a { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[2].Code); } [Fact] public void TestConstraintAfterConstraintName() { var text = "class c<t> where t where t : a { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[1].Code); } [Fact] public void TestConstraintAfterConstraintNameAndColon() { var text = "class c<t> where t : where t : a { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); } [Fact] public void TestConstraintAfterConstraintNameColonTypeAndComma() { var text = "class c<t> where t : a, where t : a { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterConstraintStart() { var text = "class c<t> where $ { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[3].Code); } [Fact] public void TestGarbageAfterConstraintName() { var text = "class c<t> where t $ { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[2].Code); } [Fact] public void TestGarbageAfterConstraintNameAndColon() { var text = "class c<t> where t : $ { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterConstraintNameColonAndType() { var text = "class c<t> where t : x $ { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterConstraintNameColonTypeAndComma() { var text = "class c<t> where t : x, $ { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterGenericClassNameStart() { var text = "class c<$> { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterGenericClassNameType() { var text = "class c<t $> { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterGenericClassNameTypeAndComma() { var text = "class c<t, $> { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestOpenBraceAfterGenericClassNameStart() { var text = "class c< { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestOpenBraceAfterGenericClassNameAndType() { var text = "class c<t { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestClassAfterGenericClassNameStart() { var text = "class c< class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[3].Code); } [Fact] public void TestClassAfterGenericClassNameAndType() { var text = "class c<t class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestClassAfterGenericClassNameTypeAndComma() { var text = "class c<t, class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[3].Code); } [Fact] public void TestBaseTypeAfterGenericClassNameStart() { var text = "class c< : x { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestBaseTypeAfterGenericClassNameAndType() { var text = "class c<t : x { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestBaseTypeAfterGenericClassNameTypeAndComma() { var text = "class c<t, : x { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestConstraintAfterGenericClassNameStart() { var text = "class c< where t : x { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestConstraintAfterGenericClassNameAndType() { var text = "class c<t where t : x { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestConstraintAfterGenericClassNameTypeAndComma() { var text = "class c<t, where t : x { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestFieldAfterFieldStart() { var text = "class c { int int y; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.IncompleteMember, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidMemberDecl, file.Errors()[0].Code); } [Fact] public void TestFieldAfterFieldTypeAndName() { var text = "class c { int x int y; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[0].Code); } [Fact] public void TestFieldAfterFieldTypeNameAndComma() { var text = "class c { int x, int y; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterFieldStart() { var text = "class c { int $ int y; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.IncompleteMember, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidMemberDecl, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_InvalidMemberDecl, file.Errors()[2].Code); } [Fact] public void TestGarbageAfterFieldTypeAndName() { var text = "class c { int x $ int y; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterFieldTypeNameAndComma() { var text = "class c { int x, $ int y; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestEndBraceAfterFieldStart() { var text = "class c { int }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IncompleteMember, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidMemberDecl, file.Errors()[0].Code); } [Fact] public void TestEndBraceAfterFieldName() { var text = "class c { int x }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[0].Code); } [Fact] public void TestEndBraceAfterFieldNameAndComma() { var text = "class c { int x, }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestEndBraceAfterMethodParameterStart() { var text = "class c { int m( }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestEndBraceAfterMethodParameterType() { var text = "class c { int m(x }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestEndBraceAfterMethodParameterName() { var text = "class c { int m(x y}"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestEndBraceAfterMethodParameterTypeNameAndComma() { var text = "class c { int m(x y, }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[3].Code); } [Fact] public void TestEndBraceAfterMethodParameters() { var text = "class c { int m() }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterMethodParameterStart() { var text = "class c { int m( $ ); }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterMethodParameterType() { var text = "class c { int m( x $ ); }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterMethodParameterTypeAndName() { var text = "class c { int m( x y $ ); }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterMethodParameterTypeNameAndComma() { var text = "class c { int m( x y, $ ); }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[2].Code); } [Fact] public void TestMethodAfterMethodParameterStart() { var text = "class c { int m( public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestMethodAfterMethodParameterType() { var text = "class c { int m(x public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestMethodAfterMethodParameterTypeAndName() { var text = "class c { int m(x y public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestMethodAfterMethodParameterTypeNameAndComma() { var text = "class c { int m(x y, public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[3].Code); } [Fact] public void TestMethodAfterMethodParameterList() { var text = "class c { int m(x y) public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[0].Code); } [Fact] public void TestMethodBodyAfterMethodParameterListStart() { var text = "class c { int m( { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); } [Fact] public void TestSemicolonAfterMethodParameterListStart() { var text = "class c { int m( ; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); } [Fact] public void TestConstructorBodyAfterConstructorParameterListStart() { var text = "class c { c( { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.ConstructorDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); } [Fact] public void TestSemicolonAfterDelegateParameterListStart() { var text = "delegate void d( ;"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); var agg = (DelegateDeclarationSyntax)file.Members[0]; Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); } [Fact] public void TestEndBraceAfterIndexerParameterStart() { var text = "class c { int this[ }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); CreateCompilation(text).VerifyDiagnostics( // (1,21): error CS1003: Syntax error, ']' expected // class c { int this[ } Diagnostic(ErrorCode.ERR_SyntaxError, "}").WithArguments("]").WithLocation(1, 21), // (1,21): error CS1514: { expected // class c { int this[ } Diagnostic(ErrorCode.ERR_LbraceExpected, "}").WithLocation(1, 21), // (1,22): error CS1513: } expected // class c { int this[ } Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(1, 22), // (1,7): warning CS8981: The type name 'c' only contains lower-cased ascii characters. Such names may become reserved for the language. // class c { int this[ } Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "c").WithArguments("c").WithLocation(1, 7), // (1,19): error CS1551: Indexers must have at least one parameter // class c { int this[ } Diagnostic(ErrorCode.ERR_IndexerNeedsParam, "[").WithLocation(1, 19), // (1,15): error CS0548: 'c.this': property or indexer must have at least one accessor // class c { int this[ } Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "this").WithArguments("c.this").WithLocation(1, 15)); } [Fact] public void TestEndBraceAfterIndexerParameterType() { var text = "class c { int this[x }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[3].Code); } [Fact] public void TestEndBraceAfterIndexerParameterName() { var text = "class c { int this[x y }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestEndBraceAfterIndexerParameterTypeNameAndComma() { var text = "class c { int this[x y, }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(5, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[3].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[4].Code); } [Fact] public void TestEndBraceAfterIndexerParameters() { var text = "class c { int this[x y] }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterIndexerParameterStart() { var text = "class c { int this[ $ ] { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); CreateCompilation(text).VerifyDiagnostics( // (1,21): error CS1056: Unexpected character '$' // class c { int this[ $ ] { } } Diagnostic(ErrorCode.ERR_UnexpectedCharacter, "").WithArguments("$").WithLocation(1, 21), // (1,7): warning CS8981: The type name 'c' only contains lower-cased ascii characters. Such names may become reserved for the language. // class c { int this[ $ ] { } } Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "c").WithArguments("c").WithLocation(1, 7), // (1,23): error CS1551: Indexers must have at least one parameter // class c { int this[ $ ] { } } Diagnostic(ErrorCode.ERR_IndexerNeedsParam, "]").WithLocation(1, 23), // (1,15): error CS0548: 'c.this': property or indexer must have at least one accessor // class c { int this[ $ ] { } } Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "this").WithArguments("c.this").WithLocation(1, 15)); } [Fact] public void TestGarbageAfterIndexerParameterType() { var text = "class c { int this[ x $ ] { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterIndexerParameterTypeAndName() { var text = "class c { int this[ x y $ ] { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterIndexerParameterTypeNameAndComma() { var text = "class c { int this[ x y, $ ] { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[2].Code); } [Fact] public void TestMethodAfterIndexerParameterStart() { var text = "class c { int this[ public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); CreateCompilation(text).VerifyDiagnostics( // (1,21): error CS1003: Syntax error, ']' expected // class c { int this[ public void m() { } } Diagnostic(ErrorCode.ERR_SyntaxError, "public").WithArguments("]").WithLocation(1, 21), // (1,21): error CS1514: { expected // class c { int this[ public void m() { } } Diagnostic(ErrorCode.ERR_LbraceExpected, "public").WithLocation(1, 21), // (1,21): error CS1513: } expected // class c { int this[ public void m() { } } Diagnostic(ErrorCode.ERR_RbraceExpected, "public").WithLocation(1, 21), // (1,7): warning CS8981: The type name 'c' only contains lower-cased ascii characters. Such names may become reserved for the language. // class c { int this[ public void m() { } } Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "c").WithArguments("c").WithLocation(1, 7), // (1,19): error CS1551: Indexers must have at least one parameter // class c { int this[ public void m() { } } Diagnostic(ErrorCode.ERR_IndexerNeedsParam, "[").WithLocation(1, 19), // (1,15): error CS0548: 'c.this': property or indexer must have at least one accessor // class c { int this[ public void m() { } } Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "this").WithArguments("c.this").WithLocation(1, 15)); } [Fact] public void TestMethodAfterIndexerParameterType() { var text = "class c { int this[x public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[3].Code); } [Fact] public void TestMethodAfterIndexerParameterTypeAndName() { var text = "class c { int this[x y public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestMethodAfterIndexerParameterTypeNameAndComma() { var text = "class c { int this[x y, public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(5, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[3].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[4].Code); } [Fact] public void TestMethodAfterIndexerParameterList() { var text = "class c { int this[x y] public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.IndexerDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); } [Fact] public void TestEOFAfterDelegateStart() { var text = "delegate"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(5, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[3].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[4].Code); } [Fact] public void TestEOFAfterDelegateType() { var text = "delegate d"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[3].Code); } [Fact] public void TestEOFAfterDelegateName() { var text = "delegate void d"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestEOFAfterDelegateParameterStart() { var text = "delegate void d("; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestEOFAfterDelegateParameterType() { var text = "delegate void d(t"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestEOFAfterDelegateParameterTypeName() { var text = "delegate void d(t n"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestEOFAfterDelegateParameterList() { var text = "delegate void d(t n)"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[0].Code); } [Fact] public void TestEOFAfterDelegateParameterTypeNameAndComma() { var text = "delegate void d(t n, "; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[3].Code); } [Fact] public void TestClassAfterDelegateStart() { var text = "delegate class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(5, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[3].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[4].Code); } [Fact] public void TestClassAfterDelegateType() { var text = "delegate d class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[3].Code); } [Fact] public void TestClassAfterDelegateName() { var text = "delegate void d class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestClassAfterDelegateParameterStart() { var text = "delegate void d( class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestClassAfterDelegateParameterType() { var text = "delegate void d(t class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestClassAfterDelegateParameterTypeName() { var text = "delegate void d(t n class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestClassAfterDelegateParameterList() { var text = "delegate void d(t n) class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[0].Code); } [Fact] public void TestClassAfterDelegateParameterTypeNameAndComma() { var text = "delegate void d(t n, class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[3].Code); } [Fact] public void TestGarbageAfterDelegateParameterStart() { var text = "delegate void d($);"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterDelegateParameterType() { var text = "delegate void d(t $);"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterDelegateParameterTypeAndName() { var text = "delegate void d(t n $);"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterDelegateParameterTypeNameAndComma() { var text = "delegate void d(t n, $);"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.DelegateDeclaration, file.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[2].Code); } [Fact] public void TestGarbageAfterEnumStart() { var text = "enum e { $ }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterEnumName() { var text = "enum e { n $ }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBeforeEnumName() { var text = "enum e { $ n }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAferEnumNameAndComma() { var text = "enum e { n, $ }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAferEnumNameCommaAndName() { var text = "enum e { n, n $ }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBetweenEnumNames() { var text = "enum e { n, $ n }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBetweenEnumNamesWithMissingComma() { var text = "enum e { n $ n }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGarbageAferEnumNameAndEquals() { var text = "enum e { n = $ }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestEOFAfterEnumStart() { var text = "enum e { "; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestEOFAfterEnumName() { var text = "enum e { n "; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestEOFAfterEnumNameAndComma() { var text = "enum e { n, "; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestClassAfterEnumStart() { var text = "enum e { class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestClassAfterEnumName() { var text = "enum e { n class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestClassAfterEnumNameAndComma() { var text = "enum e { n, class c { }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Members.Count); Assert.Equal(SyntaxKind.EnumDeclaration, file.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterFixedFieldRankStart() { var text = "class c { fixed int x[$]; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_ValueExpected, file.Errors()[1].Code); } [Fact] public void TestGarbageBeforeFixedFieldRankSize() { var text = "class c { fixed int x[$ 10]; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterFixedFieldRankSize() { var text = "class c { fixed int x[10 $]; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal(ErrorCode.ERR_SyntaxError, (ErrorCode)file.Errors()[0].Code); //expected comma Assert.Equal(ErrorCode.ERR_UnexpectedCharacter, (ErrorCode)file.Errors()[1].Code); //didn't expect '$' Assert.Equal(ErrorCode.ERR_ValueExpected, (ErrorCode)file.Errors()[2].Code); //expected value after (missing) comma } [Fact] public void TestGarbageAfterFieldTypeRankStart() { var text = "class c { int[$] x; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterFieldTypeRankComma() { var text = "class c { int[,$] x; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBeforeFieldTypeRankComma() { var text = "class c { int[$,] x; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestEndBraceAfterFieldRankStart() { var text = "class c { int[ }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(SyntaxKind.IncompleteMember, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestEndBraceAfterFieldRankComma() { var text = "class c { int[, }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(SyntaxKind.IncompleteMember, agg.Members[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestMethodAfterFieldRankStart() { var text = "class c { int[ public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.IncompleteMember, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestMethodAfterFieldRankComma() { var text = "class c { int[, public void m() { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.IncompleteMember, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestStatementAfterLocalDeclarationStart() { var text = "class c { void m() { int if (x) y(); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterLocalRankStart() { var text = "class c { void m() { int [ if (x) y(); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestStatementAfterLocalRankComma() { var text = "class c { void m() { int [, if (x) y(); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestStatementAfterLocalDeclarationWithMissingSemicolon() { var text = "class c { void m() { int a if (x) y(); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[0].Code); } [Fact] public void TestStatementAfterLocalDeclarationWithCommaAndMissingSemicolon() { var text = "class c { void m() { int a, if (x) y(); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterLocalDeclarationEquals() { var text = "class c { void m() { int a = if (x) y(); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterLocalDeclarationArrayInitializerStart() { var text = "class c { void m() { int a = { if (x) y(); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterLocalDeclarationArrayInitializerExpression() { var text = "class c { void m() { int a = { e if (x) y(); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterLocalDeclarationArrayInitializerExpressionAndComma() { var text = "class c { void m() { int a = { e, if (x) y(); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterLocalDeclarationArrayInitializerStart() { var text = "class c { void m() { int a = { $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterLocalDeclarationArrayInitializerExpression() { var text = "class c { void m() { int a = { e $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBeforeLocalDeclarationArrayInitializerExpression() { var text = "class c { void m() { int a = { $ e }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterLocalDeclarationArrayInitializerExpressionAndComma() { var text = "class c { void m() { int a = { e, $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterLocalDeclarationArrayInitializerExpressions() { var text = "class c { void m() { int a = { e, e $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBetweenLocalDeclarationArrayInitializerExpressions() { var text = "class c { void m() { int a = { e, $ e }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBetweenLocalDeclarationArrayInitializerExpressionsWithMissingComma() { var text = "class c { void m() { int a = { e $ e }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterMethodCallStart() { var text = "class c { void m() { m($); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterMethodArgument() { var text = "class c { void m() { m(a $); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBeforeMethodArgument() { var text = "class c { void m() { m($ a); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBeforeMethodArgumentAndComma() { var text = "class c { void m() { m(a, $); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestSemiColonAfterMethodCallStart() { var text = "class c { void m() { m(; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); } [Fact] public void TestSemiColonAfterMethodCallArgument() { var text = "class c { void m() { m(a; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); } [Fact] public void TestSemiColonAfterMethodCallArgumentAndComma() { var text = "class c { void m() { m(a,; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); } [Fact] public void TestClosingBraceAfterMethodCallArgumentAndCommaWithWhitespace() { var text = "class c { void m() { m(a,\t\t\n\t\t\t} }"; var file = this.ParseTree(text); var md = (file.Members[0] as TypeDeclarationSyntax).Members[0] as MethodDeclarationSyntax; var ie = (md.Body.Statements[0] as ExpressionStatementSyntax).Expression as InvocationExpressionSyntax; // whitespace trivia is part of the following '}', not the invocation expression Assert.Equal("", ie.ArgumentList.CloseParenToken.ToFullString()); Assert.Equal("\t\t\t} ", md.Body.CloseBraceToken.ToFullString()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestStatementAfterMethodCallStart() { var text = "class c { void m() { m( if(e) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterMethodCallArgument() { var text = "class c { void m() { m(a if(e) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterMethodCallArgumentAndComma() { var text = "class c { void m() { m(a, if(e) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestCloseBraceAfterMethodCallStart() { var text = "class c { void m() { m( } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestCloseBraceAfterMethodCallArgument() { var text = "class c { void m() { m(a } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestCloseBraceAfterMethodCallArgumentAndComma() { var text = "class c { void m() { m(a, } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.InvocationExpression, es.Expression.Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestGarbageAfterIndexerStart() { var text = "class c { void m() { ++a[$]; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterIndexerArgument() { var text = "class c { void m() { ++a[e $]; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBeforeIndexerArgument() { var text = "class c { void m() { ++a[$ e]; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBeforeIndexerArgumentAndComma() { var text = "class c { void m() { ++a[e, $]; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestSemiColonAfterIndexerStart() { var text = "class c { void m() { ++a[; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestSemiColonAfterIndexerArgument() { var text = "class c { void m() { ++a[e; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestSemiColonAfterIndexerArgumentAndComma() { var text = "class c { void m() { ++a[e,; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); } [Fact] public void TestStatementAfterIndexerStart() { var text = "class c { void m() { ++a[ if(e) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterIndexerArgument() { var text = "class c { void m() { ++a[e if(e) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterIndexerArgumentAndComma() { var text = "class c { void m() { ++a[e, if(e) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.IfStatement, ms.Body.Statements[1].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestCloseBraceAfterIndexerStart() { var text = "class c { void m() { ++a[ } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestCloseBraceAfterIndexerArgument() { var text = "class c { void m() { ++a[e } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestCloseBraceAfterIndexerArgumentAndComma() { var text = "class c { void m() { ++a[e, } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ExpressionStatement, ms.Body.Statements[0].Kind()); var es = (ExpressionStatementSyntax)ms.Body.Statements[0]; Assert.Equal(SyntaxKind.PreIncrementExpression, es.Expression.Kind()); Assert.Equal(SyntaxKind.ElementAccessExpression, ((PrefixUnaryExpressionSyntax)es.Expression).Operand.Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestOpenBraceAfterFixedStatementStart() { var text = "class c { void m() { fixed(t v { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.FixedStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); } [Fact] public void TestSemiColonAfterFixedStatementStart() { var text = "class c { void m() { fixed(t v; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.FixedStatement, ms.Body.Statements[0].Kind()); var diags = file.ErrorsAndWarnings(); Assert.Equal(1, diags.Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, diags[0].Code); CreateCompilation(text, parseOptions: TestOptions.Regular14).VerifyDiagnostics( // (1,31): error CS1026: ) expected // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(1, 31), // (1,7): warning CS8981: The type name 'c' only contains lower-cased ascii characters. Such names may become reserved for the language. // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "c").WithArguments("c").WithLocation(1, 7), // (1,22): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.ERR_UnsafeNeeded, "fixed(t v;").WithLocation(1, 22), // (1,28): error CS0246: The type or namespace name 't' could not be found (are you missing a using directive or an assembly reference?) // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "t").WithArguments("t").WithLocation(1, 28), // (1,30): error CS0209: The type of a local declared in a fixed statement must be a pointer type // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.ERR_BadFixedInitType, "v").WithLocation(1, 30), // (1,30): error CS0210: You must provide an initializer in a fixed or using statement declaration // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.ERR_FixedMustInit, "v").WithLocation(1, 30), // (1,31): warning CS0642: Possible mistaken empty statement // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.WRN_PossibleMistakenNullStatement, ";").WithLocation(1, 31)); var expectedPreviewDiagnostics = new[] { // (1,31): error CS1026: ) expected // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(1, 31), // (1,7): warning CS8981: The type name 'c' only contains lower-cased ascii characters. Such names may become reserved for the language. // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "c").WithArguments("c").WithLocation(1, 7), // (1,28): error CS0246: The type or namespace name 't' could not be found (are you missing a using directive or an assembly reference?) // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "t").WithArguments("t").WithLocation(1, 28), // (1,30): error CS0209: The type of a local declared in a fixed statement must be a pointer type // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.ERR_BadFixedInitType, "v").WithLocation(1, 30), // (1,30): error CS0210: You must provide an initializer in a fixed or using statement declaration // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.ERR_FixedMustInit, "v").WithLocation(1, 30), // (1,31): warning CS0642: Possible mistaken empty statement // class c { void m() { fixed(t v; } } Diagnostic(ErrorCode.WRN_PossibleMistakenNullStatement, ";").WithLocation(1, 31), }; CreateCompilation(text).VerifyDiagnostics(expectedPreviewDiagnostics); CreateCompilation(text, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedPreviewDiagnostics); } [Fact] public void TestSemiColonAfterFixedStatementType() { var text = "class c { void m() { fixed(t ) { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.FixedStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); } [Fact] public void TestCatchAfterTryBlockStart() { var text = "class c { void m() { try { catch { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.TryStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestFinallyAfterTryBlockStart() { var text = "class c { void m() { try { finally { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.TryStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestFinallyAfterCatchStart() { var text = "class c { void m() { try { } catch finally { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.TryStatement, ms.Body.Statements[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); } [Fact] public void TestCatchAfterCatchStart() { var text = "class c { void m() { try { } catch catch { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.TryStatement, ms.Body.Statements[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); } [Fact] public void TestFinallyAfterCatchParameterStart() { var text = "class c { void m() { try { } catch (t finally { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.TryStatement, ms.Body.Statements[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestCatchAfterCatchParameterStart() { var text = "class c { void m() { try { } catch (t catch { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.TryStatement, ms.Body.Statements[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestCloseBraceAfterCatchStart() { var text = "class c { void m() { try { } catch } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.TryStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[0].Code); } [Fact] public void TestCloseBraceAfterCatchParameterStart() { var text = "class c { void m() { try { } catch(t } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.TryStatement, ms.Body.Statements[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); } [Fact] public void TestSemiColonAfterDoWhileExpressionIndexer() { // this shows that ';' is an exit condition for the expression var text = "class c { void m() { do { } while(e[; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.DoStatement, ms.Body.Statements[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); } [Fact] public void TestCloseParenAfterDoWhileExpressionIndexerStart() { // this shows that ')' is an exit condition for the expression var text = "class c { void m() { do { } while(e[); } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.DoStatement, ms.Body.Statements[0].Kind()); file.Errors().Verify( // error CS1003: Syntax error, ']' expected Diagnostic(ErrorCode.ERR_SyntaxError).WithArguments("]").WithLocation(1, 1), // error CS1026: ) expected Diagnostic(ErrorCode.ERR_CloseParenExpected).WithLocation(1, 1) ); } [Fact] public void TestCloseParenAfterForStatementInitializerStart() { // this shows that ';' is an exit condition for the initializer expression var text = "class c { void m() { for (a[;;) { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ForStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestOpenBraceAfterForStatementInitializerStart() { // this shows that '{' is an exit condition for the initializer expression var text = "class c { void m() { for (a[ { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ForStatement, ms.Body.Statements[0].Kind()); Assert.Equal(5, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[3].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[4].Code); } [Fact] public void TestCloseBraceAfterForStatementInitializerStart() { // this shows that '}' is an exit condition for the initializer expression var text = "class c { void m() { for (a[ } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ForStatement, ms.Body.Statements[0].Kind()); Assert.Equal(7, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[3].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[4].Code); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[5].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[6].Code); } [Fact] public void TestCloseParenAfterForStatementConditionStart() { var text = "class c { void m() { for (;a[;) { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ForStatement, ms.Body.Statements[0].Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); } [Fact] public void TestOpenBraceAfterForStatementConditionStart() { var text = "class c { void m() { for (;a[ { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ForStatement, ms.Body.Statements[0].Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[2].Code); } [Fact] public void TestCloseBraceAfterForStatementConditionStart() { var text = "class c { void m() { for (;a[ } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ForStatement, ms.Body.Statements[0].Kind()); Assert.Equal(5, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[3].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[4].Code); } [Fact] public void TestCloseParenAfterForStatementIncrementerStart() { var text = "class c { void m() { for (;;++a[) { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ForStatement, ms.Body.Statements[0].Kind()); file.Errors().Verify( // error CS1003: Syntax error, ']' expected Diagnostic(ErrorCode.ERR_SyntaxError).WithArguments("]").WithLocation(1, 1), // error CS1026: ) expected Diagnostic(ErrorCode.ERR_CloseParenExpected).WithLocation(1, 1) ); } [Fact] public void TestOpenBraceAfterForStatementIncrementerStart() { var text = "class c { void m() { for (;;++a[ { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ForStatement, ms.Body.Statements[0].Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); } [Fact] public void TestCloseBraceAfterForStatementIncrementerStart() { var text = "class c { void m() { for (;;++a[ } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.ForStatement, ms.Body.Statements[0].Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[3].Code); } [Fact] public void TestCloseBraceAfterAnonymousTypeStart() { // empty anonymous type is perfectly legal var text = "class c { void m() { var x = new {}; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(0, file.Errors().Length); } [Fact] public void TestSemicolonAfterAnonymousTypeStart() { var text = "class c { void m() { var x = new {; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.Kind()); Assert.NotEqual(default, ds.Declaration.Variables[0].Initializer.EqualsToken); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestSemicolonAfterAnonymousTypeMemberStart() { var text = "class c { void m() { var x = new {a; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestSemicolonAfterAnonymousTypeMemberEquals() { var text = "class c { void m() { var x = new {a =; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); } [Fact] public void TestSemicolonAfterAnonymousTypeMember() { var text = "class c { void m() { var x = new {a = b; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestSemicolonAfterAnonymousTypeMemberComma() { var text = "class c { void m() { var x = new {a = b, ; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestStatementAfterAnonymousTypeStart() { var text = "class c { void m() { var x = new { while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterAnonymousTypeMemberStart() { var text = "class c { void m() { var x = new { a while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterAnonymousTypeMemberEquals() { var text = "class c { void m() { var x = new { a = while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestStatementAfterAnonymousTypeMember() { var text = "class c { void m() { var x = new { a = b while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterAnonymousTypeMemberComma() { var text = "class c { void m() { var x = new { a = b, while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterAnonymousTypeStart() { var text = "class c { void m() { var x = new { $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBeforeAnonymousTypeMemberStart() { var text = "class c { void m() { var x = new { $ a }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterAnonymousTypeMemberStart() { var text = "class c { void m() { var x = new { a $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterAnonymousTypeMemberEquals() { var text = "class c { void m() { var x = new { a = $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterAnonymousTypeMember() { var text = "class c { void m() { var x = new { a = b $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterAnonymousTypeMemberComma() { var text = "class c { void m() { var x = new { a = b, $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.AnonymousObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestCloseBraceAfterObjectInitializerStart() { // empty object initializer is perfectly legal var text = "class c { void m() { var x = new C {}; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(0, file.Errors().Length); } [Fact] public void TestSemicolonAfterObjectInitializerStart() { var text = "class c { void m() { var x = new C {; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[3].Code); } [Fact] public void TestSemicolonAfterObjectInitializerMemberStart() { var text = "class c { void m() { var x = new C { a; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestSemicolonAfterObjectInitializerMemberEquals() { var text = "class c { void m() { var x = new C { a =; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[3].Code); } [Fact] public void TestSemicolonAfterObjectInitializerMember() { var text = "class c { void m() { var x = new C { a = b; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestSemicolonAfterObjectInitializerMember2() { var text = "class c { void m() { var x = new C { a = b; }; var y = 5; } }"; UsingTree(text, // (1,43): error CS1003: Syntax error, ',' expected // class c { void m() { var x = new C { a = b; }; var y = 5; } } Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(",").WithLocation(1, 43)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "c"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.MethodDeclaration); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "m"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.LocalDeclarationStatement); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.VariableDeclarator); { N(SyntaxKind.IdentifierToken, "x"); N(SyntaxKind.EqualsValueClause); { N(SyntaxKind.EqualsToken); N(SyntaxKind.ObjectCreationExpression); { N(SyntaxKind.NewKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "C"); } N(SyntaxKind.ObjectInitializerExpression); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.SimpleAssignmentExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "a"); } N(SyntaxKind.EqualsToken); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "b"); } } N(SyntaxKind.SemicolonToken); N(SyntaxKind.CloseBraceToken); } } } } } N(SyntaxKind.SemicolonToken); } N(SyntaxKind.LocalDeclarationStatement); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.VariableDeclarator); { N(SyntaxKind.IdentifierToken, "y"); N(SyntaxKind.EqualsValueClause); { N(SyntaxKind.EqualsToken); N(SyntaxKind.NumericLiteralExpression); { N(SyntaxKind.NumericLiteralToken, "5"); } } } } N(SyntaxKind.SemicolonToken); } N(SyntaxKind.CloseBraceToken); } } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void TestSemicolonAfterObjectInitializerMember3() { var text = "class c { void m() { var x = new C { a = b; c = d, e = f; g = h }; var y = 5; } }"; UsingTree(text, // (1,43): error CS1003: Syntax error, ',' expected // class c { void m() { var x = new C { a = b; c = d, e = f; g = h }; var y = 5; } } Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(",").WithLocation(1, 43), // (1,57): error CS1003: Syntax error, ',' expected // class c { void m() { var x = new C { a = b; c = d, e = f; g = h }; var y = 5; } } Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(",").WithLocation(1, 57)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "c"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.MethodDeclaration); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "m"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.LocalDeclarationStatement); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.VariableDeclarator); { N(SyntaxKind.IdentifierToken, "x"); N(SyntaxKind.EqualsValueClause); { N(SyntaxKind.EqualsToken); N(SyntaxKind.ObjectCreationExpression); { N(SyntaxKind.NewKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "C"); } N(SyntaxKind.ObjectInitializerExpression); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.SimpleAssignmentExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "a"); } N(SyntaxKind.EqualsToken); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "b"); } } N(SyntaxKind.SemicolonToken); N(SyntaxKind.SimpleAssignmentExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "c"); } N(SyntaxKind.EqualsToken); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "d"); } } N(SyntaxKind.CommaToken); N(SyntaxKind.SimpleAssignmentExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "e"); } N(SyntaxKind.EqualsToken); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "f"); } } N(SyntaxKind.SemicolonToken); N(SyntaxKind.SimpleAssignmentExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "g"); } N(SyntaxKind.EqualsToken); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "h"); } } N(SyntaxKind.CloseBraceToken); } } } } } N(SyntaxKind.SemicolonToken); } N(SyntaxKind.LocalDeclarationStatement); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.VariableDeclarator); { N(SyntaxKind.IdentifierToken, "y"); N(SyntaxKind.EqualsValueClause); { N(SyntaxKind.EqualsToken); N(SyntaxKind.NumericLiteralExpression); { N(SyntaxKind.NumericLiteralToken, "5"); } } } } N(SyntaxKind.SemicolonToken); } N(SyntaxKind.CloseBraceToken); } } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void TestSemicolonAfterObjectInitializerMember4() { var text = "class c { void m() { var x = new C { a = b; }; if (true) return; } }"; UsingTree(text, // (1,43): error CS1003: Syntax error, ',' expected // class c { void m() { var x = new C { a = b; }; if (true) return; } } Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(",").WithLocation(1, 43)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "c"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.MethodDeclaration); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "m"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.LocalDeclarationStatement); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.VariableDeclarator); { N(SyntaxKind.IdentifierToken, "x"); N(SyntaxKind.EqualsValueClause); { N(SyntaxKind.EqualsToken); N(SyntaxKind.ObjectCreationExpression); { N(SyntaxKind.NewKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "C"); } N(SyntaxKind.ObjectInitializerExpression); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.SimpleAssignmentExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "a"); } N(SyntaxKind.EqualsToken); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "b"); } } N(SyntaxKind.SemicolonToken); N(SyntaxKind.CloseBraceToken); } } } } } N(SyntaxKind.SemicolonToken); } N(SyntaxKind.IfStatement); { N(SyntaxKind.IfKeyword); N(SyntaxKind.OpenParenToken); N(SyntaxKind.TrueLiteralExpression); { N(SyntaxKind.TrueKeyword); } N(SyntaxKind.CloseParenToken); N(SyntaxKind.ReturnStatement); { N(SyntaxKind.ReturnKeyword); N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.CloseBraceToken); } } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void TestSemicolonAfterObjectInitializerMember5() { var text = "class c { void m() { var x = new C { a = b; if (true) return; }; var y = 5; } }"; UsingTree(text, // (1,43): error CS1003: Syntax error, ',' expected // class c { void m() { var x = new C { a = b; if (true) return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(",").WithLocation(1, 43), // (1,45): error CS1513: } expected // class c { void m() { var x = new C { a = b; if (true) return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_RbraceExpected, "if").WithLocation(1, 45), // (1,45): error CS1002: ; expected // class c { void m() { var x = new C { a = b; if (true) return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_SemicolonExpected, "if").WithLocation(1, 45), // (1,64): error CS1597: Semicolon after method or accessor block is not valid // class c { void m() { var x = new C { a = b; if (true) return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_UnexpectedSemicolon, ";").WithLocation(1, 64), // (1,79): error CS1022: Type or namespace definition, or end-of-file expected // class c { void m() { var x = new C { a = b; if (true) return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(1, 79)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "c"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.MethodDeclaration); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "m"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.LocalDeclarationStatement); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.VariableDeclarator); { N(SyntaxKind.IdentifierToken, "x"); N(SyntaxKind.EqualsValueClause); { N(SyntaxKind.EqualsToken); N(SyntaxKind.ObjectCreationExpression); { N(SyntaxKind.NewKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "C"); } N(SyntaxKind.ObjectInitializerExpression); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.SimpleAssignmentExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "a"); } N(SyntaxKind.EqualsToken); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "b"); } } N(SyntaxKind.SemicolonToken); M(SyntaxKind.CloseBraceToken); } } } } } M(SyntaxKind.SemicolonToken); } N(SyntaxKind.IfStatement); { N(SyntaxKind.IfKeyword); N(SyntaxKind.OpenParenToken); N(SyntaxKind.TrueLiteralExpression); { N(SyntaxKind.TrueKeyword); } N(SyntaxKind.CloseParenToken); N(SyntaxKind.ReturnStatement); { N(SyntaxKind.ReturnKeyword); N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.SemicolonToken); } N(SyntaxKind.FieldDeclaration); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.VariableDeclarator); { N(SyntaxKind.IdentifierToken, "y"); N(SyntaxKind.EqualsValueClause); { N(SyntaxKind.EqualsToken); N(SyntaxKind.NumericLiteralExpression); { N(SyntaxKind.NumericLiteralToken, "5"); } } } } N(SyntaxKind.SemicolonToken); } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void TestSemicolonAfterObjectInitializerMember6() { var text = "class c { void m() { var x = new C { a = b; return; }; var y = 5; } }"; UsingTree(text, // (1,43): error CS1003: Syntax error, ',' expected // class c { void m() { var x = new C { a = b; return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(",").WithLocation(1, 43), // (1,45): error CS1513: } expected // class c { void m() { var x = new C { a = b; return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_RbraceExpected, "return").WithLocation(1, 45), // (1,45): error CS1002: ; expected // class c { void m() { var x = new C { a = b; return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_SemicolonExpected, "return").WithLocation(1, 45), // (1,54): error CS1597: Semicolon after method or accessor block is not valid // class c { void m() { var x = new C { a = b; return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_UnexpectedSemicolon, ";").WithLocation(1, 54), // (1,69): error CS1022: Type or namespace definition, or end-of-file expected // class c { void m() { var x = new C { a = b; return; }; var y = 5; } } Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(1, 69)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "c"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.MethodDeclaration); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.VoidKeyword); } N(SyntaxKind.IdentifierToken, "m"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.LocalDeclarationStatement); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.VariableDeclarator); { N(SyntaxKind.IdentifierToken, "x"); N(SyntaxKind.EqualsValueClause); { N(SyntaxKind.EqualsToken); N(SyntaxKind.ObjectCreationExpression); { N(SyntaxKind.NewKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "C"); } N(SyntaxKind.ObjectInitializerExpression); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.SimpleAssignmentExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "a"); } N(SyntaxKind.EqualsToken); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "b"); } } N(SyntaxKind.SemicolonToken); M(SyntaxKind.CloseBraceToken); } } } } } M(SyntaxKind.SemicolonToken); } N(SyntaxKind.ReturnStatement); { N(SyntaxKind.ReturnKeyword); N(SyntaxKind.SemicolonToken); } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.SemicolonToken); } N(SyntaxKind.FieldDeclaration); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.VariableDeclarator); { N(SyntaxKind.IdentifierToken, "y"); N(SyntaxKind.EqualsValueClause); { N(SyntaxKind.EqualsToken); N(SyntaxKind.NumericLiteralExpression); { N(SyntaxKind.NumericLiteralToken, "5"); } } } } N(SyntaxKind.SemicolonToken); } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void TestSemicolonAfterObjectInitializerMemberComma() { var text = "class c { void m() { var x = new C { a = b, ; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); file.GetDiagnostics().Verify( // (1,45): error CS1525: Invalid expression term ';' // class c { void m() { var x = new C { a = b, ; } } Diagnostic(ErrorCode.ERR_InvalidExprTerm, ";").WithArguments(";").WithLocation(1, 45), // (1,45): error CS1003: Syntax error, ',' expected // class c { void m() { var x = new C { a = b, ; } } Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(",").WithLocation(1, 45), // (1,49): error CS1002: ; expected // class c { void m() { var x = new C { a = b, ; } } Diagnostic(ErrorCode.ERR_SemicolonExpected, "}").WithLocation(1, 49), // (1,50): error CS1513: } expected // class c { void m() { var x = new C { a = b, ; } } Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(1, 50)); } [Fact] public void TestStatementAfterObjectInitializerStart() { var text = "class c { void m() { var x = new C { while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterObjectInitializerMemberStart() { var text = "class c { void m() { var x = new C { a while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterObjectInitializerMemberEquals() { var text = "class c { void m() { var x = new C { a = while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestStatementAfterObjectInitializerMember() { var text = "class c { void m() { var x = new C { a = b while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); } [Fact] public void TestStatementAfterObjectInitializerMemberComma() { var text = "class c { void m() { var x = new C { a = b, while (x) {} } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); file.GetDiagnostics().Verify( // (1,45): error CS1513: } expected // class c { void m() { var x = new C { a = b, while (x) {} } } Diagnostic(ErrorCode.ERR_RbraceExpected, "while").WithLocation(1, 45), // (1,45): error CS1002: ; expected // class c { void m() { var x = new C { a = b, while (x) {} } } Diagnostic(ErrorCode.ERR_SemicolonExpected, "while").WithLocation(1, 45)); } [Fact] public void TestGarbageAfterObjectInitializerStart() { var text = "class c { void m() { var x = new C { $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageBeforeObjectInitializerMemberStart() { var text = "class c { void m() { var x = new C { $ a }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterObjectInitializerMemberStart() { var text = "class c { void m() { var x = new C { a $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterObjectInitializerMemberEquals() { var text = "class c { void m() { var x = new C { a = $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[1].Code); } [Fact] public void TestGarbageAfterObjectInitializerMember() { var text = "class c { void m() { var x = new C { a = b $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_UnexpectedCharacter, file.Errors()[0].Code); } [Fact] public void TestGarbageAfterObjectInitializerMemberComma() { var text = "class c { void m() { var x = new C { a = b, $ }; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.ObjectCreationExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); file.GetDiagnostics().Verify( // (1,45): error CS1056: Unexpected character '$' // class c { void m() { var x = new C { a = b, $ }; } } Diagnostic(ErrorCode.ERR_UnexpectedCharacter, "").WithArguments("$").WithLocation(1, 45)); } [Fact] public void TestSemicolonAfterLambdaParameter() { var text = "class c { void m() { var x = (Y y, ; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.TupleExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); file.Errors().Verify( // error CS1525: Invalid expression term ';' Diagnostic(ErrorCode.ERR_InvalidExprTerm).WithArguments(";").WithLocation(1, 1), // error CS1026: ) expected Diagnostic(ErrorCode.ERR_CloseParenExpected).WithLocation(1, 1) ); } [Fact] public void TestSemicolonAfterUntypedLambdaParameter() { var text = "class c { void m() { var x = (y, ; } }"; var file = this.ParseTree(text, options: TestOptions.Regular); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.TupleExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); } [Fact] public void TestSemicolonAfterUntypedLambdaParameterWithCSharp6() { var text = "class c { void m() { var x = (y, ; } }"; var file = this.ParseTree(text, TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp6)); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(1, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.TupleExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(new[] { (int)ErrorCode.ERR_InvalidExprTerm, (int)ErrorCode.ERR_CloseParenExpected }, file.Errors().Select(e => e.Code)); CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (1,7): warning CS8981: The type name 'c' only contains lower-cased ascii characters. Such names may become reserved for the language. // class c { void m() { var x = (y, ; } } Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "c").WithArguments("c").WithLocation(1, 7), // (1,30): error CS8059: Feature 'tuples' is not available in C# 6. Please use language version 7.0 or greater. // class c { void m() { var x = (y, ; } } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion6, "(y, ").WithArguments("tuples", "7.0").WithLocation(1, 30), // (1,31): error CS0103: The name 'y' does not exist in the current context // class c { void m() { var x = (y, ; } } Diagnostic(ErrorCode.ERR_NameNotInContext, "y").WithArguments("y").WithLocation(1, 31), // (1,34): error CS1525: Invalid expression term ';' // class c { void m() { var x = (y, ; } } Diagnostic(ErrorCode.ERR_InvalidExprTerm, ";").WithArguments(";").WithLocation(1, 34), // (1,34): error CS1026: ) expected // class c { void m() { var x = (y, ; } } Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(1, 34)); } [Fact] public void TestStatementAfterLambdaParameter() { var text = "class c { void m() { var x = (Y y, while (c) { } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.TupleExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); file.Errors().Verify( // error CS1525: Invalid expression term 'while' Diagnostic(ErrorCode.ERR_InvalidExprTerm).WithArguments("while").WithLocation(1, 1), // error CS1026: ) expected Diagnostic(ErrorCode.ERR_CloseParenExpected).WithLocation(1, 1), // error CS1002: ; expected Diagnostic(ErrorCode.ERR_SemicolonExpected).WithLocation(1, 1) ); } [Fact] public void TestStatementAfterUntypedLambdaParameter() { var text = "class c { void m() { var x = (y, while (c) { } } }"; var file = this.ParseTree(text, options: TestOptions.Regular); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.TupleExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_CloseParenExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); } [Fact] public void TestStatementAfterUntypedLambdaParameterWithCSharp6() { var text = "class c { void m() { var x = (y, while (c) { } } }"; var file = this.ParseTree(text, options: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp6)); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var ms = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(ms.Body); Assert.Equal(2, ms.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, ms.Body.Statements[0].Kind()); Assert.Equal(SyntaxKind.WhileStatement, ms.Body.Statements[1].Kind()); var ds = (LocalDeclarationStatementSyntax)ms.Body.Statements[0]; Assert.Equal("var x = (y, ", ds.ToFullString()); Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotEqual(SyntaxKind.None, ds.Declaration.Variables[0].Initializer.EqualsToken.Kind()); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.TupleExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); Assert.Equal(new[] { (int)ErrorCode.ERR_InvalidExprTerm, (int)ErrorCode.ERR_CloseParenExpected, (int)ErrorCode.ERR_SemicolonExpected }, file.Errors().Select(e => e.Code)); CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (1,7): warning CS8981: The type name 'c' only contains lower-cased ascii characters. Such names may become reserved for the language. // class c { void m() { var x = (y, while (c) { } } } Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "c").WithArguments("c").WithLocation(1, 7), // (1,30): error CS8059: Feature 'tuples' is not available in C# 6. Please use language version 7.0 or greater. // class c { void m() { var x = (y, while (c) { } } } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion6, "(y, ").WithArguments("tuples", "7.0").WithLocation(1, 30), // (1,31): error CS0103: The name 'y' does not exist in the current context // class c { void m() { var x = (y, while (c) { } } } Diagnostic(ErrorCode.ERR_NameNotInContext, "y").WithArguments("y").WithLocation(1, 31), // (1,34): error CS1525: Invalid expression term 'while' // class c { void m() { var x = (y, while (c) { } } } Diagnostic(ErrorCode.ERR_InvalidExprTerm, "while").WithArguments("while").WithLocation(1, 34), // (1,34): error CS1026: ) expected // class c { void m() { var x = (y, while (c) { } } } Diagnostic(ErrorCode.ERR_CloseParenExpected, "while").WithLocation(1, 34), // (1,34): error CS1002: ; expected // class c { void m() { var x = (y, while (c) { } } } Diagnostic(ErrorCode.ERR_SemicolonExpected, "while").WithLocation(1, 34), // (1,41): error CS0119: 'c' is a type, which is not valid in the given context // class c { void m() { var x = (y, while (c) { } } } Diagnostic(ErrorCode.ERR_BadSKunknown, "c").WithArguments("c", "type").WithLocation(1, 41)); } [Fact] public void TestPropertyWithNoAccessors() { // this is syntactically valid (even though it will produce a binding error) var text = "class c { int p { } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.PropertyDeclaration, agg.Members[0].Kind()); var pd = (PropertyDeclarationSyntax)agg.Members[0]; Assert.NotNull(pd.AccessorList); Assert.NotEqual(default, pd.AccessorList.OpenBraceToken); Assert.False(pd.AccessorList.OpenBraceToken.IsMissing); Assert.NotEqual(default, pd.AccessorList.CloseBraceToken); Assert.False(pd.AccessorList.CloseBraceToken.IsMissing); Assert.Equal(0, pd.AccessorList.Accessors.Count); Assert.Equal(0, file.Errors().Length); } [Fact] public void TestMethodAfterPropertyStart() { // this is syntactically valid (even though it will produce a binding error) var text = "class c { int p { int M() {} }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.PropertyDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); var pd = (PropertyDeclarationSyntax)agg.Members[0]; Assert.NotNull(pd.AccessorList); Assert.NotEqual(default, pd.AccessorList.OpenBraceToken); Assert.False(pd.AccessorList.OpenBraceToken.IsMissing); Assert.NotEqual(default, pd.AccessorList.CloseBraceToken); Assert.True(pd.AccessorList.CloseBraceToken.IsMissing); Assert.Equal(0, pd.AccessorList.Accessors.Count); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); } [Fact] public void TestMethodAfterPropertyGet() { var text = "class c { int p { get int M() {} }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.PropertyDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[1].Kind()); var pd = (PropertyDeclarationSyntax)agg.Members[0]; Assert.NotNull(pd.AccessorList); Assert.NotEqual(default, pd.AccessorList.OpenBraceToken); Assert.False(pd.AccessorList.OpenBraceToken.IsMissing); Assert.NotEqual(default, pd.AccessorList.CloseBraceToken); Assert.True(pd.AccessorList.CloseBraceToken.IsMissing); Assert.Equal(1, pd.AccessorList.Accessors.Count); var acc = pd.AccessorList.Accessors[0]; Assert.Equal(SyntaxKind.GetAccessorDeclaration, acc.Kind()); Assert.NotEqual(default, acc.Keyword); Assert.False(acc.Keyword.IsMissing); Assert.Equal(SyntaxKind.GetKeyword, acc.Keyword.Kind()); Assert.Null(acc.Body); Assert.NotEqual(default, acc.SemicolonToken); Assert.True(acc.SemicolonToken.IsMissing); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_SemiOrLBraceOrArrowExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); } [Fact] public void TestClassAfterPropertyGetBrace() { var text = "class c { int p { get { class d {} }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.PropertyDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, agg.Members[1].Kind()); var pd = (PropertyDeclarationSyntax)agg.Members[0]; Assert.NotNull(pd.AccessorList); Assert.NotEqual(default, pd.AccessorList.OpenBraceToken); Assert.False(pd.AccessorList.OpenBraceToken.IsMissing); Assert.NotEqual(default, pd.AccessorList.CloseBraceToken); Assert.True(pd.AccessorList.CloseBraceToken.IsMissing); Assert.Equal(1, pd.AccessorList.Accessors.Count); var acc = pd.AccessorList.Accessors[0]; Assert.Equal(SyntaxKind.GetAccessorDeclaration, acc.Kind()); Assert.NotEqual(default, acc.Keyword); Assert.False(acc.Keyword.IsMissing); Assert.Equal(SyntaxKind.GetKeyword, acc.Keyword.Kind()); Assert.NotNull(acc.Body); Assert.NotEqual(default, acc.Body.OpenBraceToken); Assert.False(acc.Body.OpenBraceToken.IsMissing); Assert.Equal(0, acc.Body.Statements.Count); Assert.NotEqual(default, acc.Body.CloseBraceToken); Assert.True(acc.Body.CloseBraceToken.IsMissing); Assert.Equal(SyntaxKind.None, acc.SemicolonToken.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); } [Fact] public void TestModifiedMemberAfterPropertyGetBrace() { var text = "class c { int p { get { public class d {} }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.PropertyDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.ClassDeclaration, agg.Members[1].Kind()); var pd = (PropertyDeclarationSyntax)agg.Members[0]; Assert.NotNull(pd.AccessorList); Assert.NotEqual(default, pd.AccessorList.OpenBraceToken); Assert.False(pd.AccessorList.OpenBraceToken.IsMissing); Assert.NotEqual(default, pd.AccessorList.CloseBraceToken); Assert.True(pd.AccessorList.CloseBraceToken.IsMissing); Assert.Equal(1, pd.AccessorList.Accessors.Count); var acc = pd.AccessorList.Accessors[0]; Assert.Equal(SyntaxKind.GetAccessorDeclaration, acc.Kind()); Assert.NotEqual(default, acc.Keyword); Assert.False(acc.Keyword.IsMissing); Assert.Equal(SyntaxKind.GetKeyword, acc.Keyword.Kind()); Assert.NotNull(acc.Body); Assert.NotEqual(default, acc.Body.OpenBraceToken); Assert.False(acc.Body.OpenBraceToken.IsMissing); Assert.Equal(0, acc.Body.Statements.Count); Assert.NotEqual(default, acc.Body.CloseBraceToken); Assert.True(acc.Body.CloseBraceToken.IsMissing); Assert.Equal(SyntaxKind.None, acc.SemicolonToken.Kind()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[1].Code); } [Fact] public void TestPropertyAccessorMissingOpenBrace() { var text = "class c { int p { get return 0; } } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); var classDecl = (TypeDeclarationSyntax)file.Members[0]; var propertyDecl = (PropertyDeclarationSyntax)classDecl.Members[0]; var accessorDecls = propertyDecl.AccessorList.Accessors; Assert.Equal(1, accessorDecls.Count); var getDecl = accessorDecls[0]; Assert.Equal(SyntaxKind.GetKeyword, getDecl.Keyword.Kind()); var getBodyDecl = getDecl.Body; Assert.NotNull(getBodyDecl); Assert.True(getBodyDecl.OpenBraceToken.IsMissing); var getBodyStmts = getBodyDecl.Statements; Assert.Equal(1, getBodyStmts.Count); Assert.Equal(SyntaxKind.ReturnKeyword, getBodyStmts[0].GetFirstToken().Kind()); Assert.False(getBodyStmts[0].ContainsDiagnostics); Assert.Equal(1, file.Errors().Length); Assert.Equal(ErrorCode.ERR_SemiOrLBraceOrArrowExpected, (ErrorCode)file.Errors()[0].Code); } [Fact] public void TestPropertyAccessorsWithoutBodiesOrSemicolons() { var text = "class c { int p { get set } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); var classDecl = (TypeDeclarationSyntax)file.Members[0]; var propertyDecl = (PropertyDeclarationSyntax)classDecl.Members[0]; var accessorDecls = propertyDecl.AccessorList.Accessors; Assert.Equal(2, accessorDecls.Count); var getDecl = accessorDecls[0]; Assert.Equal(SyntaxKind.GetKeyword, getDecl.Keyword.Kind()); Assert.Null(getDecl.Body); Assert.True(getDecl.SemicolonToken.IsMissing); var setDecl = accessorDecls[1]; Assert.Equal(SyntaxKind.SetKeyword, setDecl.Keyword.Kind()); Assert.Null(setDecl.Body); Assert.True(setDecl.SemicolonToken.IsMissing); Assert.Equal(2, file.Errors().Length); Assert.Equal(ErrorCode.ERR_SemiOrLBraceOrArrowExpected, (ErrorCode)file.Errors()[0].Code); Assert.Equal(ErrorCode.ERR_SemiOrLBraceOrArrowExpected, (ErrorCode)file.Errors()[1].Code); } [Fact] public void TestSemicolonAfterOrderingStart() { var text = "class c { void m() { var q = from x in y orderby; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var md = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(md.Body); Assert.NotEqual(default, md.Body.OpenBraceToken); Assert.False(md.Body.OpenBraceToken.IsMissing); Assert.NotEqual(default, md.Body.CloseBraceToken); Assert.False(md.Body.CloseBraceToken.IsMissing); Assert.Equal(1, md.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, md.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)md.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.QueryExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); var qx = (QueryExpressionSyntax)ds.Declaration.Variables[0].Initializer.Value; Assert.Equal(1, qx.Body.Clauses.Count); Assert.Equal(SyntaxKind.FromClause, qx.FromClause.Kind()); Assert.Equal(SyntaxKind.OrderByClause, qx.Body.Clauses[0].Kind()); var oc = (OrderByClauseSyntax)qx.Body.Clauses[0]; Assert.NotEqual(default, oc.OrderByKeyword); Assert.False(oc.OrderByKeyword.IsMissing); Assert.Equal(1, oc.Orderings.Count); Assert.NotNull(oc.Orderings[0].Expression); Assert.Equal(SyntaxKind.IdentifierName, oc.Orderings[0].Expression.Kind()); var nm = (IdentifierNameSyntax)oc.Orderings[0].Expression; Assert.True(nm.IsMissing); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_ExpectedSelectOrGroup, file.Errors()[1].Code); } [Fact] public void TestSemicolonAfterOrderingExpression() { var text = "class c { void m() { var q = from x in y orderby e; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var md = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(md.Body); Assert.NotEqual(default, md.Body.OpenBraceToken); Assert.False(md.Body.OpenBraceToken.IsMissing); Assert.NotEqual(default, md.Body.CloseBraceToken); Assert.False(md.Body.CloseBraceToken.IsMissing); Assert.Equal(1, md.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, md.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)md.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.QueryExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); var qx = (QueryExpressionSyntax)ds.Declaration.Variables[0].Initializer.Value; Assert.Equal(1, qx.Body.Clauses.Count); Assert.Equal(SyntaxKind.FromClause, qx.FromClause.Kind()); Assert.Equal(SyntaxKind.OrderByClause, qx.Body.Clauses[0].Kind()); var oc = (OrderByClauseSyntax)qx.Body.Clauses[0]; Assert.NotEqual(default, oc.OrderByKeyword); Assert.False(oc.OrderByKeyword.IsMissing); Assert.Equal(1, oc.Orderings.Count); Assert.NotNull(oc.Orderings[0].Expression); Assert.Equal(SyntaxKind.IdentifierName, oc.Orderings[0].Expression.Kind()); var nm = (IdentifierNameSyntax)oc.Orderings[0].Expression; Assert.False(nm.IsMissing); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_ExpectedSelectOrGroup, file.Errors()[0].Code); } [Fact] public void TestSemicolonAfterOrderingExpressionAndComma() { var text = "class c { void m() { var q = from x in y orderby e, ; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(1, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); var md = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(md.Body); Assert.NotEqual(default, md.Body.OpenBraceToken); Assert.False(md.Body.OpenBraceToken.IsMissing); Assert.NotEqual(default, md.Body.CloseBraceToken); Assert.False(md.Body.CloseBraceToken.IsMissing); Assert.Equal(1, md.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, md.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)md.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.QueryExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); var qx = (QueryExpressionSyntax)ds.Declaration.Variables[0].Initializer.Value; Assert.Equal(1, qx.Body.Clauses.Count); Assert.Equal(SyntaxKind.FromClause, qx.FromClause.Kind()); Assert.Equal(SyntaxKind.OrderByClause, qx.Body.Clauses[0].Kind()); var oc = (OrderByClauseSyntax)qx.Body.Clauses[0]; Assert.NotEqual(default, oc.OrderByKeyword); Assert.False(oc.OrderByKeyword.IsMissing); Assert.Equal(2, oc.Orderings.Count); Assert.NotNull(oc.Orderings[0].Expression); Assert.Equal(SyntaxKind.IdentifierName, oc.Orderings[0].Expression.Kind()); var nm = (IdentifierNameSyntax)oc.Orderings[0].Expression; Assert.False(nm.IsMissing); Assert.NotNull(oc.Orderings[1].Expression); Assert.Equal(SyntaxKind.IdentifierName, oc.Orderings[0].Expression.Kind()); nm = (IdentifierNameSyntax)oc.Orderings[1].Expression; Assert.True(nm.IsMissing); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_ExpectedSelectOrGroup, file.Errors()[1].Code); } [Fact] public void TestMemberAfterOrderingStart() { var text = "class c { void m() { var q = from x in y orderby public int Goo; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[1].Kind()); var md = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(md.Body); Assert.NotEqual(default, md.Body.OpenBraceToken); Assert.False(md.Body.OpenBraceToken.IsMissing); Assert.NotEqual(default, md.Body.CloseBraceToken); Assert.True(md.Body.CloseBraceToken.IsMissing); Assert.Equal(1, md.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, md.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)md.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.QueryExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); var qx = (QueryExpressionSyntax)ds.Declaration.Variables[0].Initializer.Value; Assert.Equal(1, qx.Body.Clauses.Count); Assert.Equal(SyntaxKind.FromClause, qx.FromClause.Kind()); Assert.Equal(SyntaxKind.OrderByClause, qx.Body.Clauses[0].Kind()); var oc = (OrderByClauseSyntax)qx.Body.Clauses[0]; Assert.NotEqual(default, oc.OrderByKeyword); Assert.False(oc.OrderByKeyword.IsMissing); Assert.Equal(1, oc.Orderings.Count); Assert.NotNull(oc.Orderings[0].Expression); Assert.Equal(SyntaxKind.IdentifierName, oc.Orderings[0].Expression.Kind()); var nm = (IdentifierNameSyntax)oc.Orderings[0].Expression; Assert.True(nm.IsMissing); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_ExpectedSelectOrGroup, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[3].Code); } [Fact] public void TestMemberAfterOrderingExpression() { var text = "class c { void m() { var q = from x in y orderby e public int Goo; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[1].Kind()); var md = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(md.Body); Assert.NotEqual(default, md.Body.OpenBraceToken); Assert.False(md.Body.OpenBraceToken.IsMissing); Assert.NotEqual(default, md.Body.CloseBraceToken); Assert.True(md.Body.CloseBraceToken.IsMissing); Assert.Equal(1, md.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, md.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)md.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.QueryExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); var qx = (QueryExpressionSyntax)ds.Declaration.Variables[0].Initializer.Value; Assert.Equal(1, qx.Body.Clauses.Count); Assert.Equal(SyntaxKind.FromClause, qx.FromClause.Kind()); Assert.Equal(SyntaxKind.OrderByClause, qx.Body.Clauses[0].Kind()); var oc = (OrderByClauseSyntax)qx.Body.Clauses[0]; Assert.NotEqual(default, oc.OrderByKeyword); Assert.False(oc.OrderByKeyword.IsMissing); Assert.Equal(1, oc.Orderings.Count); Assert.NotNull(oc.Orderings[0].Expression); Assert.Equal(SyntaxKind.IdentifierName, oc.Orderings[0].Expression.Kind()); var nm = (IdentifierNameSyntax)oc.Orderings[0].Expression; Assert.False(nm.IsMissing); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_ExpectedSelectOrGroup, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); } [Fact] public void TestMemberAfterOrderingExpressionAndComma() { var text = "class c { void m() { var q = from x in y orderby e, public int Goo; }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var agg = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal(2, agg.Members.Count); Assert.Equal(SyntaxKind.MethodDeclaration, agg.Members[0].Kind()); Assert.Equal(SyntaxKind.FieldDeclaration, agg.Members[1].Kind()); var md = (MethodDeclarationSyntax)agg.Members[0]; Assert.NotNull(md.Body); Assert.NotEqual(default, md.Body.OpenBraceToken); Assert.False(md.Body.OpenBraceToken.IsMissing); Assert.NotEqual(default, md.Body.CloseBraceToken); Assert.True(md.Body.CloseBraceToken.IsMissing); Assert.Equal(1, md.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, md.Body.Statements[0].Kind()); var ds = (LocalDeclarationStatementSyntax)md.Body.Statements[0]; Assert.Equal(1, ds.Declaration.Variables.Count); Assert.NotNull(ds.Declaration.Variables[0].Initializer); Assert.NotNull(ds.Declaration.Variables[0].Initializer.Value); Assert.Equal(SyntaxKind.QueryExpression, ds.Declaration.Variables[0].Initializer.Value.Kind()); var qx = (QueryExpressionSyntax)ds.Declaration.Variables[0].Initializer.Value; Assert.Equal(1, qx.Body.Clauses.Count); Assert.Equal(SyntaxKind.FromClause, qx.FromClause.Kind()); Assert.Equal(SyntaxKind.OrderByClause, qx.Body.Clauses[0].Kind()); var oc = (OrderByClauseSyntax)qx.Body.Clauses[0]; Assert.NotEqual(default, oc.OrderByKeyword); Assert.False(oc.OrderByKeyword.IsMissing); Assert.Equal(2, oc.Orderings.Count); Assert.NotNull(oc.Orderings[0].Expression); Assert.Equal(SyntaxKind.IdentifierName, oc.Orderings[0].Expression.Kind()); var nm = (IdentifierNameSyntax)oc.Orderings[0].Expression; Assert.False(nm.IsMissing); Assert.NotNull(oc.Orderings[1].Expression); Assert.Equal(SyntaxKind.IdentifierName, oc.Orderings[0].Expression.Kind()); nm = (IdentifierNameSyntax)oc.Orderings[1].Expression; Assert.True(nm.IsMissing); Assert.Equal(4, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_ExpectedSelectOrGroup, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[3].Code); } [Fact] public void PartialInVariableDecl() { var text = "class C1 { void M1() { int x = 1, partial class y = 2; } }"; var file = this.ParseTree(text); Assert.NotNull(file); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Members.Count); Assert.Equal(SyntaxKind.ClassDeclaration, file.Members[0].Kind()); var item1 = (TypeDeclarationSyntax)file.Members[0]; Assert.Equal("C1", item1.Identifier.ToString()); Assert.False(item1.OpenBraceToken.IsMissing); Assert.Equal(2, item1.Members.Count); Assert.False(item1.CloseBraceToken.IsMissing); var subitem1 = (MethodDeclarationSyntax)item1.Members[0]; Assert.Equal(SyntaxKind.MethodDeclaration, subitem1.Kind()); Assert.NotNull(subitem1.Body); Assert.False(subitem1.Body.OpenBraceToken.IsMissing); Assert.True(subitem1.Body.CloseBraceToken.IsMissing); Assert.Equal(1, subitem1.Body.Statements.Count); Assert.Equal(SyntaxKind.LocalDeclarationStatement, subitem1.Body.Statements[0].Kind()); var decl = (LocalDeclarationStatementSyntax)subitem1.Body.Statements[0]; Assert.True(decl.SemicolonToken.IsMissing); Assert.Equal(2, decl.Declaration.Variables.Count); Assert.Equal("x", decl.Declaration.Variables[0].Identifier.ToString()); Assert.True(decl.Declaration.Variables[1].Identifier.IsMissing); Assert.Equal(3, subitem1.Errors().Length); Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, subitem1.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, subitem1.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, subitem1.Errors()[2].Code); var subitem2 = (TypeDeclarationSyntax)item1.Members[1]; Assert.Equal(SyntaxKind.ClassDeclaration, item1.Members[1].Kind()); Assert.Equal("y", subitem2.Identifier.ToString()); Assert.Equal(SyntaxKind.PartialKeyword, subitem2.Modifiers[0].ContextualKind()); Assert.True(subitem2.OpenBraceToken.IsMissing); Assert.True(subitem2.CloseBraceToken.IsMissing); Assert.Equal(3, subitem2.Errors().Length); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, subitem2.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, subitem2.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_InvalidMemberDecl, subitem2.Errors()[2].Code); } [WorkItem(905394, "DevDiv/Personal")] [Fact] public void TestThisKeywordInIncompleteLambdaArgumentList() { var text = @"public class Test { public void Goo() { var x = ((x, this } }"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.True(file.ContainsDiagnostics); } [WorkItem(906986, "DevDiv/Personal")] [Fact] public void TestIncompleteAttribute() { var text = @" [type: F"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.True(file.ContainsDiagnostics); } [WorkItem(908952, "DevDiv/Personal")] [Fact] public void TestNegAttributeOnTypeParameter() { var text = @" public class B { void M() { I<[Test] int> I1=new I<[Test] int>(); } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.True(file.ContainsDiagnostics); } [WorkItem(918947, "DevDiv/Personal")] [Fact] public void TestAtKeywordAsLocalOrParameter() { var text = @" class A { public void M() { int @int = 0; if (@int == 1) { @int = 0; } MM(@int); } public void MM(int n) { } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.False(file.ContainsDiagnostics); } [WorkItem(918947, "DevDiv/Personal")] [Fact] public void TestAtKeywordAsTypeNames() { var text = @"namespace @namespace { class C1 { } class @class : C1 { } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.False(file.ContainsDiagnostics); } [WorkItem(919418, "DevDiv/Personal")] [Fact] public void TestNegDefaultAsLambdaParameter() { var text = @"class C { delegate T Func<T>(); delegate T Func<A0, T>(A0 a0); delegate T Func<A0, A1, T>(A0 a0, A1 a1); delegate T Func<A0, A1, A2, A3, T>(A0 a0, A1 a1, A2 a2, A3 a3); static void X() { // Func<int,int> f1 = (int @in) => 1; // ok: @Keyword as parameter name Func<int,int> f2 = (int where, int from) => 1; // ok: contextual keyword as parameter name Func<int,int> f3 = (int default) => 1; // err: Keyword as parameter name } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.True(file.ContainsDiagnostics); } [Fact] public void TestEmptyUsingDirective() { var text = @"using;"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); var usings = file.Usings; Assert.Equal(1, usings.Count); Assert.True(usings[0].Name.IsMissing); } [Fact] public void TestNumericLiteralInUsingDirective() { var text = @"using 10;"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); var usings = file.Usings; Assert.Equal(1, usings.Count); Assert.True(usings[0].Name.IsMissing); } [Fact] public void TestNamespaceDeclarationInUsingDirective() { var text = @"using namespace Goo"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpectedKW, file.Errors()[0].Code); Assert.Equal((int)ErrorCode.ERR_LbraceExpected, file.Errors()[1].Code); Assert.Equal((int)ErrorCode.ERR_RbraceExpected, file.Errors()[2].Code); var usings = file.Usings; Assert.Equal(1, usings.Count); Assert.True(usings[0].Name.IsMissing); var members = file.Members; Assert.Equal(1, members.Count); var namespaceDeclaration = members[0]; Assert.Equal(SyntaxKind.NamespaceDeclaration, namespaceDeclaration.Kind()); Assert.False(((NamespaceDeclarationSyntax)namespaceDeclaration).Name.IsMissing); } [Fact] public void TestFileScopedNamespaceDeclarationInUsingDirective() { var text = @"using namespace Goo;"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); file.GetDiagnostics().Verify( // (1,7): error CS1041: Identifier expected; 'namespace' is a keyword // using namespace Goo; Diagnostic(ErrorCode.ERR_IdentifierExpectedKW, "namespace").WithArguments("", "namespace").WithLocation(1, 7)); var usings = file.Usings; Assert.Equal(1, usings.Count); Assert.True(usings[0].Name.IsMissing); var members = file.Members; Assert.Equal(1, members.Count); var namespaceDeclaration = members[0]; Assert.Equal(SyntaxKind.FileScopedNamespaceDeclaration, namespaceDeclaration.Kind()); Assert.False(((FileScopedNamespaceDeclarationSyntax)namespaceDeclaration).Name.IsMissing); } [Fact] public void TestContextualKeywordAsFromVariable() { var text = @" class C { int x = from equals in new[] { 1, 2, 3 } select 1; }"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); } [WorkItem(537210, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537210")] [Fact] public void RegressException4UseValueInAccessor() { var text = @"public class MyClass { public int MyProp { set { int value = 0; } // CS0136 } D x; int this[int n] { get { return 0; } set { x = (value) => { value++; }; } // CS0136 } public delegate void D(int n); public event D MyEvent { add { object value = null; } // CS0136 remove { } } }"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); // Assert.True(file.ContainsDiagnostics); // CS0136 is not parser error } [WorkItem(931315, "DevDiv/Personal")] [Fact] public void RegressException4InvalidOperator() { var text = @"class A { public static int operator &&(A a) // CS1019 { return 0; } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.True(file.ContainsDiagnostics); } [WorkItem(931316, "DevDiv/Personal")] [Fact] public void RegressNoError4NoOperator() { var text = @"class A { public static A operator (A a) // CS1019 { return a; } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.True(file.ContainsDiagnostics); } [WorkItem(537214, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537214")] [Fact] public void RegressWarning4UseContextKeyword() { var text = @"class TestClass { int partial { get; set; } static int Main() { TestClass tc = new TestClass(); tc.partial = 0; return 0; } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.False(file.ContainsDiagnostics); } [WorkItem(537150, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537150")] [Fact] public void ParseStartOfAccessor() { var text = @"class Program { int this[string s] { g } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.Equal(1, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_GetOrSetExpected, file.Errors()[0].Code); } [WorkItem(536050, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/536050")] [Fact] public void ParseMethodWithConstructorInitializer() { //someone has a typo in the name of their ctor - parse it as a ctor, and accept the initializer var text = @" class C { CTypo() : base() { //body } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.Equal(0, file.Errors().Length); // CONSIDER: Dev10 actually gives 'CS1002: ; expected', because it thinks you were trying to // specify a method without a body. This is a little silly, since we already know the method // isn't abstract. It might be reasonable to say that an open brace was expected though. var classDecl = file.ChildNodesAndTokens()[0]; Assert.Equal(SyntaxKind.ClassDeclaration, classDecl.Kind()); var methodDecl = classDecl.ChildNodesAndTokens()[3]; Assert.Equal(SyntaxKind.ConstructorDeclaration, methodDecl.Kind()); //not MethodDeclaration Assert.False(methodDecl.ContainsDiagnostics); var methodBody = methodDecl.ChildNodesAndTokens()[3]; Assert.Equal(SyntaxKind.Block, methodBody.Kind()); Assert.False(methodBody.ContainsDiagnostics); } [WorkItem(537157, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537157")] [Fact] public void MissingInternalNode() { var text = @"[1]"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); var globalStatement = (GlobalStatementSyntax)file.ChildNodesAndTokens()[0]; Assert.False(globalStatement.IsMissing); var expressionStatement = (ExpressionStatementSyntax)globalStatement.Statement; Assert.False(expressionStatement.IsMissing); Assert.True(expressionStatement.SemicolonToken.IsMissing); var collectionExpression = (CollectionExpressionSyntax)expressionStatement.Expression; Assert.False(collectionExpression.IsMissing); } [WorkItem(538469, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538469")] [Fact] public void FromKeyword() { var text = @" using System.Collections.Generic; using System.Linq; public class QueryExpressionTest { public static int Main() { int[] expr1 = new int[] { 1, 2, 3, }; IEnumerable<int> query01 = from value in expr1 select value; IEnumerable<int> query02 = from yield in expr1 select yield; IEnumerable<int> query03 = from select in expr1 select select; return 0; } }"; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.Equal(3, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_IdentifierExpected, file.Errors()[0].Code); //expecting item name - found "select" keyword Assert.Equal((int)ErrorCode.ERR_InvalidExprTerm, file.Errors()[1].Code); //expecting expression - found "select" keyword Assert.Equal((int)ErrorCode.ERR_SemicolonExpected, file.Errors()[2].Code); //we inserted a missing semicolon in a place we didn't expect } [WorkItem(538971, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538971")] [Fact] public void UnclosedGenericInExplicitInterfaceName() { var text = @" interface I<T> { void Goo(); } class C : I<int> { void I<.Goo() { } } "; var file = this.ParseTree(text); Assert.Equal(text, file.ToFullString()); Assert.Equal(2, file.Errors().Length); Assert.Equal((int)ErrorCode.ERR_TypeExpected, file.Errors()[0].Code); //expecting a type (argument) Assert.Equal((int)ErrorCode.ERR_SyntaxError, file.Errors()[1].Code); //expecting close angle bracket } [WorkItem(540788, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540788")] [Fact] public void IncompleteForEachStatement() { var text = @" public class Test { public static void Main(string[] args) { foreach"; var srcTree = this.ParseTree(text); Assert.Equal(text, srcTree.ToFullString()); Assert.Equal("foreach", srcTree.GetLastToken().ToString()); // Get the Foreach Node var foreachNode = srcTree.GetLastToken().Parent; // Verify 3 empty nodes are created by the parser for error recovery. Assert.Equal(3, foreachNode.ChildNodes().ToList().Count); } [WorkItem(542236, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542236")] [Fact] public void InsertOpenBraceBeforeCodes() { var text = @"{ this.I = i; }; }"; SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(text, TestOptions.Regular9); Assert.Equal(text, syntaxTree.GetCompilationUnitRoot().ToFullString()); // The issue (9391) was exhibited while enumerating the diagnostics Assert.True(syntaxTree.GetDiagnostics().Select(d => ((IFormattable)d).ToString(null, EnsureEnglishUICulture.PreferredOrNull)).SequenceEqual(new[] { "(4,1): error CS1022: Type or namespace definition, or end-of-file expected", })); } [WorkItem(542352, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542352")] [Fact] public void IncompleteTopLevelOperator() { var text = @" fg implicit// class C { } "; SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(text); Assert.Equal(text, syntaxTree.GetCompilationUnitRoot().ToFullString()); // 9553: Several of the locations were incorrect and one was negative Assert.True(syntaxTree.GetDiagnostics().Select(d => ((IFormattable)d).ToString(null, EnsureEnglishUICulture.PreferredOrNull)).SequenceEqual(new[] { // Error on the return type, because in C# syntax it goes after the operator and implicit/explicit keywords "(2,1): error CS1553: Declaration is not valid; use '+ operator <dest-type> (...' instead", // Error on "implicit" because there should be an operator keyword "(2,4): error CS1003: Syntax error, 'operator' expected", // Error on "implicit" because there should be an operator symbol "(2,4): error CS1037: Overloadable operator expected", // Missing parameter list and body "(2,12): error CS1003: Syntax error, '(' expected", "(2,12): error CS1026: ) expected", "(2,12): error CS1002: ; expected", })); } [WorkItem(545647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545647")] [Fact] public void IncompleteVariableDeclarationAboveDotMemberAccess() { var text = @" class C { void Main() { C Console.WriteLine(); } } "; SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(text); Assert.Equal(text, syntaxTree.GetCompilationUnitRoot().ToFullString()); Assert.True(syntaxTree.GetDiagnostics().Select(d => ((IFormattable)d).ToString(null, EnsureEnglishUICulture.PreferredOrNull)).SequenceEqual(new[] { "(6,10): error CS1001: Identifier expected", "(6,10): error CS1002: ; expected", })); } [WorkItem(545647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545647")] [Fact] public void IncompleteVariableDeclarationAbovePointerMemberAccess() { var text = @" class C { void Main() { C Console->WriteLine(); } } "; SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(text); Assert.Equal(text, syntaxTree.GetCompilationUnitRoot().ToFullString()); Assert.True(syntaxTree.GetDiagnostics().Select(d => ((IFormattable)d).ToString(null, EnsureEnglishUICulture.PreferredOrNull)).SequenceEqual(new[] { "(6,10): error CS1001: Identifier expected", "(6,10): error CS1002: ; expected", })); } [WorkItem(545647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545647")] [Fact] public void IncompleteVariableDeclarationAboveBinaryExpression() { var text = @" class C { void Main() { C A + B; } } "; SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(text); Assert.Equal(text, syntaxTree.GetCompilationUnitRoot().ToFullString()); Assert.True(syntaxTree.GetDiagnostics().Select(d => ((IFormattable)d).ToString(null, EnsureEnglishUICulture.PreferredOrNull)).SequenceEqual(new[] { "(6,10): error CS1001: Identifier expected", "(6,10): error CS1002: ; expected", })); } [WorkItem(545647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545647")] [Fact] public void IncompleteVariableDeclarationAboveMemberAccess_MultiLine() { var text = @" class C { void Main() { C Console.WriteLine(); } } "; SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(text); Assert.Equal(text, syntaxTree.GetCompilationUnitRoot().ToFullString()); Assert.True(syntaxTree.GetDiagnostics().Select(d => ((IFormattable)d).ToString(null, EnsureEnglishUICulture.PreferredOrNull)).SequenceEqual(new[] { "(6,10): error CS1001: Identifier expected", "(6,10): error CS1002: ; expected", })); } [WorkItem(545647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545647")] [Fact] public void IncompleteVariableDeclarationBeforeMemberAccessOnSameLine() { var text = @" class C { void Main() { C Console.WriteLine(); } } "; SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(text); Assert.Equal(text, syntaxTree.GetCompilationUnitRoot().ToFullString()); Assert.True(syntaxTree.GetDiagnostics().Select(d => ((IFormattable)d).ToString(null, EnsureEnglishUICulture.PreferredOrNull)).SequenceEqual(new[] { "(6,18): error CS1003: Syntax error, ',' expected", "(6,19): error CS1002: ; expected", })); } [WorkItem(545647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545647")] [Fact] public void EqualsIsNotAmbiguous() { var text = @" class C { void Main() { C A = B; } } "; SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(text); Assert.Equal(text, syntaxTree.GetCompilationUnitRoot().ToFullString()); Assert.Empty(syntaxTree.GetDiagnostics()); } [WorkItem(547120, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/547120")] [Fact] public void ColonColonInExplicitInterfaceMember() { var text = @" _ _::this "; SyntaxTree syntaxTree = SyntaxFactory.ParseSyntaxTree(text); Assert.Equal(text, syntaxTree.GetCompilationUnitRoot().ToFullString()); syntaxTree.GetDiagnostics().Verify( // (2,4): error CS1003: Syntax error, '.' expected // _ _::this Diagnostic(ErrorCode.ERR_SyntaxError, "::").WithArguments("."), // (2,10): error CS1003: Syntax error, '[' expected // _ _::this Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("["), // (2,10): error CS1003: Syntax error, ']' expected // _ _::this Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("]"), // (2,10): error CS1514: { expected // _ _::this Diagnostic(ErrorCode.ERR_LbraceExpected, ""), // (2,10): error CS1513: } expected // _ _::this Diagnostic(ErrorCode.ERR_RbraceExpected, "")); CreateCompilation(text).VerifyDiagnostics( // (2,4): error CS1003: Syntax error, '.' expected // _ _::this Diagnostic(ErrorCode.ERR_SyntaxError, "::").WithArguments(".").WithLocation(2, 4), // (2,10): error CS1003: Syntax error, '[' expected // _ _::this Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("[").WithLocation(2, 10), // (2,10): error CS1003: Syntax error, ']' expected // _ _::this Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("]").WithLocation(2, 10), // (2,10): error CS1514: { expected // _ _::this Diagnostic(ErrorCode.ERR_LbraceExpected, "").WithLocation(2, 10), // (2,10): error CS1513: } expected // _ _::this Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(2, 10), // (2,3): error CS0246: The type or namespace name '_' could not be found (are you missing a using directive or an assembly reference?) // _ _::this Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "_").WithArguments("_").WithLocation(2, 3), // (2,1): error CS0246: The type or namespace name '_' could not be found (are you missing a using directive or an assembly reference?) // _ _::this Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "_").WithArguments("_").WithLocation(2, 1), // error CS1551: Indexers must have at least one parameter Diagnostic(ErrorCode.ERR_IndexerNeedsParam).WithLocation(1, 1), // (2,3): error CS0538: '_' in explicit interface declaration is not an interface // _ _::this Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "_").WithArguments("_").WithLocation(2, 3), // (2,6): error CS0548: '<invalid-global-code>.this': property or indexer must have at least one accessor // _ _::this Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "this").WithArguments("<invalid-global-code>.this").WithLocation(2, 6)); } [WorkItem(649806, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/649806")] [Fact] public void Repro649806() { var source = "a b:: /**/\r\n"; var tree = SyntaxFactory.ParseSyntaxTree(source); var diags = tree.GetDiagnostics(); diags.Verify( // (1,4): error CS1002: ; expected // a b:: /**/ Diagnostic(ErrorCode.ERR_SemicolonExpected, "::").WithLocation(1, 4), // (1,4): error CS1001: Identifier expected // a b:: /**/ Diagnostic(ErrorCode.ERR_IdentifierExpected, "::").WithLocation(1, 4), // (1,6): error CS1001: Identifier expected // a b:: /**/ Diagnostic(ErrorCode.ERR_IdentifierExpected, "").WithLocation(1, 6), // (1,6): error CS1002: ; expected // a b:: /**/ Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 6) ); } [WorkItem(674564, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/674564")] [Fact] public void Repro674564() { var source = @" class C { int P { set . } } }"; var tree = SyntaxFactory.ParseSyntaxTree(source); var diags = tree.GetDiagnostics(); diags.ToArray(); diags.Verify( // We see this diagnostic because the accessor has no open brace. // (4,17): error CS1043: { or ; expected // int P { set . } } Diagnostic(ErrorCode.ERR_SemiOrLBraceOrArrowExpected, "."), // We see this diagnostic because we're trying to skip bad tokens in the block and // the "expected" token (i.e. the one we report when we see something that's not a // statement) is close brace. // CONSIDER: This diagnostic isn't great. // (4,17): error CS1513: } expected // int P { set . } } Diagnostic(ErrorCode.ERR_RbraceExpected, ".")); } [WorkItem(680733, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/680733")] [Fact] public void Repro680733a() { var source = @" class Test { public async Task<in{> Bar() { return 1; } } "; AssertEqualRoundtrip(source); } [WorkItem(680733, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/680733")] [Fact] public void Repro680733b() { var source = @" using System; class Test { public async Task<[Obsolete]in{> Bar() { return 1; } } "; AssertEqualRoundtrip(source); } [WorkItem(680739, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/680739")] [Fact] public void Repro680739() { var source = @"a b<c..<using.d"; AssertEqualRoundtrip(source); } [WorkItem(675600, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/675600")] [Fact] public void TestBracesToOperatorDoubleGreaterThan() { AssertEqualRoundtrip( @"/// <see cref=""operator}}""/> class C {}"); AssertEqualRoundtrip( @"/// <see cref=""operator{{""/> class C {}"); AssertEqualRoundtrip( @"/// <see cref=""operator}=""/> class C {}"); AssertEqualRoundtrip( @"/// <see cref=""operator}}=""/> class C {}"); AssertEqualRoundtrip( @"/// <see cref=""operator}}}=""/> class C {}"); } private void AssertEqualRoundtrip(string source) { var tree = SyntaxFactory.ParseSyntaxTree(source); var toString = tree.GetRoot().ToFullString(); Assert.Equal(source, toString); } [WorkItem(684816, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/684816")] [Fact] public void GenericPropertyWithMissingIdentifier() { var source = @" class C : I { int I./*missing*/< { "; var tree = SyntaxFactory.ParseSyntaxTree(source); var toString = tree.GetRoot().ToFullString(); Assert.Equal(source, toString); tree.GetDiagnostics().Verify( // (4,22): error CS1001: Identifier expected // int I./*missing*/< { Diagnostic(ErrorCode.ERR_IdentifierExpected, "<"), // (4,22): error CS7002: Unexpected use of a generic name // int I./*missing*/< { Diagnostic(ErrorCode.ERR_UnexpectedGenericName, "<"), // (4,24): error CS1003: Syntax error, '>' expected // int I./*missing*/< { Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments(">"), // (4,25): error CS1513: } expected // int I./*missing*/< { Diagnostic(ErrorCode.ERR_RbraceExpected, ""), // (4,25): error CS1513: } expected // int I./*missing*/< { Diagnostic(ErrorCode.ERR_RbraceExpected, "")); } [WorkItem(684816, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/684816")] [Fact] public void GenericEventWithMissingIdentifier() { var source = @" class C : I { event D I./*missing*/< { "; var tree = SyntaxFactory.ParseSyntaxTree(source); var toString = tree.GetRoot().ToFullString(); Assert.Equal(source, toString); tree.GetDiagnostics().Verify( // (4,26): error CS1001: Identifier expected // event D I./*missing*/< { Diagnostic(ErrorCode.ERR_IdentifierExpected, "<"), // (4,26): error CS1001: Identifier expected // event D I./*missing*/< { Diagnostic(ErrorCode.ERR_IdentifierExpected, "<"), // (4,28): error CS1003: Syntax error, '>' expected // event D I./*missing*/< { Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments(">"), // (4,26): error CS7002: Unexpected use of a generic name // event D I./*missing*/< { Diagnostic(ErrorCode.ERR_UnexpectedGenericName, "<"), // (4,29): error CS1513: } expected // event D I./*missing*/< { Diagnostic(ErrorCode.ERR_RbraceExpected, ""), // (4,29): error CS1513: } expected // event D I./*missing*/< { Diagnostic(ErrorCode.ERR_RbraceExpected, "")); } [WorkItem(684816, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/684816")] [Fact] public void ExplicitImplementationEventWithColonColon() { var source = @" class C : I { event D I:: "; var tree = SyntaxFactory.ParseSyntaxTree(source); var toString = tree.GetRoot().ToFullString(); Assert.Equal(source, toString); tree.GetDiagnostics().Verify( // (4,14): error CS0071: An explicit interface implementation of an event must use event accessor syntax // event D I:: Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "::"), // (4,14): error CS0687: The namespace alias qualifier '::' always resolves to a type or namespace so is illegal here. Consider using '.' instead. // event D I:: Diagnostic(ErrorCode.ERR_AliasQualAsExpression, "::"), // (4,16): error CS1513: } expected // event D I:: Diagnostic(ErrorCode.ERR_RbraceExpected, "")); } [WorkItem(684816, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/684816")] [Fact] public void EventNamedThis() { var source = @" class C { event System.Action this "; var tree = SyntaxFactory.ParseSyntaxTree(source); var toString = tree.GetRoot().ToFullString(); Assert.Equal(source, toString); tree.GetDiagnostics().Verify( // (4,25): error CS1001: Identifier expected // event System.Action this Diagnostic(ErrorCode.ERR_IdentifierExpected, "this"), // (4,29): error CS1514: { expected // event System.Action this Diagnostic(ErrorCode.ERR_LbraceExpected, ""), // (4,29): error CS1513: } expected // event System.Action this Diagnostic(ErrorCode.ERR_RbraceExpected, ""), // (4,29): error CS1513: } expected // event System.Action this Diagnostic(ErrorCode.ERR_RbraceExpected, "")); } [WorkItem(697022, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/697022")] [Fact] public void GenericEnumWithMissingIdentifiers() { var source = @"enum <//aaaa enum "; var tree = SyntaxFactory.ParseSyntaxTree(source); var toString = tree.GetRoot().ToFullString(); Assert.Equal(source, toString); tree.GetDiagnostics().ToArray(); } [WorkItem(703809, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/703809")] [Fact] public void ReplaceOmittedArrayRankWithMissingIdentifier() { var source = @"fixed a,b {//aaaa static "; var tree = SyntaxFactory.ParseSyntaxTree(source); var toString = tree.GetRoot().ToFullString(); Assert.Equal(source, toString); tree.GetDiagnostics().ToArray(); } [WorkItem(716245, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/716245")] [Fact] public void ManySkippedTokens() { const int numTokens = 500000; // Prohibitively slow without fix. var source = new string(',', numTokens); var tree = SyntaxFactory.ParseSyntaxTree(source); var eofToken = ((CompilationUnitSyntax)tree.GetRoot()).EndOfFileToken; Assert.Equal(numTokens, eofToken.FullWidth); Assert.Equal(numTokens, eofToken.LeadingTrivia.Count); // Confirm that we built a list. } [WorkItem(947819, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/947819")] [Fact] public void MissingOpenBraceForClass() { var source = @"namespace n { class c } "; var root = SyntaxFactory.ParseSyntaxTree(source).GetRoot(); Assert.Equal(source, root.ToFullString()); // Verify incomplete class decls don't eat tokens of surrounding nodes var classDecl = root.DescendantNodes().OfType<ClassDeclarationSyntax>().Single(); Assert.False(classDecl.Identifier.IsMissing); Assert.True(classDecl.OpenBraceToken.IsMissing); Assert.True(classDecl.CloseBraceToken.IsMissing); var ns = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>().Single(); Assert.False(ns.OpenBraceToken.IsMissing); Assert.False(ns.CloseBraceToken.IsMissing); } [WorkItem(947819, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/947819")] [Fact] public void MissingOpenBraceForClassFileScopedNamespace() { var source = @"namespace n; class c "; var root = SyntaxFactory.ParseSyntaxTree(source).GetRoot(); Assert.Equal(source, root.ToFullString()); // Verify incomplete class decls don't eat tokens of surrounding nodes var classDecl = root.DescendantNodes().OfType<ClassDeclarationSyntax>().Single(); Assert.False(classDecl.Identifier.IsMissing); Assert.True(classDecl.OpenBraceToken.IsMissing); Assert.True(classDecl.CloseBraceToken.IsMissing); var ns = root.DescendantNodes().OfType<FileScopedNamespaceDeclarationSyntax>().Single(); Assert.False(ns.SemicolonToken.IsMissing); } [WorkItem(947819, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/947819")] [Fact] public void MissingOpenBraceForStruct() { var source = @"namespace n { struct c : I } "; var root = SyntaxFactory.ParseSyntaxTree(source).GetRoot(); Assert.Equal(source, root.ToFullString()); // Verify incomplete struct decls don't eat tokens of surrounding nodes var structDecl = root.DescendantNodes().OfType<StructDeclarationSyntax>().Single(); Assert.True(structDecl.OpenBraceToken.IsMissing); Assert.True(structDecl.CloseBraceToken.IsMissing); var ns = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>().Single(); Assert.False(ns.OpenBraceToken.IsMissing); Assert.False(ns.CloseBraceToken.IsMissing); } [WorkItem(947819, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/947819")] [Fact] public void MissingNameForStruct() { var source = @"namespace n { struct : I { } } "; var root = SyntaxFactory.ParseSyntaxTree(source).GetRoot(); Assert.Equal(source, root.ToFullString()); // Verify incomplete struct decls don't eat tokens of surrounding nodes var structDecl = root.DescendantNodes().OfType<StructDeclarationSyntax>().Single(); Assert.True(structDecl.Identifier.IsMissing); Assert.False(structDecl.OpenBraceToken.IsMissing); Assert.False(structDecl.CloseBraceToken.IsMissing); var ns = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>().Single(); Assert.False(ns.OpenBraceToken.IsMissing); Assert.False(ns.CloseBraceToken.IsMissing); } [WorkItem(947819, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/947819")] [Fact] public void MissingNameForClass() { var source = @"namespace n { class { } } "; var root = SyntaxFactory.ParseSyntaxTree(source).GetRoot(); Assert.Equal(source, root.ToFullString()); // Verify incomplete class decls don't eat tokens of surrounding nodes var classDecl = root.DescendantNodes().OfType<ClassDeclarationSyntax>().Single(); Assert.True(classDecl.Identifier.IsMissing); Assert.False(classDecl.OpenBraceToken.IsMissing); Assert.False(classDecl.CloseBraceToken.IsMissing); var ns = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>().Single(); Assert.False(ns.OpenBraceToken.IsMissing); Assert.False(ns.CloseBraceToken.IsMissing); } [Fact] public void RazorCommentRecovery_Space() { UsingTree("""@ * *@""", // (1,1): error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ // @ * *@ Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral, "").WithLocation(1, 1), // (1,6): error CS1525: Invalid expression term '' // @ * *@ Diagnostic(ErrorCode.ERR_InvalidExprTerm, "@").WithArguments("").WithLocation(1, 6), // (1,6): error CS1002: ; expected // @ * *@ Diagnostic(ErrorCode.ERR_SemicolonExpected, "@").WithLocation(1, 6), // (1,6): error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ // @ * *@ Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral, "").WithLocation(1, 6)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.PointerIndirectionExpression); { N(SyntaxKind.AsteriskToken); N(SyntaxKind.PointerIndirectionExpression); { N(SyntaxKind.AsteriskToken); M(SyntaxKind.IdentifierName); { M(SyntaxKind.IdentifierToken); } } } M(SyntaxKind.SemicolonToken); } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RazorCommentRecovery_NoStart() { UsingTree("""*@""", // (1,2): error CS1525: Invalid expression term '' // *@ Diagnostic(ErrorCode.ERR_InvalidExprTerm, "@").WithArguments("").WithLocation(1, 2), // (1,2): error CS1002: ; expected // *@ Diagnostic(ErrorCode.ERR_SemicolonExpected, "@").WithLocation(1, 2), // (1,2): error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ // *@ Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral, "").WithLocation(1, 2)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.PointerIndirectionExpression); { N(SyntaxKind.AsteriskToken); M(SyntaxKind.IdentifierName); { M(SyntaxKind.IdentifierToken); } } M(SyntaxKind.SemicolonToken); } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_01() { UsingTree(""" if (#if) """, // (1,5): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // if (#if) Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(1, 5), // (1,9): error CS1733: Expected expression // if (#if) Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 9), // (1,9): error CS1026: ) expected // if (#if) Diagnostic(ErrorCode.ERR_CloseParenExpected, "").WithLocation(1, 9), // (1,9): error CS1733: Expected expression // if (#if) Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 9), // (1,9): error CS1002: ; expected // if (#if) Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 9)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.IfStatement); { N(SyntaxKind.IfKeyword); N(SyntaxKind.OpenParenToken); M(SyntaxKind.IdentifierName); { M(SyntaxKind.IdentifierToken); } M(SyntaxKind.CloseParenToken); M(SyntaxKind.ExpressionStatement); { M(SyntaxKind.IdentifierName); { M(SyntaxKind.IdentifierToken); } M(SyntaxKind.SemicolonToken); } } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_01_WhitespaceBeforeHash() { UsingTree(""" if ( #if) """, // (1,5): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // if ( #if) Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(1, 6), // (1,9): error CS1733: Expected expression // if ( #if) Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 10), // (1,9): error CS1026: ) expected // if ( #if) Diagnostic(ErrorCode.ERR_CloseParenExpected, "").WithLocation(1, 10), // (1,9): error CS1733: Expected expression // if ( #if) Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 10), // (1,9): error CS1002: ; expected // if ( #if) Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 10)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.IfStatement); { N(SyntaxKind.IfKeyword); N(SyntaxKind.OpenParenToken); M(SyntaxKind.IdentifierName); { M(SyntaxKind.IdentifierToken); } M(SyntaxKind.CloseParenToken); M(SyntaxKind.ExpressionStatement); { M(SyntaxKind.IdentifierName); { M(SyntaxKind.IdentifierToken); } M(SyntaxKind.SemicolonToken); } } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_01_WhitespaceAfterHash() { UsingTree(""" if ( # if) """, // (1,5): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // if ( # if) Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(1, 6), // (1,9): error CS1733: Expected expression // if ( # if) Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 11), // (1,9): error CS1026: ) expected // if ( # if) Diagnostic(ErrorCode.ERR_CloseParenExpected, "").WithLocation(1, 11), // (1,9): error CS1733: Expected expression // if ( # if) Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 11), // (1,9): error CS1002: ; expected // if ( # if) Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 11)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.IfStatement); { N(SyntaxKind.IfKeyword); N(SyntaxKind.OpenParenToken); M(SyntaxKind.IdentifierName); { M(SyntaxKind.IdentifierToken); } M(SyntaxKind.CloseParenToken); M(SyntaxKind.ExpressionStatement); { M(SyntaxKind.IdentifierName); { M(SyntaxKind.IdentifierToken); } M(SyntaxKind.SemicolonToken); } } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_02() { UsingTree(""" if (#if false x #else y #endif """, // (1,5): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // if (#if false Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(1, 5), // (2,2): error CS1026: ) expected // x Diagnostic(ErrorCode.ERR_CloseParenExpected, "").WithLocation(2, 2), // (3,1): error CS1028: Unexpected preprocessor directive // #else Diagnostic(ErrorCode.ERR_UnexpectedDirective, "#else").WithLocation(3, 1), // (4,2): error CS1002: ; expected // y Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(4, 2), // (5,1): error CS1028: Unexpected preprocessor directive // #endif Diagnostic(ErrorCode.ERR_UnexpectedDirective, "#endif").WithLocation(5, 1)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.IfStatement); { N(SyntaxKind.IfKeyword); N(SyntaxKind.OpenParenToken); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "x"); } M(SyntaxKind.CloseParenToken); N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "y"); } M(SyntaxKind.SemicolonToken); } } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_03() { UsingTree(""" a(); #if false b(); /* comment */ #else c(); #endif """); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "a"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_04() { UsingTree(""" a(); #if true b(); /* comment */ #elif false c(); #endif """, // (4,15): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // /* comment */ #elif false Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(4, 15)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "a"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "b"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "c"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_05() { UsingTree(""" a(); #if true b(); /* comment */ #endif #else c(); #endif d(); """, // (4,15): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // /* comment */ #endif Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(4, 15)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "a"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "b"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "d"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_Define() { UsingTree(""" /* comment */ #define ABC #if ABC x(); #else y(); #endif """, // (1,15): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // /* comment */ #define ABC Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(1, 15)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "y"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_Undefine() { UsingTree(""" #define ABC /* comment */ #undefine ABC #if ABC x(); #else y(); #endif """, // (2,15): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // /* comment */ #undefine ABC Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(2, 15)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "x"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.SemicolonToken); } } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_ErrorWarning() { UsingTree(""" /* comment */ #error E1 /* comment */ #warning W1 #error E2 #warning W2 """, // (1,15): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // /* comment */ #error E1 Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(1, 15), // (2,15): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // /* comment */ #warning W1 Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(2, 15), // (3,8): error CS1029: #error: 'E2' // #error E2 Diagnostic(ErrorCode.ERR_ErrorDirective, "E2").WithArguments("E2").WithLocation(3, 8), // (4,10): warning CS1030: #warning: 'W2' // #warning W2 Diagnostic(ErrorCode.WRN_WarningDirective, "W2").WithArguments("W2").WithLocation(4, 10)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_Line() { UsingTree(""" #line 200 /* comment */ #line 100 #error E1 """, // (200,15): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // /* comment */ #line 100 Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(200, 15), // (201,8): error CS1029: #error: 'E1' // #error E1 Diagnostic(ErrorCode.ERR_ErrorDirective, "E1").WithArguments("E1").WithLocation(201, 8)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_Pragma() { CreateCompilation(""" #pragma warning disable 8321 /* comment */ #pragma warning restore 8321 void f() { } #pragma warning restore 8321 void g() { } """).VerifyDiagnostics( // (2,15): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // /* comment */ #pragma warning restore 8321 Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(2, 15), // (5,6): warning CS8321: The local function 'g' is declared but never used // void g() { } Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "g").WithArguments("g").WithLocation(5, 6)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75583")] public void PreprocessorDirective_Trailing_Nullable() { CreateCompilation(""" #nullable disable /* comment */ #nullable enable _ = (object)null; #nullable enable _ = (object)null; // 1 """).VerifyDiagnostics( // (2,15): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // /* comment */ #nullable enable Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(2, 15), // (5,5): warning CS8600: Converting null literal or possible null value to non-nullable type. // _ = (object)null; // 1 Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "(object)null").WithLocation(5, 5)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/79935")] public void MissingNodeWithSkippedTokens1() { UsingTree(""" i,(# interface """, // (1,2): error CS1001: Identifier expected // i,(# Diagnostic(ErrorCode.ERR_IdentifierExpected, ",").WithLocation(1, 2), // (1,3): error CS1001: Identifier expected // i,(# Diagnostic(ErrorCode.ERR_IdentifierExpected, "(").WithLocation(1, 3), // (1,3): error CS1528: Expected ; or = (cannot specify constructor arguments in declaration) // i,(# Diagnostic(ErrorCode.ERR_BadVarDecl, "(").WithLocation(1, 3), // (1,3): error CS1003: Syntax error, '[' expected // i,(# Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments("[").WithLocation(1, 3), // (1,4): error CS1040: Preprocessor directives must appear as the first non-whitespace character on a line // i,(# Diagnostic(ErrorCode.ERR_BadDirectivePlacement, "#").WithLocation(1, 4), // (1,4): error CS1003: Syntax error, ']' expected // i,(# Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("]").WithLocation(1, 4), // (1,4): error CS1002: ; expected // i,(# Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 4), // (3,10): error CS1001: Identifier expected // interface Diagnostic(ErrorCode.ERR_IdentifierExpected, "").WithLocation(3, 10), // (3,10): error CS1514: { expected // interface Diagnostic(ErrorCode.ERR_LbraceExpected, "").WithLocation(3, 10), // (3,10): error CS1513: } expected // interface Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(3, 10)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.LocalDeclarationStatement); { N(SyntaxKind.VariableDeclaration); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "i"); } M(SyntaxKind.VariableDeclarator); { M(SyntaxKind.IdentifierToken); } N(SyntaxKind.CommaToken); M(SyntaxKind.VariableDeclarator); { M(SyntaxKind.IdentifierToken); M(SyntaxKind.BracketedArgumentList); { M(SyntaxKind.OpenBracketToken); M(SyntaxKind.CloseBracketToken); } } } M(SyntaxKind.SemicolonToken); } } N(SyntaxKind.InterfaceDeclaration); { N(SyntaxKind.InterfaceKeyword); M(SyntaxKind.IdentifierToken); M(SyntaxKind.OpenBraceToken); M(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } } }