提交 86bd9734 编写于 作者: W Wonseok Chae

Enable turning a method into an async method or iterator in VB

Enables an edit that updates a regular method to an async method or an iterator in VB. As in C#, there is the restriction in the presence of an active statement in the method body since the debugger doesn't support remapping active statements to a different method (from the original method to the new MoveNext added due to the change to state machine).
上级 ea99e572
......@@ -4386,32 +4386,179 @@ End Class
#Region "State Machines"
<Fact>
Public Sub MethodToIteratorMethod_WithActiveStatement()
' TODO
Dim src1 = "
Imports System
Imports System.Collections.Generic
Class C
Function F() As IEnumerable(Of Integer)
<AS:0>Console.WriteLine(1)</AS:0>
Return {1, 1}
End Function
End Class
"
Dim src2 = "
Imports System
Imports System.Collections.Generic
Class C
Iterator Function F() As IEnumerable(Of Integer)
<AS:0>Console.WriteLine(1)</AS:0>
Yield 1
End Function
End Class
"
Dim edits = GetTopEdits(src1, src2)
Dim active = GetActiveStatements(src1, src2)
edits.VerifyRudeDiagnostics(active,
Diagnostic(RudeEditKind.InsertAroundActiveStatement, "Yield 1", "Yield statement"))
End Sub
<Fact>
Public Sub MethodToIteratorMethod_WithActiveStatementInLambda()
' TODO
Dim src1 = "
Imports System
Imports System.Collections.Generic
Class C
Function F() As IEnumerable(Of Integer)
Dim a = Sub() <AS:0>Console.WriteLine(1)</AS:0>
a()
Return {1, 1}
End Function
End Class
"
Dim src2 = "
Imports System
Imports System.Collections.Generic
Class C
Iterator Function F() As IEnumerable(Of Integer)
Dim a = Sub() <AS:0>Console.WriteLine(1)</AS:0>
a()
Yield 1
End Function
End Class
"
Dim edits = GetTopEdits(src1, src2)
Dim active = GetActiveStatements(src1, src2)
' should not contain RUDE_EDIT_INSERT_AROUND
edits.VerifyRudeDiagnostics(active,
Diagnostic(RudeEditKind.RUDE_EDIT_LAMBDA_EXPRESSION, "Sub()", "method"))
End Sub
<Fact>
Public Sub MethodToIteratorMethod_WithoutActiveStatement()
' TODO
Dim src1 = "
Imports System
Imports System.Collections.Generic
Class C
Function F() As IEnumerable(Of Integer)
Console.WriteLine(1)
Return {1, 1}
End Function
End Class
"
Dim src2 = "
Imports System
Imports System.Collections.Generic
Class C
Iterator Function F() As IEnumerable(Of Integer)
Console.WriteLine(1)
Yield 1
End Function
End Class
"
Dim edits = GetTopEdits(src1, src2)
Dim active = GetActiveStatements(src1, src2)
edits.VerifyRudeDiagnostics(active)
End Sub
<Fact>
Public Sub MethodToAsyncMethod_WithActiveStatement()
' TODO
Dim src1 = "
Imports System
Imports System.Threading.Tasks
Class C
Function F() As Task(Of Integer)
<AS:0>Console.WriteLine(1)</AS:0>
Return Task.FromResult(1)
End Function
End Class
"
Dim src2 = "
Imports System
Imports System.Threading.Tasks
Class C
Async Function F() As Task(Of Integer)
<AS:0>Console.WriteLine(1)</AS:0>
Return Await Task.FromResult(1)
End Function
End Class
"
Dim edits = GetTopEdits(src1, src2)
Dim active = GetActiveStatements(src1, src2)
edits.VerifyRudeDiagnostics(active,
Diagnostic(RudeEditKind.InsertAroundActiveStatement, "Await", "Await expression"))
End Sub
<Fact>
Public Sub MethodToAsyncMethod_WithActiveStatementInLambda()
' TODO
Dim src1 = "
Imports System
Imports System.Threading.Tasks
Class C
Function F() As Task(Of Integer)
Dim a = Sub() <AS:0>Console.WriteLine(1)</AS:0>
a()
Return Task.FromResult(1)
End Function
End Class
"
Dim src2 = "
Imports System
Imports System.Threading.Tasks
Class C
Async Function F() As Task(Of Integer)
Dim a = Sub() <AS:0>Console.WriteLine(1)</AS:0>
a()
Return Await Task.FromResult(1)
End Function
End Class
"
Dim edits = GetTopEdits(src1, src2)
Dim active = GetActiveStatements(src1, src2)
edits.VerifyRudeDiagnostics(active,
Diagnostic(RudeEditKind.RUDE_EDIT_LAMBDA_EXPRESSION, "Sub()", "method"))
End Sub
<Fact>
Public Sub MethodToAsyncMethod_WithoutActiveStatement()
' TODO
Dim src1 = "
Imports System
Imports System.Threading.Tasks
Class C
Function F() As Task(Of Integer)
Console.WriteLine(1)
Return Task.FromResult(1)
End Function
End Class
"
Dim src2 = "
Imports System
Imports System.Threading.Tasks
Class C
Async Function F() As Task(Of Integer)
Console.WriteLine(1)
Return Await Task.FromResult(1)
End Function
End Class
"
Dim edits = GetTopEdits(src1, src2)
Dim active = GetActiveStatements(src1, src2)
edits.VerifyRudeDiagnostics(active)
End Sub
#End Region
......
......@@ -1905,8 +1905,7 @@ End Class
edits.VerifyEdits(
"Update [Async Function F() As Task(Of String)]@11 -> [Function F() As Task(Of String)]@11")
edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.ModifiersUpdate, "Function F()", "method"))
edits.VerifyRudeDiagnostics()
End Sub
<Fact>
......
......@@ -2378,7 +2378,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue
Return
End If
If Not SyntaxFactory.AreEquivalent(oldNode.Modifiers, newNode.Modifiers) Then
If Not ClassifyMethodModifierUpdate(oldNode.Modifiers, newNode.Modifiers) Then
ReportError(RudeEditKind.ModifiersUpdate)
Return
End If
......@@ -2395,6 +2395,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue
End If
End Sub
Private Function ClassifyMethodModifierUpdate(oldModifiers As SyntaxTokenList, newModifiers As SyntaxTokenList) As Boolean
Dim oldAsyncIndex = oldModifiers.IndexOf(SyntaxKind.AsyncKeyword)
Dim newAsyncIndex = newModifiers.IndexOf(SyntaxKind.AsyncKeyword)
If oldAsyncIndex >= 0 Then
oldModifiers = oldModifiers.RemoveAt(oldAsyncIndex)
End If
If newAsyncIndex >= 0 Then
newModifiers = newModifiers.RemoveAt(newAsyncIndex)
End If
Dim oldIteratorIndex = oldModifiers.IndexOf(SyntaxKind.IteratorKeyword)
Dim newIteratorIndex = newModifiers.IndexOf(SyntaxKind.IteratorKeyword)
If oldIteratorIndex >= 0 Then
oldModifiers = oldModifiers.RemoveAt(oldIteratorIndex)
End If
If newIteratorIndex >= 0 Then
newModifiers = newModifiers.RemoveAt(newIteratorIndex)
End If
Return SyntaxFactory.AreEquivalent(oldModifiers, newModifiers)
End Function
Private Sub ClassifyUpdate(oldNode As DeclareStatementSyntax, newNode As DeclareStatementSyntax)
If Not SyntaxFactory.AreEquivalent(oldNode.Identifier, newNode.Identifier) Then
ReportError(RudeEditKind.Renamed)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册