diff --git a/src/fsharp/Microsoft.DotNet.DependencyManager/DependencyProvider.fs b/src/fsharp/Microsoft.DotNet.DependencyManager/DependencyProvider.fs index 2146c10b7509e7dad65a0df7232cc25f31746841..c3c7046ef29ca58430cb36353c99447d400cc25d 100644 --- a/src/fsharp/Microsoft.DotNet.DependencyManager/DependencyProvider.fs +++ b/src/fsharp/Microsoft.DotNet.DependencyManager/DependencyProvider.fs @@ -8,6 +8,7 @@ open System.Reflection open System.Runtime.InteropServices open Internal.Utilities.FSharpEnvironment open Microsoft.FSharp.Reflection +open System.Collections.Concurrent [] module ReflectionHelper = @@ -88,19 +89,19 @@ type IResolveDependenciesResult = abstract Success: bool /// The resolution output log - abstract StdOut: string array + abstract StdOut: string[] /// The resolution error log (* process stderror *) - abstract StdError: string array + abstract StdError: string[] /// The resolution paths - abstract Resolutions: string seq + abstract Resolutions: seq /// The source code file paths - abstract SourceFiles: string seq + abstract SourceFiles: seq /// The roots to package directories - abstract Roots: string seq + abstract Roots: seq [] @@ -326,6 +327,8 @@ type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativePr None managers + let cache = ConcurrentDictionary<_,IResolveDependenciesResult>(HashIdentity.Structural) + /// Returns a formatted error message for the host to presentconstruct with just nativeProbing handler new (nativeProbingRoots: NativeResolutionProbe) = new DependencyProvider(Unchecked.defaultof, nativeProbingRoots) @@ -390,20 +393,24 @@ type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativePr []implicitIncludeDir: string, []mainScriptName: string, []fileName: string): IResolveDependenciesResult = + + let key = (packageManager.Key, scriptExt, Seq.toArray packageManagerTextLines, executionTfm, executionRid, implicitIncludeDir, mainScriptName, fileName) - try - let executionRid = - if isNull executionRid then - RidHelpers.platformRid - else - executionRid - packageManager.ResolveDependencies(implicitIncludeDir, mainScriptName, fileName, scriptExt, packageManagerTextLines, executionTfm, executionRid) - - with e -> - let e = stripTieWrapper e - let err, msg = (DependencyManager.SR.packageManagerError(e.Message)) - reportError.Invoke(ErrorReportType.Error, err, msg) - ReflectionDependencyManagerProvider.MakeResultFromFields(false, arrEmpty, arrEmpty, seqEmpty, seqEmpty, seqEmpty) + cache.GetOrAdd(key, System.Func<_,_>(fun _ -> + try + let executionRid = + if isNull executionRid then + RidHelpers.platformRid + else + executionRid + packageManager.ResolveDependencies(implicitIncludeDir, mainScriptName, fileName, scriptExt, packageManagerTextLines, executionTfm, executionRid) + + with e -> + let e = stripTieWrapper e + let err, msg = (DependencyManager.SR.packageManagerError(e.Message)) + reportError.Invoke(ErrorReportType.Error, err, msg) + ReflectionDependencyManagerProvider.MakeResultFromFields(false, arrEmpty, arrEmpty, seqEmpty, seqEmpty, seqEmpty) + )) interface IDisposable with diff --git a/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs b/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs index 77d349e091e82fde58311c6e1c48d5bfd4545423..916ad1e2f2920efbfcbd6af1f5280a426011b345 100644 --- a/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs +++ b/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs @@ -158,7 +158,7 @@ type internal FSharpClassificationService asyncMaybe { use _logBlock = Logger.LogBlock(LogEditorFunctionId.Classification_Semantic) - let! _, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken) + let! _, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) // If we are trying to get semantic classification for a document that is not open, get the results from the background and cache it. diff --git a/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs b/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs index 902d32357f0482a4819c7a26b151a4a9e86f66b1..5810202d7af579fcfea4ca13ccfa575567c40b15 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs @@ -96,7 +96,7 @@ type internal FSharpAddOpenCodeFixProvider override __.RegisterCodeFixesAsync context : Task = asyncMaybe { let document = context.Document - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName) let! sourceText = context.Document.GetTextAsync(context.CancellationToken) let! _, parsedInput, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName = userOpName) let line = sourceText.Lines.GetLineFromPosition(context.Span.End) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs b/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs index d50fce766fa658d0a4c51c679d4a3939a3f8e2be..4f995284b90a6bdac94a746ebb4af48a29b3b1ea 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs @@ -138,7 +138,7 @@ type internal FSharpImplementInterfaceCodeFixProvider override __.RegisterCodeFixesAsync context : Task = asyncMaybe { - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(context.Document, context.CancellationToken) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(context.Document, context.CancellationToken, userOpName) let cancellationToken = context.CancellationToken let! sourceText = context.Document.GetTextAsync(cancellationToken) let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(context.Document, projectOptions, sourceText = sourceText, userOpName = userOpName) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs b/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs index 8b659aafb32c5504b697e8caff6ad95f59cec9d1..9f9d81cb9b99301a34d64abcc109bc4d5f004a50 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs @@ -22,6 +22,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider projectInfoManager: FSharpProjectOptionsManager ) = inherit CodeFixProvider() + let userOpName = "FSharpRemoveUnusedOpensCodeFixProvider" let fixableDiagnosticIds = [FSharpIDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId] let createCodeFix (title: string, context: CodeFixContext) = @@ -32,7 +33,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider let document = context.Document let! sourceText = document.GetTextAsync() let checker = checkerProvider.Checker - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) + let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName) let! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document, projectOptions, checker) let changes = unusedOpens diff --git a/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs b/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs index 67379326323bd728e064e83fc7e7817838995adc..d4f564f75f364f9d773b74815cf01f7e54910e07 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs @@ -57,7 +57,7 @@ type internal FSharpRenameUnusedValueCodeFixProvider // We have to use the additional check for backtickes because `IsOperatorOrBacktickedName` operates on display names // where backtickes are replaced with parens. if not (PrettyNaming.IsOperatorOrBacktickedName ident) && not (ident.StartsWith "``") then - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName) let! _, _, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName=userOpName) let m = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText) let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs b/vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs index 969cfb55a16e6687f17fb51589ced692f046cf1a..628508e76b6775105fca41e4fc9a0d8b6a24cdf7 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs @@ -33,7 +33,7 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider do! Option.guard settings.CodeFixes.SuggestNamesForErrors let document = context.Document - let! _, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) + let! _, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName) let! parseFileResults, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, userOpName=userOpName) // This is all needed to get a declaration list diff --git a/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs b/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs index 668606afa208d647683af004d173364c6094960e..dd2b8271dc8bdfb70449f862c713aebabbefc522 100644 --- a/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs +++ b/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs @@ -52,6 +52,7 @@ type internal FSharpCodeLensService ) as self = let lineLens = codeLens + let userOpName = "FSharpCodeLensService" let visit pos parseTree = AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with @@ -154,7 +155,7 @@ type internal FSharpCodeLensService logInfof "Rechecking code due to buffer edit!" #endif let! document = workspace.CurrentSolution.GetDocument(documentId.Value) |> Option.ofObj - let! _, options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, bufferChangedCts.Token) + let! _, options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, bufferChangedCts.Token, userOpName) let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(document, options, "LineLens", allowStaleResults=true) #if DEBUG logInfof "Getting uses of all symbols!" diff --git a/vsintegration/src/FSharp.Editor/Commands/HelpContextService.fs b/vsintegration/src/FSharp.Editor/Commands/HelpContextService.fs index 1683cb6a4a7613e7facdaf9fc569a8c4057d3e0a..ffdb586ff5705fc79f15fcebe01911e75fe422ea 100644 --- a/vsintegration/src/FSharp.Editor/Commands/HelpContextService.fs +++ b/vsintegration/src/FSharp.Editor/Commands/HelpContextService.fs @@ -98,7 +98,7 @@ type internal FSharpHelpContextService member this.GetHelpTermAsync(document, textSpan, cancellationToken) = asyncMaybe { - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken) let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) diff --git a/vsintegration/src/FSharp.Editor/Commands/XmlDocCommandService.fs b/vsintegration/src/FSharp.Editor/Commands/XmlDocCommandService.fs index 11922d0d0d0bf2690e8a58e38a5609b9abd50995..107cde020bf86357517be5975e7be5edf363df2e 100644 --- a/vsintegration/src/FSharp.Editor/Commands/XmlDocCommandService.fs +++ b/vsintegration/src/FSharp.Editor/Commands/XmlDocCommandService.fs @@ -67,7 +67,7 @@ type internal XmlDocCommandFilter // XmlDocable line #1 are 1-based, editor is 0-based let curLineNum = wpfTextView.Caret.Position.BufferPosition.GetContainingLine().LineNumber + 1 let! document = document.Value - let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, CancellationToken.None) + let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, CancellationToken.None, userOpName) let! sourceText = document.GetTextAsync(CancellationToken.None) let! parsedInput = checker.ParseDocument(document, parsingOptions, sourceText, userOpName) let xmlDocables = XmlDocParser.getXmlDocables (sourceText.ToFSharpSourceText(), Some parsedInput) diff --git a/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs b/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs index 11c5f3f0c57cc3e7f414771a71bfd9b5e36d398a..acca943c97099574e30ec762d8fcda18c21f8c5b 100644 --- a/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs +++ b/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs @@ -228,7 +228,7 @@ type internal FSharpCompletionProvider let! sourceText = context.Document.GetTextAsync(context.CancellationToken) let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) do! Option.guard (CompletionUtils.shouldProvideCompletion(document.Id, document.FilePath, defines, sourceText, context.Position)) - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) + let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName) let! textVersion = context.Document.GetTextVersionAsync(context.CancellationToken) let getAllSymbols(fileCheckResults: FSharpCheckFileResults) = if settings.IntelliSense.IncludeSymbolsFromUnopenedNamespacesOrModules @@ -298,7 +298,7 @@ type internal FSharpCompletionProvider let! sourceText = document.GetTextAsync(cancellationToken) let textWithItemCommitted = sourceText.WithChanges(TextChange(item.Span, nameInCode)) let line = sourceText.Lines.GetLineFromPosition(item.Span.Start) - let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! parsedInput = checker.ParseDocument(document, parsingOptions, sourceText, userOpName) let fullNameIdents = fullName |> Option.map (fun x -> x.Split '.') |> Option.defaultValue [||] diff --git a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs index 02f4e9389255094e9633130ef3dd3b2a2215c788..de4d3c597d09fbfbb7359be85d5d2bbe526d3ee0 100644 --- a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs +++ b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs @@ -197,7 +197,7 @@ type internal FSharpSignatureHelpProvider member this.GetItemsAsync(document, position, triggerInfo, cancellationToken) = asyncMaybe { try - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken) diff --git a/vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs b/vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs index 42bd5f9282de5628e4e3816f3ff398d999ba1d49..17e2724d6eefee87e79b3789260c8488953ba86f 100644 --- a/vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs +++ b/vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs @@ -44,7 +44,7 @@ type internal FSharpBreakpointResolutionService interface IFSharpBreakpointResolutionService with member this.ResolveBreakpointAsync(document: Document, textSpan: TextSpan, cancellationToken: CancellationToken): Task = asyncMaybe { - let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) let! range = FSharpBreakpointResolutionService.GetBreakpointLocation(checkerProvider.Checker, sourceText, document.Name, textSpan, parsingOptions) let! span = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs index 2e7a44e251100de02124c4f4e73af4e8767a2079..a8534353c6550e335f39f71f0c38f52b42344ed8 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs @@ -112,7 +112,7 @@ type internal FSharpDocumentDiagnosticAnalyzer [] () = member this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task> = let projectInfoManager = getProjectInfoManager document asyncMaybe { - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken) return! @@ -125,7 +125,7 @@ type internal FSharpDocumentDiagnosticAnalyzer [] () = member this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task> = let projectInfoManager = getProjectInfoManager document asyncMaybe { - let! parsingOptions, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken) + let! parsingOptions, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken) if document.Project.Name <> FSharpConstants.FSharpMiscellaneousFilesName || isScriptFile document.FilePath then diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/SimplifyNameDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/SimplifyNameDiagnosticAnalyzer.fs index 09ee9cc23904f00d8c1fa61e75eb0dcfe0b9f2cd..e888ccdc7ce99ddbb498bca8b614afd109d6ce61 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/SimplifyNameDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/SimplifyNameDiagnosticAnalyzer.fs @@ -41,7 +41,7 @@ type internal SimplifyNameDiagnosticAnalyzer [] () = do! Option.guard document.FSharpOptions.CodeFixes.SimplifyName do Trace.TraceInformation("{0:n3} (start) SimplifyName", DateTime.Now.TimeOfDay.TotalSeconds) do! Async.Sleep DefaultTuning.SimplifyNameInitialDelay |> liftAsync - let! _parsingOptions, projectOptions = getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! _parsingOptions, projectOptions = getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! textVersion = document.GetTextVersionAsync(cancellationToken) let textVersionHash = textVersion.GetHashCode() let! _ = guard.WaitAsync(cancellationToken) |> Async.AwaitTask |> liftAsync diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs index 28f1b1f9c4f3698595febb07319a8ed35929680c..66c0a60e45271275f8b8228ad05a00af145a6d39 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs @@ -31,7 +31,7 @@ type internal UnusedDeclarationsAnalyzer [] () = do Trace.TraceInformation("{0:n3} (start) UnusedDeclarationsAnalyzer", DateTime.Now.TimeOfDay.TotalSeconds) do! Async.Sleep DefaultTuning.UnusedDeclarationsAnalyzerInitialDelay |> liftAsync // be less intrusive, give other work priority most of the time - match! getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) with + match! getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) with | (_parsingOptions, projectOptions) -> let! sourceText = document.GetTextAsync() let checker = getChecker document diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs index 629989ca454e108d538205db3ef938bc091c266c..f9e4d917c2d69356ca3adc64a37c3ba7f2440e33 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs @@ -51,7 +51,7 @@ type internal UnusedOpensDiagnosticAnalyzer [] () = asyncMaybe { do Trace.TraceInformation("{0:n3} (start) UnusedOpensAnalyzer", DateTime.Now.TimeOfDay.TotalSeconds) do! Async.Sleep DefaultTuning.UnusedOpensAnalyzerInitialDelay |> liftAsync // be less intrusive, give other work priority most of the time - let! _parsingOptions, projectOptions = getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! _parsingOptions, projectOptions = getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync() let checker = getChecker document let! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document, projectOptions, checker) diff --git a/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs b/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs index 10ee65337908ae31b41992ab553b4190d7519705..6ceb996cf1ea79a410f794cd10a34ed00ad182ed 100644 --- a/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs +++ b/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs @@ -75,7 +75,7 @@ type internal FSharpDocumentHighlightsService [] (checkerP interface IFSharpDocumentHighlightsService with member __.GetDocumentHighlightsAsync(document, position, _documentsToSearch, cancellationToken) : Task> = asyncMaybe { - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken) let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions diff --git a/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs b/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs index 794fd5de36272492d5339a4a5b46ef5858cf4436..8b6cacb54365adb675e8e1508c822f9e410f19e0 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs @@ -17,7 +17,7 @@ type internal FSharpBraceMatchingService projectInfoManager: FSharpProjectOptionsManager ) = - static let defaultUserOpName = "BraceMatching" + static let userOpName = "BraceMatching" static member GetBraceMatchingResult(checker: FSharpChecker, sourceText: SourceText, fileName, parsingOptions: FSharpParsingOptions, position: int, userOpName: string, [] forFormatting: bool) = async { @@ -37,9 +37,9 @@ type internal FSharpBraceMatchingService interface IFSharpBraceMatcher with member this.FindBracesAsync(document, position, cancellationToken) = asyncMaybe { - let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) - let! (left, right) = FSharpBraceMatchingService.GetBraceMatchingResult(checkerProvider.Checker, sourceText, document.Name, parsingOptions, position, defaultUserOpName) + let! (left, right) = FSharpBraceMatchingService.GetBraceMatchingResult(checkerProvider.Checker, sourceText, document.Name, parsingOptions, position, userOpName) let! leftSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, left) let! rightSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, right) return FSharpBraceMatchingResult(leftSpan, rightSpan) diff --git a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs index 4cc4b10c5a296c4ca10ae565c1fc64d7d7a193d6..01f3938758c0820362b9736aabb53eb23b9e2d17 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs @@ -29,7 +29,7 @@ type internal FSharpEditorFormattingService static let getIndentation (line : string) = line |> Seq.takeWhile ((=) ' ') |> Seq.length - static member GetFormattingChanges(documentId: DocumentId, sourceText: SourceText, filePath: string, checker: FSharpChecker, indentStyle: FormattingOptions.IndentStyle, options: (FSharpParsingOptions * FSharpProjectOptions) option, position: int) = + static member GetFormattingChanges(documentId: DocumentId, sourceText: SourceText, filePath: string, checker: FSharpChecker, indentStyle: FormattingOptions.IndentStyle, parsingOptions: FSharpParsingOptions, position: int) = // Logic for determining formatting changes: // If first token on the current line is a closing brace, // match the indent with the indent on the line that opened it @@ -40,8 +40,6 @@ type internal FSharpEditorFormattingService // (this is what C# does) do! Option.guard (indentStyle = FormattingOptions.IndentStyle.Smart) - let! parsingOptions, _projectOptions = options - let line = sourceText.Lines.[sourceText.Lines.IndexOf position] let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions @@ -151,8 +149,8 @@ type internal FSharpEditorFormattingService let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! options = document.GetOptionsAsync(cancellationToken) |> Async.AwaitTask let indentStyle = options.GetOption(FormattingOptions.SmartIndent, FSharpConstants.FSharpLanguageName) - let! projectOptionsOpt = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) - let! textChange = FSharpEditorFormattingService.GetFormattingChanges(document.Id, sourceText, document.FilePath, checkerProvider.Checker, indentStyle, projectOptionsOpt, position) + let parsingOptions = projectInfoManager.TryGetQuickParsingOptionsForEditingDocumentOrProject(document) + let! textChange = FSharpEditorFormattingService.GetFormattingChanges(document.Id, sourceText, document.FilePath, checkerProvider.Checker, indentStyle, parsingOptions, position) return textChange |> Option.toList |> toIList } @@ -162,12 +160,9 @@ type internal FSharpEditorFormattingService let! options = document.GetOptionsAsync(cancellationToken) |> Async.AwaitTask let tabSize = options.GetOption(FormattingOptions.TabSize, FSharpConstants.FSharpLanguageName) - match! projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) with - | Some (parsingOptions, _) -> - let! textChanges = FSharpEditorFormattingService.GetPasteChanges(document.Id, sourceText, document.FilePath, settings.Formatting, tabSize, parsingOptions, currentClipboard, span) - return textChanges |> Option.defaultValue Seq.empty |> toIList - | None -> - return toIList Seq.empty + let parsingOptions = projectInfoManager.TryGetQuickParsingOptionsForEditingDocumentOrProject(document) + let! textChanges = FSharpEditorFormattingService.GetPasteChanges(document.Id, sourceText, document.FilePath, settings.Formatting, tabSize, parsingOptions, currentClipboard, span) + return textChanges |> Option.defaultValue Seq.empty |> toIList } interface IFSharpEditorFormattingService with diff --git a/vsintegration/src/FSharp.Editor/Formatting/IndentationService.fs b/vsintegration/src/FSharp.Editor/Formatting/IndentationService.fs index a888518523ddeba3fc2b9919ac364af4de25172f..32b061754493ff5522c953b300bd36a1e53152d6 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/IndentationService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/IndentationService.fs @@ -61,7 +61,7 @@ type internal FSharpIndentationService true | _ -> false - static member GetDesiredIndentation(documentId: DocumentId, sourceText: SourceText, filePath: string, lineNumber: int, tabSize: int, indentStyle: FormattingOptions.IndentStyle, options: (FSharpParsingOptions * FSharpProjectOptions) option): Option = + static member GetDesiredIndentation(documentId: DocumentId, sourceText: SourceText, filePath: string, lineNumber: int, tabSize: int, indentStyle: FormattingOptions.IndentStyle, parsingOptions: FSharpParsingOptions): Option = // Match indentation with previous line let rec tryFindPreviousNonEmptyLine l = @@ -81,8 +81,6 @@ type internal FSharpIndentationService |> Seq.takeWhile ((=) ' ') |> Seq.length - let! parsingOptions, _ = options - // Only use smart indentation after tokens that need indentation // if the option is enabled return @@ -100,8 +98,8 @@ type internal FSharpIndentationService let! options = document.GetOptionsAsync(cancellationToken) |> Async.AwaitTask let tabSize = options.GetOption(FormattingOptions.TabSize, FSharpConstants.FSharpLanguageName) let indentStyle = options.GetOption(FormattingOptions.SmartIndent, FSharpConstants.FSharpLanguageName) - let! projectOptionsOpt = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) - let indent = FSharpIndentationService.GetDesiredIndentation(document.Id, sourceText, document.FilePath, lineNumber, tabSize, indentStyle, projectOptionsOpt) + let parsingOptions = projectInfoManager.TryGetQuickParsingOptionsForEditingDocumentOrProject(document) + let indent = FSharpIndentationService.GetDesiredIndentation(document.Id, sourceText, document.FilePath, lineNumber, tabSize, indentStyle, parsingOptions) return match indent with | None -> Nullable() diff --git a/vsintegration/src/FSharp.Editor/InlineRename/InlineRenameService.fs b/vsintegration/src/FSharp.Editor/InlineRename/InlineRenameService.fs index 92778109d04972e773f0a225fd8e3b421814fca8..9d05c920b8ec612db213bf29eefd6264154e2cd8 100644 --- a/vsintegration/src/FSharp.Editor/InlineRename/InlineRenameService.fs +++ b/vsintegration/src/FSharp.Editor/InlineRename/InlineRenameService.fs @@ -169,7 +169,7 @@ type internal InlineRenameService interface IFSharpEditorInlineRenameService with member __.GetRenameInfoAsync(document: Document, position: int, cancellationToken: CancellationToken) : Task = asyncMaybe { - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions return! InlineRenameService.GetInlineRenameInfo(checkerProvider.Checker, projectInfoManager, document, sourceText, position, defines, projectOptions) diff --git a/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs b/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs index 96921834f38d025379d333d517bb447a889135ce..d42c4478ed2651b5a68f4e2a5fef95e36e47ba8a 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs @@ -75,7 +75,7 @@ module private FSharpProjectOptionsHelpers = [] type private FSharpProjectOptionsMessage = - | TryGetOptionsByDocument of Document * AsyncReplyChannel<(FSharpParsingOptions * FSharpProjectOptions) option> * CancellationToken + | TryGetOptionsByDocument of Document * AsyncReplyChannel<(FSharpParsingOptions * FSharpProjectOptions) option> * CancellationToken * userOpName: string | TryGetOptionsByProject of Project * AsyncReplyChannel<(FSharpParsingOptions * FSharpProjectOptions) option> * CancellationToken | ClearOptions of ProjectId | ClearSingleFileOptionsCache of DocumentId @@ -92,13 +92,13 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor let cache = ConcurrentDictionary() let singleFileCache = ConcurrentDictionary() - let rec tryComputeOptionsByFile (document: Document) (ct: CancellationToken) = + let rec tryComputeOptionsByFile (document: Document) (ct: CancellationToken) userOpName = async { let! fileStamp = document.GetTextVersionAsync(ct) |> Async.AwaitTask match singleFileCache.TryGetValue(document.Id) with | false, _ -> let! sourceText = document.GetTextAsync(ct) |> Async.AwaitTask - let! scriptProjectOptions, _ = checkerProvider.Checker.GetProjectOptionsFromScript(document.FilePath, sourceText.ToFSharpSourceText(), SessionsProperties.fsiPreview) + let! scriptProjectOptions, _ = checkerProvider.Checker.GetProjectOptionsFromScript(document.FilePath, sourceText.ToFSharpSourceText(), SessionsProperties.fsiPreview, userOpName=userOpName) let projectOptions = if isScriptFile document.FilePath then scriptProjectOptions @@ -129,7 +129,7 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor | true, (fileStamp2, parsingOptions, projectOptions) -> if fileStamp <> fileStamp2 then singleFileCache.TryRemove(document.Id) |> ignore - return! tryComputeOptionsByFile document ct + return! tryComputeOptionsByFile document ct userOpName else return Some(parsingOptions, projectOptions) } @@ -244,7 +244,7 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor async { while true do match! agent.Receive() with - | FSharpProjectOptionsMessage.TryGetOptionsByDocument(document, reply, ct) -> + | FSharpProjectOptionsMessage.TryGetOptionsByDocument(document, reply, ct, userOpName) -> if ct.IsCancellationRequested then reply.Reply None else @@ -253,7 +253,7 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor if document.Project.Solution.Workspace.Kind = WorkspaceKind.MiscellaneousFiles then reply.Reply None elif document.Project.Name = FSharpConstants.FSharpMiscellaneousFilesName then - let! options = tryComputeOptionsByFile document ct + let! options = tryComputeOptionsByFile document ct userOpName reply.Reply options else // We only care about the latest project in the workspace's solution. @@ -300,8 +300,8 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor member __.TryGetOptionsByProjectAsync(project, ct) = agent.PostAndAsyncReply(fun reply -> FSharpProjectOptionsMessage.TryGetOptionsByProject(project, reply, ct)) - member __.TryGetOptionsByDocumentAsync(document, ct) = - agent.PostAndAsyncReply(fun reply -> FSharpProjectOptionsMessage.TryGetOptionsByDocument(document, reply, ct)) + member __.TryGetOptionsByDocumentAsync(document, ct, userOpName) = + agent.PostAndAsyncReply(fun reply -> FSharpProjectOptionsMessage.TryGetOptionsByDocument(document, reply, ct, userOpName)) member __.ClearOptionsByProjectId(projectId) = agent.Post(FSharpProjectOptionsMessage.ClearOptions(projectId)) @@ -379,23 +379,29 @@ type internal FSharpProjectOptionsManager reactor.TryGetOptionsByProjectAsync(project) /// Get the exact options for a document or project - member this.TryGetOptionsForDocumentOrProject(document: Document, cancellationToken) = + member this.TryGetOptionsForDocumentOrProject(document: Document, cancellationToken, userOpName) = async { - match! reactor.TryGetOptionsByDocumentAsync(document, cancellationToken) with + match! reactor.TryGetOptionsByDocumentAsync(document, cancellationToken, userOpName) with | Some(parsingOptions, projectOptions) -> return Some(parsingOptions, None, projectOptions) | _ -> return None } - /// Get the options for a document or project relevant for syntax processing. - /// Quicker then TryGetOptionsForDocumentOrProject as it doesn't need to recompute the exact project options for a script. - member this.TryGetOptionsForEditingDocumentOrProject(document:Document, cancellationToken) = + /// Get the exact options for a document or project relevant for syntax processing. + member this.TryGetOptionsForEditingDocumentOrProject(document:Document, cancellationToken, userOpName) = async { - let! result = this.TryGetOptionsForDocumentOrProject(document, cancellationToken) + let! result = this.TryGetOptionsForDocumentOrProject(document, cancellationToken, userOpName) return result |> Option.map(fun (parsingOptions, _, projectOptions) -> parsingOptions, projectOptions) } + /// Get the options for a document or project relevant for syntax processing. + /// Quicker it doesn't need to recompute the exact project options for a script. + member this.TryGetQuickParsingOptionsForEditingDocumentOrProject(document:Document) = + match reactor.TryGetCachedOptionsByProjectId(document.Project.Id) with + | Some (_, parsingOptions, _) -> parsingOptions + | _ -> { FSharpParsingOptions.Default with IsInteractive = FSharpFileUtilities.isScriptFile document.Name } + [] /// This handles commandline change notifications from the Dotnet Project-system /// Prior to VS 15.7 path contained path to project file, post 15.7 contains target binpath diff --git a/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs b/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs index 3dbe12fc40d0065541db1bf53155d72e84e87c2d..22100b4f158fadbec09afac7b5ba70d63e0ce5e7 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs @@ -25,7 +25,7 @@ module internal SymbolHelpers = let textLine = sourceText.Lines.GetLineFromPosition(position) let textLinePos = sourceText.Lines.GetLinePosition(position) let fcsTextLineNumber = Line.fromZ textLinePos.Line - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, false) let settings = document.FSharpOptions @@ -118,7 +118,7 @@ module internal SymbolHelpers = let! sourceText = document.GetTextAsync(cancellationToken) let originalText = sourceText.ToString(symbolSpan) do! Option.guard (originalText.Length > 0) - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, symbolSpan.Start, document.FilePath, defines, SymbolLookupKind.Greedy, false) let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, userOpName = userOpName) diff --git a/vsintegration/src/FSharp.Editor/Navigation/FindUsagesService.fs b/vsintegration/src/FSharp.Editor/Navigation/FindUsagesService.fs index ff841e4b5fc9d546b561ffedbe84fd8eaa20f4b1..f742a679474abcfa48c22395a566d65492790f06 100644 --- a/vsintegration/src/FSharp.Editor/Navigation/FindUsagesService.fs +++ b/vsintegration/src/FSharp.Editor/Navigation/FindUsagesService.fs @@ -51,7 +51,7 @@ type internal FSharpFindUsagesService asyncMaybe { let! sourceText = document.GetTextAsync(context.CancellationToken) |> Async.AwaitTask |> liftAsync let checker = checkerProvider.Checker - let! parsingOptions, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, context.CancellationToken) + let! parsingOptions, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, context.CancellationToken, userOpName) let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName = userOpName) let textLine = sourceText.Lines.GetLineFromPosition(position).ToString() let lineNumber = sourceText.Lines.GetLinePosition(position).Line + 1 diff --git a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs index a607442e462ed9be08a6880bc900326ddee69775..4c3c00e69434edac2624581abc9ca3c6ae20521f 100644 --- a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs +++ b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs @@ -168,7 +168,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP /// Helper function that is used to determine the navigation strategy to apply, can be tuned towards signatures or implementation files. member private __.FindSymbolHelper (originDocument: Document, originRange: range, sourceText: SourceText, preferSignature: bool) = asyncMaybe { - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(originDocument, CancellationToken.None) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(originDocument, CancellationToken.None, userOpName) let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! originTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sourceText, originRange) let position = originTextSpan.Start @@ -190,7 +190,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP if not (File.Exists fsfilePath) then return! None else let! implDoc = originDocument.Project.Solution.TryGetDocumentFromPath fsfilePath let! implSourceText = implDoc.GetTextAsync () - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(implDoc, CancellationToken.None) + let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(implDoc, CancellationToken.None, userOpName) let! _, _, checkFileResults = checker.ParseAndCheckDocument (implDoc, projectOptions, sourceText=implSourceText, userOpName=userOpName) let! symbolUses = checkFileResults.GetUsesOfSymbolInFile symbol |> liftAsync let! implSymbol = symbolUses |> Array.tryHead @@ -220,7 +220,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP member private this.FindDefinitionAtPosition(originDocument: Document, position: int) = asyncMaybe { - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(originDocument, CancellationToken.None) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(originDocument, CancellationToken.None, userOpName) let! sourceText = originDocument.GetTextAsync () |> liftTaskAsync let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let textLine = sourceText.Lines.GetLineFromPosition position @@ -307,7 +307,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP let! implDocument = originDocument.Project.Solution.TryGetDocumentFromPath implFilePath let! implVersion = implDocument.GetTextVersionAsync () |> liftTaskAsync let! implSourceText = implDocument.GetTextAsync () |> liftTaskAsync - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(implDocument, CancellationToken.None) + let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(implDocument, CancellationToken.None, userOpName) let! targetRange = this.FindSymbolDeclarationInFile(targetSymbolUse, implFilePath, implSourceText, projectOptions, implVersion.GetHashCode()) diff --git a/vsintegration/src/FSharp.Editor/Navigation/NavigateToSearchService.fs b/vsintegration/src/FSharp.Editor/Navigation/NavigateToSearchService.fs index 428ca48ef62fa6b7ffa18701fea71ca569183ca5..3fb063047ecfe4fe29be9f7fdf59a49cdd1702b0 100644 --- a/vsintegration/src/FSharp.Editor/Navigation/NavigateToSearchService.fs +++ b/vsintegration/src/FSharp.Editor/Navigation/NavigateToSearchService.fs @@ -172,6 +172,7 @@ type internal FSharpNavigateToSearchService projectInfoManager: FSharpProjectOptionsManager ) = + let userOpName = "FSharpNavigateToSearchService" let kindsProvided = ImmutableHashSet.Create(FSharpNavigateToItemKind.Module, FSharpNavigateToItemKind.Class, FSharpNavigateToItemKind.Field, FSharpNavigateToItemKind.Property, FSharpNavigateToItemKind.Method, FSharpNavigateToItemKind.Enum, FSharpNavigateToItemKind.EnumItem) :> IImmutableSet // Save the backing navigation data in a memory cache held in a sliding window @@ -261,7 +262,7 @@ type internal FSharpNavigateToSearchService member __.SearchDocumentAsync(document, searchPattern, kinds, cancellationToken) : Task> = asyncMaybe { - let! parsingOptions, _, _ = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken) + let! parsingOptions, _, _ = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken, userOpName) let! items = getCachedIndexedNavigableItems(document, parsingOptions, kinds) |> liftAsync return items.Find(searchPattern) } diff --git a/vsintegration/src/FSharp.Editor/Navigation/NavigationBarItemService.fs b/vsintegration/src/FSharp.Editor/Navigation/NavigationBarItemService.fs index d8edebd3ac1391e2fd2ef8062e8952f1ffe66d19..13350004ab12cff0fd7d9eec946a298da28d3f5d 100644 --- a/vsintegration/src/FSharp.Editor/Navigation/NavigationBarItemService.fs +++ b/vsintegration/src/FSharp.Editor/Navigation/NavigationBarItemService.fs @@ -32,7 +32,7 @@ type internal FSharpNavigationBarItemService interface IFSharpNavigationBarItemService with member __.GetItemsAsync(document, cancellationToken) : Task> = asyncMaybe { - let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) let! parsedInput = checkerProvider.Checker.ParseDocument(document, parsingOptions, sourceText=sourceText, userOpName=userOpName) let navItems = FSharpNavigation.getNavigation parsedInput diff --git a/vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs b/vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs index a6ea0c90332b6c2224715759bba35a4cb1c7ab60..cd5d0fc143e6d9dafb0b49231ab8b7a0b173698e 100644 --- a/vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs +++ b/vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs @@ -92,7 +92,7 @@ module internal FSharpQuickInfo = asyncMaybe { let! sourceText = document.GetTextAsync cancellationToken - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, true) let idRange = lexerSymbol.Ident.idRange diff --git a/vsintegration/src/FSharp.Editor/Structure/BlockStructureService.fs b/vsintegration/src/FSharp.Editor/Structure/BlockStructureService.fs index 9123aea5f1eb0b0701c04412ac4d58e41c97bdb2..13c74ef0f53891ca95eda7e5f3cff8d111ab9949 100644 --- a/vsintegration/src/FSharp.Editor/Structure/BlockStructureService.fs +++ b/vsintegration/src/FSharp.Editor/Structure/BlockStructureService.fs @@ -152,7 +152,7 @@ type internal FSharpBlockStructureService [] (checkerProvi member __.GetBlockStructureAsync(document, cancellationToken) : Task = asyncMaybe { - let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName) let! sourceText = document.GetTextAsync(cancellationToken) let! parsedInput = checkerProvider.Checker.ParseDocument(document, parsingOptions, sourceText, userOpName) return createBlockSpans document.FSharpOptions.Advanced.IsBlockStructureEnabled sourceText parsedInput |> Seq.toImmutableArray diff --git a/vsintegration/tests/UnitTests/EditorFormattingServiceTests.fs b/vsintegration/tests/UnitTests/EditorFormattingServiceTests.fs index fbcfc1125afac9a45a026af4f87d99ede5522568..3a5b70f2051b3e97c8e29050617741eeacb33ce2 100644 --- a/vsintegration/tests/UnitTests/EditorFormattingServiceTests.fs +++ b/vsintegration/tests/UnitTests/EditorFormattingServiceTests.fs @@ -78,7 +78,7 @@ marker4""" let lineNumber = sourceText.Lines |> Seq.findIndex (fun line -> line.Span.Contains position) let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - let changesOpt = FSharpEditorFormattingService.GetFormattingChanges(documentId, sourceText, filePath, checker, indentStyle, Some (parsingOptions, projectOptions), position) |> Async.RunSynchronously + let changesOpt = FSharpEditorFormattingService.GetFormattingChanges(documentId, sourceText, filePath, checker, indentStyle, parsingOptions, position) |> Async.RunSynchronously match changesOpt with | None -> Assert.Fail("Expected a text change, but got None") | Some changes -> diff --git a/vsintegration/tests/UnitTests/IndentationServiceTests.fs b/vsintegration/tests/UnitTests/IndentationServiceTests.fs index d16c48ddab22d6fe444f75431b7089d2b11958df..a1a8cb0943fecd8d022a84d6b901e720b2944540 100644 --- a/vsintegration/tests/UnitTests/IndentationServiceTests.fs +++ b/vsintegration/tests/UnitTests/IndentationServiceTests.fs @@ -176,7 +176,7 @@ while true do let sourceText = SourceText.From(template) let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - let actualIndentation = FSharpIndentationService.GetDesiredIndentation(documentId, sourceText, filePath, lineNumber, tabSize, indentStyle, Some (parsingOptions, projectOptions)) + let actualIndentation = FSharpIndentationService.GetDesiredIndentation(documentId, sourceText, filePath, lineNumber, tabSize, indentStyle, parsingOptions) match expectedIndentation with | None -> Assert.IsTrue(actualIndentation.IsNone, "No indentation was expected at line {0}", lineNumber) | Some indentation -> Assert.AreEqual(expectedIndentation.Value, actualIndentation.Value, "Indentation on line {0} doesn't match", lineNumber) @@ -189,7 +189,7 @@ while true do let sourceText = SourceText.From(template) let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - let actualIndentation = FSharpIndentationService.GetDesiredIndentation(documentId, sourceText, filePath, lineNumber, tabSize, indentStyle, Some (parsingOptions, projectOptions)) + let actualIndentation = FSharpIndentationService.GetDesiredIndentation(documentId, sourceText, filePath, lineNumber, tabSize, indentStyle, parsingOptions) match expectedIndentation with | None -> Assert.IsTrue(actualIndentation.IsNone, "No indentation was expected at line {0}", lineNumber) | Some indentation -> Assert.AreEqual(expectedIndentation.Value, actualIndentation.Value, "Indentation on line {0} doesn't match", lineNumber)