/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Semantic/Semantics/ExpressionBodiedMemberTests.cs
1 056 строк
35 KB
Jared Parsons
Move net451 test assets to net461 (#74766)
17 авг 2024, 19:21
Не верифицирован
17 авг 2024, 19:21
75b26a2
Код
Авторство
О чём код?
// 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 System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.UnitTests; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.Semantics { /// <summary> /// Contains tests for expression-bodied members in the semantic model. /// </summary> [CompilerTrait(CompilerFeature.ExpressionBody)] public class ExpressionBodiedMemberTests : SemanticModelTestBase { [Fact] public void PartialMethods() { var comp = CreateCompilationWithMscorlib461(@" public partial class C { static partial void goo() => System.Console.WriteLine(""test""); } public partial class C { static partial void goo(); } "); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot() .DescendantNodes() .OfType<MethodDeclarationSyntax>() .ElementAt(1); var gooDef = model.GetDeclaredSymbol(node).GetSymbol<SourceOrdinaryMethodSymbol>(); Assert.NotNull(gooDef); Assert.True(gooDef.IsPartial); Assert.True(gooDef.IsPartialDefinition); Assert.False(gooDef.IsPartialImplementation); Assert.Null(gooDef.PartialDefinitionPart); var gooImpl = gooDef.PartialImplementationPart as SourceOrdinaryMethodSymbol; Assert.NotNull(gooImpl); Assert.True(gooImpl.IsPartial); Assert.True(gooImpl.IsPartialImplementation); Assert.False(gooImpl.IsPartialDefinition); Assert.True(gooImpl.IsExpressionBodied); } [Fact] public void ExprBodiedProp01() { var comp = CreateCompilationWithMscorlib461(@" class Program { public int F = 1; public int P2 => /*<bind>*/this.F/*</bind>*/; } "); comp.VerifyDiagnostics(); var semanticInfo = GetSemanticInfoForTest<MemberAccessExpressionSyntax>(comp); Assert.Equal(SpecialType.System_Int32, semanticInfo.Type.SpecialType); Assert.Equal(SpecialType.System_Int32, semanticInfo.ConvertedType.SpecialType); Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind); var semanticSymbol = semanticInfo.Symbol; var global = comp.GlobalNamespace; var program = global.GetTypeMember("Program"); var field = program.GetMember<SourceFieldSymbol>("F"); Assert.Equal(field, semanticSymbol.GetSymbol()); Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); Assert.Equal(0, semanticInfo.MethodGroup.Length); Assert.False(semanticInfo.IsCompileTimeConstant); } [Fact] public void ExprBodiedProp03() { var semanticInfo = GetSemanticInfoForTest<LiteralExpressionSyntax>(@" using System; class C { int P => /*<bind>*/10/*</bind>*/; }"); Assert.NotNull(semanticInfo); Assert.Null(semanticInfo.Symbol); Assert.True(semanticInfo.IsCompileTimeConstant); Assert.Equal(10, semanticInfo.ConstantValue); } [Fact] public void ExprBodiedProp04() { var tree = Parse(@" using System; class C { int P => /*<bind>*/P/*</bind>*/; }"); var comp = CreateCompilationWithMscorlib461(new[] { tree }); var info = GetSemanticInfoForTest<IdentifierNameSyntax>(comp); Assert.NotNull(info); var sym = Assert.IsType<SourcePropertySymbol>(info.Symbol.GetSymbol()); var c = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("C"); Assert.Equal(c.GetMember<SourcePropertySymbol>("P"), sym); } [Fact] public void ExprBodiedIndexer01() { var semanticInfo = GetSemanticInfoForTest<IdentifierNameSyntax>(@" using System; class Program { public int this[int i] => /*<bind>*/i/*</bind>*/; }"); Assert.NotNull(semanticInfo); Assert.Equal(SpecialType.System_Int32, semanticInfo.Type.SpecialType); Assert.Equal("i", semanticInfo.Symbol.Name); Assert.Equal(SymbolKind.Parameter, semanticInfo.Symbol.Kind); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); Assert.False(semanticInfo.IsCompileTimeConstant); } [Fact] public void ExprBodiedIndexer02() { var semanticInfo = GetSemanticInfoForTest<IdentifierNameSyntax>(@" using System; class C {} class Program { public C this[C c] => /*<bind>*/c/*</bind>*/; }"); Assert.NotNull(semanticInfo); Assert.Equal("C", semanticInfo.Type.Name); Assert.Equal("c", semanticInfo.Symbol.Name); Assert.Equal(SymbolKind.Parameter, semanticInfo.Symbol.Kind); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); Assert.False(semanticInfo.IsCompileTimeConstant); } [Fact] public void ExprBodiedIndexer03() { var semanticInfo = GetSemanticInfoForTest<IdentifierNameSyntax>(@" class C { public object this[string s] => /*<bind>*/s/*</bind>*/; }"); Assert.NotNull(semanticInfo); Assert.Equal("s", semanticInfo.Symbol.Name); Assert.Equal(SymbolKind.Parameter, semanticInfo.Symbol.Kind); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); Assert.False(semanticInfo.IsCompileTimeConstant); Assert.Equal(SpecialType.System_String, semanticInfo.Type.SpecialType); Assert.Equal(SpecialType.System_Object, semanticInfo.ConvertedType.SpecialType); } [Fact] public void ExprBodiedIndexer04() { var semanticInfo = GetSemanticInfoForTest<InvocationExpressionSyntax>(@" class C { int M(int i) => i; long M(long l) => l; string this[string s] => /*<bind>*/M(s)/*</bind>*/; }"); Assert.NotNull(semanticInfo); Assert.Equal(2, semanticInfo.CandidateSymbols.Length); Assert.Equal("System.Int32 C.M(System.Int32 i)", semanticInfo.CandidateSymbols[0].ToTestDisplayString()); Assert.Equal("System.Int64 C.M(System.Int64 l)", semanticInfo.CandidateSymbols[1].ToTestDisplayString()); Assert.Equal(CandidateReason.OverloadResolutionFailure, semanticInfo.CandidateReason); } [Fact] public void ExprBodiedIndexer05() { var semanticInfo = GetSemanticInfoForTest<SimpleNameSyntax>(@" class C { int this[int i] => /*<bind>*/i/*</bind>*/; }"); Assert.NotNull(semanticInfo); var sym = semanticInfo.Symbol; var accessor = Assert.IsType<SourcePropertyAccessorSymbol>(sym.ContainingSymbol.GetSymbol()); var prop = accessor.AssociatedSymbol; Assert.IsType<SourcePropertySymbol>(prop); } [Fact] public void ExprBodiedFunc01() { var comp = CreateCompilationWithMscorlib461(@" class Program { public int M(int i) => /*<bind>*/i/*</bind>*/; }"); comp.VerifyDiagnostics(); var semanticInfo = GetSemanticInfoForTest<IdentifierNameSyntax>(comp); Assert.Equal(SpecialType.System_Int32, semanticInfo.Type.SpecialType); Assert.Equal(SpecialType.System_Int32, semanticInfo.ConvertedType.SpecialType); Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind); var semanticSymbol = semanticInfo.Symbol; var global = comp.GlobalNamespace; var program = global.GetTypeMember("Program"); var method = program.GetMember<SourceOrdinaryMethodSymbol>("M"); var i = method.Parameters[0]; Assert.Equal(i, semanticSymbol.GetSymbol()); Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); Assert.Equal(0, semanticInfo.MethodGroup.Length); Assert.False(semanticInfo.IsCompileTimeConstant); } [Fact] [WorkItem(1009638, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1009638")] public void ExprBodiedFunc02() { var comp = CreateCompilationWithMscorlib461(@" class C { public T M<T>(T t) where T : class => /*<bind>*/t/*</bind>*/; }"); comp.VerifyDiagnostics(); var semanticInfo = GetSemanticInfoForTest<IdentifierNameSyntax>(comp); Assert.Equal(TypeKind.TypeParameter, semanticInfo.Type.TypeKind); Assert.Equal("T", semanticInfo.Type.Name); Assert.Equal("t", semanticInfo.Symbol.Name); var m = semanticInfo.Symbol.ContainingSymbol.GetSymbol<SourceOrdinaryMethodSymbol>(); Assert.Equal(1, m.TypeParameters.Length); Assert.Equal(m.TypeParameters[0], semanticInfo.Type.GetSymbol()); Assert.Equal(m.TypeParameters[0], m.ReturnType); Assert.Equal(m, semanticInfo.Type.ContainingSymbol.GetSymbol()); Assert.Equal(SymbolKind.Parameter, semanticInfo.Symbol.Kind); } [Fact] public void ExprBodiedOperator01() { var comp = CreateCompilationWithMscorlib461(@" class Program { public static Program operator ++(Program p) => /*<bind>*/p/*</bind>*/; }"); comp.VerifyDiagnostics(); var semanticInfo = GetSemanticInfoForTest<IdentifierNameSyntax>(comp); Assert.Equal("Program", semanticInfo.Type.Name); Assert.Equal("Program", semanticInfo.ConvertedType.Name); Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind); var semanticSymbol = semanticInfo.Symbol; var global = comp.GlobalNamespace; var program = global.GetTypeMember("Program"); var method = program.GetMember<SourceUserDefinedOperatorSymbol>("op_Increment"); var p = method.Parameters[0]; Assert.Equal(p, semanticSymbol.GetSymbol()); Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); Assert.Equal(0, semanticInfo.MethodGroup.Length); Assert.False(semanticInfo.IsCompileTimeConstant); } [Fact] public void ExprBodiedConversion01() { var comp = CreateCompilationWithMscorlib461(@" class C { public static C M(int i) => new C(); public static explicit operator C(int i) => M(/*<bind>*/i/*</bind>*/); }"); comp.VerifyDiagnostics(); var semanticInfo = GetSemanticInfoForTest<IdentifierNameSyntax>(comp); Assert.Equal(SpecialType.System_Int32, semanticInfo.Type.SpecialType); Assert.Equal(SpecialType.System_Int32, semanticInfo.ConvertedType.SpecialType); Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind); var semanticSymbol = semanticInfo.Symbol; var global = comp.GlobalNamespace; var program = global.GetTypeMember("C"); var method = program.GetMember<SourceUserDefinedConversionSymbol>("op_Explicit"); var p = method.Parameters[0]; Assert.Equal(p, semanticSymbol.GetSymbol()); Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); Assert.Equal(0, semanticInfo.MethodGroup.Length); Assert.False(semanticInfo.IsCompileTimeConstant); } [WorkItem(1065375, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1065375"), WorkItem(313, "CodePlex")] [Fact] public void Bug1065375_1() { string source = @" using System; public static class TestExtension { static void Main() { GetAction(1)(); } public static Action GetAction(int x) => () => Console.WriteLine(""GetAction {0}"", x); } "; CompileAndVerify(source, expectedOutput: "GetAction 1"); } [Fact, WorkItem(13691, "https://github.com/dotnet/roslyn/issues/13691")] public void RunCtorProp() { string source = @" using System; public class Program { static void Main() { var p = new Program(); p.Prop = 2; } Program() => Console.Write(1); int Prop { set => Console.Write(value); } ~Program() => Console.Write(string.Empty); } "; CompileAndVerify(source, expectedOutput: "12"); } [Fact, WorkItem(13691, "https://github.com/dotnet/roslyn/issues/13691")] public void RunCtorWithBase01() { string source = @" using System; public class Program { static void Main() { var p = new Program(); } Program() : base() => Console.Write(1); } "; CompileAndVerify(source, expectedOutput: "1"); } [Fact, WorkItem(13691, "https://github.com/dotnet/roslyn/issues/13691")] public void RunCtorWithBase02() { string source = @" using System; public class Base { public Base(int i) { Console.Write(i); } } public class Program : Base { static void Main() { var p = new Program(); } Program() : base(1) => Console.Write(2); } "; CompileAndVerify(source, expectedOutput: "12"); } [Fact, WorkItem(1069421, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1069421")] public void Bug1069421() { var comp = CreateCompilationWithMscorlib461(@" class Program { private int x => () => { } "); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().Single(); var typeInfo1 = model.GetTypeInfo(node); var typeInfo2 = model.GetTypeInfo(node); Assert.Equal(typeInfo1.Type, typeInfo2.Type); } [WorkItem(1112875, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1112875")] [Fact] public void Bug1112875() { var comp = CreateCompilation(@" class Program { private void M() => (new object()); } "); comp.VerifyDiagnostics( // (4,25): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement // private void M() => (new object()); Diagnostic(ErrorCode.ERR_IllegalStatement, "(new object())").WithLocation(4, 25)); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_01() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} static void M1() { } => P1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // static void M1() Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"static void M1() { } => P1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ArrowExpressionClauseSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_02() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} static public int operator + (C x, C y) { return 1; } => P1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // static public int operator + (C x, C y) Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"static public int operator + (C x, C y) { return 1; } => P1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ArrowExpressionClauseSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_03() { var comp = CreateCompilation(@" public class C { int P1 {get; set;} C() { P1 = 1; } => P1; } "); comp.VerifyDiagnostics( // (5,5): error CS8057: Block bodies and expression bodies cannot both be provided. Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"C() { P1 = 1; } => P1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ArrowExpressionClauseSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); Assert.Contains("P1", model.LookupNames(tree.GetRoot().DescendantNodes().OfType<ConstructorDeclarationSyntax>().Single().Body.Position)); var node2 = tree.GetRoot().DescendantNodes().OfType<ConstructorDeclarationSyntax>().Single() .Body.DescendantNodes().OfType<AssignmentExpressionSyntax>() .Single().Left; Assert.Equal("P1", node2.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node2).Symbol.ToTestDisplayString()); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_04() { var comp = CreateCompilation(@" public class C { int P1 {get; set;} ~C() { P1 = 1; } => P1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // ~C() Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"~C() { P1 = 1; } => P1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ArrowExpressionClauseSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); Assert.Contains("P1", model.LookupNames(tree.GetRoot().DescendantNodes().OfType<DestructorDeclarationSyntax>().Single().Body.Position)); var node2 = tree.GetRoot().DescendantNodes().OfType<DestructorDeclarationSyntax>().Single() .Body.DescendantNodes().OfType<AssignmentExpressionSyntax>() .Single().Left; Assert.Equal("P1", node2.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node2).Symbol.ToTestDisplayString()); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_05() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} static public int P2 { get { return 1; } => P1; } } "); comp.VerifyDiagnostics( // (8,9): error CS8057: Block bodies and expression bodies cannot both be provided. // get Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"get { return 1; } => P1;").WithLocation(8, 9) ); var tree = comp.SyntaxTrees[0]; Assert.Equal(1, tree.GetRoot().DescendantNodes().OfType<ArrowExpressionClauseSyntax>().Count()); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_06() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} static public int P2 { } => P1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // static public int P2 Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"static public int P2 { } => P1;").WithLocation(6, 5), // (6,23): error CS0548: 'C.P2': property or indexer must have at least one accessor // static public int P2 Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "P2").WithArguments("C.P2").WithLocation(6, 23) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ArrowExpressionClauseSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Null(model.GetSymbolInfo(node).Symbol); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_07() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} static public explicit operator int (C x) { return 1; } => P1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // static public explicit operator int (C x) Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"static public explicit operator int (C x) { return 1; } => P1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ArrowExpressionClauseSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_08() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} static int M1() { return P1; } => 1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // static int M1() Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"static int M1() { return P1; } => 1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ReturnStatementSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_09() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} static public int operator + (C x, C y) { return P1; } => 1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // static public int operator + (C x, C y) Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"static public int operator + (C x, C y) { return P1; } => 1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ReturnStatementSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_10() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} static public int P2 { get { return P1; } } => 1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // static public int P2 Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"static public int P2 { get { return P1; } } => 1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ReturnStatementSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } [Fact, WorkItem(1702, "https://github.com/dotnet/roslyn/issues/1702")] public void BlockBodyAndExpressionBody_11() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} static public explicit operator int (C x) { return P1; } => 1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // static public explicit operator int (C x) Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"static public explicit operator int (C x) { return P1; } => 1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var node = tree.GetRoot().DescendantNodes().OfType<ReturnStatementSyntax>().Single().Expression; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } [Fact] public void BlockBodyAndExpressionBody_12() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} public C() { P1 = 1; } => P1 = 1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // public C() Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"public C() { P1 = 1; } => P1 = 1;").WithLocation(6, 5) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var nodes = tree.GetRoot().DescendantNodes().OfType<AssignmentExpressionSyntax>(); Assert.Equal(2, nodes.Count()); foreach (var assign in nodes) { var node = assign.Left; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } } [Fact] public void BlockBodyAndExpressionBody_13() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} ~C() { P1 = 1; } => P1 = 1; } "); comp.VerifyDiagnostics( // (6,5): error CS8057: Block bodies and expression bodies cannot both be provided. // public C() Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"~C() { P1 = 1; } => P1 = 1;").WithLocation(6, 5)); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var nodes = tree.GetRoot().DescendantNodes().OfType<AssignmentExpressionSyntax>(); Assert.Equal(2, nodes.Count()); foreach (var assign in nodes) { var node = assign.Left; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } } [Fact] public void BlockBodyAndExpressionBody_14() { var comp = CreateCompilation(@" public class C { static int P1 {get; set;} int P2 { set { P1 = 1; } => P1 = 1; } } "); comp.VerifyDiagnostics( // (8,9): error CS8057: Block bodies and expression bodies cannot both be provided. // set Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, @"set { P1 = 1; } => P1 = 1;").WithLocation(8, 9) ); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var nodes = tree.GetRoot().DescendantNodes().OfType<AssignmentExpressionSyntax>(); Assert.Equal(2, nodes.Count()); foreach (var assign in nodes) { var node = assign.Left; Assert.Equal("P1", node.ToString()); Assert.Equal("System.Int32 C.P1 { get; set; }", model.GetSymbolInfo(node).Symbol.ToTestDisplayString()); } } [Fact] public void BlockBodyAndExpressionBody_15() { var comp = CreateCompilation(@" public class C { void Goo() { int Bar() { return 0; } => 0; } } "); comp.VerifyDiagnostics( // (6,9): error CS8057: Block bodies and expression bodies cannot both be provided. // int Bar() { return 0; } => 0; Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, "int Bar() { return 0; } => 0;").WithLocation(6, 9), // (6,13): warning CS8321: The local function 'Bar' is declared but never used // int Bar() { return 0; } => 0; Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Bar").WithArguments("Bar").WithLocation(6, 13)); } [Fact] public void BlockBodyAndExpressionBody_16() { var comp = CreateCompilation(@" public class C { int this[int i] { get { return 0; } } => 0; } "); comp.VerifyDiagnostics( // (4,5): error CS8057: Block bodies and expression bodies cannot both be provided. // int this[int i] { get { return 0; } } => 0; Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, "int this[int i] { get { return 0; } } => 0;").WithLocation(4, 5)); } [Fact] public void BlockBodyAndExpressionBody_17() { var comp = CreateCompilation(@" public class C { int this[int i] { get { return 0; } => 0; } } "); comp.VerifyDiagnostics( // (4,23): error CS8057: Block bodies and expression bodies cannot both be provided. // int this[int i] { get { return 0; } => 0; } Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, "get { return 0; } => 0;").WithLocation(4, 23)); } [Fact] public void BlockBodyAndExpressionBody_18() { var comp = CreateCompilation(@" using System; public class C { event Action E { add { } => null; remove { } } } "); comp.VerifyDiagnostics( // (5,22): error CS8057: Block bodies and expression bodies cannot both be provided. // event Action E { add { } => null; remove { } } Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, "add { } => null;").WithLocation(5, 22)); } [Fact, WorkItem(971, "https://github.com/dotnet/roslyn/issues/971")] public void LookupSymbols() { var comp = CreateCompilation(@" using System; public class C { Func<int, int> U() => delegate (int y0) { return 0; } int V(int y1) => 1; } Func<int, int> W() => delegate (int y2) { return 2; } public class D { public D(int y3) => M(3); public ~D() => M(y4 => 4); public Func<int, int> Prop { get => y5 => 5; } public static void M(int i) {} public static void M(Func<int, int> d) {} } "); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var nodes = tree.GetRoot().DescendantNodes().OfType<LiteralExpressionSyntax>().ToArray(); Assert.Equal(6, nodes.Length); for (int i = 0; i < nodes.Length; i++) { Assert.Equal($"{i}", nodes[i].ToString()); Assert.Equal($"System.Int32 y{i}", model.LookupSymbols(nodes[i].SpanStart, name: $"y{i}").Single().ToTestDisplayString()); } } [Fact, WorkItem(13578, "https://github.com/dotnet/roslyn/issues/13578")] public void ExpressionBodiesNotSupported() { var source = @" using System; public class C { C() => Console.WriteLine(1); ~C() => Console.WriteLine(2); int P { set => Console.WriteLine(value); } } "; CreateCompilation(source, parseOptions: TestOptions.Regular).VerifyDiagnostics(); CreateCompilation(source, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (5,9): error CS8059: Feature 'expression body constructor and destructor' is not available in C# 6. Please use language version 7.0 or greater. // C() => Console.WriteLine(1); Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion6, "=>").WithArguments("expression body constructor and destructor", "7.0").WithLocation(5, 9), // (6,10): error CS8059: Feature 'expression body constructor and destructor' is not available in C# 6. Please use language version 7.0 or greater. // ~C() => Console.WriteLine(2); Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion6, "=>").WithArguments("expression body constructor and destructor", "7.0").WithLocation(6, 10), // (7,17): error CS8059: Feature 'expression body property accessor' is not available in C# 6. Please use language version 7.0 or greater. // int P { set => Console.WriteLine(value); } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion6, "=>").WithArguments("expression body property accessor", "7.0").WithLocation(7, 17)); } } }