< Summary - FSharp.Interop.Dlr

Information
Class: FSharp.Interop.Dlr.DlrBuilder
Assembly: FSharp.Interop.Dlr
File(s): /home/runner/work/FSharp.Interop.Dlr/FSharp.Interop.Dlr/FSharp.Interop.Dlr/Builder.fs
Line coverage
100%
Covered lines: 7
Uncovered lines: 0
Coverable lines: 7
Total lines: 88
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
Delay(...)100%11100%
Run(...)100%11100%

File(s)

/home/runner/work/FSharp.Interop.Dlr/FSharp.Interop.Dlr/FSharp.Interop.Dlr/Builder.fs

#LineLine coverage
 1namespace FSharp.Interop.Dlr
 2
 3// 3513: "resumable code invocation" at `code.Invoke(&sm)` in Run, expected when defining a
 4// resumable builder (FSharp.Core's task builder suppresses it the same way).
 5#nowarn "3513"
 6
 7open System
 8open System.Diagnostics.CodeAnalysis
 9open System.Runtime.CompilerServices
 10open System.Runtime.InteropServices
 11open Microsoft.FSharp.Core.CompilerServices
 12open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers
 13
 14/// <summary>
 15/// Builder for <c>dlr { }</c>. The body is never executed as written: it is compiled as F#
 16/// resumable code into a struct state machine whose fields are the block's captured variables,
 17/// the block's quotation comes from the <c>[&lt;ReflectedDefinition&gt;]</c> on the function or
 18/// member containing it (or on an enclosing type or module), and it is compiled once into a
 19/// delegate whose DLR call sites are constants and whose input is that struct. Where the
 20/// compiler cannot build the state machine (Debug builds on the 10.0 compiler; the 8.0, 9.0 and 11.0 compilers build it
 21/// the same role.
 22/// </summary>
 23[<Sealed>]
 624type DlrBuilder() =
 25    /// <summary>Returns the body unevaluated, wrapped as resumable code; in the fallback path <c>Run</c> reads the clos
 26    /// The caller's file and line are here rather than on <c>Run</c>: compilers have treated
 27    /// caller-info arguments on <c>Delay</c> the same across versions, while on <c>Run</c>, the
 28    /// member holding the <c>if __useResumableCode</c> branches, they have broken Debug builds more
 29    /// than once (#126, #235). A block's outermost Delay is on the line the block starts on, and
 30    /// answers a probe (<c>DlrLocation</c>) with them.
 31    member inline _.Delay([<InlineIfLambda>] delayed: unit -> ResumableCode<'D, 'T>,
 32                          [<CallerFilePath; Optional; DefaultParameterValue("")>] file: string,
 33                          [<CallerLineNumber; Optional; DefaultParameterValue(0)>] line: int) : ResumableCode<'D, 'T> =
 80905734        ResumableCode<'D, 'T>(fun sm ->
 446435            if DlrLocation.Probing then
 446436                DlrLocation.Answer(file, line)
 446437                true
 80905738            else (delayed ()).Invoke(&sm))
 39
 40    // Return through Using are inlined at every call site in Debug and Release alike, so their
 41    // compiled methods are never called and are excluded from coverage. (Delay and Run are
 42    // called in Debug, so they stay.)
 43    [<ExcludeFromCodeCoverage>]
 44    member inline _.Return(value: 'T) : ResumableCode<DlrData<'T>, 'T> =
 45        ResumableCode<DlrData<'T>, 'T>(fun sm -> sm.Data.Result <- value; true)
 46
 47    [<ExcludeFromCodeCoverage>]
 48    member inline _.Zero() : ResumableCode<'D, unit> = ResumableCode.Zero()
 49
 50    [<ExcludeFromCodeCoverage>]
 51    member inline _.Combine(first: ResumableCode<'D, unit>, rest: ResumableCode<'D, 'T>) : ResumableCode<'D, 'T> =
 52        ResumableCode.Combine(first, rest)
 53
 54    [<ExcludeFromCodeCoverage>]
 55    member inline _.For(items: seq<'X>, [<InlineIfLambda>] body: 'X -> ResumableCode<'D, unit>) : ResumableCode<'D, unit
 56        ResumableCode.For(items, body)
 57
 58    [<ExcludeFromCodeCoverage>]
 59    member inline _.While([<InlineIfLambda>] guard: unit -> bool, body: ResumableCode<'D, unit>) : ResumableCode<'D, uni
 60        ResumableCode.While(guard, body)
 61
 62    [<ExcludeFromCodeCoverage>]
 63    member inline _.TryWith(body: ResumableCode<'D, 'T>, [<InlineIfLambda>] handler: exn -> ResumableCode<'D, 'T>) : Res
 64        ResumableCode.TryWith(body, handler)
 65
 66    [<ExcludeFromCodeCoverage>]
 67    member inline _.TryFinally(body: ResumableCode<'D, 'T>, [<InlineIfLambda>] compensation: unit -> unit) : ResumableCo
 68        ResumableCode.TryFinally(body, ResumableCode<'D, unit>(fun _ -> compensation (); true))
 69
 70    [<ExcludeFromCodeCoverage>]
 71    member inline _.Using(resource: 'R, [<InlineIfLambda>] body: 'R -> ResumableCode<'D, 'T>) : ResumableCode<'D, 'T> wh
 72        ResumableCode.Using(resource, body)
 73
 74    member inline this.Run(code: ResumableCode<DlrData<'T>, 'T>) : 'T =
 75        if __useResumableCode then
 76            // The compiler builds a struct per block: the captured variables are its fields, its
 77            // type is a JIT constant in Machine, and MoveNext (the body as written) is never
 78            // called, except as the probe for the block's file and line when it is first compiled.
 79            __stateMachine<DlrData<'T>, 'T>
 80                (MoveNextMethodImpl<DlrData<'T>>(fun sm -> __resumeAt sm.ResumptionPoint; code.Invoke(&sm) |> ignore))
 81                (SetStateMachineMethodImpl<DlrData<'T>>(fun _ _ -> ()))
 82                (AfterCode<DlrData<'T>, 'T>(fun sm -> DlrRun.Machine(this, &sm)))
 83        else
 80905984            DlrRun.Closure(this, code)
 85
 86[<AutoOpen>]
 87module Builder =
 88    let dlr = DlrBuilder()