From d945d9cbbd9e705174b3ff5d97e616b30df4e2d5 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Fri, 18 Mar 2022 16:10:55 +0300 Subject: [PATCH] add GetCachedProjectOptions --- src/fsharp/InternalCollections.fs | 8 ++++++-- src/fsharp/InternalCollections.fsi | 7 ++++++- src/fsharp/service/service.fs | 15 +++++++++++++-- src/fsharp/service/service.fsi | 6 ++++++ ...mpilerService.SurfaceArea.netstandard.expected | 1 + 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/fsharp/InternalCollections.fs b/src/fsharp/InternalCollections.fs index a2c3b3ad65a..2f380e37b5e 100755 --- a/src/fsharp/InternalCollections.fs +++ b/src/fsharp/InternalCollections.fs @@ -142,7 +142,10 @@ type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct>(keepStro let keep = FilterAndHold(tok) AssignWithStrength(tok,keep) - + member al.Keys(tok) = + FilterAndHold(tok) |> List.map fst + + type internal MruCache<'Token, 'Key,'Value when 'Value : not struct>(keepStrongly, areSame, ?isStillValid : 'Key*'Value->bool, ?areSimilar, ?requiredToKeep, ?keepMax) = @@ -199,4 +202,5 @@ type internal MruCache<'Token, 'Key,'Value when 'Value : not struct>(keepStrongl member bc.Resize(tok, newKeepStrongly, ?newKeepMax) = cache.Resize(tok, newKeepStrongly, ?newKeepMax=newKeepMax) - + + member bc.Keys(tok) = cache.Keys(tok) diff --git a/src/fsharp/InternalCollections.fsi b/src/fsharp/InternalCollections.fsi index 3cd62bae5fa..72e829a18f3 100755 --- a/src/fsharp/InternalCollections.fsi +++ b/src/fsharp/InternalCollections.fsi @@ -38,7 +38,10 @@ type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct> = /// Resize member Resize : 'Token * newKeepStrongly: int * ?newKeepMax : int -> unit - + + /// Keys + member Keys : 'Token -> 'Key list + /// Simple priority caching for a small number of key/value associations. /// This cache may age-out results that have been Set by the caller. /// Because of this, the caller must be able to tolerate values @@ -84,3 +87,5 @@ type internal MruCache<'Token, 'Key,'Value when 'Value : not struct> = /// Resize member Resize : 'Token * newKeepStrongly: int * ?newKeepMax : int -> unit + /// Keys + member Keys : 'Token -> 'Key list diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs index 91537a49e3f..a55f4f3a910 100644 --- a/src/fsharp/service/service.fs +++ b/src/fsharp/service/service.fs @@ -223,6 +223,8 @@ type BackgroundCompiler( let fileChecked = Event() let projectChecked = Event() + let getScriptProjectFileName scriptFileName = scriptFileName + ".fsproj" + // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.backgroundCompiler.scriptClosureCache /// Information about the derived script closure. let scriptClosureCache = @@ -908,7 +910,7 @@ type BackgroundCompiler( let options = { - ProjectFileName = filename + ".fsproj" // Make a name that is unique in this directory. + ProjectFileName = getScriptProjectFileName filename // Make a name that is unique in this directory. ProjectId = None SourceFiles = loadClosure.SourceFiles |> List.map fst |> List.toArray OtherOptions = otherFlags @@ -925,7 +927,13 @@ type BackgroundCompiler( return options, (diags @ errors.Diagnostics) } |> Cancellable.toAsync - + + member _.GetCachedProjectOptions(projectOrScriptFileName, isScript) = + let projectFileName = + if isScript then getScriptProjectFileName projectOrScriptFileName + else projectOrScriptFileName + incrementalBuildersCache.Keys(AnyCallerThread) |> List.filter (fun x -> x.ProjectFileName = projectFileName) + member bc.InvalidateConfiguration(options: FSharpProjectOptions, userOpName) = if incrementalBuildersCache.ContainsSimilarKey (AnyCallerThread, options) then let _ = createBuilderNode (options, userOpName, CancellationToken.None) @@ -1078,6 +1086,9 @@ type FSharpChecker(legacyReferenceResolver, let argv = List.ofArray options.OtherOptions ic.GetParsingOptionsFromCommandLineArgs(sourceFiles, argv, options.UseScriptResolutionRules) + member _.GetCachedProjectOptions(projectOrScriptFileName, isScript) = + backgroundCompiler.GetCachedProjectOptions(projectOrScriptFileName, isScript) + member ic.ParseFile(filename, sourceText, options, ?cache, ?userOpName: string) = let cache = defaultArg cache true let userOpName = defaultArg userOpName "Unknown" diff --git a/src/fsharp/service/service.fsi b/src/fsharp/service/service.fsi index c27fc86ca3f..80eab80b484 100644 --- a/src/fsharp/service/service.fsi +++ b/src/fsharp/service/service.fsi @@ -184,6 +184,12 @@ type public FSharpChecker = ?userOpName: string -> Async + /// Get the list of FSharpProjectOptions for the project/script if they exist in the FCS cache. + /// + /// The project or script filename. + /// Is the passed the path to the script file. + member GetCachedProjectOptions: projectOrScriptFileName: string * isScript: bool -> FSharpProjectOptions list + /// Get the FSharpProjectOptions implied by a set of command line arguments. /// /// Used to differentiate between projects and for the base directory of the project. diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected index 6384964188c..0943d1e1cf4 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected @@ -2015,6 +2015,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 ActualCheckFileCount FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 ActualParseFileCount FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 get_ActualCheckFileCount() FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 get_ActualParseFileCount() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] GetCachedProjectOptions(System.String, Boolean) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer] CheckFileInProject(FSharp.Compiler.CodeAnalysis.FSharpParseFileResults, System.String, Int32, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults] ParseAndCheckProject(FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults] GetBackgroundParseResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])