未验证 提交 4978145c 编写于 作者: B Brett V. Forsgren 提交者: GitHub

fire event when a value is bound at the root of a script evaluation (#7919)

* fire event when a value is bound at the root of a script evaluation

* simplify event notifying bound values in interactive
上级 b757c165
......@@ -38,6 +38,8 @@ type FSharpScript(?captureInput: bool, ?captureOutput: bool, ?additionalArgs: st
member __.AssemblyReferenceAdded = fsi.AssemblyReferenceAdded
member __.ValueBound = fsi.ValueBound
member __.ProvideInput = stdin.ProvideInput
member __.OutputProduced = outputProduced.Publish
......
......@@ -950,6 +950,7 @@ type internal FsiDynamicCompiler
let assemblyName = "FSI-ASSEMBLY"
let assemblyReferenceAddedEvent = Control.Event<string>()
let valueBoundEvent = Control.Event<_>()
let mutable fragmentId = 0
let mutable prevIt : ValRef option = None
......@@ -1155,6 +1156,10 @@ type internal FsiDynamicCompiler
if v.CompiledName = "it" then
itValue <- fsiValueOpt
match fsiValueOpt with
| Some fsiValue -> valueBoundEvent.Trigger(fsiValue.ReflectionValue, fsiValue.ReflectionType, v.CompiledName)
| None -> ()
let symbol = FSharpSymbol.Create(cenv, v.Item)
let symbolUse = FSharpSymbolUse(tcGlobals, newState.tcState.TcEnvFromImpls.DisplayEnv, symbol, ItemOccurence.Binding, v.DeclarationLocation)
fsi.TriggerEvaluation (fsiValueOpt, symbolUse, decl)
......@@ -1331,6 +1336,8 @@ type internal FsiDynamicCompiler
member __.AssemblyReferenceAdded = assemblyReferenceAddedEvent.Publish
member __.ValueBound = valueBoundEvent.Publish
//----------------------------------------------------------------------------
// ctrl-c handling
//----------------------------------------------------------------------------
......@@ -2222,7 +2229,6 @@ type internal FsiInteractionProcessor
let fsiInteractiveChecker = FsiInteractiveChecker(legacyReferenceResolver, checker, tcConfig, istate.tcGlobals, istate.tcImports, istate.tcState)
fsiInteractiveChecker.ParseAndCheckInteraction(ctok, SourceText.ofString text)
//----------------------------------------------------------------------------
// Server mode:
//----------------------------------------------------------------------------
......@@ -2630,6 +2636,9 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i
/// Event fires every time an assembly reference is added to the execution environment, e.g., via `#r`.
member __.AssemblyReferenceAdded = fsiDynamicCompiler.AssemblyReferenceAdded
/// Event fires when a root-level value is bound to an identifier, e.g., via `let x = ...`.
member __.ValueBound = fsiDynamicCompiler.ValueBound
/// Performs these steps:
/// - Load the dummy interaction, if any
......
......@@ -237,6 +237,9 @@ type FsiEvaluationSession =
/// Event fires every time an assembly reference is added to the execution environment, e.g., via `#r`.
member AssemblyReferenceAdded : IEvent<string>
/// Event fires when a root-level value is bound to an identifier, e.g., via `let x = ...`.
member ValueBound : IEvent<obj * System.Type * string>
/// Load the dummy interaction, load the initial files, and,
/// if interacting, start the background thread to read the standard input.
///
......
......@@ -122,3 +122,49 @@ type InteractiveTests() =
Assert.True(wasCancelled)
Assert.LessOrEqual(sw.ElapsedMilliseconds, sleepTime)
Assert.AreEqual(None, result)
[<Test>]
member _.``Values bound at the root trigger an event``() =
let mutable foundX = false
let mutable foundY = false
let mutable foundCount = 0
use script = new FSharpScript()
script.ValueBound
|> Event.add (fun (value, typ, name) ->
foundX <- foundX || (name = "x" && typ = typeof<int> && value :?> int = 1)
foundY <- foundY || (name = "y" && typ = typeof<int> && value :?> int = 2)
foundCount <- foundCount + 1)
let code = @"
let x = 1
let y = 2
"
script.Eval(code) |> ignoreValue
Assert.True(foundX)
Assert.True(foundY)
Assert.AreEqual(2, foundCount)
[<Test>]
member _.``Values re-bound trigger an event``() =
let mutable foundXCount = 0
use script = new FSharpScript()
script.ValueBound
|> Event.add (fun (_value, typ, name) ->
if name = "x" && typ = typeof<int> then foundXCount <- foundXCount + 1)
script.Eval("let x = 1") |> ignoreValue
script.Eval("let x = 2") |> ignoreValue
Assert.AreEqual(2, foundXCount)
[<Test>]
member _.``Nested let bindings don't trigger event``() =
let mutable foundInner = false
use script = new FSharpScript()
script.ValueBound
|> Event.add (fun (_value, _typ, name) ->
foundInner <- foundInner || name = "inner")
let code = @"
let x =
let inner = 1
()
"
script.Eval(code) |> ignoreValue
Assert.False(foundInner)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册