Skip to content

Commit 4936143

Browse files
authored
Merge pull request #7927 from dotnet/merges/master-to-release/dev16.5
Merge master to release/dev16.5
2 parents 8e92cca + 4978145 commit 4936143

File tree

6 files changed

+64
-4
lines changed

6 files changed

+64
-4
lines changed

eng/Version.Details.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
<ProductDependencies>
44
</ProductDependencies>
55
<ToolsetDependencies>
6-
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="5.0.0-beta.19601.1">
6+
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="5.0.0-beta.19602.4">
77
<Uri>https://github.com/dotnet/arcade</Uri>
8-
<Sha>c0b56ff3569e3c7475070486c40543ea4c6f6dc7</Sha>
8+
<Sha>9d34fd008e754e1ada35c8b6bc3694e7a90b4ed7</Sha>
99
</Dependency>
1010
</ToolsetDependencies>
1111
</Dependencies>

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
}
1111
},
1212
"msbuild-sdks": {
13-
"Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.19601.1",
13+
"Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.19602.4",
1414
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2"
1515
}
1616
}

src/fsharp/FSharp.Compiler.Private.Scripting/FSharpScript.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ type FSharpScript(?captureInput: bool, ?captureOutput: bool, ?additionalArgs: st
3838

3939
member __.AssemblyReferenceAdded = fsi.AssemblyReferenceAdded
4040

41+
member __.ValueBound = fsi.ValueBound
42+
4143
member __.ProvideInput = stdin.ProvideInput
4244

4345
member __.OutputProduced = outputProduced.Publish

src/fsharp/fsi/fsi.fs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ type internal FsiDynamicCompiler
950950
let assemblyName = "FSI-ASSEMBLY"
951951

952952
let assemblyReferenceAddedEvent = Control.Event<string>()
953+
let valueBoundEvent = Control.Event<_>()
953954

954955
let mutable fragmentId = 0
955956
let mutable prevIt : ValRef option = None
@@ -1155,6 +1156,10 @@ type internal FsiDynamicCompiler
11551156
if v.CompiledName = "it" then
11561157
itValue <- fsiValueOpt
11571158

1159+
match fsiValueOpt with
1160+
| Some fsiValue -> valueBoundEvent.Trigger(fsiValue.ReflectionValue, fsiValue.ReflectionType, v.CompiledName)
1161+
| None -> ()
1162+
11581163
let symbol = FSharpSymbol.Create(cenv, v.Item)
11591164
let symbolUse = FSharpSymbolUse(tcGlobals, newState.tcState.TcEnvFromImpls.DisplayEnv, symbol, ItemOccurence.Binding, v.DeclarationLocation)
11601165
fsi.TriggerEvaluation (fsiValueOpt, symbolUse, decl)
@@ -1331,6 +1336,8 @@ type internal FsiDynamicCompiler
13311336

13321337
member __.AssemblyReferenceAdded = assemblyReferenceAddedEvent.Publish
13331338

1339+
member __.ValueBound = valueBoundEvent.Publish
1340+
13341341
//----------------------------------------------------------------------------
13351342
// ctrl-c handling
13361343
//----------------------------------------------------------------------------
@@ -2222,7 +2229,6 @@ type internal FsiInteractionProcessor
22222229
let fsiInteractiveChecker = FsiInteractiveChecker(legacyReferenceResolver, checker, tcConfig, istate.tcGlobals, istate.tcImports, istate.tcState)
22232230
fsiInteractiveChecker.ParseAndCheckInteraction(ctok, SourceText.ofString text)
22242231

2225-
22262232
//----------------------------------------------------------------------------
22272233
// Server mode:
22282234
//----------------------------------------------------------------------------
@@ -2630,6 +2636,9 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i
26302636

26312637
/// Event fires every time an assembly reference is added to the execution environment, e.g., via `#r`.
26322638
member __.AssemblyReferenceAdded = fsiDynamicCompiler.AssemblyReferenceAdded
2639+
2640+
/// Event fires when a root-level value is bound to an identifier, e.g., via `let x = ...`.
2641+
member __.ValueBound = fsiDynamicCompiler.ValueBound
26332642

26342643
/// Performs these steps:
26352644
/// - Load the dummy interaction, if any

src/fsharp/fsi/fsi.fsi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ type FsiEvaluationSession =
237237
/// Event fires every time an assembly reference is added to the execution environment, e.g., via `#r`.
238238
member AssemblyReferenceAdded : IEvent<string>
239239

240+
/// Event fires when a root-level value is bound to an identifier, e.g., via `let x = ...`.
241+
member ValueBound : IEvent<obj * System.Type * string>
242+
240243
/// Load the dummy interaction, load the initial files, and,
241244
/// if interacting, start the background thread to read the standard input.
242245
///

tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,49 @@ type InteractiveTests() =
122122
Assert.True(wasCancelled)
123123
Assert.LessOrEqual(sw.ElapsedMilliseconds, sleepTime)
124124
Assert.AreEqual(None, result)
125+
126+
[<Test>]
127+
member _.``Values bound at the root trigger an event``() =
128+
let mutable foundX = false
129+
let mutable foundY = false
130+
let mutable foundCount = 0
131+
use script = new FSharpScript()
132+
script.ValueBound
133+
|> Event.add (fun (value, typ, name) ->
134+
foundX <- foundX || (name = "x" && typ = typeof<int> && value :?> int = 1)
135+
foundY <- foundY || (name = "y" && typ = typeof<int> && value :?> int = 2)
136+
foundCount <- foundCount + 1)
137+
let code = @"
138+
let x = 1
139+
let y = 2
140+
"
141+
script.Eval(code) |> ignoreValue
142+
Assert.True(foundX)
143+
Assert.True(foundY)
144+
Assert.AreEqual(2, foundCount)
145+
146+
[<Test>]
147+
member _.``Values re-bound trigger an event``() =
148+
let mutable foundXCount = 0
149+
use script = new FSharpScript()
150+
script.ValueBound
151+
|> Event.add (fun (_value, typ, name) ->
152+
if name = "x" && typ = typeof<int> then foundXCount <- foundXCount + 1)
153+
script.Eval("let x = 1") |> ignoreValue
154+
script.Eval("let x = 2") |> ignoreValue
155+
Assert.AreEqual(2, foundXCount)
156+
157+
[<Test>]
158+
member _.``Nested let bindings don't trigger event``() =
159+
let mutable foundInner = false
160+
use script = new FSharpScript()
161+
script.ValueBound
162+
|> Event.add (fun (_value, _typ, name) ->
163+
foundInner <- foundInner || name = "inner")
164+
let code = @"
165+
let x =
166+
let inner = 1
167+
()
168+
"
169+
script.Eval(code) |> ignoreValue
170+
Assert.False(foundInner)

0 commit comments

Comments
 (0)