diff --git a/FSharpWorkspaceShim/FSharpWorkspaceShim.fsproj b/FSharpWorkspaceShim/FSharpWorkspaceShim.fsproj
index c06b373c6..41b0ba9c3 100644
--- a/FSharpWorkspaceShim/FSharpWorkspaceShim.fsproj
+++ b/FSharpWorkspaceShim/FSharpWorkspaceShim.fsproj
@@ -19,7 +19,7 @@
-
+
diff --git a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs
index c46ec2144..2ff9293d5 100644
--- a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs
+++ b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs
@@ -3,70 +3,35 @@
namespace Microsoft.DotNet.Interactive.FSharp
-open System
-open System.ComponentModel
-open System.Diagnostics
-open System.Text
open System.Threading.Tasks
+open FSharp.Compiler.Scripting
open Microsoft.DotNet.Interactive
open Microsoft.DotNet.Interactive.Commands
open Microsoft.DotNet.Interactive.Events
-open MLS.Agent.Tools
type FSharpKernel() =
inherit KernelBase()
- let mutable proc: Process = null
- let write (s: string) = proc.StandardInput.Write(s)
- let sentinelValue = Guid.NewGuid().ToString()
- let sentinelFound = Event<_>()
- let stdout = StringBuilder()
- let waitForReady () =
- async {
- write <| sprintf ";;printfn \"\\n%s\";;\n" sentinelValue
- do! Async.AwaitEvent sentinelFound.Publish
- }
- let startProcess () =
- async {
- if isNull proc then
- let outputReceived line =
- if line = sentinelValue then
- sentinelFound.Trigger()
- else
- stdout.AppendLine(line) |> ignore
- proc <- Dotnet().StartProcess("fsi --nologo", output = Action(outputReceived))
- do! waitForReady()
- }
- let eval (code: string) =
- async {
- do! startProcess ()
- stdout.Clear() |> ignore
- write code
- do! waitForReady ()
- let value = stdout.ToString()
- // trim garbage
- let nl = Environment.NewLine
- let headerGarbage = sprintf "val it : unit = ()%s%s" nl nl
- let value = if value.StartsWith(headerGarbage) then value.Substring(headerGarbage.Length) else value
- let footerGarbage = sprintf "%s%s> %s" nl nl nl
- let value = if value.EndsWith(footerGarbage) then value.Substring(0, value.Length - footerGarbage.Length) else value
- return value
- }
- do base.AddDisposable({ new IDisposable with
- member __.Dispose() =
- if not <| isNull proc then
- try
- proc.Kill()
- with
- | :? InvalidOperationException -> ()
- | :? NotSupportedException -> ()
- | :? Win32Exception -> () })
+ let script = new FSharpScript()
+ do base.AddDisposable(script)
let handleSubmitCode (codeSubmission: SubmitCode) (context: KernelInvocationContext) =
async {
let codeSubmissionReceived = CodeSubmissionReceived(codeSubmission.Code, codeSubmission)
context.OnNext(codeSubmissionReceived)
- // submit code
- let! value = eval codeSubmission.Code
- context.OnNext(ValueProduced(value, codeSubmission, true, [FormattedValue("text/plain", value)]))
+ let result, errors =
+ try
+ script.Eval(codeSubmission.Code)
+ with
+ | ex -> Error(ex), [||]
+ if errors.Length > 0 then
+ let aggregateErrorMessage = System.String.Join("\n", errors)
+ context.OnNext(CodeSubmissionEvaluationFailed(aggregateErrorMessage, codeSubmission))
+ match result with
+ | Ok(Some(value)) ->
+ let value = value.ReflectionValue
+ let formattedValues = FormattedValue.FromObject(value)
+ context.OnNext(ValueProduced(value, codeSubmission, true, formattedValues))
+ | Ok(None) -> ()
+ | Error(ex) -> context.OnError(ex)
context.OnNext(CodeSubmissionEvaluated(codeSubmission))
context.OnCompleted()
}
diff --git a/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj b/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj
index e3fd56688..e8ba17359 100644
--- a/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj
+++ b/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj
@@ -21,7 +21,13 @@
+
+
+
+
+
+
diff --git a/Microsoft.DotNet.Interactive.Jupyter/ExecuteRequestHandler.cs b/Microsoft.DotNet.Interactive.Jupyter/ExecuteRequestHandler.cs
index 15d2e3681..a87da41cd 100644
--- a/Microsoft.DotNet.Interactive.Jupyter/ExecuteRequestHandler.cs
+++ b/Microsoft.DotNet.Interactive.Jupyter/ExecuteRequestHandler.cs
@@ -208,19 +208,20 @@ private void OnValueProduced(ValueProduced valueProduced)
private void OnCodeSubmissionEvaluated(CodeSubmissionEvaluated codeSubmissionEvaluated)
{
- InFlightRequests.TryRemove(codeSubmissionEvaluated.Command, out var openRequest);
-
- // reply ok
- var executeReplyPayload = new ExecuteReplyOk(executionCount: openRequest.ExecutionCount);
+ if (InFlightRequests.TryRemove(codeSubmissionEvaluated.Command, out var openRequest))
+ {
+ // reply ok
+ var executeReplyPayload = new ExecuteReplyOk(executionCount: openRequest.ExecutionCount);
- // send to server
- var executeReply = Message.CreateResponse(
- executeReplyPayload,
- openRequest.Context.Request);
+ // send to server
+ var executeReply = Message.CreateResponse(
+ executeReplyPayload,
+ openRequest.Context.Request);
- openRequest.Context.ServerChannel.Send(executeReply);
- openRequest.Context.RequestHandlerStatus.SetAsIdle();
- openRequest.Dispose();
+ openRequest.Context.ServerChannel.Send(executeReply);
+ openRequest.Context.RequestHandlerStatus.SetAsIdle();
+ openRequest.Dispose();
+ }
}
}
}
\ No newline at end of file
diff --git a/Microsoft.DotNet.Interactive.Rendering/Formatter.cs b/Microsoft.DotNet.Interactive.Rendering/Formatter.cs
index 969f40635..201b85c78 100644
--- a/Microsoft.DotNet.Interactive.Rendering/Formatter.cs
+++ b/Microsoft.DotNet.Interactive.Rendering/Formatter.cs
@@ -113,7 +113,7 @@ public static void ResetToDefault()
}
public static string ToDisplayString(
- this object obj,
+ this object obj,
string mimeType = Rendering.PlainTextFormatter.MimeType)
{
// TODO: (ToDisplayString) rename
@@ -143,7 +143,7 @@ public static string ToDisplayString(
}
public static void FormatTo(
- this T obj,
+ this T obj,
TextWriter writer,
string mimeType = Rendering.PlainTextFormatter.MimeType)
{
@@ -181,7 +181,7 @@ internal static Action