@@ -13,7 +13,10 @@ Imports NuGet.ProjectManagement
1313Imports NuGet.Protocol.Core.Types
1414Imports NuGet.Resolver
1515'TODO: Child variables only
16+ 'TODO: Async
1617'TODO: Non method things
18+ 'TODO: Maybe replace variable references with dictionary lookups
19+ 'TODO: State save should be inserted before all returns
1720Public Class REPL
1821 Private _imports As New List( Of ImportsStatementSyntax)
1922 Private _state As New Dictionary( Of String , Object )
@@ -22,8 +25,8 @@ Public Class REPL
2225 Private ReadOnly _nugetCache As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DeveloperCore.REPL" , "NuGetCache" )
2326
2427 Public Function Evaluate(str As String ) As EvaluationResults
25- Dim newStatement As StatementSyntax = SyntaxCreator.ParseStatement (str)
26- Dim comp As VisualBasicCompilation = GetCompilation(str )
28+ Dim newStatement As StatementSyntax = SyntaxFactory.ParseExecutableStatement (str)
29+ Dim comp As VisualBasicCompilation = GetCompilation(newStatement )
2730 Using ms As New MemoryStream
2831 Dim res As EmitResult = comp.Emit(ms)
2932 Dim results As Object
@@ -37,34 +40,43 @@ Public Class REPL
3740 End Using
3841 End Function
3942
40- Public Function GetCompilation(str As String ) As VisualBasicCompilation
41- Dim newStatement As StatementSyntax = SyntaxCreator.ParseStatement(str)
43+ Public Function GetCompilation(newStatement As StatementSyntax) As VisualBasicCompilation
4244 Dim stateName As String = GetRandomString( 10 )
43- Dim unit As CompilationUnitSyntax = SyntaxFactory.ParseCompilationUnit(GetUnit (newStatement, stateName ).ToString)
44- Dim method As MethodBlockSyntax = unit.DescendantNodes.OfType( Of MethodBlockSyntax ).First
45- unit = unit.ReplaceNode(method, UpdateMethod(method, stateName )).NormalizeWhitespace
45+ Dim unit As CompilationUnitSyntax = SyntaxFactory.ParseCompilationUnit(GetCompilationUnit (newStatement).ToString)
46+ Dim classNode As ClassBlockSyntax = unit.DescendantNodes.OfType( Of ClassBlockSyntax ).First
47+ unit = unit.ReplaceNode(classNode, classNode.AddMembers(GetMethod(stateName, newStatement) )).NormalizeWhitespace
4648 Return CompilationCreator.GetCompilation(unit).AddReferences(_references).AddSyntaxTrees(_trees)
4749 End Function
4850
49- Private Function UpdateMethod(method As MethodBlockSyntax, stateName As String ) As MethodBlockSyntax
50- Dim stateVars As New List( Of VariableDeclaratorSyntax)
51- For Each key As String In _state.Keys
52- Dim var As VariableDeclaratorSyntax = SyntaxFactory.VariableDeclarator(SyntaxFactory.ModifiedIdentifier( key )).WithAsClause(SyntaxFactory.SimpleAsClause(SyntaxFactory.ParseTypeName(GetTypeName( key )))).WithInitializer(SyntaxFactory.EqualsValue(SyntaxFactory.ParseExpression( $"{stateName}(""{key}"")" )))
53- stateVars.Add(var)
54- Next
55- method = method.WithStatements(method.Statements.Insert( 0 , SyntaxFactory.LocalDeclarationStatement( New SyntaxTokenList().Add(SyntaxFactory.ParseToken( "Dim" )), New SeparatedSyntaxList( Of VariableDeclaratorSyntax)().AddRange(stateVars)))).NormalizeWhitespace
56- Dim retIndex As Integer = method.Statements.IndexOf(method.DescendantNodes.OfType( Of ReturnStatementSyntax).First)
57- Dim varUpdates As New List( Of StatementSyntax)
58- Dim vars As VariableDeclaratorSyntax() = method.DescendantNodes.OfType( Of VariableDeclaratorSyntax).ToArray
59- For Each var As VariableDeclaratorSyntax In vars
60- Dim name As String = var.Names.First.Identifier.Text
61- If Not _state.ContainsKey(name) Then
62- varUpdates.Add(SyntaxFactory.ParseExecutableStatement( $"{stateName}.Add(""{name}"", {name})" ))
63- Else
64- varUpdates.Add(SyntaxFactory.ParseExecutableStatement( $"{stateName}(""{name}"") = {name}" ))
65- End If
66- Next
67- method = method.WithStatements(method.Statements.InsertRange(retIndex, varUpdates))
51+ Private Function GetCompilationUnit(statement As StatementSyntax) As CompilationUnitSyntax
52+ Dim unit As CompilationUnitSyntax = SyntaxFactory.CompilationUnit().AddMembers(SyntaxCreator.GetModule()).AddImports(_imports.Concat( If ( TypeOf statement Is ImportsStatementSyntax, { DirectCast (statement, ImportsStatementSyntax)}, {})).ToArray).NormalizeWhitespace
53+ Return unit
54+ End Function
55+
56+ Private Function GetMethod(stateName As String , statement As StatementSyntax) As MethodBlockSyntax
57+ Dim method As MethodBlockSyntax = SyntaxCreator.GetMethod(stateName)
58+ Dim defaultReturn As ReturnStatementSyntax = SyntaxFactory.ReturnStatement(SyntaxFactory.NothingLiteralExpression(SyntaxFactory.ParseToken( "Nothing" )))
59+ If TypeOf statement Is ImportsStatementSyntax Then
60+ method = method.AddStatements(defaultReturn)
61+ Else
62+ Dim stateVars As New List( Of VariableDeclaratorSyntax)
63+ For Each key As String In _state.Keys
64+ Dim var As VariableDeclaratorSyntax = SyntaxFactory.VariableDeclarator(SyntaxFactory.ModifiedIdentifier( key )).WithAsClause(SyntaxFactory.SimpleAsClause(SyntaxFactory.ParseTypeName(GetTypeName( key )))).WithInitializer(SyntaxFactory.EqualsValue(SyntaxFactory.ParseExpression( $"{stateName}(""{key}"")" )))
65+ stateVars.Add(var)
66+ Next
67+ Dim varDeclaration As LocalDeclarationStatementSyntax = SyntaxFactory.LocalDeclarationStatement( New SyntaxTokenList().Add(SyntaxFactory.ParseToken( "Dim" )), New SeparatedSyntaxList( Of VariableDeclaratorSyntax)().AddRange(stateVars))
68+ Dim varUpdates As New List( Of StatementSyntax)
69+ Dim vars As VariableDeclaratorSyntax() = varDeclaration.Declarators.Concat(statement.DescendantNodes.OfType( Of VariableDeclaratorSyntax)).ToArray
70+ For Each var As VariableDeclaratorSyntax In vars
71+ Dim name As String = var.Names.First.Identifier.Text
72+ If Not _state.ContainsKey(name) Then
73+ varUpdates.Add(SyntaxFactory.ParseExecutableStatement( $"{stateName}.Add(""{name}"", {name})" ))
74+ Else
75+ varUpdates.Add(SyntaxFactory.ParseExecutableStatement( $"{stateName}(""{name}"") = {name}" ))
76+ End If
77+ Next
78+ method = method.WithStatements( New SyntaxList( Of StatementSyntax)().AddRange({varDeclaration, statement}).AddRange(varUpdates).Add(defaultReturn))
79+ End If
6880 Return method
6981 End Function
7082
@@ -79,11 +91,6 @@ Public Class REPL
7991 End Try
8092 End Function
8193
82- Private Function GetUnit(statement As StatementSyntax, param As String )
83- Dim unit As CompilationUnitSyntax = SyntaxCreator.GetCompilationUnit(SyntaxCreator.GetModule.AddMembers(SyntaxCreator.GetMainMethod(param).AddStatements( If ( TypeOf statement Is ImportsStatementSyntax, {}, {statement}).Concat({SyntaxFactory.ReturnStatement(SyntaxFactory.NothingLiteralExpression(SyntaxFactory.ParseToken( "Nothing" )))}).ToArray))).AddImports(_imports.Concat( If ( TypeOf statement Is ImportsStatementSyntax, { DirectCast (statement, ImportsStatementSyntax)}, {})).ToArray).NormalizeWhitespace
84- Return unit
85- End Function
86-
8794 Private Function GetTypeName( key As String ) As String
8895 Dim obj As Object = _state( key )
8996 If obj Is Nothing Then
@@ -94,7 +101,7 @@ Public Class REPL
94101 End If
95102 End Function
96103
97- Public Function GetTypeName(type As Type) As String
104+ Private Function GetTypeName(type As Type) As String
98105 If type.IsGenericType Then
99106 Return SyntaxFactory.GenericName(GetGenericNameActual(type), SyntaxFactory.TypeArgumentList( New SeparatedSyntaxList( Of TypeSyntax)().AddRange(type.GenericTypeArguments.Select( Function (x) SyntaxFactory.ParseTypeName(GetTypeName(x)))))).NormalizeWhitespace.ToFullString
100107 ElseIf type.IsArray Then
0 commit comments