/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Syntax/Parsing/ExtensionsParsingTests.cs
5 336 строк
189 KB
Jan Jones
Unsafe evolution: make pointers safe regardless of memory safety rules version (#83133)
21 апр 2026, 11:27
Не верифицирован
21 апр 2026, 11:27
fca0128
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using 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) { } [Theory, CombinatorialData] public void LangVer_01(bool useCSharp14) { var src = """ static class C { extension<T>(object o) where T : struct { } } """; var comp = CreateCompilation(src, parseOptions: TestOptions.Regular13); comp.VerifyEmitDiagnostics( // (3,5): error CS9260: Feature 'extensions' is not available in C# 13.0. Please use language version 14.0 or greater. // extension<T>(object o) where T : struct { } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion13, "extension").WithArguments("extensions", "14.0").WithLocation(3, 5)); UsingTree(src, TestOptions.Regular13); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.StaticKeyword); N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.ExtensionBlockDeclaration); { 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(); UsingTree(src, useCSharp14 ? TestOptions.Regular14 : TestOptions.RegularPreview); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.StaticKeyword); N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.ExtensionBlockDeclaration); { 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(); } [Theory, CombinatorialData] public void LangVer_02(bool useCSharp14) { // Without type parameters var src = """ static class C { extension(object o) { } } """; var comp = CreateCompilation(src, parseOptions: TestOptions.Regular13); comp.VerifyEmitDiagnostics( // (3,5): error CS9260: Feature 'extensions' is not available in C# 13.0. Please use language version 14.0 or greater. // extension(object o) { } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion13, "extension(object o) { }").WithArguments("extensions", "14.0").WithLocation(3, 5), // (3,5): error CS0710: Static classes cannot have instance constructors // extension(object o) { } Diagnostic(ErrorCode.ERR_ConstructorInStaticClass, "extension").WithLocation(3, 5)); UsingTree(src, TestOptions.Regular13); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.StaticKeyword); N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.ConstructorDeclaration); { N(SyntaxKind.IdentifierToken, "extension"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.Parameter); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.ObjectKeyword); } N(SyntaxKind.IdentifierToken, "o"); } N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); UsingTree(src, useCSharp14 ? TestOptions.Regular14 : TestOptions.RegularPreview); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.StaticKeyword); N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.ExtensionBlockDeclaration); { 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.CloseBraceToken); } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Fact] public void LangVer_03() { // Without type parameters, escaped identifier var src = """ static class C { @extension(object o) { } } """; var comp = CreateCompilation(src, parseOptions: TestOptions.Regular13); comp.VerifyEmitDiagnostics( // (3,5): error CS1520: Method must have a return type // @extension(object o) { } Diagnostic(ErrorCode.ERR_MemberNeedsType, "@extension").WithLocation(3, 5), // (3,5): error CS0710: Static classes cannot have instance constructors // @extension(object o) { } Diagnostic(ErrorCode.ERR_ConstructorInStaticClass, "@extension").WithLocation(3, 5)); UsingTree(src, TestOptions.Regular13); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.StaticKeyword); N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.ConstructorDeclaration); { N(SyntaxKind.IdentifierToken, "@extension"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.Parameter); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.ObjectKeyword); } N(SyntaxKind.IdentifierToken, "o"); } N(SyntaxKind.CloseParenToken); } N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Theory, CombinatorialData] public void LangVer_04(bool useCSharp14) { // Without parameter list var src = """ class C { extension { } } """; var comp = CreateCompilation(src, parseOptions: TestOptions.Regular13); comp.VerifyEmitDiagnostics( // (3,15): error CS1519: Invalid token '{' in a member declaration // extension { } Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(3, 15), // (3,15): error CS1519: Invalid token '{' in a member declaration // extension { } Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(3, 15), // (4,1): error CS1022: Type or namespace definition, or end-of-file expected // } Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(4, 1)); UsingTree(src, TestOptions.Regular13, // (3,15): error CS1519: Invalid token '{' in a member declaration // extension { } Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(3, 15), // (3,15): error CS1519: Invalid token '{' in a member declaration // extension { } Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(3, 15), // (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.IdentifierName); { N(SyntaxKind.IdentifierToken, "extension"); } } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); UsingTree(src, useCSharp14 ? TestOptions.Regular14 : 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.ExtensionBlockDeclaration); { N(SyntaxKind.ExtensionKeyword); M(SyntaxKind.ParameterList); { M(SyntaxKind.OpenParenToken); M(SyntaxKind.Parameter); { M(SyntaxKind.IdentifierName); { M(SyntaxKind.IdentifierToken); } } M(SyntaxKind.CloseParenToken); } N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Theory, CombinatorialData] public void LangVer_05(bool useCSharp14) { // Top-level var src = """ extension<T>(object o) { } """; var comp = CreateCompilation(src, parseOptions: TestOptions.Regular13); comp.VerifyEmitDiagnostics( // (1,1): error CS9260: Feature 'extensions' is not available in C# 13.0. Please use language version 14.0 or greater. // extension<T>(object o) { } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion13, "extension").WithArguments("extensions", "14.0").WithLocation(1, 1), // (1,1): error CS9283: Extensions must be declared in a top-level, non-generic, static class // extension<T>(object o) { } Diagnostic(ErrorCode.ERR_BadExtensionContainingType, "extension").WithLocation(1, 1)); UsingTree(src, TestOptions.Regular13); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ExtensionBlockDeclaration); { 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.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); UsingTree(src, useCSharp14 ? TestOptions.Regular14 : TestOptions.RegularPreview); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ExtensionBlockDeclaration); { 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.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.EndOfFileToken); } EOF(); } [Theory, CombinatorialData] public void LangVer_06(bool useCSharp14) { // Top-level, without type parameters var src = """ extension(object o) { } """; var comp = CreateCompilation(src, parseOptions: TestOptions.Regular13); comp.VerifyEmitDiagnostics( // (1,1): error CS0103: The name 'extension' does not exist in the current context // extension(object o) { } Diagnostic(ErrorCode.ERR_NameNotInContext, "extension").WithArguments("extension").WithLocation(1, 1), // (1,11): error CS1525: Invalid expression term 'object' // extension(object o) { } Diagnostic(ErrorCode.ERR_InvalidExprTerm, "object").WithArguments("object").WithLocation(1, 11), // (1,18): error CS1003: Syntax error, ',' expected // extension(object o) { } Diagnostic(ErrorCode.ERR_SyntaxError, "o").WithArguments(",").WithLocation(1, 18), // (1,18): error CS0103: The name 'o' does not exist in the current context // extension(object o) { } Diagnostic(ErrorCode.ERR_NameNotInContext, "o").WithArguments("o").WithLocation(1, 18), // (1,21): error CS1002: ; expected // extension(object o) { } Diagnostic(ErrorCode.ERR_SemicolonExpected, "{").WithLocation(1, 21)); UsingTree(src, TestOptions.Regular13, // (1,11): error CS1525: Invalid expression term 'object' // extension(object o) { } Diagnostic(ErrorCode.ERR_InvalidExprTerm, "object").WithArguments("object").WithLocation(1, 11), // (1,18): error CS1003: Syntax error, ',' expected // extension(object o) { } Diagnostic(ErrorCode.ERR_SyntaxError, "o").WithArguments(",").WithLocation(1, 18), // (1,21): error CS1002: ; expected // extension(object o) { } Diagnostic(ErrorCode.ERR_SemicolonExpected, "{").WithLocation(1, 21)); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.InvocationExpression); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "extension"); } N(SyntaxKind.ArgumentList); { N(SyntaxKind.OpenParenToken); N(SyntaxKind.Argument); { N(SyntaxKind.PredefinedType); { N(SyntaxKind.ObjectKeyword); } } M(SyntaxKind.CommaToken); N(SyntaxKind.Argument); { N(SyntaxKind.IdentifierName); { N(SyntaxKind.IdentifierToken, "o"); } } N(SyntaxKind.CloseParenToken); } } M(SyntaxKind.SemicolonToken); } } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); N(SyntaxKind.CloseBraceToken); } } N(SyntaxKind.EndOfFileToken); } EOF(); UsingTree(src, useCSharp14 ? TestOptions.Regular14 : TestOptions.RegularPreview); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ExtensionBlockDeclaration); { 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.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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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(); // Note: break from C# 13 UsingTree(""" class extension { extension(Type constructorParameter) { } } """, useCSharp14 ? TestOptions.Regular14 : TestOptions.RegularPreview); N(SyntaxKind.CompilationUnit); { N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); N(SyntaxKind.IdentifierToken, "extension"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.ExtensionBlockDeclaration); { 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.Regular14 : 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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: This member is not allowed in an extension block // 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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: This member is not allowed in an extension block // 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.ExtensionBlockDeclaration); { 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, parseOptions: TestOptions.Regular14); 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: This member is not allowed in an extension block // fixed int field[10]; Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "field").WithLocation(5, 19)); var expectedPreviewDiagnostics = new[] { // (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 CS9282: This member is not allowed in an extension block // fixed int field[10]; Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "field").WithLocation(5, 19), }; CreateCompilation(src).VerifyEmitDiagnostics(expectedPreviewDiagnostics); CreateCompilation(src, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedPreviewDiagnostics); 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.ExtensionBlockDeclaration); { 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: This member is not allowed in an extension block // event System.EventHandler eventField; Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "eventField").WithLocation(5, 35), // (5,35): error CS9282: This member is not allowed in an extension block // event System.EventHandler eventField; Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "eventField").WithLocation(5, 35), // (5,35): error CS9282: This member is not allowed in an extension block // 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.ExtensionBlockDeclaration); { 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: This member is not allowed in an extension block // event System.EventHandler Event { add { } remove { } } Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "Event").WithLocation(5, 35), // (5,43): error CS9282: This member is not allowed in an extension block // event System.EventHandler Event { add { } remove { } } Diagnostic(ErrorCode.ERR_ExtensionDisallowsMember, "add").WithLocation(5, 43), // (5,51): error CS9282: This member is not allowed in an extension block // 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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: This member is not allowed in an extension block // 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.ExtensionBlockDeclaration); { 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: This member is not allowed in an extension block // 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.ExtensionBlockDeclaration); { 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: This member is not allowed in an extension block // 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.ExtensionBlockDeclaration); { 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: This member is not allowed in an extension block // ~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.ExtensionBlockDeclaration); { 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: This member is not allowed in an extension block // 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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; } } """; 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.ExtensionBlockDeclaration); { 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 CS9282: This member is not allowed in an extension block // 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.Regular14 : 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.ExtensionBlockDeclaration); { 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.Regular14 : 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.Regular14 : 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.ExtensionBlockDeclaration); { 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.Regular14 : 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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.ExtensionBlockDeclaration); { 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")); } }