|
// 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.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests;
[CompilerTrait(CompilerFeature.Extensions)]
public class ExtensionsParsingTests : ParsingTests
{
public ExtensionsParsingTests(ITestOutputHelper output) : base(output) { }
[Fact]
public void LangVer13()
{
// Tracked by https://github.com/dotnet/roslyn/issues/76130 : consider giving a LangVer error to trigger UpgradeProject
UsingTree("""
class C
{
extension<T>(object o) where T : struct { }
}
""",
TestOptions.Regular13,
// (3,17): error CS1519: Invalid token '(' in class, record, struct, or interface member declaration
// extension<T>(object o) where T : struct { }
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "(").WithArguments("(").WithLocation(3, 17),
// (3,26): error CS8124: Tuple must contain at least two elements.
// extension<T>(object o) where T : struct { }
Diagnostic(ErrorCode.ERR_TupleTooFewElements, ")").WithLocation(3, 26),
// (3,34): error CS1002: ; expected
// extension<T>(object o) where T : struct { }
Diagnostic(ErrorCode.ERR_SemicolonExpected, "T").WithLocation(3, 34),
// (3,36): error CS1519: Invalid token ':' in class, record, struct, or interface member declaration
// extension<T>(object o) where T : struct { }
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ":").WithArguments(":").WithLocation(3, 36),
// (3,36): error CS1519: Invalid token ':' in class, record, struct, or interface member declaration
// extension<T>(object o) where T : struct { }
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ":").WithArguments(":").WithLocation(3, 36),
// (3,45): error CS1001: Identifier expected
// extension<T>(object o) where T : struct { }
Diagnostic(ErrorCode.ERR_IdentifierExpected, "{").WithLocation(3, 45));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.IncompleteMember);
{
N(SyntaxKind.GenericName);
{
N(SyntaxKind.IdentifierToken, "extension");
N(SyntaxKind.TypeArgumentList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.GreaterThanToken);
}
}
}
N(SyntaxKind.FieldDeclaration);
{
N(SyntaxKind.VariableDeclaration);
{
N(SyntaxKind.TupleType);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.TupleElement);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
M(SyntaxKind.CommaToken);
M(SyntaxKind.TupleElement);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.VariableDeclarator);
{
N(SyntaxKind.IdentifierToken, "where");
}
}
M(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.IncompleteMember);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T");
}
}
N(SyntaxKind.StructDeclaration);
{
N(SyntaxKind.StructKeyword);
M(SyntaxKind.IdentifierToken);
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Theory, CombinatorialData]
public void LangVer14(bool useCSharp14)
{
UsingTree("""
class C
{
extension<T>(object o) where T : struct { }
}
""",
useCSharp14 ? TestOptions.RegularNext : TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.GreaterThanToken);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.ColonToken);
N(SyntaxKind.StructConstraint);
{
N(SyntaxKind.StructKeyword);
}
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void MultipleConstraints()
{
UsingTree("""
class C
{
extension<T1, T2>(object o) where T1 : struct where T2 : class { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T1");
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T2");
}
N(SyntaxKind.GreaterThanToken);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T1");
}
N(SyntaxKind.ColonToken);
N(SyntaxKind.StructConstraint);
{
N(SyntaxKind.StructKeyword);
}
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T2");
}
N(SyntaxKind.ColonToken);
N(SyntaxKind.ClassConstraint);
{
N(SyntaxKind.ClassKeyword);
}
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void MultipleConstraints_Incomplete()
{
UsingTree("""
class C
{
extension<T1, T2>(object o) where T1 where T2 : class { }
}
""",
TestOptions.RegularPreview,
// (3,42): error CS1003: Syntax error, ':' expected
// extension<T1, T2>(object o) where T1 where T2 : class { }
Diagnostic(ErrorCode.ERR_SyntaxError, "where").WithArguments(":").WithLocation(3, 42),
// (3,42): error CS1031: Type expected
// extension<T1, T2>(object o) where T1 where T2 : class { }
Diagnostic(ErrorCode.ERR_TypeExpected, "where").WithLocation(3, 42));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T1");
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T2");
}
N(SyntaxKind.GreaterThanToken);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T1");
}
M(SyntaxKind.ColonToken);
M(SyntaxKind.TypeConstraint);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T2");
}
N(SyntaxKind.ColonToken);
N(SyntaxKind.ClassConstraint);
{
N(SyntaxKind.ClassKeyword);
}
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithName()
{
UsingTree("""
class C
{
extension Name(Type) { }
}
""",
TestOptions.RegularPreview,
// (3,15): error CS9500: Extension declarations may not have a name.
// extension Name(Type) { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsName, "Name").WithLocation(3, 15));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithName_02()
{
UsingTree("""
class C
{
extension Name<T>(Type) { }
}
""",
TestOptions.RegularPreview,
// (3,15): error CS9500: Extension declarations may not have a name.
// extension Name<T>(Type) { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsName, "Name").WithLocation(3, 15));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.GreaterThanToken);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithDefaultParameterValue()
{
var src = """
static class C
{
extension(object x = null) { }
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (3,15): error CS9284: The receiver parameter of an extension cannot have a default value
// extension(object x = null) { }
Diagnostic(ErrorCode.ERR_ExtensionParameterDisallowsDefaultValue, "object x = null").WithLocation(3, 15));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "x");
N(SyntaxKind.EqualsValueClause);
{
N(SyntaxKind.EqualsToken);
N(SyntaxKind.NullLiteralExpression);
{
N(SyntaxKind.NullKeyword);
}
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithDefaultParameterValue_02()
{
var src = """
static class C
{
extension(object = null) { }
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (3,15): error CS9284: The receiver parameter of an extension cannot have a default value
// extension(object = null) { }
Diagnostic(ErrorCode.ERR_ExtensionParameterDisallowsDefaultValue, "object = null").WithLocation(3, 15));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.EqualsValueClause);
{
N(SyntaxKind.EqualsToken);
N(SyntaxKind.NullLiteralExpression);
{
N(SyntaxKind.NullKeyword);
}
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithDefaultParameterValue_03()
{
var src = """
class C
{
extension(Type =) { }
}
""";
UsingTree(src, TestOptions.RegularPreview,
// (3,21): error CS1525: Invalid expression term ')'
// extension(Type =) { }
Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(3, 21));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.EqualsValueClause);
{
N(SyntaxKind.EqualsToken);
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithBaseList()
{
var src = """
class C
{
extension Name(Type) : Type2() { }
}
""";
UsingTree(src, TestOptions.RegularPreview,
// (3,15): error CS9500: Extension declarations may not have a name.
// extension Name(Type) : Type2() { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsName, "Name").WithLocation(3, 15),
// (3,26): error CS1514: { expected
// extension Name(Type) : Type2() { }
Diagnostic(ErrorCode.ERR_LbraceExpected, ":").WithLocation(3, 26),
// (3,26): error CS1513: } expected
// extension Name(Type) : Type2() { }
Diagnostic(ErrorCode.ERR_RbraceExpected, ":").WithLocation(3, 26),
// (3,26): error CS1519: Invalid token ':' in a member declaration
// extension Name(Type) : Type2() { }
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ":").WithArguments(":").WithLocation(3, 26));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
M(SyntaxKind.OpenBraceToken);
M(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.ConstructorDeclaration);
{
N(SyntaxKind.IdentifierToken, "Type2");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Theory, CombinatorialData]
public void TypeNamedExtension(bool useCSharp14)
{
UsingTree("""
class extension
{
extension(Type constructorParameter) { }
}
""",
TestOptions.Regular13);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "extension");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ConstructorDeclaration);
{
N(SyntaxKind.IdentifierToken, "extension");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.IdentifierToken, "constructorParameter");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
// Tracked by https://github.com/dotnet/roslyn/issues/76130 : report error for declaring type named "extension"
// Note: break from C# 13
UsingTree("""
class extension
{
extension(Type constructorParameter) { }
}
""",
useCSharp14 ? TestOptions.RegularNext : TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "extension");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.IdentifierToken, "constructorParameter");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
UsingTree("""
class extension
{
@extension(Type constructorParameter) { }
}
""",
useCSharp14 ? TestOptions.RegularNext : TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "extension");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ConstructorDeclaration);
{
N(SyntaxKind.IdentifierToken, "@extension");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.IdentifierToken, "constructorParameter");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_NoName()
{
UsingTree("""
class C
{
extension(Type) { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_NoName_02()
{
UsingTree("""
class C
{
extension(object) { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_Multiple()
{
var src = """
static class C
{
extension(object x1, string x2) { }
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (3,26): error CS9285: An extension container can have only one receiver parameter
// extension(object x1, string x2) { }
Diagnostic(ErrorCode.ERR_ReceiverParameterOnlyOne, "string x2").WithLocation(3, 26));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "x1");
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.StringKeyword);
}
N(SyntaxKind.IdentifierToken, "x2");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_Multiple_02()
{
var src = """
static class C
{
extension(object, string) { }
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (3,23): error CS9285: An extension container can have only one receiver parameter
// extension(object, string) { }
Diagnostic(ErrorCode.ERR_ReceiverParameterOnlyOne, "string").WithLocation(3, 23));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.StringKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_Multiple_03()
{
var src = """
class C
{
extension(object object) { }
}
""";
UsingTree(src, TestOptions.RegularPreview,
// (3,22): error CS1003: Syntax error, ',' expected
// extension(object object) { }
Diagnostic(ErrorCode.ERR_SyntaxError, "object").WithArguments(",").WithLocation(3, 22));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
M(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_Multiple_04()
{
var src = """
class C
{
extension(Type, object object) { }
}
""";
UsingTree(src, TestOptions.RegularPreview,
// (3,28): error CS1003: Syntax error, ',' expected
// extension(Type, object object) { }
Diagnostic(ErrorCode.ERR_SyntaxError, "object").WithArguments(",").WithLocation(3, 28));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
M(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_Multiple_05()
{
var src = """
class C
{
extension(Type, object =) { }
}
""";
UsingTree(src, TestOptions.RegularPreview,
// (3,29): error CS1525: Invalid expression term ')'
// extension(Type, object =) { }
Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(3, 29));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.EqualsValueClause);
{
N(SyntaxKind.EqualsToken);
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_Multiple_06()
{
var src = """
class C
{
extension(Type, object { }
}
""";
UsingTree(src, TestOptions.RegularPreview,
// (3,28): error CS1026: ) expected
// extension(Type, object { }
Diagnostic(ErrorCode.ERR_CloseParenExpected, "{").WithLocation(3, 28));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
M(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_Multiple_07()
{
var src = """
static class C
{
extension(object, params object[]) { }
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (3,23): error CS9285: An extension container can have only one receiver parameter
// extension(object, params object[]) { }
Diagnostic(ErrorCode.ERR_ReceiverParameterOnlyOne, "params object[]").WithLocation(3, 23));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.ParamsKeyword);
N(SyntaxKind.ArrayType);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.ArrayRankSpecifier);
{
N(SyntaxKind.OpenBracketToken);
N(SyntaxKind.OmittedArraySizeExpression);
{
N(SyntaxKind.OmittedArraySizeExpressionToken);
}
N(SyntaxKind.CloseBracketToken);
}
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ReceiverParameter_MissingClosingParen()
{
var src = """
class C
{
extension(object { }
}
""";
UsingTree(src, TestOptions.RegularPreview,
// (3,22): error CS1026: ) expected
// extension(object { }
Diagnostic(ErrorCode.ERR_CloseParenExpected, "{").WithLocation(3, 22));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
M(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void NoClosingBrace()
{
UsingTree("""
class C
{
extension(Type) { void M() { }
}
""",
TestOptions.RegularPreview,
// (4,2): error CS1513: } expected
// }
Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(4, 2));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
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.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
M(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void TopLevel()
{
var src = """
extension(object) { }
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (1,1): error CS9283: Extensions must be declared in a top-level, non-generic, static class
// extension(Type) { }
Diagnostic(ErrorCode.ERR_BadExtensionContainingType, "extension").WithLocation(1, 1));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void InNestedType()
{
var src = """
static class C
{
class Nested
{
extension(object) { }
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,9): error CS9283: Extensions must be declared in a top-level, non-generic, static class
// extension(object) { }
Diagnostic(ErrorCode.ERR_BadExtensionContainingType, "extension").WithLocation(5, 9));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "Nested");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void InExtension()
{
var src = """
static class C
{
extension(object)
{
extension(string) { }
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,9): error CS9282: Extension declarations can include only methods or properties
// extension(Type2) { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "extension").WithLocation(5, 9));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.StringKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithAttributes()
{
UsingTree("""
class C
{
[MyAttribute]
extension(Type) { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.AttributeList);
{
N(SyntaxKind.OpenBracketToken);
N(SyntaxKind.Attribute);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "MyAttribute");
}
}
N(SyntaxKind.CloseBracketToken);
}
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithModifiers_Partial()
{
var src = """
static class C
{
partial extension(Type) { }
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (3,13): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'record', 'struct', 'interface', 'event', an instance constructor name, or a method or property return type.
// partial extension(Type) { }
Diagnostic(ErrorCode.ERR_PartialMisplaced, "extension").WithLocation(3, 13),
// (3,23): error CS0246: The type or namespace name 'Type' could not be found (are you missing a using directive or an assembly reference?)
// partial extension(Type) { }
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Type").WithArguments("Type").WithLocation(3, 23)
);
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.PartialKeyword);
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithModifiers_Scoped()
{
UsingTree("""
class C
{
scoped extension(Type) { }
}
""",
TestOptions.RegularPreview,
// (3,26): error CS1001: Identifier expected
// scoped extension(Type) { }
Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(3, 26));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.MethodDeclaration);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "scoped");
}
N(SyntaxKind.IdentifierToken, "extension");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
M(SyntaxKind.IdentifierToken);
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithModifiers_Async()
{
UsingTree("""
class C
{
async extension(Type) { }
}
""",
TestOptions.RegularPreview,
// (3,25): error CS1001: Identifier expected
// async extension(Type) { }
Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(3, 25));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.MethodDeclaration);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "async");
}
N(SyntaxKind.IdentifierToken, "extension");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
M(SyntaxKind.IdentifierToken);
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithModifiers_Const()
{
UsingTree("""
class C
{
const extension(Type) { }
}
""",
TestOptions.RegularPreview,
// (3,20): error CS1001: Identifier expected
// const extension(Type) { }
Diagnostic(ErrorCode.ERR_IdentifierExpected, "(").WithLocation(3, 20),
// (3,20): error CS1528: Expected ; or = (cannot specify constructor arguments in declaration)
// const extension(Type) { }
Diagnostic(ErrorCode.ERR_BadVarDecl, "(Type").WithLocation(3, 20),
// (3,20): error CS1003: Syntax error, '[' expected
// const extension(Type) { }
Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments("[").WithLocation(3, 20),
// (3,25): error CS1003: Syntax error, ']' expected
// const extension(Type) { }
Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments("]").WithLocation(3, 25),
// (3,27): error CS1003: Syntax error, ',' expected
// const extension(Type) { }
Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments(",").WithLocation(3, 27),
// (3,29): error CS1002: ; expected
// const extension(Type) { }
Diagnostic(ErrorCode.ERR_SemicolonExpected, "}").WithLocation(3, 29),
// (4,1): error CS1022: Type or namespace definition, or end-of-file expected
// }
Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(4, 1));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.FieldDeclaration);
{
N(SyntaxKind.ConstKeyword);
N(SyntaxKind.VariableDeclaration);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "extension");
}
N(SyntaxKind.VariableDeclarator);
{
M(SyntaxKind.IdentifierToken);
N(SyntaxKind.BracketedArgumentList);
{
M(SyntaxKind.OpenBracketToken);
N(SyntaxKind.Argument);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
M(SyntaxKind.CloseBracketToken);
}
}
}
M(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithModifiers_Fixed()
{
UsingTree("""
class C
{
fixed extension(Type) { }
}
""",
TestOptions.RegularPreview,
// (3,20): error CS1001: Identifier expected
// fixed extension(Type) { }
Diagnostic(ErrorCode.ERR_IdentifierExpected, "(").WithLocation(3, 20),
// (3,20): error CS1528: Expected ; or = (cannot specify constructor arguments in declaration)
// fixed extension(Type) { }
Diagnostic(ErrorCode.ERR_BadVarDecl, "(Type").WithLocation(3, 20),
// (3,20): error CS1003: Syntax error, '[' expected
// fixed extension(Type) { }
Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments("[").WithLocation(3, 20),
// (3,25): error CS1003: Syntax error, ']' expected
// fixed extension(Type) { }
Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments("]").WithLocation(3, 25),
// (3,27): error CS1003: Syntax error, ',' expected
// fixed extension(Type) { }
Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments(",").WithLocation(3, 27),
// (3,29): error CS1002: ; expected
// fixed extension(Type) { }
Diagnostic(ErrorCode.ERR_SemicolonExpected, "}").WithLocation(3, 29),
// (4,1): error CS1022: Type or namespace definition, or end-of-file expected
// }
Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(4, 1));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.FieldDeclaration);
{
N(SyntaxKind.FixedKeyword);
N(SyntaxKind.VariableDeclaration);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "extension");
}
N(SyntaxKind.VariableDeclarator);
{
M(SyntaxKind.IdentifierToken);
N(SyntaxKind.BracketedArgumentList);
{
M(SyntaxKind.OpenBracketToken);
N(SyntaxKind.Argument);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
M(SyntaxKind.CloseBracketToken);
}
}
}
M(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithModifiers_Ref()
{
UsingTree("""
class C
{
ref extension(Type) { }
}
""",
TestOptions.RegularPreview,
// (3,18): error CS1519: Invalid token '(' in a member declaration
// ref extension(Type) { }
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "(").WithArguments("(").WithLocation(3, 18),
// (3,23): error CS8124: Tuple must contain at least two elements.
// ref extension(Type) { }
Diagnostic(ErrorCode.ERR_TupleTooFewElements, ")").WithLocation(3, 23),
// (3,25): error CS1519: Invalid token '{' in a member declaration
// ref extension(Type) { }
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(3, 25),
// (4,1): error CS1022: Type or namespace definition, or end-of-file expected
// }
Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(4, 1));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.IncompleteMember);
{
N(SyntaxKind.RefType);
{
N(SyntaxKind.RefKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "extension");
}
}
}
N(SyntaxKind.IncompleteMember);
{
N(SyntaxKind.TupleType);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.TupleElement);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
M(SyntaxKind.CommaToken);
M(SyntaxKind.TupleElement);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
N(SyntaxKind.CloseParenToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Theory]
[InlineData("abstract", SyntaxKind.AbstractKeyword)]
[InlineData("sealed", SyntaxKind.SealedKeyword)]
[InlineData("static", SyntaxKind.StaticKeyword)]
[InlineData("new", SyntaxKind.NewKeyword)]
[InlineData("public", SyntaxKind.PublicKeyword)]
[InlineData("protected", SyntaxKind.ProtectedKeyword)]
[InlineData("private", SyntaxKind.PrivateKeyword)]
[InlineData("readonly", SyntaxKind.ReadOnlyKeyword)]
[InlineData("volatile", SyntaxKind.VolatileKeyword)]
[InlineData("extern", SyntaxKind.ExternKeyword)]
[InlineData("unsafe", SyntaxKind.UnsafeKeyword)]
[InlineData("virtual", SyntaxKind.VirtualKeyword)]
[InlineData("override", SyntaxKind.OverrideKeyword)]
[InlineData("required", SyntaxKind.RequiredKeyword)]
[InlineData("file", SyntaxKind.FileKeyword)]
public void WithModifiers_Misc(string modifier, SyntaxKind expected)
{
var src = $$"""
static class C
{
{{modifier}} extension(object) { }
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (3,14): error CS0106: The modifier 'abstract' is not valid for this item
// abstract extension(object) { }
Diagnostic(ErrorCode.ERR_BadMemberFlag, "extension").WithArguments(modifier));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(expected);
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_Const()
{
var src = """
static class C
{
extension(object)
{
const int i = 0;
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,19): error CS9282: Extension declarations can include only methods or properties
// const int i = 0;
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "i").WithLocation(5, 19));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.FieldDeclaration);
{
N(SyntaxKind.ConstKeyword);
N(SyntaxKind.VariableDeclaration);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
}
N(SyntaxKind.VariableDeclarator);
{
N(SyntaxKind.IdentifierToken, "i");
N(SyntaxKind.EqualsValueClause);
{
N(SyntaxKind.EqualsToken);
N(SyntaxKind.NumericLiteralExpression);
{
N(SyntaxKind.NumericLiteralToken, "0");
}
}
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_FixedField()
{
var src = """
static class C
{
extension(object o)
{
fixed int field[10];
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,19): error CS1642: Fixed size buffer fields may only be members of structs
// fixed int field[10];
Diagnostic(ErrorCode.ERR_FixedNotInStruct, "field").WithLocation(5, 19),
// (5,19): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
// fixed int field[10];
Diagnostic(ErrorCode.ERR_UnsafeNeeded, "field[10]").WithLocation(5, 19),
// (5,19): error CS9282: Extension declarations can include only methods or properties
// fixed int field[10];
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "field").WithLocation(5, 19));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.FieldDeclaration);
{
N(SyntaxKind.FixedKeyword);
N(SyntaxKind.VariableDeclaration);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
}
N(SyntaxKind.VariableDeclarator);
{
N(SyntaxKind.IdentifierToken, "field");
N(SyntaxKind.BracketedArgumentList);
{
N(SyntaxKind.OpenBracketToken);
N(SyntaxKind.Argument);
{
N(SyntaxKind.NumericLiteralExpression);
{
N(SyntaxKind.NumericLiteralToken, "10");
}
}
N(SyntaxKind.CloseBracketToken);
}
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_EventField()
{
var src = """
static class C
{
extension(object o)
{
event System.EventHandler eventField;
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,35): error CS9282: Extension declarations can include only methods or properties
// event System.EventHandler eventField;
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "eventField").WithLocation(5, 35),
// (5,35): error CS9282: Extension declarations can include only methods or properties
// event System.EventHandler eventField;
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "eventField").WithLocation(5, 35),
// (5,35): error CS9282: Extension declarations can include only methods or properties
// event System.EventHandler eventField;
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "eventField").WithLocation(5, 35),
// (5,35): warning CS0067: The event 'C.extension(object).eventField' is never used
// event System.EventHandler eventField;
Diagnostic(ErrorCode.WRN_UnreferencedEvent, "eventField").WithArguments("C.extension(object).eventField").WithLocation(5, 35));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.EventFieldDeclaration);
{
N(SyntaxKind.EventKeyword);
N(SyntaxKind.VariableDeclaration);
{
N(SyntaxKind.QualifiedName);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "System");
}
N(SyntaxKind.DotToken);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "EventHandler");
}
}
N(SyntaxKind.VariableDeclarator);
{
N(SyntaxKind.IdentifierToken, "eventField");
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_Event()
{
var src = """
static class C
{
extension(object o)
{
event System.EventHandler Event { add { } remove { } }
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,35): error CS9282: Extension declarations can include only methods or properties
// event System.EventHandler Event { add { } remove { } }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "Event").WithLocation(5, 35),
// (5,43): error CS9282: Extension declarations can include only methods or properties
// event System.EventHandler Event { add { } remove { } }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "add").WithLocation(5, 43),
// (5,51): error CS9282: Extension declarations can include only methods or properties
// event System.EventHandler Event { add { } remove { } }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "remove").WithLocation(5, 51));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.EventDeclaration);
{
N(SyntaxKind.EventKeyword);
N(SyntaxKind.QualifiedName);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "System");
}
N(SyntaxKind.DotToken);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "EventHandler");
}
}
N(SyntaxKind.IdentifierToken, "Event");
N(SyntaxKind.AccessorList);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.AddAccessorDeclaration);
{
N(SyntaxKind.AddKeyword);
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.RemoveAccessorDeclaration);
{
N(SyntaxKind.RemoveKeyword);
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_MethodAndProperty()
{
UsingTree("""
class C
{
extension(Type)
{
void M() { }
int Property { get; set; }
}
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
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.CloseBraceToken);
}
}
N(SyntaxKind.PropertyDeclaration);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
}
N(SyntaxKind.IdentifierToken, "Property");
N(SyntaxKind.AccessorList);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.GetAccessorDeclaration);
{
N(SyntaxKind.GetKeyword);
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.SetAccessorDeclaration);
{
N(SyntaxKind.SetKeyword);
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_NestedType()
{
var src = """
static class C
{
extension(object)
{
class Nested { }
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,15): error CS9282: Extension declarations can include only methods or properties
// class Nested { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "Nested").WithLocation(5, 15));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "Nested");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_Constructor()
{
var src = """
static class C
{
extension(object o)
{
Constructor() { }
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,9): error CS1520: Method must have a return type
// Constructor() { }
Diagnostic(ErrorCode.ERR_MemberNeedsType, "Constructor").WithLocation(5, 9),
// (5,9): error CS9282: Extension declarations can include only methods or properties
// Constructor() { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "Constructor").WithLocation(5, 9));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ConstructorDeclaration);
{
N(SyntaxKind.IdentifierToken, "Constructor");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_StaticConstructor()
{
var src = """
static class C
{
extension(object)
{
static Constructor() { }
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,16): error CS1520: Method must have a return type
// static Constructor() { }
Diagnostic(ErrorCode.ERR_MemberNeedsType, "Constructor").WithLocation(5, 16),
// (5,16): error CS9282: Extension declarations can include only methods or properties
// static Constructor() { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "Constructor").WithLocation(5, 16));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ConstructorDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.IdentifierToken, "Constructor");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_Finalizer()
{
var src = """
static class C
{
extension(object o)
{
~Finalizer() { }
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,10): error CS9282: Extension declarations can include only methods or properties
// ~Finalizer() { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "Finalizer").WithLocation(5, 10));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.DestructorDeclaration);
{
N(SyntaxKind.TildeToken);
N(SyntaxKind.IdentifierToken, "Finalizer");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_Field()
{
var src = """
static class C
{
extension(object o)
{
int field;
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,13): error CS9282: Extension declarations can include only methods or properties
// int field;
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "field").WithLocation(5, 13),
// (5,13): warning CS0169: The field 'C.extension(object).field' is never used
// int field;
Diagnostic(ErrorCode.WRN_UnreferencedField, "field").WithArguments("C.extension(object).field").WithLocation(5, 13));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "o");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.FieldDeclaration);
{
N(SyntaxKind.VariableDeclaration);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
}
N(SyntaxKind.VariableDeclarator);
{
N(SyntaxKind.IdentifierToken, "field");
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_Indexer()
{
var src = """
class C
{
extension(Type)
{
int this[int i] { get => 0; set { } }
}
}
""";
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.IndexerDeclaration);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
}
N(SyntaxKind.ThisKeyword);
N(SyntaxKind.BracketedParameterList);
{
N(SyntaxKind.OpenBracketToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
}
N(SyntaxKind.IdentifierToken, "i");
}
N(SyntaxKind.CloseBracketToken);
}
N(SyntaxKind.AccessorList);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.GetAccessorDeclaration);
{
N(SyntaxKind.GetKeyword);
N(SyntaxKind.ArrowExpressionClause);
{
N(SyntaxKind.EqualsGreaterThanToken);
N(SyntaxKind.NumericLiteralExpression);
{
N(SyntaxKind.NumericLiteralToken, "0");
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.SetAccessorDeclaration);
{
N(SyntaxKind.SetKeyword);
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_Operator()
{
var src = """
static class C
{
extension(object)
{
public static object operator +(object a, object b) => a;
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,39): error CS0563: One of the parameters of a binary operator must be the containing type
// public static object operator +(object a, object b) => a;
Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "+").WithLocation(5, 39),
// (5,39): error CS9282: Extension declarations can include only methods or properties
// public static object operator +(object a, object b) => a;
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "+").WithLocation(5, 39));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.OperatorDeclaration);
{
N(SyntaxKind.PublicKeyword);
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.OperatorKeyword);
N(SyntaxKind.PlusToken);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "a");
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "b");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.ArrowExpressionClause);
{
N(SyntaxKind.EqualsGreaterThanToken);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "a");
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void Member_ConversionOperator()
{
var src = """
static class C
{
extension(object)
{
public static implicit operator int(object t) => 0;
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (5,41): error CS0556: User-defined conversion must convert to or from the enclosing type
// public static implicit operator int(object t) => 0;
Diagnostic(ErrorCode.ERR_ConversionNotInvolvingContainedType, "int").WithLocation(5, 41),
// (5,41): error CS9282: Extension declarations can include only methods or properties
// public static implicit operator int(object t) => 0;
Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "int").WithLocation(5, 41));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ConversionOperatorDeclaration);
{
N(SyntaxKind.PublicKeyword);
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ImplicitKeyword);
N(SyntaxKind.OperatorKeyword);
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
N(SyntaxKind.IdentifierToken, "t");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.ArrowExpressionClause);
{
N(SyntaxKind.EqualsGreaterThanToken);
N(SyntaxKind.NumericLiteralExpression);
{
N(SyntaxKind.NumericLiteralToken, "0");
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithRef()
{
UsingTree("""
class C
{
ref extension(Type) { }
}
""",
TestOptions.RegularPreview,
// (3,18): error CS1519: Invalid token '(' in class, record, struct, or interface member declaration
// ref extension(Type) { }
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "(").WithArguments("(").WithLocation(3, 18),
// (3,23): error CS8124: Tuple must contain at least two elements.
// ref extension(Type) { }
Diagnostic(ErrorCode.ERR_TupleTooFewElements, ")").WithLocation(3, 23),
// (3,25): error CS1519: Invalid token '{' in class, record, struct, or interface member declaration
// ref extension(Type) { }
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(3, 25),
// (4,1): error CS1022: Type or namespace definition, or end-of-file expected
// }
Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(4, 1));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.IncompleteMember);
{
N(SyntaxKind.RefType);
{
N(SyntaxKind.RefKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "extension");
}
}
}
N(SyntaxKind.IncompleteMember);
{
N(SyntaxKind.TupleType);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.TupleElement);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
M(SyntaxKind.CommaToken);
M(SyntaxKind.TupleElement);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
N(SyntaxKind.CloseParenToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithAttributeOnParameter()
{
UsingTree("""
class C
{
extension([MyAttribute] Type) { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.AttributeList);
{
N(SyntaxKind.OpenBracketToken);
N(SyntaxKind.Attribute);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "MyAttribute");
}
}
N(SyntaxKind.CloseBracketToken);
}
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithModifierOnParameter()
{
UsingTree("""
class C
{
extension(ref Type) { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.RefKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithModifierOnParameter_Scoped()
{
UsingTree("""
class C
{
extension(scoped Type x) { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.IdentifierToken, "x");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithModifierOnParameter_ScopedRef()
{
UsingTree("""
class C
{
extension(scoped ref Type x) { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.RefKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.IdentifierToken, "x");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Theory]
[InlineData("partial")]
[InlineData("await")]
[InlineData("on")]
[InlineData("by")]
public void MiscIdentifier(string identifier)
{
UsingTree($$"""
class C
{
extension(Type {{identifier}}) { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.IdentifierToken, identifier);
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithTerminator_SemiColon()
{
UsingTree("""
class C
{
extension(Type) { ;
class D { }
}
""",
TestOptions.RegularPreview,
// (3,23): error CS1519: Invalid token ';' in a member declaration
// extension(Type) { ;
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(3, 23),
// (5,2): error CS1513: } expected
// }
Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(5, 2));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "D");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
M(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithTerminator_SemiColon_02()
{
UsingTree("""
class C
{
extension(Type) { ;
}
""",
TestOptions.RegularPreview,
// (3,23): error CS1519: Invalid token ';' in a member declaration
// extension(Type) { ;
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(3, 23),
// (4,2): error CS1513: } expected
// }
Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(4, 2));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
M(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithTerminator_SemiColon_03()
{
UsingTree("""
class C
{
extension<T ;
class D { }
}
""",
TestOptions.RegularPreview,
// (3,17): error CS1003: Syntax error, '>' expected
// extension<T ;
Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(">").WithLocation(3, 17),
// (3,17): error CS1003: Syntax error, '(' expected
// extension<T ;
Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("(").WithLocation(3, 17),
// (3,17): error CS1031: Type expected
// extension<T ;
Diagnostic(ErrorCode.ERR_TypeExpected, ";").WithLocation(3, 17),
// (3,17): error CS1026: ) expected
// extension<T ;
Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(3, 17));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T");
}
M(SyntaxKind.GreaterThanToken);
}
M(SyntaxKind.ParameterList);
{
M(SyntaxKind.OpenParenToken);
M(SyntaxKind.Parameter);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
M(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "D");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void MissingParameterList()
{
UsingTree("""
class C
{
extension ;
class D { }
}
""",
TestOptions.RegularPreview,
// (3,15): error CS1003: Syntax error, '(' expected
// extension ;
Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("(").WithLocation(3, 15),
// (3,15): error CS1031: Type expected
// extension ;
Diagnostic(ErrorCode.ERR_TypeExpected, ";").WithLocation(3, 15),
// (3,15): error CS1026: ) expected
// extension ;
Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(3, 15));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
M(SyntaxKind.ParameterList);
{
M(SyntaxKind.OpenParenToken);
M(SyntaxKind.Parameter);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
M(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "D");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void SemiColonBody()
{
UsingTree("""
class C
{
extension<T>(Type) where T : struct;
class D { }
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.GreaterThanToken);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.ColonToken);
N(SyntaxKind.StructConstraint);
{
N(SyntaxKind.StructKeyword);
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "D");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithTerminator_OpenBrace()
{
UsingTree("""
class C
{
extension(Type) { {
}
""",
TestOptions.RegularPreview,
// (3,23): error CS1519: Invalid token '{' in a member declaration
// extension(Type) { {
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(3, 23),
// (4,2): error CS1513: } expected
// }
Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(4, 2));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
M(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithTerminator_OpenBrace_02()
{
UsingTree("""
class C
{
extension<T>(Type) where { }
}
""",
TestOptions.RegularPreview,
// (3,30): error CS1001: Identifier expected
// extension<T>(Type) where { }
Diagnostic(ErrorCode.ERR_IdentifierExpected, "{").WithLocation(3, 30),
// (3,30): error CS1003: Syntax error, ':' expected
// extension<T>(Type) where { }
Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments(":").WithLocation(3, 30),
// (3,30): error CS1031: Type expected
// extension<T>(Type) where { }
Diagnostic(ErrorCode.ERR_TypeExpected, "{").WithLocation(3, 30));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.GreaterThanToken);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
M(SyntaxKind.ColonToken);
M(SyntaxKind.TypeConstraint);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithTerminator_OpenBrace_03()
{
UsingTree("""
class C
{
extension<T>(Type) where T { }
class D { }
}
""",
TestOptions.RegularPreview,
// (3,32): error CS1003: Syntax error, ':' expected
// extension<T>(Type) where T { }
Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments(":").WithLocation(3, 32),
// (3,32): error CS1031: Type expected
// extension<T>(Type) where T { }
Diagnostic(ErrorCode.ERR_TypeExpected, "{").WithLocation(3, 32));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.GreaterThanToken);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T");
}
M(SyntaxKind.ColonToken);
M(SyntaxKind.TypeConstraint);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "D");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithTerminator_OpenBrace_04()
{
UsingTree("""
class C
{
extension<T>(Type) where T : { }
}
""",
TestOptions.RegularPreview,
// (3,34): error CS1031: Type expected
// extension<T>(Type) where T : { }
Diagnostic(ErrorCode.ERR_TypeExpected, "{").WithLocation(3, 34));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.GreaterThanToken);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.ColonToken);
M(SyntaxKind.TypeConstraint);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithTerminator_OpenBrace_05()
{
UsingTree("""
class C
{
extension<T>(Type) where T : struct, { }
}
""",
TestOptions.RegularPreview,
// (3,42): error CS1031: Type expected
// extension<T>(Type) where T : struct, { }
Diagnostic(ErrorCode.ERR_TypeExpected, "{").WithLocation(3, 42));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.GreaterThanToken);
}
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
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);
M(SyntaxKind.TypeConstraint);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithTerminator_OpenBrace_06()
{
UsingTree("""
class C
{
extension<T {
class D { }
}
""",
TestOptions.RegularPreview,
// (3,17): error CS1003: Syntax error, '>' expected
// extension<T {
Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments(">").WithLocation(3, 17),
// (3,17): error CS1003: Syntax error, '(' expected
// extension<T {
Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments("(").WithLocation(3, 17),
// (3,17): error CS1031: Type expected
// extension<T {
Diagnostic(ErrorCode.ERR_TypeExpected, "{").WithLocation(3, 17),
// (3,17): error CS1026: ) expected
// extension<T {
Diagnostic(ErrorCode.ERR_CloseParenExpected, "{").WithLocation(3, 17),
// (5,2): error CS1513: } expected
// }
Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(5, 2));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.TypeParameterList);
{
N(SyntaxKind.LessThanToken);
N(SyntaxKind.TypeParameter);
{
N(SyntaxKind.IdentifierToken, "T");
}
M(SyntaxKind.GreaterThanToken);
}
M(SyntaxKind.ParameterList);
{
M(SyntaxKind.OpenParenToken);
M(SyntaxKind.Parameter);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
M(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "D");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
M(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void MissingBraces_WithMethod()
{
UsingTree("""
class C
{
extension(Type)
void M() { }
}
""",
TestOptions.RegularPreview,
// (3,20): error CS1514: { expected
// extension(Type)
Diagnostic(ErrorCode.ERR_LbraceExpected, "").WithLocation(3, 20),
// (3,20): error CS1513: } expected
// extension(Type)
Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(3, 20));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
}
N(SyntaxKind.CloseParenToken);
}
M(SyntaxKind.OpenBraceToken);
M(SyntaxKind.CloseBraceToken);
}
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.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void MissingTypeAndIdentifier()
{
UsingTree("""
class C
{
extension() { }
}
""",
TestOptions.RegularPreview,
// (3,15): error CS1031: Type expected
// extension() { }
Diagnostic(ErrorCode.ERR_TypeExpected, ")").WithLocation(3, 15));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
M(SyntaxKind.Parameter);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void MissingTypeAndIdentifier_Ref()
{
UsingTree("""
class C
{
extension(ref) { }
}
""",
TestOptions.RegularPreview,
// (3,18): error CS1031: Type expected
// extension(ref) { }
Diagnostic(ErrorCode.ERR_TypeExpected, ")").WithLocation(3, 18));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.RefKeyword);
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Theory, CombinatorialData]
public void MethodReturningExtension(bool useCSharp14)
{
var src = """
class C
{
extension M() { }
}
""";
UsingTree(src, TestOptions.Regular13);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.MethodDeclaration);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "extension");
}
N(SyntaxKind.IdentifierToken, "M");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
// Note: break from C# 13
UsingTree(src, useCSharp14 ? TestOptions.RegularNext : TestOptions.RegularPreview,
// (3,15): error CS9500: Extension declarations may not have a name.
// extension M() { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsName, "M").WithLocation(3, 15),
// (3,17): error CS1031: Type expected
// extension M() { }
Diagnostic(ErrorCode.ERR_TypeExpected, ")").WithLocation(3, 17));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
M(SyntaxKind.Parameter);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
UsingTree("""
class C
{
@extension M() { }
}
""",
useCSharp14 ? TestOptions.RegularNext : TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.MethodDeclaration);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "@extension");
}
N(SyntaxKind.IdentifierToken, "M");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Theory, CombinatorialData]
public void MethodReturningExtension_02(bool useCSharp14)
{
var src = """
class C
{
extension M(Type x) { }
}
""";
UsingTree(src, TestOptions.Regular13);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.MethodDeclaration);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "extension");
}
N(SyntaxKind.IdentifierToken, "M");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.IdentifierToken, "x");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
// Note: break from C# 13
UsingTree(src, useCSharp14 ? TestOptions.RegularNext : TestOptions.RegularPreview,
// (3,15): error CS9500: Extension declarations may not have a name.
// extension M(Type x) { }
Diagnostic(ErrorCode.ERR_ExtensionDisallowsName, "M").WithLocation(3, 15));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.IdentifierToken, "x");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
UsingTree("""
class C
{
@extension M(Type x) { }
}
""",
useCSharp14 ? TestOptions.RegularNext : TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.MethodDeclaration);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "@extension");
}
N(SyntaxKind.IdentifierToken, "M");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Type");
}
N(SyntaxKind.IdentifierToken, "x");
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ExtensionInExpression()
{
UsingTree("""
class C
{
void extension() { extension(); }
void M()
{
extension extension = null;
}
}
""",
TestOptions.RegularPreview);
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, "extension");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExpressionStatement);
{
N(SyntaxKind.InvocationExpression);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "extension");
}
N(SyntaxKind.ArgumentList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.CloseParenToken);
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
}
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, "extension");
}
N(SyntaxKind.VariableDeclarator);
{
N(SyntaxKind.IdentifierToken, "extension");
N(SyntaxKind.EqualsValueClause);
{
N(SyntaxKind.EqualsToken);
N(SyntaxKind.NullLiteralExpression);
{
N(SyntaxKind.NullKeyword);
}
}
}
}
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ArgListParameter()
{
var src = """
static class C
{
extension(__arglist) { }
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics(
// (3,15): error CS1669: __arglist is not valid in this context
// extension(__arglist) { }
Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist").WithLocation(3, 15));
UsingTree(src, TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.StaticKeyword);
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.ArgListKeyword);
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void ParameterNameIsWhereOfConstraint()
{
UsingTree("""
class C
{
extension(object where T :
}
""",
TestOptions.RegularPreview,
// (3,22): error CS1026: ) expected
// extension(object where T :
Diagnostic(ErrorCode.ERR_CloseParenExpected, "where").WithLocation(3, 22),
// (3,31): error CS1031: Type expected
// extension(object where T :
Diagnostic(ErrorCode.ERR_TypeExpected, "").WithLocation(3, 31),
// (3,31): error CS1514: { expected
// extension(object where T :
Diagnostic(ErrorCode.ERR_LbraceExpected, "").WithLocation(3, 31),
// (3,31): error CS1513: } expected
// extension(object where T :
Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(3, 31));
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
M(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.TypeParameterConstraintClause);
{
N(SyntaxKind.WhereKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "T");
}
N(SyntaxKind.ColonToken);
M(SyntaxKind.TypeConstraint);
{
M(SyntaxKind.IdentifierName);
{
M(SyntaxKind.IdentifierToken);
}
}
}
M(SyntaxKind.OpenBraceToken);
M(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void WithBodyAndSemiColon()
{
UsingTree("""
class C
{
extension(object) { };
}
""",
TestOptions.RegularPreview);
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ExtensionDeclaration);
{
N(SyntaxKind.ExtensionKeyword);
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.ObjectKeyword);
}
}
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
N(SyntaxKind.SemicolonToken);
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}
[Fact]
public void SyntaxFactsAPIs()
{
Assert.Equal("extension", SyntaxFacts.GetText(SyntaxKind.ExtensionKeyword));
Assert.Contains(SyntaxKind.ExtensionKeyword, SyntaxFacts.GetContextualKeywordKinds());
Assert.True(SyntaxFacts.IsContextualKeyword(SyntaxKind.ExtensionKeyword));
Assert.Equal(SyntaxKind.ExtensionKeyword, SyntaxFacts.GetContextualKeywordKind("extension"));
}
}
|