@@ -401,25 +401,23 @@ type ConcurrentCapturingDiagnosticsLogger(nm, ?eagerFormat) =
401401 errors |> Array.iter diagnosticsLogger.DiagnosticSink
402402
403403/// Type holds thread-static globals for use by the compiler.
404- type DiagnosticsThreadStatics =
405- static let buildPhase = new AsyncLocal< BuildPhase>()
406- static let diagnosticsLogger = new AsyncLocal< DiagnosticsLogger>()
404+ type DiagnosticsAsyncState =
405+ static let buildPhase = new AsyncLocal< BuildPhase voption >()
406+ static let diagnosticsLogger = new AsyncLocal< DiagnosticsLogger voption >()
407407
408- static let EnsureCreated ( h : AsyncLocal < _ >) d =
409- if box h.Value |> isNull then
410- h.Value <- d
408+ static let getOrCreate ( holder : AsyncLocal < _ >) defaultValue =
409+ holder.Value
410+ |> ValueOption.defaultWith ( fun () ->
411+ holder.Value <- ValueSome defaultValue
412+ defaultValue)
411413
412414 static member BuildPhase
413- with get () =
414- EnsureCreated buildPhase BuildPhase.DefaultPhase
415- buildPhase.Value
416- and set v = buildPhase.Value <- v
415+ with get () = getOrCreate buildPhase BuildPhase.DefaultPhase
416+ and set v = buildPhase.Value <- ValueSome v
417417
418418 static member DiagnosticsLogger
419- with get () =
420- EnsureCreated diagnosticsLogger AssertFalseDiagnosticsLogger
421- diagnosticsLogger.Value
422- and set v = diagnosticsLogger.Value <- v
419+ with get () = getOrCreate diagnosticsLogger AssertFalseDiagnosticsLogger
420+ and set v = diagnosticsLogger.Value <- ValueSome v
423421
424422[<AutoOpen>]
425423module DiagnosticsLoggerExtensions =
@@ -461,7 +459,7 @@ module DiagnosticsLoggerExtensions =
461459 | ReportedError _ ->
462460 PreserveStackTrace exn
463461 raise exn
464- | _ -> x.DiagnosticSink( PhasedDiagnostic.Create( exn, DiagnosticsThreadStatics .BuildPhase), severity)
462+ | _ -> x.DiagnosticSink( PhasedDiagnostic.Create( exn, DiagnosticsAsyncState .BuildPhase), severity)
465463
466464 member x.ErrorR exn =
467465 x.EmitDiagnostic( exn, FSharpDiagnosticSeverity.Error)
@@ -521,45 +519,32 @@ module DiagnosticsLoggerExtensions =
521519
522520/// NOTE: The change will be undone when the returned "unwind" object disposes
523521let UseBuildPhase ( phase : BuildPhase ) =
524- let oldBuildPhase = DiagnosticsThreadStatics .BuildPhase
525- DiagnosticsThreadStatics .BuildPhase <- phase
522+ let oldBuildPhase = DiagnosticsAsyncState .BuildPhase
523+ DiagnosticsAsyncState .BuildPhase <- phase
526524
527525 { new IDisposable with
528526 member x.Dispose () =
529- DiagnosticsThreadStatics .BuildPhase <- oldBuildPhase
527+ DiagnosticsAsyncState .BuildPhase <- oldBuildPhase
530528 }
531529
532530/// NOTE: The change will be undone when the returned "unwind" object disposes
533531let UseTransformedDiagnosticsLogger ( transformer : DiagnosticsLogger -> #DiagnosticsLogger ) =
534- let oldLogger = DiagnosticsThreadStatics .DiagnosticsLogger
535- DiagnosticsThreadStatics .DiagnosticsLogger <- transformer oldLogger
532+ let oldLogger = DiagnosticsAsyncState .DiagnosticsLogger
533+ DiagnosticsAsyncState .DiagnosticsLogger <- transformer oldLogger
536534
537535 { new IDisposable with
538536 member _.Dispose () =
539- DiagnosticsThreadStatics .DiagnosticsLogger <- oldLogger
537+ DiagnosticsAsyncState .DiagnosticsLogger <- oldLogger
540538 }
541539
542540let UseDiagnosticsLogger newLogger =
543541 UseTransformedDiagnosticsLogger( fun _ -> newLogger)
544542
545- let CaptureDiagnosticsConcurrently () =
546- let newLogger =
547- ConcurrentCapturingDiagnosticsLogger( " CaptureDiagnosticsConcurrently" )
548-
549- let oldLogger = DiagnosticsThreadStatics.DiagnosticsLogger
550- DiagnosticsThreadStatics.DiagnosticsLogger <- newLogger
551-
552- { new IDisposable with
553- member _.Dispose () =
554- newLogger.CommitDelayedDiagnostics oldLogger
555- DiagnosticsThreadStatics.DiagnosticsLogger <- oldLogger
556- }
557-
558543let SetThreadBuildPhaseNoUnwind ( phase : BuildPhase ) =
559- DiagnosticsThreadStatics .BuildPhase <- phase
544+ DiagnosticsAsyncState .BuildPhase <- phase
560545
561546let SetThreadDiagnosticsLoggerNoUnwind diagnosticsLogger =
562- DiagnosticsThreadStatics .DiagnosticsLogger <- diagnosticsLogger
547+ DiagnosticsAsyncState .DiagnosticsLogger <- diagnosticsLogger
563548
564549/// This represents the thread-local state established as each task function runs as part of the build.
565550///
@@ -577,30 +562,43 @@ type CompilationGlobalsScope(diagnosticsLogger: DiagnosticsLogger, buildPhase: B
577562 unwindBP.Dispose()
578563 unwindEL.Dispose()
579564
565+ type CaptureDiagnosticsConcurrently ( target ) =
566+ let loggers = System.Collections.Concurrent.ConcurrentQueue()
567+
568+ member _.LoggerForTask : DiagnosticsLogger =
569+ let logger = CapturingDiagnosticsLogger( " One of parallel computations" )
570+ loggers.Enqueue logger
571+ logger
572+
573+ interface IDisposable with
574+ member _.Dispose () =
575+ for logger in loggers do
576+ logger.CommitDelayedDiagnostics target
577+
580578// Global functions are still used by parser and TAST ops.
581579
582580/// Raises an exception with error recovery and returns unit.
583581let errorR exn =
584- DiagnosticsThreadStatics .DiagnosticsLogger.ErrorR exn
582+ DiagnosticsAsyncState .DiagnosticsLogger.ErrorR exn
585583
586584/// Raises a warning with error recovery and returns unit.
587585let warning exn =
588- DiagnosticsThreadStatics .DiagnosticsLogger.Warning exn
586+ DiagnosticsAsyncState .DiagnosticsLogger.Warning exn
589587
590588/// Raises a warning with error recovery and returns unit.
591589let informationalWarning exn =
592- DiagnosticsThreadStatics .DiagnosticsLogger.InformationalWarning exn
590+ DiagnosticsAsyncState .DiagnosticsLogger.InformationalWarning exn
593591
594592/// Raises a special exception and returns 'T - can be caught later at an errorRecovery point.
595593let error exn =
596- DiagnosticsThreadStatics .DiagnosticsLogger.Error exn
594+ DiagnosticsAsyncState .DiagnosticsLogger.Error exn
597595
598596/// Simulates an error. For test purposes only.
599597let simulateError ( diagnostic : PhasedDiagnostic ) =
600- DiagnosticsThreadStatics .DiagnosticsLogger.SimulateError diagnostic
598+ DiagnosticsAsyncState .DiagnosticsLogger.SimulateError diagnostic
601599
602600let diagnosticSink ( diagnostic , severity ) =
603- DiagnosticsThreadStatics .DiagnosticsLogger.DiagnosticSink( diagnostic, severity)
601+ DiagnosticsAsyncState .DiagnosticsLogger.DiagnosticSink( diagnostic, severity)
604602
605603let errorSink diagnostic =
606604 diagnosticSink ( diagnostic, FSharpDiagnosticSeverity.Error)
@@ -609,13 +607,13 @@ let warnSink diagnostic =
609607 diagnosticSink ( diagnostic, FSharpDiagnosticSeverity.Warning)
610608
611609let errorRecovery exn m =
612- DiagnosticsThreadStatics .DiagnosticsLogger.ErrorRecovery exn m
610+ DiagnosticsAsyncState .DiagnosticsLogger.ErrorRecovery exn m
613611
614612let stopProcessingRecovery exn m =
615- DiagnosticsThreadStatics .DiagnosticsLogger.StopProcessingRecovery exn m
613+ DiagnosticsAsyncState .DiagnosticsLogger.StopProcessingRecovery exn m
616614
617615let errorRecoveryNoRange exn =
618- DiagnosticsThreadStatics .DiagnosticsLogger.ErrorRecoveryNoRange exn
616+ DiagnosticsAsyncState .DiagnosticsLogger.ErrorRecoveryNoRange exn
619617
620618let deprecatedWithError s m = errorR ( Deprecated( s, m))
621619
@@ -634,7 +632,7 @@ let mlCompatError s m =
634632
635633[<DebuggerStepThrough>]
636634let suppressErrorReporting f =
637- let diagnosticsLogger = DiagnosticsThreadStatics .DiagnosticsLogger
635+ let diagnosticsLogger = DiagnosticsAsyncState .DiagnosticsLogger
638636
639637 try
640638 let diagnosticsLogger =
0 commit comments