|
// 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();
}
}
}
|