diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser_InterpolatedString.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser_InterpolatedString.cs index 782da84abe473..58ed047d24cd0 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser_InterpolatedString.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser_InterpolatedString.cs @@ -109,7 +109,7 @@ CodeAnalysis.Syntax.InternalSyntax.SyntaxList g originalTextSpan[currentContentStart..interpolation.OpenBraceRange.Start])); // Now parse the interpolation itself. - var interpolationNode = ParseInterpolation(this.Options, originalText, interpolation, kind); + var interpolationNode = ParseInterpolation(this.Options, originalText, interpolation, kind, IsInFieldKeywordContext); // Make sure the interpolation starts at the right location. var indentationError = getInterpolationIndentationError(indentationWhitespace, interpolation); @@ -361,7 +361,8 @@ private static InterpolationSyntax ParseInterpolation( CSharpParseOptions options, string text, Lexer.Interpolation interpolation, - Lexer.InterpolatedStringKind kind) + Lexer.InterpolatedStringKind kind, + bool isInFieldKeywordContext) { // Grab the text from after the { all the way to the start of the } (or the start of the : if present). This // will be used to parse out the expression of the interpolation. @@ -377,6 +378,7 @@ private static InterpolationSyntax ParseInterpolation( // Now create a parser to actually handle the expression portion of the interpolation using var tempParser = new LanguageParser(tempLexer, oldTree: null, changes: null); + using var _ = new FieldKeywordContext(tempParser, isInFieldKeywordContext); var result = tempParser.ParseInterpolation( text, interpolation, kind, diff --git a/src/Compilers/CSharp/Test/Emit3/FieldKeywordTests.cs b/src/Compilers/CSharp/Test/Emit3/FieldKeywordTests.cs index dfa456b2337a9..fb7367886e267 100644 --- a/src/Compilers/CSharp/Test/Emit3/FieldKeywordTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/FieldKeywordTests.cs @@ -10171,6 +10171,299 @@ partial class B VerifyMergedProperties(actualProperties, actualFields); } + [Theory] + [CombinatorialData] + public void InterpolatedString( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion) + { + string source = $$""" + using System; + class C + { + public object P1 => $"P1: {field is null}"; + public object P2 { get; set { field = value; field = $"{field}"; } } + } + class Program + { + static void Main() + { + var c = new C(); + c.P2 = 2; + Console.WriteLine(c.P1); + Console.WriteLine(c.P2); + } + } + """; + var comp = CreateCompilation( + source, + parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), + options: TestOptions.ReleaseExe, + targetFramework: TargetFramework.Net80); + + if (languageVersion == LanguageVersion.CSharp13) + { + comp.VerifyEmitDiagnostics( + // (4,32): error CS0103: The name 'field' does not exist in the current context + // public object P1 => $"P1: {field is null}"; + Diagnostic(ErrorCode.ERR_NameNotInContext, "field").WithArguments("field").WithLocation(4, 32), + // (5,19): error CS8652: The feature 'field keyword' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public object P2 { get; set { field = value; field = $"{field}"; } } + Diagnostic(ErrorCode.ERR_FeatureInPreview, "P2").WithArguments("field keyword").WithLocation(5, 19), + // (5,35): error CS0103: The name 'field' does not exist in the current context + // public object P2 { get; set { field = value; field = $"{field}"; } } + Diagnostic(ErrorCode.ERR_NameNotInContext, "field").WithArguments("field").WithLocation(5, 35), + // (5,50): error CS0103: The name 'field' does not exist in the current context + // public object P2 { get; set { field = value; field = $"{field}"; } } + Diagnostic(ErrorCode.ERR_NameNotInContext, "field").WithArguments("field").WithLocation(5, 50), + // (5,61): error CS0103: The name 'field' does not exist in the current context + // public object P2 { get; set { field = value; field = $"{field}"; } } + Diagnostic(ErrorCode.ERR_NameNotInContext, "field").WithArguments("field").WithLocation(5, 61)); + } + else + { + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(""" + P1: True + 2 + """)); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.P1.get", """ + { + // Code size 45 (0x2d) + .maxstack 3 + .locals init (System.Runtime.CompilerServices.DefaultInterpolatedStringHandler V_0) + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.4 + IL_0003: ldc.i4.1 + IL_0004: call "System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(int, int)" + IL_0009: ldloca.s V_0 + IL_000b: ldstr "P1: " + IL_0010: call "void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendLiteral(string)" + IL_0015: ldloca.s V_0 + IL_0017: ldarg.0 + IL_0018: ldfld "object C.k__BackingField" + IL_001d: ldnull + IL_001e: ceq + IL_0020: call "void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(bool)" + IL_0025: ldloca.s V_0 + IL_0027: call "string System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.ToStringAndClear()" + IL_002c: ret + } + """); + verifier.VerifyIL("C.P2.set", """ + { + // Code size 43 (0x2b) + .maxstack 4 + .locals init (System.Runtime.CompilerServices.DefaultInterpolatedStringHandler V_0) + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld "object C.k__BackingField" + IL_0007: ldarg.0 + IL_0008: ldloca.s V_0 + IL_000a: ldc.i4.0 + IL_000b: ldc.i4.1 + IL_000c: call "System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(int, int)" + IL_0011: ldloca.s V_0 + IL_0013: ldarg.0 + IL_0014: ldfld "object C.k__BackingField" + IL_0019: call "void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(object)" + IL_001e: ldloca.s V_0 + IL_0020: call "string System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.ToStringAndClear()" + IL_0025: stfld "object C.k__BackingField" + IL_002a: ret + } + """); + } + } + + [Theory] + [CombinatorialData] + public void InterpolatedString_Alignment( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion) + { + string source = $$""" + using System; + class C + { + int x = 42; + const int field = 5; + public int P1 { get { Console.WriteLine($"{x,field}"); return 1; } } + } + class Program + { + static void Main() + { + var c = new C(); + Console.WriteLine(c.P1); + } + } + """; + var comp = CreateCompilation( + source, + parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), + options: TestOptions.ReleaseExe, + targetFramework: TargetFramework.Net80); + + if (languageVersion == LanguageVersion.CSharp13) + { + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(""" + 42 + 1 + """)); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.P1.get", """ + { + // Code size 37 (0x25) + .maxstack 3 + .locals init (System.Runtime.CompilerServices.DefaultInterpolatedStringHandler V_0) + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.0 + IL_0003: ldc.i4.1 + IL_0004: call "System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(int, int)" + IL_0009: ldloca.s V_0 + IL_000b: ldarg.0 + IL_000c: ldfld "int C.x" + IL_0011: ldc.i4.5 + IL_0012: call "void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(int, int)" + IL_0017: ldloca.s V_0 + IL_0019: call "string System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.ToStringAndClear()" + IL_001e: call "void System.Console.WriteLine(string)" + IL_0023: ldc.i4.1 + IL_0024: ret + } + """); + } + else + { + comp.VerifyEmitDiagnostics( + // (6,50): warning CS9258: In language version preview, the 'field' keyword binds to a synthesized backing field for the property. To avoid generating a synthesized backing field, and to refer to the existing member, use 'this.field' or '@field' instead. + // public int P1 { get { Console.WriteLine($"{x,field}"); return 1; } } + Diagnostic(ErrorCode.WRN_FieldIsAmbiguous, "field").WithArguments("preview").WithLocation(6, 50), + // (6,50): error CS0150: A constant value is expected + // public int P1 { get { Console.WriteLine($"{x,field}"); return 1; } } + Diagnostic(ErrorCode.ERR_ConstantExpected, "field").WithLocation(6, 50)); + } + + var containingType = comp.GetMember("C"); + var actualFields = containingType.GetMembers().OfType().Where(f => f.IsImplicitlyDeclared).ToImmutableArray(); + if (languageVersion == LanguageVersion.CSharp13) + { + Assert.Empty(actualFields.ToTestDisplayStrings()); + } + else + { + var expectedFields = new[] + { + "System.Int32 C.k__BackingField", + }; + AssertEx.Equal(expectedFields, actualFields.ToTestDisplayStrings()); + } + + var actualProperties = containingType.GetMembers().OfType().ToImmutableArray(); + Assert.Equal(1, actualProperties.Length); + if (languageVersion == LanguageVersion.CSharp13) + { + Assert.True(actualProperties[0] is SourcePropertySymbol { Name: "P1", IsAutoProperty: false, UsesFieldKeyword: false, BackingField: null }); + } + else + { + Assert.True(actualProperties[0] is SourcePropertySymbol { Name: "P1", IsAutoProperty: false, UsesFieldKeyword: true, BackingField: { } }); + } + + VerifyMergedProperties(actualProperties, actualFields); + } + + [Theory] + [CombinatorialData] + public void InterpolatedString_Format( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion) + { + string source = $$""" + using System; + class C + { + int x = 42; + const int y = 3; + const int field = 5; + public int P2 { get { Console.WriteLine($"{x:field}"); return 2; } } + public int P3 { get { Console.WriteLine($"{x,y:field}"); return 3; } } + } + class Program + { + static void Main() + { + var c = new C(); + Console.WriteLine((c.P2, c.P3)); + } + } + """; + var comp = CreateCompilation( + source, + parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), + options: TestOptions.ReleaseExe, + targetFramework: TargetFramework.Net80); + + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput(""" + field + field + (2, 3) + """)); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.P2.get", """ + { + // Code size 41 (0x29) + .maxstack 3 + .locals init (System.Runtime.CompilerServices.DefaultInterpolatedStringHandler V_0) + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.0 + IL_0003: ldc.i4.1 + IL_0004: call "System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(int, int)" + IL_0009: ldloca.s V_0 + IL_000b: ldarg.0 + IL_000c: ldfld "int C.x" + IL_0011: ldstr "field" + IL_0016: call "void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(int, string)" + IL_001b: ldloca.s V_0 + IL_001d: call "string System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.ToStringAndClear()" + IL_0022: call "void System.Console.WriteLine(string)" + IL_0027: ldc.i4.2 + IL_0028: ret + } + """); + verifier.VerifyIL("C.P3.get", """ + { + // Code size 42 (0x2a) + .maxstack 4 + .locals init (System.Runtime.CompilerServices.DefaultInterpolatedStringHandler V_0) + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.0 + IL_0003: ldc.i4.1 + IL_0004: call "System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(int, int)" + IL_0009: ldloca.s V_0 + IL_000b: ldarg.0 + IL_000c: ldfld "int C.x" + IL_0011: ldc.i4.3 + IL_0012: ldstr "field" + IL_0017: call "void System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(int, int, string)" + IL_001c: ldloca.s V_0 + IL_001e: call "string System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.ToStringAndClear()" + IL_0023: call "void System.Console.WriteLine(string)" + IL_0028: ldc.i4.3 + IL_0029: ret + } + """); + + var containingType = comp.GetMember("C"); + var actualFields = containingType.GetMembers().OfType().Where(f => f.IsImplicitlyDeclared).ToImmutableArray(); + Assert.Empty(actualFields.ToTestDisplayStrings()); + + var actualProperties = containingType.GetMembers().OfType().ToImmutableArray(); + Assert.Equal(2, actualProperties.Length); + Assert.True(actualProperties[0] is SourcePropertySymbol { Name: "P2", IsAutoProperty: false, UsesFieldKeyword: false, BackingField: null }); + Assert.True(actualProperties[1] is SourcePropertySymbol { Name: "P3", IsAutoProperty: false, UsesFieldKeyword: false, BackingField: null }); + + VerifyMergedProperties(actualProperties, actualFields); + } + [Theory] [InlineData("{ get; }")] [InlineData("{ get; set; }")] diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/FieldKeywordParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/FieldKeywordParsingTests.cs index 9492d589e19da..d0102aba7b567 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/FieldKeywordParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/FieldKeywordParsingTests.cs @@ -1906,6 +1906,487 @@ class C EOF(); } + [Theory] + [CombinatorialData] + public void InterpolatedString_01( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview)] LanguageVersion languageVersion) + { + UsingTree($$""" + class C + { + object P => $"{field}"; + } + """, + TestOptions.Regular.WithLanguageVersion(languageVersion)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.PropertyDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.ObjectKeyword); + } + N(SyntaxKind.IdentifierToken, "P"); + N(SyntaxKind.ArrowExpressionClause); + { + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.InterpolatedStringExpression); + { + N(SyntaxKind.InterpolatedStringStartToken); + N(SyntaxKind.Interpolation); + { + N(SyntaxKind.OpenBraceToken); + IdentifierNameOrFieldExpression(languageVersion, escapeIdentifier: false); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.InterpolatedStringEndToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Theory] + [CombinatorialData] + public void InterpolatedString_01_Alignment( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview)] LanguageVersion languageVersion) + { + UsingTree($$""" + class C + { + object P => $"{x,field}"; + } + """, + TestOptions.Regular.WithLanguageVersion(languageVersion)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.PropertyDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.ObjectKeyword); + } + N(SyntaxKind.IdentifierToken, "P"); + N(SyntaxKind.ArrowExpressionClause); + { + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.InterpolatedStringExpression); + { + N(SyntaxKind.InterpolatedStringStartToken); + N(SyntaxKind.Interpolation); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.InterpolationAlignmentClause); + { + N(SyntaxKind.CommaToken); + IdentifierNameOrFieldExpression(languageVersion, escapeIdentifier: false); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.InterpolatedStringEndToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Theory] + [CombinatorialData] + public void InterpolatedString_01_Format( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview)] LanguageVersion languageVersion) + { + UsingTree($$""" + class C + { + object P => $"{x:field}"; + } + """, + TestOptions.Regular.WithLanguageVersion(languageVersion)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.PropertyDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.ObjectKeyword); + } + N(SyntaxKind.IdentifierToken, "P"); + N(SyntaxKind.ArrowExpressionClause); + { + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.InterpolatedStringExpression); + { + N(SyntaxKind.InterpolatedStringStartToken); + N(SyntaxKind.Interpolation); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.InterpolationFormatClause); + { + N(SyntaxKind.ColonToken); + N(SyntaxKind.InterpolatedStringTextToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.InterpolatedStringEndToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Theory] + [CombinatorialData] + public void InterpolatedString_01_AlignmentAndFormat( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview)] LanguageVersion languageVersion) + { + UsingTree($$""" + class C + { + object P => $"{x,field:field}"; + } + """, + TestOptions.Regular.WithLanguageVersion(languageVersion)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.PropertyDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.ObjectKeyword); + } + N(SyntaxKind.IdentifierToken, "P"); + N(SyntaxKind.ArrowExpressionClause); + { + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.InterpolatedStringExpression); + { + N(SyntaxKind.InterpolatedStringStartToken); + N(SyntaxKind.Interpolation); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.InterpolationAlignmentClause); + { + N(SyntaxKind.CommaToken); + IdentifierNameOrFieldExpression(languageVersion, escapeIdentifier: false); + } + N(SyntaxKind.InterpolationFormatClause); + { + N(SyntaxKind.ColonToken); + N(SyntaxKind.InterpolatedStringTextToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.InterpolatedStringEndToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Theory] + [CombinatorialData] + public void InterpolatedString_02( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview)] LanguageVersion languageVersion) + { + UsingTree($$""" + class C + { + object P { get { return $"x{field}y"; } } + } + """, + TestOptions.Regular.WithLanguageVersion(languageVersion)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.PropertyDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.ObjectKeyword); + } + N(SyntaxKind.IdentifierToken, "P"); + N(SyntaxKind.AccessorList); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.GetAccessorDeclaration); + { + N(SyntaxKind.GetKeyword); + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.ReturnStatement); + { + N(SyntaxKind.ReturnKeyword); + N(SyntaxKind.InterpolatedStringExpression); + { + N(SyntaxKind.InterpolatedStringStartToken); + N(SyntaxKind.InterpolatedStringText); + { + N(SyntaxKind.InterpolatedStringTextToken); + } + N(SyntaxKind.Interpolation); + { + N(SyntaxKind.OpenBraceToken); + IdentifierNameOrFieldExpression(languageVersion, escapeIdentifier: false); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.InterpolatedStringText); + { + N(SyntaxKind.InterpolatedStringTextToken); + } + N(SyntaxKind.InterpolatedStringEndToken); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + } + N(SyntaxKind.CloseBraceToken); + } + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Theory] + [CombinatorialData] + public void InterpolatedString_03( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview)] LanguageVersion languageVersion) + { + UsingTree($$$"""" + class C + { + object P => $"""{field}"""; + } + """", + TestOptions.Regular.WithLanguageVersion(languageVersion)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.PropertyDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.ObjectKeyword); + } + N(SyntaxKind.IdentifierToken, "P"); + N(SyntaxKind.ArrowExpressionClause); + { + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.InterpolatedStringExpression); + { + N(SyntaxKind.InterpolatedSingleLineRawStringStartToken); + N(SyntaxKind.Interpolation); + { + N(SyntaxKind.OpenBraceToken); + IdentifierNameOrFieldExpression(languageVersion, escapeIdentifier: false); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.InterpolatedRawStringEndToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Theory] + [CombinatorialData] + public void InterpolatedString_04( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview)] LanguageVersion languageVersion) + { + UsingTree($$$"""" + class C + { + object P => $""" + {field} + """; + } + """", + TestOptions.Regular.WithLanguageVersion(languageVersion)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.PropertyDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.ObjectKeyword); + } + N(SyntaxKind.IdentifierToken, "P"); + N(SyntaxKind.ArrowExpressionClause); + { + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.InterpolatedStringExpression); + { + N(SyntaxKind.InterpolatedMultiLineRawStringStartToken); + N(SyntaxKind.InterpolatedStringText); + { + N(SyntaxKind.InterpolatedStringTextToken); + } + N(SyntaxKind.Interpolation); + { + N(SyntaxKind.OpenBraceToken); + IdentifierNameOrFieldExpression(languageVersion, escapeIdentifier: false); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.InterpolatedRawStringEndToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Theory] + [CombinatorialData] + public void InterpolatedString_05( + [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview)] LanguageVersion languageVersion) + { + UsingTree($$""" + class C + { + object this[int i] => $"{field}"; + } + """, + TestOptions.Regular.WithLanguageVersion(languageVersion)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.IndexerDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.ObjectKeyword); + } + 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.ArrowExpressionClause); + { + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.InterpolatedStringExpression); + { + N(SyntaxKind.InterpolatedStringStartToken); + N(SyntaxKind.Interpolation); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "field"); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.InterpolatedStringEndToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + [Fact] public void Incremental_ChangeBetweenMethodAndProperty() {