/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Features/CSharpTest/EditAndContinue/SyntaxUtilitiesTests.cs
267 строк
10 KB
Cyrus Najmabadi
Cleanup test methods
24 июл 2025, 11:15
24 июл 2025, 11:15
9b3e554
Код
Авторство
О чём код?
// 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; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.EditAndContinue; using Roslyn.Test.Utilities; using Xunit; using SyntaxUtilities = Microsoft.CodeAnalysis.CSharp.EditAndContinue.SyntaxUtilities; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.EditAndContinue; public sealed class SyntaxUtilitiesTests { private static void VerifySyntaxMap(string oldSource, string newSource) { var oldRoot = SyntaxFactory.ParseSyntaxTree(oldSource).GetRoot(); var newRoot = SyntaxFactory.ParseSyntaxTree(newSource).GetRoot(); foreach (var oldNode in oldRoot.DescendantNodes().Where(n => n.FullSpan.Length > 0)) { var newNode = AbstractEditAndContinueAnalyzer.FindPartner(newRoot, oldRoot, oldNode); Assert.True(SyntaxFactory.AreEquivalent(oldNode, newNode), $"Node '{oldNode}' not equivalent to '{newNode}'."); } } [Fact] public void FindPartner1() => VerifySyntaxMap(""" using System; class C { static void Main(string[] args) { // sdasd var b = true; do { Console.WriteLine("hi"); } while (b == true); } } """, """ using System; class C { static void Main(string[] args) { var b = true; do { Console.WriteLine("hi"); } while (b == true); } } """); [Fact] public void FindLeafNodeAndPartner1() { var leftRoot = SyntaxFactory.ParseSyntaxTree(""" using System; class C { public void M() { if (0 == 1) { Console.WriteLine(0); } } } """).GetRoot(); var leftPosition = leftRoot.DescendantNodes().OfType<LiteralExpressionSyntax>().ElementAt(2).SpanStart; // 0 within Console.WriteLine(0) var rightRoot = SyntaxFactory.ParseSyntaxTree(""" using System; class C { public void M() { if (0 == 1) { if (2 == 3) { Console.WriteLine(0); } } } } """).GetRoot(); AbstractEditAndContinueAnalyzer.FindLeafNodeAndPartner(leftRoot, leftPosition, rightRoot, out var leftNode, out var rightNodeOpt); Assert.Equal("0", leftNode.ToString()); Assert.Null(rightNodeOpt); } [Fact] public void FindLeafNodeAndPartner2() { // Check that the method does not fail even if the index of the child (4) // is greater than the count of children on the corresponding (from the upper side) node (3). var leftRoot = SyntaxFactory.ParseSyntaxTree(""" using System; class C { public void M() { if (0 == 1) { Console.WriteLine(0); Console.WriteLine(1); Console.WriteLine(2); Console.WriteLine(3); } } } """).GetRoot(); var leftPosition = leftRoot.DescendantNodes().OfType<LiteralExpressionSyntax>().ElementAt(5).SpanStart; // 3 within Console.WriteLine(3) var rightRoot = SyntaxFactory.ParseSyntaxTree(""" using System; class C { public void M() { if (0 == 1) { if (2 == 3) { Console.WriteLine(0); Console.WriteLine(1); Console.WriteLine(2); Console.WriteLine(3); } } } } """).GetRoot(); AbstractEditAndContinueAnalyzer.FindLeafNodeAndPartner(leftRoot, leftPosition, rightRoot, out var leftNode, out var rightNodeOpt); Assert.Equal("3", leftNode.ToString()); Assert.Null(rightNodeOpt); } [Fact] public void IsAsyncDeclaration() { var tree = SyntaxFactory.ParseSyntaxTree(""" class C { async Task<int> M0() => 1; async Task<int> M1() => await Task.FromResult(1); async Task<int> M2() { return await Task.FromResult(1); } void M3() { async Task<int> f1() => await Task.FromResult(1); async Task<int> f2() { return await Task.FromResult(1); } var l1 = new Func<Task<int>>(async () => await Task.FromResult(1)); var l2 = new Func<Task<int>>(async () => { return await Task.FromResult(1); }); var l3 = new Func<Task<int>>(async delegate () { return await Task.FromResult(1); }); } } """); var m0 = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(m => m.Identifier.ValueText == "M0"); var m1 = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(m => m.Identifier.ValueText == "M1"); var m2 = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(m => m.Identifier.ValueText == "M2"); var m3 = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(m => m.Identifier.ValueText == "M3"); var f1 = tree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single(m => m.Identifier.ValueText == "f1"); var f2 = tree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single(m => m.Identifier.ValueText == "f2"); var l1 = m3.DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(m => m.Identifier.ValueText == "l1").Initializer. DescendantNodes().OfType<LambdaExpressionSyntax>().Single(); var l2 = m3.DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(m => m.Identifier.ValueText == "l2").Initializer. DescendantNodes().OfType<LambdaExpressionSyntax>().Single(); var l3 = m3.DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(m => m.Identifier.ValueText == "l3").Initializer. DescendantNodes().OfType<AnonymousFunctionExpressionSyntax>().Single(); Assert.True(SyntaxUtilities.IsAsyncDeclaration(m0.ExpressionBody)); Assert.True(SyntaxUtilities.IsAsyncDeclaration(m1.ExpressionBody)); Assert.True(SyntaxUtilities.IsAsyncDeclaration(m2)); Assert.False(SyntaxUtilities.IsAsyncDeclaration(m3)); Assert.True(SyntaxUtilities.IsAsyncDeclaration(f1.ExpressionBody)); Assert.True(SyntaxUtilities.IsAsyncDeclaration(f2)); Assert.True(SyntaxUtilities.IsAsyncDeclaration(l1)); Assert.True(SyntaxUtilities.IsAsyncDeclaration(l2)); Assert.True(SyntaxUtilities.IsAsyncDeclaration(l3)); Assert.Equal(0, SyntaxUtilities.GetSuspensionPoints(m0.ExpressionBody).Count()); Assert.Equal(1, SyntaxUtilities.GetSuspensionPoints(m1.ExpressionBody).Count()); Assert.Equal(1, SyntaxUtilities.GetSuspensionPoints(m2.Body).Count()); Assert.Equal(0, SyntaxUtilities.GetSuspensionPoints(m3.Body).Count()); Assert.Equal(1, SyntaxUtilities.GetSuspensionPoints(f1.ExpressionBody).Count()); Assert.Equal(1, SyntaxUtilities.GetSuspensionPoints(f2.Body).Count()); Assert.Equal(1, SyntaxUtilities.GetSuspensionPoints(l1.Body).Count()); Assert.Equal(1, SyntaxUtilities.GetSuspensionPoints(l2.Body).Count()); Assert.Equal(1, SyntaxUtilities.GetSuspensionPoints(l3.Body).Count()); } [Fact] public void GetSuspensionPoints() { var tree = SyntaxFactory.ParseSyntaxTree(""" class C { IEnumerable<int> X = new[] { 1, 2, 3 }; IEnumerable<int> M1() { yield return 1; } void M2() { IAsyncEnumerable<int> f() { yield return 1; yield break; await Task.FromResult(1); await foreach (var x in F()) { } await foreach (var (x, y) in F()) { } await using T x1 = F1(), x2 = F2(), x3 = F3(); } } } """); var x = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(m => m.Identifier.ValueText == "X"); var m1 = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(m => m.Identifier.ValueText == "M1"); var m2 = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(m => m.Identifier.ValueText == "M2"); var f = m2.DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single(m => m.Identifier.ValueText == "f"); AssertEx.Empty(SyntaxUtilities.GetSuspensionPoints(x.Initializer)); AssertEx.Equal(["yield return 1;"], SyntaxUtilities.GetSuspensionPoints(m1.Body).Select(n => n.ToString())); AssertEx.Empty(SyntaxUtilities.GetSuspensionPoints(m2.Body)); AssertEx.Equal( [ "yield return 1;", "await Task.FromResult(1)", "await foreach (var x in F()) { }", "await foreach (var (x, y) in F()) { }", "x1 = F1()", "x2 = F2()", "x3 = F3()", ], SyntaxUtilities.GetSuspensionPoints(f.Body).Select(n => n.ToString())); } }