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

Commit

Permalink
fix script editing perf (dotnet#10159)
Browse files Browse the repository at this point in the history
Co-authored-by: Don Syme <donsyme@fastmail.com>
  • Loading branch information
2 people authored and nosami committed Feb 22, 2021
1 parent 3159e4a commit 175221c
Show file tree
Hide file tree
Showing 32 changed files with 94 additions and 85 deletions.
43 changes: 25 additions & 18 deletions src/fsharp/Microsoft.DotNet.DependencyManager/DependencyProvider.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ open System.Reflection
open System.Runtime.InteropServices
open Internal.Utilities.FSharpEnvironment
open Microsoft.FSharp.Reflection
open System.Collections.Concurrent

[<AutoOpen>]
module ReflectionHelper =
Expand Down Expand Up @@ -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<string>

/// The source code file paths
abstract SourceFiles: string seq
abstract SourceFiles: seq<string>

/// The roots to package directories
abstract Roots: string seq
abstract Roots: seq<string>


[<AllowNullLiteralAttribute>]
Expand Down Expand Up @@ -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<AssemblyResolutionProbe>, nativeProbingRoots)
Expand Down Expand Up @@ -390,20 +393,24 @@ type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativePr
[<Optional;DefaultParameterValue("")>]implicitIncludeDir: string,
[<Optional;DefaultParameterValue("")>]mainScriptName: string,
[<Optional;DefaultParameterValue("")>]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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider
projectInfoManager: FSharpProjectOptionsManager
) =
inherit CodeFixProvider()
let userOpName = "FSharpRemoveUnusedOpensCodeFixProvider"
let fixableDiagnosticIds = [FSharpIDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId]

let createCodeFix (title: string, context: CodeFixContext) =
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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!"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 [||]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type internal FSharpBreakpointResolutionService
interface IFSharpBreakpointResolutionService with
member this.ResolveBreakpointAsync(document: Document, textSpan: TextSpan, cancellationToken: CancellationToken): Task<FSharpBreakpointResolutionResult> =
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ type internal FSharpDocumentDiagnosticAnalyzer [<ImportingConstructor>] () =
member this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
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!
Expand All @@ -135,7 +135,7 @@ type internal FSharpDocumentDiagnosticAnalyzer [<ImportingConstructor>] () =
member this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type internal SimplifyNameDiagnosticAnalyzer [<ImportingConstructor>] () =
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type internal UnusedDeclarationsAnalyzer [<ImportingConstructor>] () =

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type internal UnusedOpensDiagnosticAnalyzer [<ImportingConstructor>] () =
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP
interface IFSharpDocumentHighlightsService with
member __.GetDocumentHighlightsAsync(document, position, _documentsToSearch, cancellationToken) : Task<ImmutableArray<FSharpDocumentHighlights>> =
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
Expand Down
Loading

0 comments on commit 175221c

Please sign in to comment.