未验证 提交 7e4b03f1 编写于 作者: D Don Syme 提交者: GitHub

fix script editing perf (#10159)

Co-authored-by: NDon Syme <donsyme@fastmail.com>
上级 eb5cf1a6
...@@ -8,6 +8,7 @@ open System.Reflection ...@@ -8,6 +8,7 @@ open System.Reflection
open System.Runtime.InteropServices open System.Runtime.InteropServices
open Internal.Utilities.FSharpEnvironment open Internal.Utilities.FSharpEnvironment
open Microsoft.FSharp.Reflection open Microsoft.FSharp.Reflection
open System.Collections.Concurrent
[<AutoOpen>] [<AutoOpen>]
module ReflectionHelper = module ReflectionHelper =
...@@ -88,19 +89,19 @@ type IResolveDependenciesResult = ...@@ -88,19 +89,19 @@ type IResolveDependenciesResult =
abstract Success: bool abstract Success: bool
/// The resolution output log /// The resolution output log
abstract StdOut: string array abstract StdOut: string[]
/// The resolution error log (* process stderror *) /// The resolution error log (* process stderror *)
abstract StdError: string array abstract StdError: string[]
/// The resolution paths /// The resolution paths
abstract Resolutions: string seq abstract Resolutions: seq<string>
/// The source code file paths /// The source code file paths
abstract SourceFiles: string seq abstract SourceFiles: seq<string>
/// The roots to package directories /// The roots to package directories
abstract Roots: string seq abstract Roots: seq<string>
[<AllowNullLiteralAttribute>] [<AllowNullLiteralAttribute>]
...@@ -326,6 +327,8 @@ type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativePr ...@@ -326,6 +327,8 @@ type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativePr
None None
managers managers
let cache = ConcurrentDictionary<_,IResolveDependenciesResult>(HashIdentity.Structural)
/// Returns a formatted error message for the host to presentconstruct with just nativeProbing handler /// Returns a formatted error message for the host to presentconstruct with just nativeProbing handler
new (nativeProbingRoots: NativeResolutionProbe) = new (nativeProbingRoots: NativeResolutionProbe) =
new DependencyProvider(Unchecked.defaultof<AssemblyResolutionProbe>, nativeProbingRoots) new DependencyProvider(Unchecked.defaultof<AssemblyResolutionProbe>, nativeProbingRoots)
...@@ -390,20 +393,24 @@ type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativePr ...@@ -390,20 +393,24 @@ type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativePr
[<Optional;DefaultParameterValue("")>]implicitIncludeDir: string, [<Optional;DefaultParameterValue("")>]implicitIncludeDir: string,
[<Optional;DefaultParameterValue("")>]mainScriptName: string, [<Optional;DefaultParameterValue("")>]mainScriptName: string,
[<Optional;DefaultParameterValue("")>]fileName: string): IResolveDependenciesResult = [<Optional;DefaultParameterValue("")>]fileName: string): IResolveDependenciesResult =
let key = (packageManager.Key, scriptExt, Seq.toArray packageManagerTextLines, executionTfm, executionRid, implicitIncludeDir, mainScriptName, fileName)
try cache.GetOrAdd(key, System.Func<_,_>(fun _ ->
let executionRid = try
if isNull executionRid then let executionRid =
RidHelpers.platformRid if isNull executionRid then
else RidHelpers.platformRid
executionRid else
packageManager.ResolveDependencies(implicitIncludeDir, mainScriptName, fileName, scriptExt, packageManagerTextLines, executionTfm, executionRid) executionRid
packageManager.ResolveDependencies(implicitIncludeDir, mainScriptName, fileName, scriptExt, packageManagerTextLines, executionTfm, executionRid)
with e ->
let e = stripTieWrapper e with e ->
let err, msg = (DependencyManager.SR.packageManagerError(e.Message)) let e = stripTieWrapper e
reportError.Invoke(ErrorReportType.Error, err, msg) let err, msg = (DependencyManager.SR.packageManagerError(e.Message))
ReflectionDependencyManagerProvider.MakeResultFromFields(false, arrEmpty, arrEmpty, seqEmpty, seqEmpty, seqEmpty) reportError.Invoke(ErrorReportType.Error, err, msg)
ReflectionDependencyManagerProvider.MakeResultFromFields(false, arrEmpty, arrEmpty, seqEmpty, seqEmpty, seqEmpty)
))
interface IDisposable with interface IDisposable with
......
...@@ -158,7 +158,7 @@ type internal FSharpClassificationService ...@@ -158,7 +158,7 @@ type internal FSharpClassificationService
asyncMaybe { asyncMaybe {
use _logBlock = Logger.LogBlock(LogEditorFunctionId.Classification_Semantic) 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) 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. // If we are trying to get semantic classification for a document that is not open, get the results from the background and cache it.
......
...@@ -96,7 +96,7 @@ type internal FSharpAddOpenCodeFixProvider ...@@ -96,7 +96,7 @@ type internal FSharpAddOpenCodeFixProvider
override __.RegisterCodeFixesAsync context : Task = override __.RegisterCodeFixesAsync context : Task =
asyncMaybe { asyncMaybe {
let document = context.Document 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! sourceText = context.Document.GetTextAsync(context.CancellationToken)
let! _, parsedInput, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName = userOpName) let! _, parsedInput, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName = userOpName)
let line = sourceText.Lines.GetLineFromPosition(context.Span.End) let line = sourceText.Lines.GetLineFromPosition(context.Span.End)
......
...@@ -138,7 +138,7 @@ type internal FSharpImplementInterfaceCodeFixProvider ...@@ -138,7 +138,7 @@ type internal FSharpImplementInterfaceCodeFixProvider
override __.RegisterCodeFixesAsync context : Task = override __.RegisterCodeFixesAsync context : Task =
asyncMaybe { 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 cancellationToken = context.CancellationToken
let! sourceText = context.Document.GetTextAsync(cancellationToken) let! sourceText = context.Document.GetTextAsync(cancellationToken)
let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(context.Document, projectOptions, sourceText = sourceText, userOpName = userOpName) let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(context.Document, projectOptions, sourceText = sourceText, userOpName = userOpName)
......
...@@ -22,6 +22,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider ...@@ -22,6 +22,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider
projectInfoManager: FSharpProjectOptionsManager projectInfoManager: FSharpProjectOptionsManager
) = ) =
inherit CodeFixProvider() inherit CodeFixProvider()
let userOpName = "FSharpRemoveUnusedOpensCodeFixProvider"
let fixableDiagnosticIds = [FSharpIDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId] let fixableDiagnosticIds = [FSharpIDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId]
let createCodeFix (title: string, context: CodeFixContext) = let createCodeFix (title: string, context: CodeFixContext) =
...@@ -32,7 +33,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider ...@@ -32,7 +33,7 @@ type internal FSharpRemoveUnusedOpensCodeFixProvider
let document = context.Document let document = context.Document
let! sourceText = document.GetTextAsync() let! sourceText = document.GetTextAsync()
let checker = checkerProvider.Checker 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! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document, projectOptions, checker)
let changes = let changes =
unusedOpens unusedOpens
......
...@@ -57,7 +57,7 @@ type internal FSharpRenameUnusedValueCodeFixProvider ...@@ -57,7 +57,7 @@ type internal FSharpRenameUnusedValueCodeFixProvider
// We have to use the additional check for backtickes because `IsOperatorOrBacktickedName` operates on display names // We have to use the additional check for backtickes because `IsOperatorOrBacktickedName` operates on display names
// where backtickes are replaced with parens. // where backtickes are replaced with parens.
if not (PrettyNaming.IsOperatorOrBacktickedName ident) && not (ident.StartsWith "``") then 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! _, _, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName=userOpName)
let m = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText) let m = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText)
let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
......
...@@ -33,7 +33,7 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider ...@@ -33,7 +33,7 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider
do! Option.guard settings.CodeFixes.SuggestNamesForErrors do! Option.guard settings.CodeFixes.SuggestNamesForErrors
let document = context.Document 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) let! parseFileResults, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, userOpName=userOpName)
// This is all needed to get a declaration list // This is all needed to get a declaration list
......
...@@ -52,6 +52,7 @@ type internal FSharpCodeLensService ...@@ -52,6 +52,7 @@ type internal FSharpCodeLensService
) as self = ) as self =
let lineLens = codeLens let lineLens = codeLens
let userOpName = "FSharpCodeLensService"
let visit pos parseTree = let visit pos parseTree =
AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with
...@@ -154,7 +155,7 @@ type internal FSharpCodeLensService ...@@ -154,7 +155,7 @@ type internal FSharpCodeLensService
logInfof "Rechecking code due to buffer edit!" logInfof "Rechecking code due to buffer edit!"
#endif #endif
let! document = workspace.CurrentSolution.GetDocument(documentId.Value) |> Option.ofObj 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) let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(document, options, "LineLens", allowStaleResults=true)
#if DEBUG #if DEBUG
logInfof "Getting uses of all symbols!" logInfof "Getting uses of all symbols!"
......
...@@ -98,7 +98,7 @@ type internal FSharpHelpContextService ...@@ -98,7 +98,7 @@ type internal FSharpHelpContextService
member this.GetHelpTermAsync(document, textSpan, cancellationToken) = member this.GetHelpTermAsync(document, textSpan, cancellationToken) =
asyncMaybe { asyncMaybe {
let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! textVersion = document.GetTextVersionAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken)
let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document)
......
...@@ -67,7 +67,7 @@ type internal XmlDocCommandFilter ...@@ -67,7 +67,7 @@ type internal XmlDocCommandFilter
// XmlDocable line #1 are 1-based, editor is 0-based // XmlDocable line #1 are 1-based, editor is 0-based
let curLineNum = wpfTextView.Caret.Position.BufferPosition.GetContainingLine().LineNumber + 1 let curLineNum = wpfTextView.Caret.Position.BufferPosition.GetContainingLine().LineNumber + 1
let! document = document.Value 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! sourceText = document.GetTextAsync(CancellationToken.None)
let! parsedInput = checker.ParseDocument(document, parsingOptions, sourceText, userOpName) let! parsedInput = checker.ParseDocument(document, parsingOptions, sourceText, userOpName)
let xmlDocables = XmlDocParser.getXmlDocables (sourceText.ToFSharpSourceText(), Some parsedInput) let xmlDocables = XmlDocParser.getXmlDocables (sourceText.ToFSharpSourceText(), Some parsedInput)
......
...@@ -228,7 +228,7 @@ type internal FSharpCompletionProvider ...@@ -228,7 +228,7 @@ type internal FSharpCompletionProvider
let! sourceText = context.Document.GetTextAsync(context.CancellationToken) let! sourceText = context.Document.GetTextAsync(context.CancellationToken)
let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document)
do! Option.guard (CompletionUtils.shouldProvideCompletion(document.Id, document.FilePath, defines, sourceText, context.Position)) 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! textVersion = context.Document.GetTextVersionAsync(context.CancellationToken)
let getAllSymbols(fileCheckResults: FSharpCheckFileResults) = let getAllSymbols(fileCheckResults: FSharpCheckFileResults) =
if settings.IntelliSense.IncludeSymbolsFromUnopenedNamespacesOrModules if settings.IntelliSense.IncludeSymbolsFromUnopenedNamespacesOrModules
...@@ -298,7 +298,7 @@ type internal FSharpCompletionProvider ...@@ -298,7 +298,7 @@ type internal FSharpCompletionProvider
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let textWithItemCommitted = sourceText.WithChanges(TextChange(item.Span, nameInCode)) let textWithItemCommitted = sourceText.WithChanges(TextChange(item.Span, nameInCode))
let line = sourceText.Lines.GetLineFromPosition(item.Span.Start) 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! parsedInput = checker.ParseDocument(document, parsingOptions, sourceText, userOpName)
let fullNameIdents = fullName |> Option.map (fun x -> x.Split '.') |> Option.defaultValue [||] let fullNameIdents = fullName |> Option.map (fun x -> x.Split '.') |> Option.defaultValue [||]
......
...@@ -197,7 +197,7 @@ type internal FSharpSignatureHelpProvider ...@@ -197,7 +197,7 @@ type internal FSharpSignatureHelpProvider
member this.GetItemsAsync(document, position, triggerInfo, cancellationToken) = member this.GetItemsAsync(document, position, triggerInfo, cancellationToken) =
asyncMaybe { asyncMaybe {
try try
let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! textVersion = document.GetTextVersionAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken)
......
...@@ -44,7 +44,7 @@ type internal FSharpBreakpointResolutionService ...@@ -44,7 +44,7 @@ type internal FSharpBreakpointResolutionService
interface IFSharpBreakpointResolutionService with interface IFSharpBreakpointResolutionService with
member this.ResolveBreakpointAsync(document: Document, textSpan: TextSpan, cancellationToken: CancellationToken): Task<FSharpBreakpointResolutionResult> = member this.ResolveBreakpointAsync(document: Document, textSpan: TextSpan, cancellationToken: CancellationToken): Task<FSharpBreakpointResolutionResult> =
asyncMaybe { asyncMaybe {
let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! range = FSharpBreakpointResolutionService.GetBreakpointLocation(checkerProvider.Checker, sourceText, document.Name, textSpan, parsingOptions) let! range = FSharpBreakpointResolutionService.GetBreakpointLocation(checkerProvider.Checker, sourceText, document.Name, textSpan, parsingOptions)
let! span = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) let! span = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range)
......
...@@ -112,7 +112,7 @@ type internal FSharpDocumentDiagnosticAnalyzer [<ImportingConstructor>] () = ...@@ -112,7 +112,7 @@ type internal FSharpDocumentDiagnosticAnalyzer [<ImportingConstructor>] () =
member this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> = member this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
let projectInfoManager = getProjectInfoManager document let projectInfoManager = getProjectInfoManager document
asyncMaybe { asyncMaybe {
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! textVersion = document.GetTextVersionAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken)
return! return!
...@@ -125,7 +125,7 @@ type internal FSharpDocumentDiagnosticAnalyzer [<ImportingConstructor>] () = ...@@ -125,7 +125,7 @@ type internal FSharpDocumentDiagnosticAnalyzer [<ImportingConstructor>] () =
member this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> = member this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
let projectInfoManager = getProjectInfoManager document let projectInfoManager = getProjectInfoManager document
asyncMaybe { asyncMaybe {
let! parsingOptions, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken) let! parsingOptions, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! textVersion = document.GetTextVersionAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken)
if document.Project.Name <> FSharpConstants.FSharpMiscellaneousFilesName || isScriptFile document.FilePath then if document.Project.Name <> FSharpConstants.FSharpMiscellaneousFilesName || isScriptFile document.FilePath then
......
...@@ -41,7 +41,7 @@ type internal SimplifyNameDiagnosticAnalyzer [<ImportingConstructor>] () = ...@@ -41,7 +41,7 @@ type internal SimplifyNameDiagnosticAnalyzer [<ImportingConstructor>] () =
do! Option.guard document.FSharpOptions.CodeFixes.SimplifyName do! Option.guard document.FSharpOptions.CodeFixes.SimplifyName
do Trace.TraceInformation("{0:n3} (start) SimplifyName", DateTime.Now.TimeOfDay.TotalSeconds) do Trace.TraceInformation("{0:n3} (start) SimplifyName", DateTime.Now.TimeOfDay.TotalSeconds)
do! Async.Sleep DefaultTuning.SimplifyNameInitialDelay |> liftAsync 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! textVersion = document.GetTextVersionAsync(cancellationToken)
let textVersionHash = textVersion.GetHashCode() let textVersionHash = textVersion.GetHashCode()
let! _ = guard.WaitAsync(cancellationToken) |> Async.AwaitTask |> liftAsync let! _ = guard.WaitAsync(cancellationToken) |> Async.AwaitTask |> liftAsync
......
...@@ -31,7 +31,7 @@ type internal UnusedDeclarationsAnalyzer [<ImportingConstructor>] () = ...@@ -31,7 +31,7 @@ type internal UnusedDeclarationsAnalyzer [<ImportingConstructor>] () =
do Trace.TraceInformation("{0:n3} (start) UnusedDeclarationsAnalyzer", DateTime.Now.TimeOfDay.TotalSeconds) 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 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) -> | (_parsingOptions, projectOptions) ->
let! sourceText = document.GetTextAsync() let! sourceText = document.GetTextAsync()
let checker = getChecker document let checker = getChecker document
......
...@@ -51,7 +51,7 @@ type internal UnusedOpensDiagnosticAnalyzer [<ImportingConstructor>] () = ...@@ -51,7 +51,7 @@ type internal UnusedOpensDiagnosticAnalyzer [<ImportingConstructor>] () =
asyncMaybe { asyncMaybe {
do Trace.TraceInformation("{0:n3} (start) UnusedOpensAnalyzer", DateTime.Now.TimeOfDay.TotalSeconds) 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 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! sourceText = document.GetTextAsync()
let checker = getChecker document let checker = getChecker document
let! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document, projectOptions, checker) let! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document, projectOptions, checker)
......
...@@ -75,7 +75,7 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP ...@@ -75,7 +75,7 @@ type internal FSharpDocumentHighlightsService [<ImportingConstructor>] (checkerP
interface IFSharpDocumentHighlightsService with interface IFSharpDocumentHighlightsService with
member __.GetDocumentHighlightsAsync(document, position, _documentsToSearch, cancellationToken) : Task<ImmutableArray<FSharpDocumentHighlights>> = member __.GetDocumentHighlightsAsync(document, position, _documentsToSearch, cancellationToken) : Task<ImmutableArray<FSharpDocumentHighlights>> =
asyncMaybe { asyncMaybe {
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! textVersion = document.GetTextVersionAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken)
let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
......
...@@ -17,7 +17,7 @@ type internal FSharpBraceMatchingService ...@@ -17,7 +17,7 @@ type internal FSharpBraceMatchingService
projectInfoManager: FSharpProjectOptionsManager projectInfoManager: FSharpProjectOptionsManager
) = ) =
static let defaultUserOpName = "BraceMatching" static let userOpName = "BraceMatching"
static member GetBraceMatchingResult(checker: FSharpChecker, sourceText: SourceText, fileName, parsingOptions: FSharpParsingOptions, position: int, userOpName: string, [<Optional; DefaultParameterValue(false)>] forFormatting: bool) = static member GetBraceMatchingResult(checker: FSharpChecker, sourceText: SourceText, fileName, parsingOptions: FSharpParsingOptions, position: int, userOpName: string, [<Optional; DefaultParameterValue(false)>] forFormatting: bool) =
async { async {
...@@ -37,9 +37,9 @@ type internal FSharpBraceMatchingService ...@@ -37,9 +37,9 @@ type internal FSharpBraceMatchingService
interface IFSharpBraceMatcher with interface IFSharpBraceMatcher with
member this.FindBracesAsync(document, position, cancellationToken) = member this.FindBracesAsync(document, position, cancellationToken) =
asyncMaybe { asyncMaybe {
let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) 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! leftSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, left)
let! rightSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, right) let! rightSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, right)
return FSharpBraceMatchingResult(leftSpan, rightSpan) return FSharpBraceMatchingResult(leftSpan, rightSpan)
......
...@@ -29,7 +29,7 @@ type internal FSharpEditorFormattingService ...@@ -29,7 +29,7 @@ type internal FSharpEditorFormattingService
static let getIndentation (line : string) = line |> Seq.takeWhile ((=) ' ') |> Seq.length 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: // Logic for determining formatting changes:
// If first token on the current line is a closing brace, // If first token on the current line is a closing brace,
// match the indent with the indent on the line that opened it // match the indent with the indent on the line that opened it
...@@ -40,8 +40,6 @@ type internal FSharpEditorFormattingService ...@@ -40,8 +40,6 @@ type internal FSharpEditorFormattingService
// (this is what C# does) // (this is what C# does)
do! Option.guard (indentStyle = FormattingOptions.IndentStyle.Smart) do! Option.guard (indentStyle = FormattingOptions.IndentStyle.Smart)
let! parsingOptions, _projectOptions = options
let line = sourceText.Lines.[sourceText.Lines.IndexOf position] let line = sourceText.Lines.[sourceText.Lines.IndexOf position]
let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
...@@ -151,8 +149,8 @@ type internal FSharpEditorFormattingService ...@@ -151,8 +149,8 @@ type internal FSharpEditorFormattingService
let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask
let! options = document.GetOptionsAsync(cancellationToken) |> Async.AwaitTask let! options = document.GetOptionsAsync(cancellationToken) |> Async.AwaitTask
let indentStyle = options.GetOption(FormattingOptions.SmartIndent, FSharpConstants.FSharpLanguageName) let indentStyle = options.GetOption(FormattingOptions.SmartIndent, FSharpConstants.FSharpLanguageName)
let! projectOptionsOpt = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let parsingOptions = projectInfoManager.TryGetQuickParsingOptionsForEditingDocumentOrProject(document)
let! textChange = FSharpEditorFormattingService.GetFormattingChanges(document.Id, sourceText, document.FilePath, checkerProvider.Checker, indentStyle, projectOptionsOpt, position) let! textChange = FSharpEditorFormattingService.GetFormattingChanges(document.Id, sourceText, document.FilePath, checkerProvider.Checker, indentStyle, parsingOptions, position)
return textChange |> Option.toList |> toIList return textChange |> Option.toList |> toIList
} }
...@@ -162,12 +160,9 @@ type internal FSharpEditorFormattingService ...@@ -162,12 +160,9 @@ type internal FSharpEditorFormattingService
let! options = document.GetOptionsAsync(cancellationToken) |> Async.AwaitTask let! options = document.GetOptionsAsync(cancellationToken) |> Async.AwaitTask
let tabSize = options.GetOption<int>(FormattingOptions.TabSize, FSharpConstants.FSharpLanguageName) let tabSize = options.GetOption<int>(FormattingOptions.TabSize, FSharpConstants.FSharpLanguageName)
match! projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) with let parsingOptions = projectInfoManager.TryGetQuickParsingOptionsForEditingDocumentOrProject(document)
| Some (parsingOptions, _) -> let! textChanges = FSharpEditorFormattingService.GetPasteChanges(document.Id, sourceText, document.FilePath, settings.Formatting, tabSize, parsingOptions, currentClipboard, span)
let! textChanges = FSharpEditorFormattingService.GetPasteChanges(document.Id, sourceText, document.FilePath, settings.Formatting, tabSize, parsingOptions, currentClipboard, span) return textChanges |> Option.defaultValue Seq.empty |> toIList
return textChanges |> Option.defaultValue Seq.empty |> toIList
| None ->
return toIList Seq.empty
} }
interface IFSharpEditorFormattingService with interface IFSharpEditorFormattingService with
......
...@@ -61,7 +61,7 @@ type internal FSharpIndentationService ...@@ -61,7 +61,7 @@ type internal FSharpIndentationService
true true
| _ -> false | _ -> false
static member GetDesiredIndentation(documentId: DocumentId, sourceText: SourceText, filePath: string, lineNumber: int, tabSize: int, indentStyle: FormattingOptions.IndentStyle, options: (FSharpParsingOptions * FSharpProjectOptions) option): Option<int> = static member GetDesiredIndentation(documentId: DocumentId, sourceText: SourceText, filePath: string, lineNumber: int, tabSize: int, indentStyle: FormattingOptions.IndentStyle, parsingOptions: FSharpParsingOptions): Option<int> =
// Match indentation with previous line // Match indentation with previous line
let rec tryFindPreviousNonEmptyLine l = let rec tryFindPreviousNonEmptyLine l =
...@@ -81,8 +81,6 @@ type internal FSharpIndentationService ...@@ -81,8 +81,6 @@ type internal FSharpIndentationService
|> Seq.takeWhile ((=) ' ') |> Seq.takeWhile ((=) ' ')
|> Seq.length |> Seq.length
let! parsingOptions, _ = options
// Only use smart indentation after tokens that need indentation // Only use smart indentation after tokens that need indentation
// if the option is enabled // if the option is enabled
return return
...@@ -100,8 +98,8 @@ type internal FSharpIndentationService ...@@ -100,8 +98,8 @@ type internal FSharpIndentationService
let! options = document.GetOptionsAsync(cancellationToken) |> Async.AwaitTask let! options = document.GetOptionsAsync(cancellationToken) |> Async.AwaitTask
let tabSize = options.GetOption<int>(FormattingOptions.TabSize, FSharpConstants.FSharpLanguageName) let tabSize = options.GetOption<int>(FormattingOptions.TabSize, FSharpConstants.FSharpLanguageName)
let indentStyle = options.GetOption(FormattingOptions.SmartIndent, FSharpConstants.FSharpLanguageName) let indentStyle = options.GetOption(FormattingOptions.SmartIndent, FSharpConstants.FSharpLanguageName)
let! projectOptionsOpt = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let parsingOptions = projectInfoManager.TryGetQuickParsingOptionsForEditingDocumentOrProject(document)
let indent = FSharpIndentationService.GetDesiredIndentation(document.Id, sourceText, document.FilePath, lineNumber, tabSize, indentStyle, projectOptionsOpt) let indent = FSharpIndentationService.GetDesiredIndentation(document.Id, sourceText, document.FilePath, lineNumber, tabSize, indentStyle, parsingOptions)
return return
match indent with match indent with
| None -> Nullable() | None -> Nullable()
......
...@@ -169,7 +169,7 @@ type internal InlineRenameService ...@@ -169,7 +169,7 @@ type internal InlineRenameService
interface IFSharpEditorInlineRenameService with interface IFSharpEditorInlineRenameService with
member __.GetRenameInfoAsync(document: Document, position: int, cancellationToken: CancellationToken) : Task<IFSharpInlineRenameInfo> = member __.GetRenameInfoAsync(document: Document, position: int, cancellationToken: CancellationToken) : Task<IFSharpInlineRenameInfo> =
asyncMaybe { asyncMaybe {
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
return! InlineRenameService.GetInlineRenameInfo(checkerProvider.Checker, projectInfoManager, document, sourceText, position, defines, projectOptions) return! InlineRenameService.GetInlineRenameInfo(checkerProvider.Checker, projectInfoManager, document, sourceText, position, defines, projectOptions)
......
...@@ -75,7 +75,7 @@ module private FSharpProjectOptionsHelpers = ...@@ -75,7 +75,7 @@ module private FSharpProjectOptionsHelpers =
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
type private FSharpProjectOptionsMessage = 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 | TryGetOptionsByProject of Project * AsyncReplyChannel<(FSharpParsingOptions * FSharpProjectOptions) option> * CancellationToken
| ClearOptions of ProjectId | ClearOptions of ProjectId
| ClearSingleFileOptionsCache of DocumentId | ClearSingleFileOptionsCache of DocumentId
...@@ -92,13 +92,13 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor ...@@ -92,13 +92,13 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor
let cache = ConcurrentDictionary<ProjectId, Project * FSharpParsingOptions * FSharpProjectOptions>() let cache = ConcurrentDictionary<ProjectId, Project * FSharpParsingOptions * FSharpProjectOptions>()
let singleFileCache = ConcurrentDictionary<DocumentId, VersionStamp * FSharpParsingOptions * FSharpProjectOptions>() let singleFileCache = ConcurrentDictionary<DocumentId, VersionStamp * FSharpParsingOptions * FSharpProjectOptions>()
let rec tryComputeOptionsByFile (document: Document) (ct: CancellationToken) = let rec tryComputeOptionsByFile (document: Document) (ct: CancellationToken) userOpName =
async { async {
let! fileStamp = document.GetTextVersionAsync(ct) |> Async.AwaitTask let! fileStamp = document.GetTextVersionAsync(ct) |> Async.AwaitTask
match singleFileCache.TryGetValue(document.Id) with match singleFileCache.TryGetValue(document.Id) with
| false, _ -> | false, _ ->
let! sourceText = document.GetTextAsync(ct) |> Async.AwaitTask 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 = let projectOptions =
if isScriptFile document.FilePath then if isScriptFile document.FilePath then
scriptProjectOptions scriptProjectOptions
...@@ -129,7 +129,7 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor ...@@ -129,7 +129,7 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor
| true, (fileStamp2, parsingOptions, projectOptions) -> | true, (fileStamp2, parsingOptions, projectOptions) ->
if fileStamp <> fileStamp2 then if fileStamp <> fileStamp2 then
singleFileCache.TryRemove(document.Id) |> ignore singleFileCache.TryRemove(document.Id) |> ignore
return! tryComputeOptionsByFile document ct return! tryComputeOptionsByFile document ct userOpName
else else
return Some(parsingOptions, projectOptions) return Some(parsingOptions, projectOptions)
} }
...@@ -244,7 +244,7 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor ...@@ -244,7 +244,7 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor
async { async {
while true do while true do
match! agent.Receive() with match! agent.Receive() with
| FSharpProjectOptionsMessage.TryGetOptionsByDocument(document, reply, ct) -> | FSharpProjectOptionsMessage.TryGetOptionsByDocument(document, reply, ct, userOpName) ->
if ct.IsCancellationRequested then if ct.IsCancellationRequested then
reply.Reply None reply.Reply None
else else
...@@ -253,7 +253,7 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor ...@@ -253,7 +253,7 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor
if document.Project.Solution.Workspace.Kind = WorkspaceKind.MiscellaneousFiles then if document.Project.Solution.Workspace.Kind = WorkspaceKind.MiscellaneousFiles then
reply.Reply None reply.Reply None
elif document.Project.Name = FSharpConstants.FSharpMiscellaneousFilesName then elif document.Project.Name = FSharpConstants.FSharpMiscellaneousFilesName then
let! options = tryComputeOptionsByFile document ct let! options = tryComputeOptionsByFile document ct userOpName
reply.Reply options reply.Reply options
else else
// We only care about the latest project in the workspace's solution. // We only care about the latest project in the workspace's solution.
...@@ -300,8 +300,8 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor ...@@ -300,8 +300,8 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor
member __.TryGetOptionsByProjectAsync(project, ct) = member __.TryGetOptionsByProjectAsync(project, ct) =
agent.PostAndAsyncReply(fun reply -> FSharpProjectOptionsMessage.TryGetOptionsByProject(project, reply, ct)) agent.PostAndAsyncReply(fun reply -> FSharpProjectOptionsMessage.TryGetOptionsByProject(project, reply, ct))
member __.TryGetOptionsByDocumentAsync(document, ct) = member __.TryGetOptionsByDocumentAsync(document, ct, userOpName) =
agent.PostAndAsyncReply(fun reply -> FSharpProjectOptionsMessage.TryGetOptionsByDocument(document, reply, ct)) agent.PostAndAsyncReply(fun reply -> FSharpProjectOptionsMessage.TryGetOptionsByDocument(document, reply, ct, userOpName))
member __.ClearOptionsByProjectId(projectId) = member __.ClearOptionsByProjectId(projectId) =
agent.Post(FSharpProjectOptionsMessage.ClearOptions(projectId)) agent.Post(FSharpProjectOptionsMessage.ClearOptions(projectId))
...@@ -379,23 +379,29 @@ type internal FSharpProjectOptionsManager ...@@ -379,23 +379,29 @@ type internal FSharpProjectOptionsManager
reactor.TryGetOptionsByProjectAsync(project) reactor.TryGetOptionsByProjectAsync(project)
/// Get the exact options for a document or project /// Get the exact options for a document or project
member this.TryGetOptionsForDocumentOrProject(document: Document, cancellationToken) = member this.TryGetOptionsForDocumentOrProject(document: Document, cancellationToken, userOpName) =
async { async {
match! reactor.TryGetOptionsByDocumentAsync(document, cancellationToken) with match! reactor.TryGetOptionsByDocumentAsync(document, cancellationToken, userOpName) with
| Some(parsingOptions, projectOptions) -> | Some(parsingOptions, projectOptions) ->
return Some(parsingOptions, None, projectOptions) return Some(parsingOptions, None, projectOptions)
| _ -> | _ ->
return None return None
} }
/// Get the options for a document or project relevant for syntax processing. /// Get the exact 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, userOpName) =
member this.TryGetOptionsForEditingDocumentOrProject(document:Document, cancellationToken) =
async { async {
let! result = this.TryGetOptionsForDocumentOrProject(document, cancellationToken) let! result = this.TryGetOptionsForDocumentOrProject(document, cancellationToken, userOpName)
return result |> Option.map(fun (parsingOptions, _, projectOptions) -> parsingOptions, projectOptions) 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 }
[<Export>] [<Export>]
/// This handles commandline change notifications from the Dotnet Project-system /// 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 /// Prior to VS 15.7 path contained path to project file, post 15.7 contains target binpath
......
...@@ -25,7 +25,7 @@ module internal SymbolHelpers = ...@@ -25,7 +25,7 @@ module internal SymbolHelpers =
let textLine = sourceText.Lines.GetLineFromPosition(position) let textLine = sourceText.Lines.GetLineFromPosition(position)
let textLinePos = sourceText.Lines.GetLinePosition(position) let textLinePos = sourceText.Lines.GetLinePosition(position)
let fcsTextLineNumber = Line.fromZ textLinePos.Line 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 defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, false) let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, false)
let settings = document.FSharpOptions let settings = document.FSharpOptions
...@@ -118,7 +118,7 @@ module internal SymbolHelpers = ...@@ -118,7 +118,7 @@ module internal SymbolHelpers =
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let originalText = sourceText.ToString(symbolSpan) let originalText = sourceText.ToString(symbolSpan)
do! Option.guard (originalText.Length > 0) 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 defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, symbolSpan.Start, document.FilePath, defines, SymbolLookupKind.Greedy, false) let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, symbolSpan.Start, document.FilePath, defines, SymbolLookupKind.Greedy, false)
let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, userOpName = userOpName) let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, userOpName = userOpName)
......
...@@ -51,7 +51,7 @@ type internal FSharpFindUsagesService ...@@ -51,7 +51,7 @@ type internal FSharpFindUsagesService
asyncMaybe { asyncMaybe {
let! sourceText = document.GetTextAsync(context.CancellationToken) |> Async.AwaitTask |> liftAsync let! sourceText = document.GetTextAsync(context.CancellationToken) |> Async.AwaitTask |> liftAsync
let checker = checkerProvider.Checker 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! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName = userOpName)
let textLine = sourceText.Lines.GetLineFromPosition(position).ToString() let textLine = sourceText.Lines.GetLineFromPosition(position).ToString()
let lineNumber = sourceText.Lines.GetLinePosition(position).Line + 1 let lineNumber = sourceText.Lines.GetLinePosition(position).Line + 1
......
...@@ -168,7 +168,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP ...@@ -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. /// 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) = member private __.FindSymbolHelper (originDocument: Document, originRange: range, sourceText: SourceText, preferSignature: bool) =
asyncMaybe { asyncMaybe {
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(originDocument, CancellationToken.None) let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(originDocument, CancellationToken.None, userOpName)
let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
let! originTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sourceText, originRange) let! originTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sourceText, originRange)
let position = originTextSpan.Start let position = originTextSpan.Start
...@@ -190,7 +190,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP ...@@ -190,7 +190,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
if not (File.Exists fsfilePath) then return! None else if not (File.Exists fsfilePath) then return! None else
let! implDoc = originDocument.Project.Solution.TryGetDocumentFromPath fsfilePath let! implDoc = originDocument.Project.Solution.TryGetDocumentFromPath fsfilePath
let! implSourceText = implDoc.GetTextAsync () 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! _, _, checkFileResults = checker.ParseAndCheckDocument (implDoc, projectOptions, sourceText=implSourceText, userOpName=userOpName)
let! symbolUses = checkFileResults.GetUsesOfSymbolInFile symbol |> liftAsync let! symbolUses = checkFileResults.GetUsesOfSymbolInFile symbol |> liftAsync
let! implSymbol = symbolUses |> Array.tryHead let! implSymbol = symbolUses |> Array.tryHead
...@@ -220,7 +220,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP ...@@ -220,7 +220,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
member private this.FindDefinitionAtPosition(originDocument: Document, position: int) = member private this.FindDefinitionAtPosition(originDocument: Document, position: int) =
asyncMaybe { asyncMaybe {
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(originDocument, CancellationToken.None) let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(originDocument, CancellationToken.None, userOpName)
let! sourceText = originDocument.GetTextAsync () |> liftTaskAsync let! sourceText = originDocument.GetTextAsync () |> liftTaskAsync
let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
let textLine = sourceText.Lines.GetLineFromPosition position let textLine = sourceText.Lines.GetLineFromPosition position
...@@ -307,7 +307,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP ...@@ -307,7 +307,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
let! implDocument = originDocument.Project.Solution.TryGetDocumentFromPath implFilePath let! implDocument = originDocument.Project.Solution.TryGetDocumentFromPath implFilePath
let! implVersion = implDocument.GetTextVersionAsync () |> liftTaskAsync let! implVersion = implDocument.GetTextVersionAsync () |> liftTaskAsync
let! implSourceText = implDocument.GetTextAsync () |> 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()) let! targetRange = this.FindSymbolDeclarationInFile(targetSymbolUse, implFilePath, implSourceText, projectOptions, implVersion.GetHashCode())
......
...@@ -172,6 +172,7 @@ type internal FSharpNavigateToSearchService ...@@ -172,6 +172,7 @@ type internal FSharpNavigateToSearchService
projectInfoManager: FSharpProjectOptionsManager projectInfoManager: FSharpProjectOptionsManager
) = ) =
let userOpName = "FSharpNavigateToSearchService"
let kindsProvided = ImmutableHashSet.Create(FSharpNavigateToItemKind.Module, FSharpNavigateToItemKind.Class, FSharpNavigateToItemKind.Field, FSharpNavigateToItemKind.Property, FSharpNavigateToItemKind.Method, FSharpNavigateToItemKind.Enum, FSharpNavigateToItemKind.EnumItem) :> IImmutableSet<string> let kindsProvided = ImmutableHashSet.Create(FSharpNavigateToItemKind.Module, FSharpNavigateToItemKind.Class, FSharpNavigateToItemKind.Field, FSharpNavigateToItemKind.Property, FSharpNavigateToItemKind.Method, FSharpNavigateToItemKind.Enum, FSharpNavigateToItemKind.EnumItem) :> IImmutableSet<string>
// Save the backing navigation data in a memory cache held in a sliding window // Save the backing navigation data in a memory cache held in a sliding window
...@@ -261,7 +262,7 @@ type internal FSharpNavigateToSearchService ...@@ -261,7 +262,7 @@ type internal FSharpNavigateToSearchService
member __.SearchDocumentAsync(document, searchPattern, kinds, cancellationToken) : Task<ImmutableArray<FSharpNavigateToSearchResult>> = member __.SearchDocumentAsync(document, searchPattern, kinds, cancellationToken) : Task<ImmutableArray<FSharpNavigateToSearchResult>> =
asyncMaybe { asyncMaybe {
let! parsingOptions, _, _ = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken) let! parsingOptions, _, _ = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken, userOpName)
let! items = getCachedIndexedNavigableItems(document, parsingOptions, kinds) |> liftAsync let! items = getCachedIndexedNavigableItems(document, parsingOptions, kinds) |> liftAsync
return items.Find(searchPattern) return items.Find(searchPattern)
} }
......
...@@ -32,7 +32,7 @@ type internal FSharpNavigationBarItemService ...@@ -32,7 +32,7 @@ type internal FSharpNavigationBarItemService
interface IFSharpNavigationBarItemService with interface IFSharpNavigationBarItemService with
member __.GetItemsAsync(document, cancellationToken) : Task<IList<FSharpNavigationBarItem>> = member __.GetItemsAsync(document, cancellationToken) : Task<IList<FSharpNavigationBarItem>> =
asyncMaybe { asyncMaybe {
let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! parsedInput = checkerProvider.Checker.ParseDocument(document, parsingOptions, sourceText=sourceText, userOpName=userOpName) let! parsedInput = checkerProvider.Checker.ParseDocument(document, parsingOptions, sourceText=sourceText, userOpName=userOpName)
let navItems = FSharpNavigation.getNavigation parsedInput let navItems = FSharpNavigation.getNavigation parsedInput
......
...@@ -92,7 +92,7 @@ module internal FSharpQuickInfo = ...@@ -92,7 +92,7 @@ module internal FSharpQuickInfo =
asyncMaybe { asyncMaybe {
let! sourceText = document.GetTextAsync cancellationToken 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 defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, true) let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, true)
let idRange = lexerSymbol.Ident.idRange let idRange = lexerSymbol.Ident.idRange
......
...@@ -152,7 +152,7 @@ type internal FSharpBlockStructureService [<ImportingConstructor>] (checkerProvi ...@@ -152,7 +152,7 @@ type internal FSharpBlockStructureService [<ImportingConstructor>] (checkerProvi
member __.GetBlockStructureAsync(document, cancellationToken) : Task<FSharpBlockStructure> = member __.GetBlockStructureAsync(document, cancellationToken) : Task<FSharpBlockStructure> =
asyncMaybe { asyncMaybe {
let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken, userOpName)
let! sourceText = document.GetTextAsync(cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken)
let! parsedInput = checkerProvider.Checker.ParseDocument(document, parsingOptions, sourceText, userOpName) let! parsedInput = checkerProvider.Checker.ParseDocument(document, parsingOptions, sourceText, userOpName)
return createBlockSpans document.FSharpOptions.Advanced.IsBlockStructureEnabled sourceText parsedInput |> Seq.toImmutableArray return createBlockSpans document.FSharpOptions.Advanced.IsBlockStructureEnabled sourceText parsedInput |> Seq.toImmutableArray
......
...@@ -78,7 +78,7 @@ marker4""" ...@@ -78,7 +78,7 @@ marker4"""
let lineNumber = sourceText.Lines |> Seq.findIndex (fun line -> line.Span.Contains position) let lineNumber = sourceText.Lines |> Seq.findIndex (fun line -> line.Span.Contains position)
let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions 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 match changesOpt with
| None -> Assert.Fail("Expected a text change, but got None") | None -> Assert.Fail("Expected a text change, but got None")
| Some changes -> | Some changes ->
......
...@@ -176,7 +176,7 @@ while true do ...@@ -176,7 +176,7 @@ while true do
let sourceText = SourceText.From(template) let sourceText = SourceText.From(template)
let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions 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 match expectedIndentation with
| None -> Assert.IsTrue(actualIndentation.IsNone, "No indentation was expected at line {0}", lineNumber) | 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) | Some indentation -> Assert.AreEqual(expectedIndentation.Value, actualIndentation.Value, "Indentation on line {0} doesn't match", lineNumber)
...@@ -189,7 +189,7 @@ while true do ...@@ -189,7 +189,7 @@ while true do
let sourceText = SourceText.From(template) let sourceText = SourceText.From(template)
let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions 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 match expectedIndentation with
| None -> Assert.IsTrue(actualIndentation.IsNone, "No indentation was expected at line {0}", lineNumber) | 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) | Some indentation -> Assert.AreEqual(expectedIndentation.Value, actualIndentation.Value, "Indentation on line {0} doesn't match", lineNumber)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册