/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Syntax/Parsing/AllowsConstraintParsing.cs
1 893 строки
71 KB
AlekseyTs
Bind `allows` constraint clause (#72386)
06 мар 2024, 07:10
Не верифицирован
06 мар 2024, 07:10
ac9b1c2
Код
Авторство
О чём код?
// 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 Microsoft.CodeAnalysis.CSharp.Symbols; 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 AllowsConstraintParsing : ParsingTests { private new SyntaxTree UsingTree(string text, params DiagnosticDescription[] expectedErrors) => UsingTree(text, options: null, expectedErrors); public AllowsConstraintParsing(ITestOutputHelper output) : base(output) { } [Fact] public void RefStruct_Single() { var text = @" class C<T> where T : allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_Single_MissingRef() { var text = @" class C<T> where T : allows struct {}"; UsingTree(text, // (2,29): error CS1003: Syntax error, ',' expected // class C<T> where T : allows struct Diagnostic(ErrorCode.ERR_SyntaxError, "struct").WithArguments(",").WithLocation(2, 29) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "allows"); } } M(SyntaxKind.CommaToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_Single_MissingStruct() { var text = @" class C<T> where T : allows ref {}"; UsingTree(text, // (2,32): error CS1003: Syntax error, 'struct' expected // class C<T> where T : allows ref Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("struct").WithLocation(2, 32) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); M(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_Single_MissingRefAndStruct() { var text = @" class C<T> where T : allows {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "allows"); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_Single_EscapedAllows() { var text = @" class C<T> where T : @allows ref struct {}"; UsingTree(text, // (2,30): error CS1003: Syntax error, ',' expected // class C<T> where T : @allows ref struct Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(2, 30), // (2,34): error CS1003: Syntax error, ',' expected // class C<T> where T : @allows ref struct Diagnostic(ErrorCode.ERR_SyntaxError, "struct").WithArguments(",").WithLocation(2, 34) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "@allows"); } } M(SyntaxKind.CommaToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_Single_EscapedRef() { var text = @" class C<T> where T : allows @ref struct {}"; UsingTree(text, // (2,29): error CS1003: Syntax error, ',' expected // class C<T> where T : allows @ref struct Diagnostic(ErrorCode.ERR_SyntaxError, "@ref").WithArguments(",").WithLocation(2, 29), // (2,34): error CS1003: Syntax error, ',' expected // class C<T> where T : allows @ref struct Diagnostic(ErrorCode.ERR_SyntaxError, "struct").WithArguments(",").WithLocation(2, 34) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "allows"); } } M(SyntaxKind.CommaToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "@ref"); } } M(SyntaxKind.CommaToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_Single_EscapedStruct() { var text = @" class C<T> where T : allows ref @struct {}"; UsingTree(text, // (2,33): error CS1003: Syntax error, 'struct' expected // class C<T> where T : allows ref @struct Diagnostic(ErrorCode.ERR_SyntaxError, "@struct").WithArguments("struct").WithLocation(2, 33), // (2,33): error CS1003: Syntax error, ',' expected // class C<T> where T : allows ref @struct Diagnostic(ErrorCode.ERR_SyntaxError, "@struct").WithArguments(",").WithLocation(2, 33) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); M(SyntaxKind.StructKeyword); } } M(SyntaxKind.CommaToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "@struct"); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_TwoInARow() { var text = @" class C<T> where T : allows ref struct, ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } N(SyntaxKind.CommaToken); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_TwoInARow_MissingRef() { var text = @" class C<T> where T : allows ref struct, struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } N(SyntaxKind.CommaToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_TwoInARow_MissingStruct() { var text = @" class C<T> where T : allows ref struct, ref {}"; UsingTree(text, // (2,44): error CS1003: Syntax error, 'struct' expected // class C<T> where T : allows ref struct, ref Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("struct").WithLocation(2, 44) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } N(SyntaxKind.CommaToken); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); M(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_TwoAllowsInARow() { var text = @" class C<T> where T : allows ref struct, allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_FollowedByAComma_01() { var text = @" class C<T> where T : allows ref struct, {}"; UsingTree(text, // (2,39): error CS1073: Unexpected token ',' // class C<T> where T : allows ref struct, Diagnostic(ErrorCode.ERR_UnexpectedToken, ",").WithArguments(",").WithLocation(2, 39) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_FollowedByAComma_02() { var text = @" class C<T> where T : struct, allows ref struct, {}"; UsingTree(text, // (2,47): error CS1073: Unexpected token ',' // class C<T> where T : struct, allows ref struct, Diagnostic(ErrorCode.ERR_UnexpectedToken, ",").WithArguments(",").WithLocation(2, 47) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_FollowedByACommaAndWhere_01() { var text = @" class C<T, S> where T : allows ref struct, where S : class {}"; UsingTree(text, // (2,42): error CS1073: Unexpected token ',' // class C<T, S> where T : allows ref struct, where S : class Diagnostic(ErrorCode.ERR_UnexpectedToken, ",").WithArguments(",").WithLocation(2, 42) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.CommaToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "S"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "S"); } N(SyntaxKind.ColonToken); N(SyntaxKind.ClassConstraint); { N(SyntaxKind.ClassKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_FollowedByACommaAndWhere_02() { var text = @" class C<T, S> where T : struct, allows ref struct, where S : class {}"; UsingTree(text, // (2,50): error CS1073: Unexpected token ',' // class C<T, S> where T : struct, allows ref struct, where S : class Diagnostic(ErrorCode.ERR_UnexpectedToken, ",").WithArguments(",").WithLocation(2, 50) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.CommaToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "S"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "S"); } N(SyntaxKind.ColonToken); N(SyntaxKind.ClassConstraint); { N(SyntaxKind.ClassKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_FollowedByWhere_01() { var text = @" class C<T, S> where T : allows ref struct where S : class {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.CommaToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "S"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "S"); } N(SyntaxKind.ColonToken); N(SyntaxKind.ClassConstraint); { N(SyntaxKind.ClassKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_FollowedByWhere_02() { var text = @" class C<T, S> where T : struct, allows ref struct where S : class {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.CommaToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "S"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "S"); } N(SyntaxKind.ColonToken); N(SyntaxKind.ClassConstraint); { N(SyntaxKind.ClassKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_AfterStruct() { var text = @" class C<T> where T : struct, allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_AfterStructAndMissingComma() { var text = @" class C<T> where T : struct allows ref struct {}"; UsingTree(text, // (2,29): error CS1003: Syntax error, ',' expected // class C<T> where T : struct allows ref struct Diagnostic(ErrorCode.ERR_SyntaxError, "allows").WithArguments(",").WithLocation(2, 29) ); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } M(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_AfterClass() { var text = @" class C<T> where T : class, allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.ClassConstraint); { N(SyntaxKind.ClassKeyword); } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_AfterDefault() { var text = @" class C<T> where T : default, allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.DefaultConstraint); { N(SyntaxKind.DefaultKeyword); } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_AfterUnmanaged() { var text = @" class C<T> where T : unmanaged, allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "unmanaged"); } } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_AfterNotNull() { var text = @" class C<T> where T : notnull, allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "notnull"); } } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_AfterTypeConstraint() { var text = @" class C<T> where T : SomeType, allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "SomeType"); } } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_AfterNew() { var text = @" class C<T> where T : new(), allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.ConstructorConstraint); { N(SyntaxKind.NewKeyword); N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_AfterMultiple() { var text = @" class C<T> where T : struct, SomeType, new(), allows ref struct {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.StructConstraint); { N(SyntaxKind.StructKeyword); } N(SyntaxKind.CommaToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "SomeType"); } } N(SyntaxKind.CommaToken); N(SyntaxKind.ConstructorConstraint); { N(SyntaxKind.NewKeyword); N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } N(SyntaxKind.CommaToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_BeforeClass() { var text = @" class C<T> where T : allows ref struct, class {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } N(SyntaxKind.CommaToken); N(SyntaxKind.ClassConstraint); { N(SyntaxKind.ClassKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_BeforeDefault() { var text = @" class C<T> where T : allows ref struct, default {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } N(SyntaxKind.CommaToken); N(SyntaxKind.DefaultConstraint); { N(SyntaxKind.DefaultKeyword); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_BeforeUnmanaged() { var text = @" class C<T> where T : allows ref struct, unmanaged {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } N(SyntaxKind.CommaToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "unmanaged"); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_BeforeNotNull() { var text = @" class C<T> where T : allows ref struct, notnull {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } N(SyntaxKind.CommaToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "notnull"); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_BeforeTypeConstraint() { var text = @" class C<T> where T : allows ref struct, SomeType {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } N(SyntaxKind.CommaToken); N(SyntaxKind.TypeConstraint); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "SomeType"); } } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void RefStruct_BeforeNew() { var text = @" class C<T> where T : allows ref struct, new() {}"; UsingTree(text); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.TypeParameterList); { N(SyntaxKind.LessThanToken); N(SyntaxKind.TypeParameter); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.GreaterThanToken); } N(SyntaxKind.TypeParameterConstraintClause); { N(SyntaxKind.WhereKeyword); N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "T"); } N(SyntaxKind.ColonToken); N(SyntaxKind.AllowsConstraintClause); { N(SyntaxKind.AllowsKeyword); N(SyntaxKind.RefStructConstraint); { N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); } } N(SyntaxKind.CommaToken); N(SyntaxKind.ConstructorConstraint); { N(SyntaxKind.NewKeyword); N(SyntaxKind.OpenParenToken); N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } } }