From 0c833628ee5e4ac221ce9b0f01000a871793c713 Mon Sep 17 00:00:00 2001 From: nosami Date: Tue, 7 Mar 2017 13:20:03 +0000 Subject: [F#] Fixes interactive window. Fixes #52721 --- .../MonoDevelop.FSharp.Tests/Interactive.fs | 29 +++++++++++++++ .../MonoDevelop.FSharp.Tests.fsproj | 43 +++++++++++----------- .../FSharpInteractivePad.fs | 3 +- .../Services/InteractiveSession.fs | 13 ++++--- .../MonoDevelop.FSharpInteractive.Service.fsproj | 1 - 5 files changed, 60 insertions(+), 29 deletions(-) create mode 100644 main/external/fsharpbinding/MonoDevelop.FSharp.Tests/Interactive.fs diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/Interactive.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/Interactive.fs new file mode 100644 index 0000000000..a0937e152c --- /dev/null +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/Interactive.fs @@ -0,0 +1,29 @@ +namespace MonoDevelopTests +open System.Threading +open NUnit.Framework +open MonoDevelop.FSharp.MonoDevelop +open MonoDevelop.FSharp +open System.IO +open System.Reflection +open System.Threading.Tasks +open System.Runtime.CompilerServices + +[] +module Interactive = + let toTask computation : Task = Async.StartAsTask computation :> _ + + [)>] + let ``Interactive receives prompt``() = + async { + let (/) a b = Path.Combine(a,b) + let testDllFolder = Assembly.GetExecutingAssembly().Location |> Path.GetDirectoryName + let pathToExe = "\"" + testDllFolder/".."/".."/".."/".."/".."/"build"/"AddIns"/"BackendBindings"/"MonoDevelop.FSharpInteractive.Service.exe\"" + let ses = InteractiveSession(pathToExe) + do! Async.Sleep 1000 // give the process chance to start + if ses.HasExited() then + Assert.Fail("Interactive session has exited") + ses.StartReceiving() + let finished = new AutoResetEvent(false) // using AutoResetEvent because I can't get Async.AwaitEvent to work here without a hang + ses.PromptReady.Add(fun _ -> finished.Set() |> ignore) + finished.WaitOne() |> ignore + Assert.Pass() } |> toTask diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj index 74415feab3..167edaf570 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj @@ -137,26 +137,6 @@ MonoDevelop.PackageManagement - - - - - - - - - - - - - - - - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets @@ -179,6 +159,25 @@ + + + + + + + + + + + + + + + + + + + @@ -194,10 +193,10 @@ PreserveNewest - + PreserveNewest - + PreserveNewest diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpInteractivePad.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpInteractivePad.fs index 2aa2a6e912..af682b528f 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpInteractivePad.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpInteractivePad.fs @@ -189,7 +189,8 @@ type FSharpInteractivePad() = let setupSession() = try - let ses = InteractiveSession() + let pathToExe = "\"" + Path.Combine(Reflection.Assembly.GetExecutingAssembly().Location |> Path.GetDirectoryName, "MonoDevelop.FSharpInteractive.Service.exe") + "\"" + let ses = InteractiveSession(pathToExe) input.Clear() promptReceived <- false let textReceived = ses.TextReceived.Subscribe(fun t -> Runtime.RunInMainThread(fun () -> fsiOutput t) |> ignore) diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/InteractiveSession.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/InteractiveSession.fs index f461f22c5d..0736a082e7 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/InteractiveSession.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/InteractiveSession.fs @@ -18,7 +18,7 @@ type CompletionData = { description: string } -type InteractiveSession() = +type InteractiveSession(pathToExe) = let (|Completion|_|) (command: string) = if command.StartsWith("completion ") then let payload = command.[11..] @@ -40,15 +40,14 @@ type InteractiveSession() = else None - let path = "\"" + Path.Combine(Reflection.Assembly.GetExecutingAssembly().Location |> Path.GetDirectoryName, "MonoDevelop.FSharpInteractive.Service.exe") + "\"" let mutable waitingForResponse = false let fsiProcess = let processName = - if Environment.runningOnMono then Environment.getMonoPath() else path + if Environment.runningOnMono then Environment.getMonoPath() else pathToExe let arguments = - if Environment.runningOnMono then path else null + if Environment.runningOnMono then pathToExe else null let startInfo = new ProcessStartInfo @@ -98,7 +97,7 @@ type InteractiveSession() = | ParameterHints hints -> parameterHintReceivedEvent.Trigger hints | _ -> LoggingService.logDebug "[fsharpi] don't know how to process command %s" de.Data - + with | :? JsonException -> LoggingService.logError "[fsharpi] - error deserializing error stream - %s" de.Data @@ -120,6 +119,8 @@ type InteractiveSession() = member x.TextReceived = textReceived.Publish member x.PromptReady = promptReady.Publish + member x.HasExited() = fsiProcess.HasExited + member x.Kill() = if not fsiProcess.HasExited then x.SendInput "#q;;" @@ -135,6 +136,8 @@ type InteractiveSession() = LoggingService.logDebug "Interactive: waiting for process exit after kill... %d" (i*200) fsiProcess.WaitForExit(200) |> ignore + member x.KillNow() = fsiProcess.Kill() + member x.SendInput input = for line in String.getLines input do sendCommand ("input " + line) diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj b/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj index eb8a2b1df7..c2dab81f56 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj @@ -200,7 +200,6 @@ ..\packages\Newtonsoft.Json\lib\net45\Newtonsoft.Json.dll - False True -- cgit v1.2.3