/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Test/Syntax/Parser/ParseAsyncTests.vb
441 строка
14 KB
Tomáš Matoušek
Refactoring of extension methods in source packages (#78620) - take 2 (#78894)
26 июн 2025, 18:42
Не верифицирован
26 июн 2025, 18:42
05fc006
Код
Авторство
О чём код?
' 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. Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Public Class ParseAsyncTests Inherits BasicTestBase <Fact> Public Sub ParseAsyncModifier() Dim tree = ParseAndVerify(<![CDATA[ Imports Async = System.Threading.Tasks.Task Module Program Public Const Async As Integer = 0 Public Async <Async(Async)> Async Function M() As Async Dim l = Sub() Dim async As Async = Nothing End Sub Dim l2 = Async Sub() Dim async As Async = Nothing End Sub End Function End Module Class AsyncAttribute Inherits Attribute Sub New(p) End Sub End Class]]>) Assert.Equal(2, Aggregate t In tree.GetRoot().DescendantTokens Where t.Kind = SyntaxKind.AsyncKeyword Into Count()) Dim fields = tree.GetRoot().DescendantNodes.OfType(Of FieldDeclarationSyntax)().ToArray() Assert.Equal(2, Aggregate f In fields Where f.Declarators(0).Names(0).Identifier.ValueText = "Async" Into Count()) End Sub <Fact> Public Sub ParseAwaitExpressions() Dim tree = ParseAndVerify(<![CDATA[ Imports System.Console Module Program Private t1 As Task Private t2 As Task(Of Integer) Async Sub M() Await t1 WriteLine(Await t2) End Sub Sub M2() Await t1 WriteLine(Await t2) End Sub Async Function N() As Task(Of Integer) Await t1 Return Await t2 End Function Function N2() Await t1 Return (Await t2) End Function End Module]]>, <errors> <error id="30800" message="Method arguments must be enclosed in parentheses." start="206" end="208"/> <error id="32017" message="Comma, ')', or a valid expression continuation expected." start="234" end="236"/> <error id="30800" message="Method arguments must be enclosed in parentheses." start="398" end="400"/> <error id="30198" message="')' expected." start="424" end="424"/> </errors>) Dim awaitExpressions = tree.GetRoot().DescendantNodes.OfType(Of AwaitExpressionSyntax)() Assert.Equal(4, awaitExpressions.Count) Dim firstStatementOfM = tree.GetRoot().DescendantNodes.OfType(Of MethodBlockBaseSyntax).First.Statements.First Assert.Equal(SyntaxKind.ExpressionStatement, firstStatementOfM.Kind) Assert.Equal(SyntaxKind.AwaitExpression, CType(firstStatementOfM, ExpressionStatementSyntax).Expression.Kind) Dim firstStatementOfM2 = tree.GetRoot().DescendantNodes.OfType(Of MethodBlockBaseSyntax)()(1).Statements.First Assert.Equal(SyntaxKind.ExpressionStatement, firstStatementOfM2.Kind) Assert.Equal(SyntaxKind.InvocationExpression, CType(firstStatementOfM2, ExpressionStatementSyntax).Expression.Kind) Dim firstStatementOfN = tree.GetRoot().DescendantNodes.OfType(Of MethodBlockBaseSyntax)()(2).Statements.First Assert.Equal(SyntaxKind.ExpressionStatement, firstStatementOfM.Kind) Assert.Equal(SyntaxKind.AwaitExpression, CType(firstStatementOfM, ExpressionStatementSyntax).Expression.Kind) Dim firstStatementOfN2 = tree.GetRoot().DescendantNodes.OfType(Of MethodBlockBaseSyntax)()(3).Statements.First Assert.Equal(SyntaxKind.ExpressionStatement, firstStatementOfM2.Kind) Assert.Equal(SyntaxKind.InvocationExpression, CType(firstStatementOfM2, ExpressionStatementSyntax).Expression.Kind) End Sub <Fact> Public Sub ParseAwaitExpressionsWithPrecedence() Dim tree = ParseAndVerify(<![CDATA[ Module Program Async Function M(a As Task(Of Integer), x As Task(Of Integer), y As Task(Of Integer), b As Task(Of Integer)) As Task(Of Integer) Return Await a * Await x ^ Await y + Await b End Function End Module]]>) Dim returnStatement = tree.GetRoot().DescendantNodes.OfType(Of ReturnStatementSyntax).Single() Dim expression = CType(returnStatement.Expression, BinaryExpressionSyntax) Assert.Equal(SyntaxKind.AddExpression, expression.Kind) Assert.Equal(SyntaxKind.MultiplyExpression, expression.Left.Kind) Dim left = CType(expression.Left, BinaryExpressionSyntax) Assert.Equal(SyntaxKind.AwaitExpression, left.Left.Kind) Assert.Equal(SyntaxKind.ExponentiateExpression, left.Right.Kind) Dim right = expression.Right Assert.Equal(SyntaxKind.AwaitExpression, right.Kind) End Sub <Fact> Public Sub ParseAwaitStatements() Dim tree = ParseAndVerify(<![CDATA[ Imports System.Console Module Program Private t1 As Task Private t2 As Task(Of Integer) Async Sub M() ' await 1 Await t1 End Sub Sub M2() ' await 2 Await t1 Dim lambda = Async Sub() If True Then Await t1 : Await t2 ' await 3 and 4 End Sub Async Function N() As Task(Of Integer) ' await 5 Await t1 ' await 6 Return Await t2 End Function Function N2() Await t1 Return (Await t2) End Function Async Function N3(a, x, y) As Task ' This is a parse error, end of statement expected after 'Await a' Await a * Await x * Await y End Function End Module]]>, <errors> <error id="30800" message="Method arguments must be enclosed in parentheses." start="177" end="179"/> <error id="30800" message="Method arguments must be enclosed in parentheses." start="407" end="409"/> <error id="30198" message="')' expected." start="433" end="433"/> <error id="30205" message="End of statement expected." start="588" end="589"/> </errors>) Dim awaitExpressions = tree.GetRoot().DescendantNodes.OfType(Of AwaitExpressionSyntax)().ToArray() Assert.Equal(6, awaitExpressions.Count) Dim firstStatementOfM = tree.GetRoot().DescendantNodes.OfType(Of MethodBlockBaseSyntax).First.Statements.First Assert.Equal(SyntaxKind.ExpressionStatement, firstStatementOfM.Kind) Assert.Equal(SyntaxKind.AwaitExpression, CType(firstStatementOfM, ExpressionStatementSyntax).Expression.Kind) Dim firstStatementOfM2 = tree.GetRoot().DescendantNodes.OfType(Of MethodBlockBaseSyntax)()(1).Statements.First Assert.Equal(SyntaxKind.ExpressionStatement, firstStatementOfM2.Kind) Assert.Equal(SyntaxKind.InvocationExpression, CType(firstStatementOfM2, ExpressionStatementSyntax).Expression.Kind) Dim firstStatementOfN = tree.GetRoot().DescendantNodes.OfType(Of MethodBlockBaseSyntax)()(2).Statements.First Assert.Equal(SyntaxKind.ExpressionStatement, firstStatementOfM.Kind) Assert.Equal(SyntaxKind.AwaitExpression, CType(firstStatementOfM, ExpressionStatementSyntax).Expression.Kind) Dim firstStatementOfN2 = tree.GetRoot().DescendantNodes.OfType(Of MethodBlockBaseSyntax)()(3).Statements.First Assert.Equal(SyntaxKind.ExpressionStatement, firstStatementOfM2.Kind) Assert.Equal(SyntaxKind.InvocationExpression, CType(firstStatementOfM2, ExpressionStatementSyntax).Expression.Kind) End Sub <Fact> Public Sub ParseAsyncLambdas() Dim tree = ParseAndVerify(<![CDATA[ Module Program Private t1 As Task Private t2 As Task(Of Integer) Private f As Integer Sub Main() ' Statement Dim slAsyncSub1 = Async Sub() Await t1 ' Assignment Dim slAsyncSub2 = Async Sub() f = Await t2 ' Expression Dim slAsyncFunction1 = Async Function() Await t2 ' Comparison Dim slAsyncFunction2 = Async Function() f = Await t2 Dim mlAsyncSub = Async Sub() Await t1 End Sub Dim mlAsyncFunction1 = Async Function() Await t1 End Function Dim mlAsyncFunction2 = Async Function() Await t1 Return Await t2 End Function End Sub End Module]]>) Dim lambdas = tree.GetRoot().DescendantNodes.OfType(Of LambdaExpressionSyntax)().ToArray() Assert.Equal(7, lambdas.Count) Assert.Equal(4, lambdas.Count(Function(l) SyntaxFacts.IsSingleLineLambdaExpression(l.Kind))) Assert.Equal(SyntaxKind.ExpressionStatement, CType(lambdas(0), SingleLineLambdaExpressionSyntax).Body.Kind) Assert.Equal(SyntaxKind.AwaitExpression, CType(CType(lambdas(0), SingleLineLambdaExpressionSyntax).Body, ExpressionStatementSyntax).Expression.Kind) Assert.Equal(SyntaxKind.SimpleAssignmentStatement, CType(lambdas(1), SingleLineLambdaExpressionSyntax).Body.Kind) Assert.Equal(SyntaxKind.AwaitExpression, CType(CType(lambdas(1), SingleLineLambdaExpressionSyntax).Body, AssignmentStatementSyntax).Right.Kind) Assert.Equal(SyntaxKind.AwaitExpression, CType(lambdas(2), SingleLineLambdaExpressionSyntax).Body.Kind) Assert.Equal(SyntaxKind.EqualsExpression, CType(lambdas(3), SingleLineLambdaExpressionSyntax).Body.Kind) Assert.Equal(SyntaxKind.AwaitExpression, CType(CType(lambdas(3), SingleLineLambdaExpressionSyntax).Body, BinaryExpressionSyntax).Right.Kind) Assert.Equal(3, lambdas.Count(Function(l) SyntaxFacts.IsMultiLineLambdaExpression(l.Kind))) End Sub <Fact> Public Sub ParseAsyncWithNesting() Dim tree = VisualBasicSyntaxTree.ParseText(<![CDATA[ Imports Async = System.Threading.Tasks.Task Class C Public Const Async As Integer = 0 <Async(Async)> Async Function M() As Async Dim t As Task Await (t) ' Yes Dim lambda1 = Function() Await (t) ' No Dim lambda1a = Sub() Await (t) ' No Dim lambda1b = Async Function() Await t ' Yes Dim lambda1c = Async Function() Await (Sub() Await (Function() Await (Function() (Function() Async Sub() Await t)())()) End Sub) ' Yes, No, No, Yes Return Await t ' Yes End Function [Await] t ' No End Function Sub Await(Optional p = Nothing) Dim t As Task Await (t) ' No Dim lambda1 = Async Function() Await (t) ' Yes Dim lambda1a = Async Sub() Await (t) ' Yes Dim lambda1b = Function() Await (t) ' No Dim lambda1c = Function() Await (Async Sub() Await (Async Function() Await (Async Function() (Function() Sub() Await t)())()) End Sub) ' No, Yes, Yes, No Return Await (t) ' No End Function Await t End Sub Function Await(t) Return Nothing End Function End Class Class AsyncAttribute Inherits Attribute Sub New(p) End Sub End Class]]>.Value) ' Error BC30800: Method arguments must be enclosed in parentheses. Assert.True(Aggregate d In tree.GetDiagnostics() Into All(d.Code = ERRID.ERR_ObsoleteArgumentsNeedParens)) Dim asyncExpressions = tree.GetRoot().DescendantNodes.OfType(Of AwaitExpressionSyntax).ToArray() Assert.Equal(9, asyncExpressions.Count) Dim invocationExpression = tree.GetRoot().DescendantNodes.OfType(Of InvocationExpressionSyntax).ToArray() Assert.Equal(9, asyncExpressions.Count) Dim allParsedExpressions = tree.GetRoot().DescendantNodes.OfType(Of ExpressionSyntax)() Dim parsedExpressions = From expression In allParsedExpressions Where expression.Kind = SyntaxKind.AwaitExpression OrElse (expression.Kind = SyntaxKind.IdentifierName AndAlso DirectCast(expression, IdentifierNameSyntax).Identifier.ValueText.Equals("Await")) Order By expression.Position Select expression.Kind Dim expected = {SyntaxKind.AwaitExpression, SyntaxKind.IdentifierName, SyntaxKind.IdentifierName, SyntaxKind.AwaitExpression, SyntaxKind.AwaitExpression, SyntaxKind.IdentifierName, SyntaxKind.IdentifierName, SyntaxKind.AwaitExpression, SyntaxKind.AwaitExpression, SyntaxKind.IdentifierName, SyntaxKind.IdentifierName, SyntaxKind.AwaitExpression, SyntaxKind.AwaitExpression, SyntaxKind.IdentifierName, SyntaxKind.IdentifierName, SyntaxKind.AwaitExpression, SyntaxKind.AwaitExpression, SyntaxKind.IdentifierName, SyntaxKind.IdentifierName, SyntaxKind.IdentifierName} Assert.Equal(expected, parsedExpressions) End Sub <Fact> Public Sub ParseAwaitInScriptingAndInteractive() Dim source = " Dim i = Await T + Await(T) ' Yes, Yes Dim l = Sub() Await T ' No End Sub Function M() Return Await T ' No End Function Async Sub N() Await T ' Yes Await(T) ' Yes End Sub Async Function F() Return Await(T) ' Yes End Function" Dim tree = VisualBasicSyntaxTree.ParseText(source, options:=TestOptions.Script) Dim awaitExpressions = tree.GetRoot().DescendantNodes.OfType(Of AwaitExpressionSyntax).ToArray() Assert.Equal(5, awaitExpressions.Count) Dim awaitParsedAsIdentifier = tree.GetRoot().DescendantNodes.OfType(Of IdentifierNameSyntax).Where(Function(id) id.Identifier.ValueText.Equals("Await")).ToArray() Assert.Equal(2, awaitParsedAsIdentifier.Count) End Sub End Class