Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/8.0.300.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@
* Reduce allocations in compiler checking via `ValueOption` usage ([PR #16323](https://github.com/dotnet/fsharp/pull/16323), [PR #16567](https://github.com/dotnet/fsharp/pull/16567))
* Reverted [#16348](https://github.com/dotnet/fsharp/pull/16348) `ThreadStatic` `CancellationToken` changes to improve test stability and prevent potential unwanted cancellations. ([PR #16536](https://github.com/dotnet/fsharp/pull/16536))
* Refactored parenthesization API. ([PR #16461])(https://github.com/dotnet/fsharp/pull/16461))
* Replaced `ThreadStatic` diagnostics globals with `AsyncLocal` for better stability of Transparent Compiler. ([PR #16602](https://github.com/dotnet/fsharp/pull/16602))
2 changes: 1 addition & 1 deletion src/Compiler/Driver/CompilerConfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ and IProjectReference =
abstract FileName: string

/// Evaluate raw contents of the assembly file generated by the project
abstract EvaluateRawContents: unit -> NodeCode<ProjectAssemblyDataResult>
abstract EvaluateRawContents: unit -> Async<ProjectAssemblyDataResult>

/// Get the logical timestamp that would be the timestamp of the assembly file generated by the project
///
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Driver/CompilerConfig.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ and IProjectReference =
/// Evaluate raw contents of the assembly file generated by the project.
/// 'None' may be returned if an in-memory view of the contents is, for some reason,
/// not available. In this case the on-disk view of the contents will be preferred.
abstract EvaluateRawContents: unit -> NodeCode<ProjectAssemblyDataResult>
abstract EvaluateRawContents: unit -> Async<ProjectAssemblyDataResult>

/// Get the logical timestamp that would be the timestamp of the assembly file generated by the project.
///
Expand Down
28 changes: 15 additions & 13 deletions src/Compiler/Driver/CompilerImports.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2158,14 +2158,14 @@ and [<Sealed>] TcImports
(
ctok,
r: AssemblyResolution
) : NodeCode<(_ * (unit -> AvailableImportedAssembly list)) option> =
node {
) : Async<(_ * (unit -> AvailableImportedAssembly list)) option> =
async {
CheckDisposed()
let m = r.originalReference.Range
let fileName = r.resolvedPath

let! contentsOpt =
node {
async {
match r.ProjectReference with
| Some ilb -> return! ilb.EvaluateRawContents()
| None -> return ProjectAssemblyDataResult.Unavailable true
Expand Down Expand Up @@ -2228,23 +2228,25 @@ and [<Sealed>] TcImports

// NOTE: When used in the Language Service this can cause the transitive checking of projects. Hence it must be cancellable.
member tcImports.RegisterAndImportReferencedAssemblies(ctok, nms: AssemblyResolution list) =
node {
async {
CheckDisposed()

let tcConfig = tcConfigP.Get ctok

let runMethod =
match tcConfig.parallelReferenceResolution with
| ParallelReferenceResolution.On -> NodeCode.Parallel
| ParallelReferenceResolution.Off -> NodeCode.Sequential
| ParallelReferenceResolution.On -> Async.Parallel
| ParallelReferenceResolution.Off -> Async.Sequential

let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger
let! results =
nms
|> List.map (fun nm ->
node {
async {
try
return! tcImports.TryRegisterAndPrepareToImportReferencedDll(ctok, nm)
with e ->
use _ = UseDiagnosticsLogger diagnosticsLogger
errorR (Error(FSComp.SR.buildProblemReadingAssembly (nm.resolvedPath, e.Message), nm.originalReference.Range))
return None
})
Expand Down Expand Up @@ -2282,7 +2284,7 @@ and [<Sealed>] TcImports
ReportWarnings warns

tcImports.RegisterAndImportReferencedAssemblies(ctok, res)
|> NodeCode.RunImmediateWithoutCancellation
|> Async.RunImmediateWithoutCancellation
|> ignore

true
Expand Down Expand Up @@ -2383,7 +2385,7 @@ and [<Sealed>] TcImports
// we dispose TcImports is because we need to dispose type providers, and type providers are never included in the framework DLL set.
// If a framework set ever includes type providers, you will not have to worry about explicitly calling Dispose as the Finalizer will handle it.
static member BuildFrameworkTcImports(tcConfigP: TcConfigProvider, frameworkDLLs, nonFrameworkDLLs) =
node {
async {
let ctok = CompilationThreadToken()
let tcConfig = tcConfigP.Get ctok

Expand Down Expand Up @@ -2460,7 +2462,7 @@ and [<Sealed>] TcImports
resolvedAssemblies |> List.choose tryFindEquivPrimaryAssembly

let! fslibCcu, fsharpCoreAssemblyScopeRef =
node {
async {
if tcConfig.compilingFSharpCore then
// When compiling FSharp.Core.dll, the fslibCcu reference to FSharp.Core.dll is a delayed ccu thunk fixed up during type checking
return CcuThunk.CreateDelayed getFSharpCoreLibraryName, ILScopeRef.Local
Expand Down Expand Up @@ -2553,7 +2555,7 @@ and [<Sealed>] TcImports
dependencyProvider
) =

node {
async {
let ctok = CompilationThreadToken()
let tcConfig = tcConfigP.Get ctok

Expand All @@ -2571,7 +2573,7 @@ and [<Sealed>] TcImports
}

static member BuildTcImports(tcConfigP: TcConfigProvider, dependencyProvider) =
node {
async {
let ctok = CompilationThreadToken()
let tcConfig = tcConfigP.Get ctok

Expand Down Expand Up @@ -2603,7 +2605,7 @@ let RequireReferences (ctok, tcImports: TcImports, tcEnv, thisAssemblyName, reso

let ccuinfos =
tcImports.RegisterAndImportReferencedAssemblies(ctok, resolutions)
|> NodeCode.RunImmediateWithoutCancellation
|> Async.RunImmediateWithoutCancellation

let asms =
ccuinfos
Expand Down
6 changes: 3 additions & 3 deletions src/Compiler/Driver/CompilerImports.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,14 @@ type TcImports =
member internal Base: TcImports option

static member BuildFrameworkTcImports:
TcConfigProvider * AssemblyResolution list * AssemblyResolution list -> NodeCode<TcGlobals * TcImports>
TcConfigProvider * AssemblyResolution list * AssemblyResolution list -> Async<TcGlobals * TcImports>

static member BuildNonFrameworkTcImports:
TcConfigProvider * TcImports * AssemblyResolution list * UnresolvedAssemblyReference list * DependencyProvider ->
NodeCode<TcImports>
Async<TcImports>

static member BuildTcImports:
tcConfigP: TcConfigProvider * dependencyProvider: DependencyProvider -> NodeCode<TcGlobals * TcImports>
tcConfigP: TcConfigProvider * dependencyProvider: DependencyProvider -> Async<TcGlobals * TcImports>

/// Process a group of #r in F# Interactive.
/// Adds the reference to the tcImports and add the ccu to the type checking environment.
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Driver/fsc.fs
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ let main1
// Import basic assemblies
let tcGlobals, frameworkTcImports =
TcImports.BuildFrameworkTcImports(foundationalTcConfigP, sysRes, otherRes)
|> NodeCode.RunImmediateWithoutCancellation
|> Async.RunImmediateWithoutCancellation

let ilSourceDocs =
[
Expand Down Expand Up @@ -663,7 +663,7 @@ let main1

let tcImports =
TcImports.BuildNonFrameworkTcImports(tcConfigP, frameworkTcImports, otherRes, knownUnresolved, dependencyProvider)
|> NodeCode.RunImmediateWithoutCancellation
|> Async.RunImmediateWithoutCancellation

// register tcImports to be disposed in future
disposables.Register tcImports
Expand Down
18 changes: 9 additions & 9 deletions src/Compiler/Facilities/AsyncMemoize.fs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ type internal MemoizeReply<'TValue> =
| New of CancellationToken
| Existing of Task<'TValue>

type internal MemoizeRequest<'TValue> = GetOrCompute of NodeCode<'TValue> * CancellationToken
type internal MemoizeRequest<'TValue> = GetOrCompute of Async<'TValue> * CancellationToken

[<DebuggerDisplay("{DebuggerDisplay}")>]
type internal Job<'TValue> =
| Running of TaskCompletionSource<'TValue> * CancellationTokenSource * NodeCode<'TValue> * DateTime * ResizeArray<DiagnosticsLogger>
| Running of TaskCompletionSource<'TValue> * CancellationTokenSource * Async<'TValue> * DateTime * ResizeArray<DiagnosticsLogger>
| Completed of 'TValue * (PhasedDiagnostic * FSharpDiagnosticSeverity) list
| Canceled of DateTime
| Failed of DateTime * exn // TODO: probably we don't need to keep this
Expand Down Expand Up @@ -358,7 +358,7 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T
DiagnosticsThreadStatics.DiagnosticsLogger <- cachingLogger

try
let! result = computation |> Async.AwaitNodeCode
let! result = computation
post (key, (JobCompleted(result, cachingLogger.CapturedDiagnostics)))
return ()
finally
Expand Down Expand Up @@ -481,14 +481,14 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T
Version = key.GetVersion()
}

node {
let! ct = NodeCode.CancellationToken
async {
let! ct = Async.CancellationToken

let callerDiagnosticLogger = DiagnosticsThreadStatics.DiagnosticsLogger

match!
processRequest post (key, GetOrCompute(computation, ct)) callerDiagnosticLogger
|> NodeCode.AwaitTask
|> Async.AwaitTask
with
| New internalCt ->

Expand All @@ -506,15 +506,15 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T
log (Started, key)

try
let! result = computation |> Async.AwaitNodeCode
let! result = computation
post (key, (JobCompleted(result, cachingLogger.CapturedDiagnostics)))
return result
finally
DiagnosticsThreadStatics.DiagnosticsLogger <- currentLogger
},
cancellationToken = linkedCtSource.Token
)
|> NodeCode.AwaitTask
|> Async.AwaitTask
with
| TaskCancelled ex ->
// TODO: do we need to do anything else here? Presumably it should be done by the registration on
Expand All @@ -530,7 +530,7 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T
post (key, (JobFailed(ex, cachingLogger.CapturedDiagnostics)))
return raise ex

| Existing job -> return! job |> NodeCode.AwaitTask
| Existing job -> return! job |> Async.AwaitTask

}

Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Facilities/AsyncMemoize.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T

member Clear: predicate: ('TKey -> bool) -> unit

member Get: key: ICacheKey<'TKey, 'TVersion> * computation: NodeCode<'TValue> -> NodeCode<'TValue>
member Get: key: ICacheKey<'TKey, 'TVersion> * computation: Async<'TValue> -> Async<'TValue>

member Get': key: 'TKey * computation: NodeCode<'TValue> -> NodeCode<'TValue>
member Get': key: 'TKey * computation: Async<'TValue> -> Async<'TValue>

member Event: IEvent<JobEvent * (string * 'TKey * 'TVersion)>

Expand Down
Loading