Skip to content
This repository was archived by the owner on Dec 23, 2024. It is now read-only.

Commit 175221c

Browse files
dsymeDon Syme
authored andcommitted
fix script editing perf (dotnet#10159)
Co-authored-by: Don Syme <[email protected]>
1 parent 3159e4a commit 175221c

32 files changed

+94
-85
lines changed

src/fsharp/Microsoft.DotNet.DependencyManager/DependencyProvider.fs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ open System.Reflection
88
open System.Runtime.InteropServices
99
open Internal.Utilities.FSharpEnvironment
1010
open Microsoft.FSharp.Reflection
11+
open System.Collections.Concurrent
1112

1213
[<AutoOpen>]
1314
module ReflectionHelper =
@@ -88,19 +89,19 @@ type IResolveDependenciesResult =
8889
abstract Success: bool
8990

9091
/// The resolution output log
91-
abstract StdOut: string array
92+
abstract StdOut: string[]
9293

9394
/// The resolution error log (* process stderror *)
94-
abstract StdError: string array
95+
abstract StdError: string[]
9596

9697
/// The resolution paths
97-
abstract Resolutions: string seq
98+
abstract Resolutions: seq<string>
9899

99100
/// The source code file paths
100-
abstract SourceFiles: string seq
101+
abstract SourceFiles: seq<string>
101102

102103
/// The roots to package directories
103-
abstract Roots: string seq
104+
abstract Roots: seq<string>
104105

105106

106107
[<AllowNullLiteralAttribute>]
@@ -326,6 +327,8 @@ type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativePr
326327
None
327328
managers
328329

330+
let cache = ConcurrentDictionary<_,IResolveDependenciesResult>(HashIdentity.Structural)
331+
329332
/// Returns a formatted error message for the host to presentconstruct with just nativeProbing handler
330333
new (nativeProbingRoots: NativeResolutionProbe) =
331334
new DependencyProvider(Unchecked.defaultof<AssemblyResolutionProbe>, nativeProbingRoots)
@@ -390,20 +393,24 @@ type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativePr
390393
[<Optional;DefaultParameterValue("")>]implicitIncludeDir: string,
391394
[<Optional;DefaultParameterValue("")>]mainScriptName: string,
392395
[<Optional;DefaultParameterValue("")>]fileName: string): IResolveDependenciesResult =
396+
397+
let key = (packageManager.Key, scriptExt, Seq.toArray packageManagerTextLines, executionTfm, executionRid, implicitIncludeDir, mainScriptName, fileName)
393398

394-
try
395-
let executionRid =
396-
if isNull executionRid then
397-
RidHelpers.platformRid
398-
else
399-
executionRid
400-
packageManager.ResolveDependencies(implicitIncludeDir, mainScriptName, fileName, scriptExt, packageManagerTextLines, executionTfm, executionRid)
401-
402-
with e ->
403-
let e = stripTieWrapper e
404-
let err, msg = (DependencyManager.SR.packageManagerError(e.Message))
405-
reportError.Invoke(ErrorReportType.Error, err, msg)
406-
ReflectionDependencyManagerProvider.MakeResultFromFields(false, arrEmpty, arrEmpty, seqEmpty, seqEmpty, seqEmpty)
399+
cache.GetOrAdd(key, System.Func<_,_>(fun _ ->
400+
try
401+
let executionRid =
402+
if isNull executionRid then
403+
RidHelpers.platformRid
404+
else
405+
executionRid
406+
packageManager.ResolveDependencies(implicitIncludeDir, mainScriptName, fileName, scriptExt, packageManagerTextLines, executionTfm, executionRid)
407+
408+
with e ->
409+
let e = stripTieWrapper e
410+
let err, msg = (DependencyManager.SR.packageManagerError(e.Message))
411+
reportError.Invoke(ErrorReportType.Error, err, msg)
412+
ReflectionDependencyManagerProvider.MakeResultFromFields(false, arrEmpty, arrEmpty, seqEmpty, seqEmpty, seqEmpty)
413+
))
407414

408415
interface IDisposable with
409416

vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ type internal FSharpClassificationService
158158
asyncMaybe {
159159
use _logBlock = Logger.LogBlock(LogEditorFunctionId.Classification_Semantic)
160160

161-
let! _, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken)
161+
let! _, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken, userOpName)
162162
let! sourceText = document.GetTextAsync(cancellationToken)
163163

164164
// If we are trying to get semantic classification for a document that is not open, get the results from the background and cache it.

vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ type internal FSharpAddOpenCodeFixProvider
9696
override __.RegisterCodeFixesAsync context : Task =
9797
asyncMaybe {
9898
let document = context.Document
99-
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken)
99+
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName)
100100
let! sourceText = context.Document.GetTextAsync(context.CancellationToken)
101101
let! _, parsedInput, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName = userOpName)
102102
let line = sourceText.Lines.GetLineFromPosition(context.Span.End)

vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ type internal FSharpImplementInterfaceCodeFixProvider
138138

139139
override __.RegisterCodeFixesAsync context : Task =
140140
asyncMaybe {
141-
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(context.Document, context.CancellationToken)
141+
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(context.Document, context.CancellationToken, userOpName)
142142
let cancellationToken = context.CancellationToken
143143
let! sourceText = context.Document.GetTextAsync(cancellationToken)
144144
let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(context.Document, projectOptions, sourceText = sourceText, userOpName = userOpName)

vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider
2222
projectInfoManager: FSharpProjectOptionsManager
2323
) =
2424
inherit CodeFixProvider()
25+
let userOpName = "FSharpRemoveUnusedOpensCodeFixProvider"
2526
let fixableDiagnosticIds = [FSharpIDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId]
2627

2728
let createCodeFix (title: string, context: CodeFixContext) =
@@ -32,7 +33,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider
3233
let document = context.Document
3334
let! sourceText = document.GetTextAsync()
3435
let checker = checkerProvider.Checker
35-
let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken)
36+
let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName)
3637
let! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document, projectOptions, checker)
3738
let changes =
3839
unusedOpens

vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ type internal FSharpRenameUnusedValueCodeFixProvider
5757
// We have to use the additional check for backtickes because `IsOperatorOrBacktickedName` operates on display names
5858
// where backtickes are replaced with parens.
5959
if not (PrettyNaming.IsOperatorOrBacktickedName ident) && not (ident.StartsWith "``") then
60-
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken)
60+
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName)
6161
let! _, _, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName=userOpName)
6262
let m = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText)
6363
let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions

vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider
3333
do! Option.guard settings.CodeFixes.SuggestNamesForErrors
3434

3535
let document = context.Document
36-
let! _, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken)
36+
let! _, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken, userOpName)
3737
let! parseFileResults, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, userOpName=userOpName)
3838

3939
// This is all needed to get a declaration list

vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type internal FSharpCodeLensService
5252
) as self =
5353

5454
let lineLens = codeLens
55+
let userOpName = "FSharpCodeLensService"
5556

5657
let visit pos parseTree =
5758
AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with
@@ -154,7 +155,7 @@ type internal FSharpCodeLensService
154155
logInfof "Rechecking code due to buffer edit!"
155156
#endif
156157
let! document = workspace.CurrentSolution.GetDocument(documentId.Value) |> Option.ofObj
157-
let! _, options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, bufferChangedCts.Token)
158+
let! _, options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, bufferChangedCts.Token, userOpName)
158159
let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(document, options, "LineLens", allowStaleResults=true)
159160
#if DEBUG
160161
logInfof "Getting uses of all symbols!"

vsintegration/src/FSharp.Editor/Commands/HelpContextService.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ type internal FSharpHelpContextService
9898

9999
member this.GetHelpTermAsync(document, textSpan, cancellationToken) =
100100
asyncMaybe {
101-
let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken)
101+
let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
102102
let! sourceText = document.GetTextAsync(cancellationToken)
103103
let! textVersion = document.GetTextVersionAsync(cancellationToken)
104104
let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document)

vsintegration/src/FSharp.Editor/Commands/XmlDocCommandService.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ type internal XmlDocCommandFilter
6767
// XmlDocable line #1 are 1-based, editor is 0-based
6868
let curLineNum = wpfTextView.Caret.Position.BufferPosition.GetContainingLine().LineNumber + 1
6969
let! document = document.Value
70-
let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, CancellationToken.None)
70+
let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, CancellationToken.None, userOpName)
7171
let! sourceText = document.GetTextAsync(CancellationToken.None)
7272
let! parsedInput = checker.ParseDocument(document, parsingOptions, sourceText, userOpName)
7373
let xmlDocables = XmlDocParser.getXmlDocables (sourceText.ToFSharpSourceText(), Some parsedInput)

0 commit comments

Comments
 (0)