diff --git a/src/FsAutoComplete.Core/AdaptiveExtensions.fs b/src/FsAutoComplete.Core/AdaptiveExtensions.fs index a50f02374..aad397d08 100644 --- a/src/FsAutoComplete.Core/AdaptiveExtensions.fs +++ b/src/FsAutoComplete.Core/AdaptiveExtensions.fs @@ -27,9 +27,9 @@ module AdaptiveExtensions = member cts.TryDispose() = // try - if not <| isNull cts then - cts.Dispose() - // with _ -> () + if not <| isNull cts then + cts.Dispose() + // with _ -> () type TaskCompletionSource<'a> with @@ -37,28 +37,15 @@ module AdaptiveExtensions = /// https://github.com/dotnet/runtime/issues/47998 member tcs.TrySetFromTask(real: Task<'a>) = - real.ContinueWith(fun (task : Task<_>) -> + real.ContinueWith(fun (task: Task<_>) -> match task.Status with | TaskStatus.RanToCompletion -> tcs.TrySetResult task.Result |> ignore - | TaskStatus.Canceled -> tcs.TrySetCanceled(TaskCanceledException(task).CancellationToken) |> ignore + | TaskStatus.Canceled -> + tcs.TrySetCanceled(TaskCanceledException(task).CancellationToken) + |> ignore | TaskStatus.Faulted -> - logger.error( - Log.setMessage "Error in TrySetFromTask with {count}" - >> Log.addExn task.Exception.InnerException - >> Log.addContext "count" task.Exception.InnerExceptions.Count - ) - logger.warn( - Log.setMessage "task.Exception.StackTrace {trace}" - >> Log.addContext "trace" task.Exception.StackTrace - ) - logger.warn( - Log.setMessage "task.Exception.StackTrace {trace}" - >> Log.addContext "trace" task.Exception.InnerException.StackTrace - ) - // if task.Exception.StackTrace = null then tcs.TrySetException(task.Exception.InnerExceptions) |> ignore - // else - // tcs.TrySetException(task.Exception) |> ignore + | _ -> ()) |> ignore @@ -416,9 +403,9 @@ and AdaptiveCancellableTask<'a>(cancel: unit -> unit, real: Task<'a>) = if real.IsCompleted then real else - cachedTcs <- new TaskCompletionSource<'a>() - cachedTcs.TrySetFromTask real - cachedTcs.Task + cachedTcs <- new TaskCompletionSource<'a>() + cachedTcs.TrySetFromTask real + cachedTcs.Task cached <- match cached with @@ -434,12 +421,12 @@ and AdaptiveCancellableTask<'a>(cancel: unit -> unit, real: Task<'a>) = cached /// Will run the cancel function passed into the constructor and set the output Task to cancelled state. - member x.Cancel(cancellationToken : CancellationToken) = + member x.Cancel(cancellationToken: CancellationToken) = lock x (fun () -> cancel () + if not <| isNull cachedTcs then - cachedTcs.TrySetCanceled(cancellationToken) |> ignore - ) + cachedTcs.TrySetCanceled(cancellationToken) |> ignore) /// The output of the passed in task to the constructor. /// @@ -684,13 +671,11 @@ module AsyncAVal = member x.Compute t = if x.OutOfDate || Option.isNone cache then let ref = - RefCountingTaskCreator( - fun ct -> task { + RefCountingTaskCreator(fun ct -> + task { let v = input.GetValue t - use _s = - ct.Register(fun () -> - v.Cancel(ct)) + use _s = ct.Register(fun () -> v.Cancel(ct)) let! i = v.Task @@ -700,8 +685,7 @@ module AsyncAVal = let! b = mapping i ct dataCache <- ValueSome(struct (i, b)) return b - } - ) + }) cache <- Some ref ref.New() @@ -736,8 +720,8 @@ module AsyncAVal = member x.Compute t = if x.OutOfDate || Option.isNone cache then let ref = - RefCountingTaskCreator( - fun ct -> task { + RefCountingTaskCreator(fun ct -> + task { let ta = ca.GetValue t let tb = cb.GetValue t @@ -755,8 +739,7 @@ module AsyncAVal = let! vc = mapping ia ib ct dataCache <- ValueSome(struct (ia, ib, vc)) return vc - } - ) + }) cache <- Some ref ref.New() @@ -790,12 +773,10 @@ module AsyncAVal = if x.OutOfDate then if Interlocked.Exchange(&inputChanged, 0) = 1 || Option.isNone cache then let outerTask = - RefCountingTaskCreator( - fun ct -> task { + RefCountingTaskCreator(fun ct -> + task { let v = value.GetValue t - use _s = - ct.Register(fun () -> - v.Cancel(ct)) + use _s = ct.Register(fun () -> v.Cancel(ct)) let! i = v.Task @@ -806,22 +787,19 @@ module AsyncAVal = outerDataCache <- Some(i, inner) return inner - } - ) + }) cache <- Some outerTask let outerTask = cache.Value let ref = - RefCountingTaskCreator( - fun ct -> task { + RefCountingTaskCreator(fun ct -> + task { let inner = outerTask.New() - use _s = - ct.Register(fun () -> - inner.Cancel(ct)) + use _s = ct.Register(fun () -> inner.Cancel(ct)) let! inner = inner.Task @@ -836,8 +814,7 @@ module AsyncAVal = return! innerTask.Task - } - ) + }) innerCache <- Some ref diff --git a/src/FsAutoComplete.Core/CompilerServiceInterface.fs b/src/FsAutoComplete.Core/CompilerServiceInterface.fs index 512876b4f..fe81dece9 100644 --- a/src/FsAutoComplete.Core/CompilerServiceInterface.fs +++ b/src/FsAutoComplete.Core/CompilerServiceInterface.fs @@ -318,26 +318,19 @@ type FSharpCompilerServiceChecker(hasAnalyzers, typecheckCacheSize, parallelRefe | (true, v) -> Some v | _ -> None - member _.TryGetRecentCheckResultsForFile - ( - file: string, - snapshot: FSharpProjectSnapshot - ) = - let opName = sprintf "TryGetRecentCheckResultsForFile - %A" file + member _.TryGetRecentCheckResultsForFile(file: string, snapshot: FSharpProjectSnapshot) = + let opName = sprintf "TryGetRecentCheckResultsForFile - %A" file + + checkerLogger.info (Log.setMessage "{opName} - {hash}" >> Log.addContextDestructured "opName" opName) + checker.TryGetRecentCheckResultsForFile(UMX.untag file, snapshot, opName) + |> Option.map (fun (pr, cr) -> checkerLogger.info ( - Log.setMessage "{opName} - {hash}" + Log.setMessage "{opName} - got results - {version}" >> Log.addContextDestructured "opName" opName ) - checker.TryGetRecentCheckResultsForFile(UMX.untag file, snapshot, opName) - |> Option.map (fun (pr, cr) -> - checkerLogger.info ( - Log.setMessage "{opName} - got results - {version}" - >> Log.addContextDestructured "opName" opName - ) - - ParseAndCheckResults(pr, cr, entityCache)) + ParseAndCheckResults(pr, cr, entityCache)) member _.GetUsesOfSymbol @@ -370,34 +363,34 @@ type FSharpCompilerServiceChecker(hasAnalyzers, typecheckCacheSize, parallelRefe return res |> Array.concat } - member x.FindReferencesForSymbolInFile(file : string, project: FSharpProjectSnapshot, symbol) = + member x.FindReferencesForSymbolInFile(file: string, project: FSharpProjectSnapshot, symbol) = async { checkerLogger.info ( Log.setMessage "FindReferencesForSymbolInFile - {file} - {projectFile}" >> Log.addContextDestructured "file" file >> Log.addContextDestructured "projectFile" project.ProjectFileName ) + let file = UMX.untag file - // let file = - // file.Substring(0, 1).ToUpper() + file.Substring(1) try - // let! _ = checker.ParseAndCheckFileInProject(file, project) let! results = checker.FindBackgroundReferencesInFile(file, project, symbol, userOpName = "find references") checkerLogger.info ( Log.setMessage "FindReferencesForSymbolInFile - {file} - {projectFile} - {results}" >> Log.addContextDestructured "file" file - >> Log.addContextDestructured "projectFile" project.ProjectFileName + >> Log.addContextDestructured "projectFile" project.ProjectFileName >> Log.addContextDestructured "results" results ) + return results with e -> checkerLogger.error ( Log.setMessage "FindReferencesForSymbolInFile - {file} - {projectFile}" - >> Log.addContextDestructured "projectFile" project.ProjectFileName + >> Log.addContextDestructured "projectFile" project.ProjectFileName >> Log.addContextDestructured "file" file >> Log.addExn e ) + return [||] } diff --git a/src/FsAutoComplete.Core/Utils.fs b/src/FsAutoComplete.Core/Utils.fs index e8573de8c..70346bcc7 100644 --- a/src/FsAutoComplete.Core/Utils.fs +++ b/src/FsAutoComplete.Core/Utils.fs @@ -67,6 +67,7 @@ module Seq = module ProcessHelper = open IcedTasks + let WaitForExitAsync (p: Process) = asyncEx { let tcs = TaskCompletionSource() diff --git a/src/FsAutoComplete/LspServers/AdaptiveServerState.fs b/src/FsAutoComplete/LspServers/AdaptiveServerState.fs index 0aca3e75f..04b85334c 100644 --- a/src/FsAutoComplete/LspServers/AdaptiveServerState.fs +++ b/src/FsAutoComplete/LspServers/AdaptiveServerState.fs @@ -96,7 +96,9 @@ type FindFirstProject() = |> Seq.sortBy (fun p -> p.ProjectFileName) |> Seq.tryFind (fun p -> p.SourceFilesTagged |> Array.exists (fun f -> f = sourceFile)) |> Result.ofOption (fun () -> - let allProjects = String.join ", " (projects |> Seq.map (fun p -> p.ProjectFileName)) + let allProjects = + String.join ", " (projects |> Seq.map (fun p -> p.ProjectFileName)) + $"Couldn't find a corresponding project for {sourceFile}. \n Projects include {allProjects}. \nHave the projects loaded yet or have you tried restoring your project/solution?") @@ -1024,8 +1026,7 @@ type AdaptiveState(lspClient: FSharpLspClient, sourceTextFactory: ISourceTextFac let! projects = // need to bind to a single value to keep the threadpool from being exhausted as LoadingProjects can be a long running operation // and when other adaptive values await on this, the scheduler won't block those other tasks - loadProjects loader binlogConfig projects - |> AMap.toAVal + loadProjects loader binlogConfig projects |> AMap.toAVal and! checker = checker checker.ClearCaches() @@ -1079,11 +1080,7 @@ type AdaptiveState(lspClient: FSharpLspClient, sourceTextFactory: ISourceTextFac // |> Observable.subscribe (fun _ -> forceLoadProjects () |> ignore>) // |> disposables.Add - let AMapReKeyMany f map = - map - |> AMap.toASet - |> ASet.collect f - |> AMap.ofASet + let AMapReKeyMany f map = map |> AMap.toASet |> ASet.collect f |> AMap.ofASet let sourceFileToProjectOptions = asyncAVal { @@ -1091,11 +1088,7 @@ type AdaptiveState(lspClient: FSharpLspClient, sourceTextFactory: ISourceTextFac let sourceFileToProjectOptions = loadedProjects - |> AMapReKeyMany(fun (_,v) -> - v.SourceFilesTagged - |> ASet.ofArray - |> ASet.map(fun source -> source, v) - ) + |> AMapReKeyMany(fun (_, v) -> v.SourceFilesTagged |> ASet.ofArray |> ASet.map (fun source -> source, v)) |> AMap.map' HashSet.toList return sourceFileToProjectOptions @@ -1477,13 +1470,12 @@ type AdaptiveState(lspClient: FSharpLspClient, sourceTextFactory: ISourceTextFac = asyncEx { let tags = - [ - SemanticConventions.fsac_sourceCodePath, box (UMX.untag file.Source.FileName) + [ SemanticConventions.fsac_sourceCodePath, box (UMX.untag file.Source.FileName) SemanticConventions.projectFilePath, box (options.ProjectFileName) "source.text", box (file.Source.String) "source.version", box (file.Version) - ] + ] use _ = fsacActivitySource.StartActivityForType(thisType, tags = tags) @@ -2185,7 +2177,9 @@ type AdaptiveState(lspClient: FSharpLspClient, sourceTextFactory: ISourceTextFac let dependentProjectsAndSourceFiles = dependentProjects - |> List.collect (fun (snap) -> snap.SourceFiles |> List.map (fun sourceFile -> snap, Utils.normalizePath sourceFile.FileName)) + |> List.collect (fun (snap) -> + snap.SourceFiles + |> List.map (fun sourceFile -> snap, Utils.normalizePath sourceFile.FileName)) |> List.toArray let mutable checksCompleted = 0 @@ -2203,6 +2197,7 @@ type AdaptiveState(lspClient: FSharpLspClient, sourceTextFactory: ISourceTextFac Array.concat [| dependentFiles; dependentProjectsAndSourceFiles |] |> Array.filter (fun (_, file) -> let file = UMX.untag file + file.Contains "AssemblyInfo.fs" |> not && file.Contains "AssemblyAttributes.fs" |> not) diff --git a/src/FsAutoComplete/LspServers/ProjectWorkspace.fs b/src/FsAutoComplete/LspServers/ProjectWorkspace.fs index 2790051c8..f2c477fb8 100644 --- a/src/FsAutoComplete/LspServers/ProjectWorkspace.fs +++ b/src/FsAutoComplete/LspServers/ProjectWorkspace.fs @@ -119,7 +119,10 @@ module Snapshots = unresolvedReferences originalLoadReferences - let private createFSharpFileSnapshotOnDisk (sourceTextFactory: aval) (sourceFilePath: string) = + let private createFSharpFileSnapshotOnDisk + (sourceTextFactory: aval) + (sourceFilePath: string) + = aval { let file = UMX.untag sourceFilePath let! writeTime = AdaptiveFile.GetLastWriteTimeUtc file @@ -236,8 +239,7 @@ module Snapshots = | None -> return! createFSharpFileSnapshotOnDisk sourceTextFactory sourcePath }) - let references = - p.OtherOptions |> List.filter (fun x -> x.StartsWith("-r:")) + let references = p.OtherOptions |> List.filter (fun x -> x.StartsWith("-r:")) let otherOptions = p.OtherOptions |> ASet.ofList |> ASet.map (AVal.constant) @@ -292,7 +294,5 @@ module Snapshots = let optionsToSnapshot = optionsToSnapshot cachedSnapshots inMemorySourceFiles sourceTextFactory mapReferences - ps - |> HashMap.map (fun _ v -> (v, optionsToSnapshot v)) - ) + ps |> HashMap.map (fun _ v -> (v, optionsToSnapshot v))) |> AMap.ofAVal