Skip to content

Commit 8c7743f

Browse files
Add await parsing workaround
1 parent 755126e commit 8c7743f

2 files changed

Lines changed: 24 additions & 20 deletions

File tree

DeveloperCore.REPL/REPL.vb

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,25 @@ Imports Microsoft.CodeAnalysis
33
Imports Microsoft.CodeAnalysis.Emit
44
Imports Microsoft.CodeAnalysis.VisualBasic
55
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
6-
'TODO: Async - Can't parse Await with ParseExecutableStatement
76
'TODO: Non method things
87
'TODO: State save should be inserted before all returns
98
Public Class REPL
109
Private _imports As New List(Of ImportsStatementSyntax)
1110
Private _state As New Dictionary(Of String, Object)
1211
Private _references As New List(Of MetadataReference)
1312
Private _trees As New List(Of SyntaxTree)
14-
Private ReadOnly _nugetCache As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DeveloperCore.REPL", "NuGetCache")
13+
Private Const Template As String = "Public Async Sub Test()
14+
{0}
15+
End Sub"
1516

1617
Public Async Function Evaluate(str As String) As Task(Of EvaluationResults)
17-
Dim newStatement As StatementSyntax = SyntaxFactory.ParseExecutableStatement(str)
18+
Dim statements = SyntaxFactory.ParseCompilationUnit(String.Format(Template, str)).DescendantNodes.First.DescendantNodes.OfType(Of StatementSyntax).ToArray()
19+
Dim newStatement As StatementSyntax = Nothing
20+
If statements.Length >= 3 Then
21+
newStatement = statements(1)
22+
Else
23+
newStatement = SyntaxFactory.ParseExecutableStatement(str)
24+
End If
1825
Dim comp As VisualBasicCompilation = GetCompilation(newStatement)
1926
Using ms As New MemoryStream
2027
Dim res As EmitResult = comp.Emit(ms)
@@ -38,12 +45,12 @@ Public Class REPL
3845
End Function
3946

4047
Private Function GetCompilationUnit(statement As StatementSyntax) As CompilationUnitSyntax
41-
Dim unit As CompilationUnitSyntax = SyntaxFactory.CompilationUnit().AddMembers(SyntaxCreator.GetModule()).AddImports(_imports.Concat(If(TypeOf statement Is ImportsStatementSyntax, {DirectCast(statement, ImportsStatementSyntax)}, {})).ToArray).NormalizeWhitespace
48+
Dim unit As CompilationUnitSyntax = SyntaxFactory.CompilationUnit().AddMembers(GetModule()).AddImports(_imports.Concat(If(TypeOf statement Is ImportsStatementSyntax, {DirectCast(statement, ImportsStatementSyntax)}, {})).ToArray).NormalizeWhitespace
4249
Return unit
4350
End Function
4451

4552
Private Function GetMethod(stateName As String, statement As StatementSyntax) As MethodBlockSyntax
46-
Dim method As MethodBlockSyntax = SyntaxCreator.GetMethod(stateName)
53+
Dim method As MethodBlockSyntax = GetBaseMethod(stateName)
4754
Dim defaultReturn As ReturnStatementSyntax = SyntaxFactory.ReturnStatement(SyntaxFactory.NothingLiteralExpression(SyntaxFactory.ParseToken("Nothing")))
4855
Dim taskYield As ExpressionStatementSyntax = SyntaxFactory.ExpressionStatement(SyntaxFactory.AwaitExpression(SyntaxFactory.ParseExpression("System.Threading.Tasks.Task.Yield()")))
4956
If TypeOf statement Is ImportsStatementSyntax Then
@@ -65,11 +72,22 @@ Public Class REPL
6572
varUpdates.Add(SyntaxFactory.ParseExecutableStatement($"{stateName}(""{name}"") = {name}"))
6673
End If
6774
Next
68-
method = method.WithStatements(New SyntaxList(Of StatementSyntax)().AddRange({varDeclaration, statement}).AddRange(varUpdates).Add(taskYield).Add(defaultReturn))
75+
If stateVars.Count > 0 Then
76+
method = method.AddStatements(varDeclaration)
77+
End If
78+
method = method.AddStatements(statement).AddStatements(varUpdates.ToArray).AddStatements(taskYield, defaultReturn)
6979
End If
7080
Return method
7181
End Function
7282

83+
Private Function GetBaseMethod(param As String) As MethodBlockSyntax
84+
Return SyntaxFactory.FunctionBlock(SyntaxFactory.FunctionStatement("Evaluate").AddModifiers(SyntaxFactory.Token(SyntaxKind.AsyncKeyword)).WithAsClause(SyntaxFactory.SimpleAsClause(SyntaxFactory.ParseTypeName("System.Threading.Tasks.Task(Of Object)"))).AddImplementsClauseInterfaceMembers(SyntaxFactory.QualifiedName(SyntaxFactory.ParseTypeName("DeveloperCore.REPL.IExpression"), SyntaxFactory.ParseName("Evaluate"))).AddParameterListParameters(SyntaxFactory.Parameter(SyntaxFactory.ModifiedIdentifier(param)).WithAsClause(SyntaxFactory.SimpleAsClause(SyntaxFactory.ParseTypeName("System.Collections.Generic.Dictionary(Of String, Object)")))))
85+
End Function
86+
87+
Private Function GetModule() As ClassBlockSyntax
88+
Return SyntaxFactory.ClassBlock(SyntaxFactory.ClassStatement(SyntaxFactory.ParseToken("Expression"))).AddImplements(SyntaxFactory.ImplementsStatement(SyntaxFactory.ParseTypeName("DeveloperCore.REPL.IExpression")))
89+
End Function
90+
7391
Private Async Function Run(ms As MemoryStream) As Task(Of Object)
7492
Dim asm As Reflection.Assembly = Reflection.Assembly.Load(ms.ToArray)
7593
Dim type As Type = asm.GetType("Expression")

DeveloperCore.REPL/SyntaxCreator.vb

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)