From 8e31924fdee7fe5c45aedc812f3b35366c49a405 Mon Sep 17 00:00:00 2001 From: dsyme Date: Sun, 27 Nov 2016 18:43:13 +0000 Subject: [PATCH] Get correct options for scripts --- src/fsharp/vs/IncrementalBuild.fs | 16 +- src/fsharp/vs/IncrementalBuild.fsi | 2 +- src/fsharp/vs/service.fs | 29 +-- src/fsharp/vs/service.fsi | 14 +- tests/service/FileSystemTests.fs | 3 +- .../src/FSharp.Editor/BraceMatchingService.fs | 2 +- .../BreakpointResolutionService.fs | 2 +- .../src/FSharp.Editor/ColorizationService.fs | 10 +- .../src/FSharp.Editor/CommonHelpers.fs | 4 +- .../src/FSharp.Editor/CompletionProvider.fs | 10 +- .../DocumentDiagnosticAnalyzer.fs | 7 +- .../FSharp.Editor/GoToDefinitionService.fs | 2 +- .../FSharp.Editor/LanguageDebugInfoService.fs | 19 +- .../src/FSharp.Editor/LanguageService.fs | 176 +++++++++++++----- .../ProjectDiagnosticAnalyzer.fs | 2 +- .../src/FSharp.Editor/QuickInfoProvider.fs | 14 +- .../src/FSharp.Editor/SignatureHelp.fs | 2 +- .../BackgroundRequests.fs | 2 +- .../FSharp.LanguageService/FSharpSource.fs | 3 +- .../ProjectSitesAndFiles.fs | 5 +- .../Salsa/FSharpLanguageServiceTestable.fs | 6 +- .../unittests/BraceMatchingServiceTests.fs | 1 + .../unittests/BreakpointResolutionService.fs | 1 + .../unittests/CompletionProviderTests.fs | 1 + .../DocumentDiagnosticAnalyzerTests.fs | 1 + .../unittests/GoToDefinitionServiceTests.fs | 1 + .../tests/unittests/QuickInfoProviderTests.fs | 1 + .../unittests/SignatureHelpProviderTests.fs | 2 +- 28 files changed, 213 insertions(+), 125 deletions(-) diff --git a/src/fsharp/vs/IncrementalBuild.fs b/src/fsharp/vs/IncrementalBuild.fs index 5110eda78ea..482e77c6784 100755 --- a/src/fsharp/vs/IncrementalBuild.fs +++ b/src/fsharp/vs/IncrementalBuild.fs @@ -1272,10 +1272,10 @@ type IncrementalBuilder(frameworkTcImportsCache: FrameworkImportsCache, tcConfig let tcConfigP = TcConfigProvider.Constant(tcConfig) let importsInvalidated = new Event() - let fileParsed = new Event<_>() - let beforeTypeCheckFile = new Event<_>() - let fileChecked = new Event<_>() - let projectChecked = new Event<_>() + let fileParsed = new Event() + let beforeFileChecked = new Event() + let fileChecked = new Event() + let projectChecked = new Event() // Resolve assemblies and create the framework TcImports. This is done when constructing the // builder itself, rather than as an incremental task. This caches a level of "system" references. No type providers are @@ -1361,7 +1361,7 @@ type IncrementalBuilder(frameworkTcImportsCache: FrameworkImportsCache, tcConfig try IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBEParsed filename) let result = ParseOneInputFile(tcConfig,lexResourceManager, [], filename ,isLastCompiland,errorLogger,(*retryLocked*)true) - fileParsed.Trigger filename + fileParsed.Trigger (filename) result,sourceRange,filename,errorLogger.GetErrors () with exn -> System.Diagnostics.Debug.Assert(false, sprintf "unexpected failure in IncrementalFSharpBuild.Parse\nerror = %s" (exn.ToString())) @@ -1457,7 +1457,7 @@ type IncrementalBuilder(frameworkTcImportsCache: FrameworkImportsCache, tcConfig let errorLogger = GetErrorLoggerFilteringByScopedPragmas(false,GetScopedPragmasForInput(input),capturingErrorLogger) let fullComputation = eventually { - beforeTypeCheckFile.Trigger filename + beforeFileChecked.Trigger (filename) ApplyMetaCommandsFromInputToTcConfig tcConfig (input, Path.GetDirectoryName filename) |> ignore let sink = TcResultsSinkImpl(tcAcc.tcGlobals) @@ -1475,7 +1475,7 @@ type IncrementalBuilder(frameworkTcImportsCache: FrameworkImportsCache, tcConfig let typedImplFiles = if keepAssemblyContents then typedImplFiles else [] let tcResolutions = if keepAllBackgroundResolutions then sink.GetResolutions() else TcResolutions.Empty let tcSymbolUses = sink.GetSymbolUses() - fileChecked.Trigger filename + fileChecked.Trigger (filename) return {tcAcc with tcState=tcState tcEnvAtEndOfFile=tcEnvAtEndOfFile topAttribs=Some topAttribs @@ -1656,7 +1656,7 @@ type IncrementalBuilder(frameworkTcImportsCache: FrameworkImportsCache, tcConfig member __.TcConfig = tcConfig member __.FileParsed = fileParsed.Publish - member __.BeforeTypeCheckFile = beforeTypeCheckFile.Publish + member __.BeforeFileChecked = beforeFileChecked.Publish member __.FileChecked = fileChecked.Publish member __.ProjectChecked = projectChecked.Publish member __.ImportedCcusInvalidated = importsInvalidated.Publish diff --git a/src/fsharp/vs/IncrementalBuild.fsi b/src/fsharp/vs/IncrementalBuild.fsi index 5698b25b369..6ca31a191ea 100755 --- a/src/fsharp/vs/IncrementalBuild.fsi +++ b/src/fsharp/vs/IncrementalBuild.fsi @@ -122,7 +122,7 @@ type internal IncrementalBuilder = /// Raised just before a file is type-checked, to invalidate the state of the file in VS and force VS to request a new direct typecheck of the file. /// The incremental builder also typechecks the file (error and intellisense results from the backgroud builder are not /// used by VS). - member BeforeTypeCheckFile : IEvent + member BeforeFileChecked : IEvent /// Raised just after a file is parsed member FileParsed : IEvent diff --git a/src/fsharp/vs/service.fs b/src/fsharp/vs/service.fs index e31c120fc73..199c46318af 100755 --- a/src/fsharp/vs/service.fs +++ b/src/fsharp/vs/service.fs @@ -1732,6 +1732,7 @@ type FSharpProjectOptions = UseScriptResolutionRules : bool LoadTime : System.DateTime UnresolvedReferences : UnresolvedReferencesSet option + ExtraProjectInfo : obj option } member x.ProjectOptions = x.OtherOptions /// Whether the two parse options refer to the same project. @@ -2048,10 +2049,10 @@ module Helpers = type BackgroundCompiler(referenceResolver, projectCacheSize, keepAssemblyContents, keepAllBackgroundResolutions) as self = // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.backgroundCompiler.reactor: The one and only Reactor let reactor = Reactor.Singleton - let beforeFileChecked = Event() - let fileParsed = Event() - let fileChecked = Event() - let projectChecked = Event() + let beforeFileChecked = Event() + let fileParsed = Event() + let fileChecked = Event() + let projectChecked = Event() let mutable implicitlyStartBackgroundWork = true let reactorOps = @@ -2105,10 +2106,10 @@ type BackgroundCompiler(referenceResolver, projectCacheSize, keepAssemblyContent // // This indicates to the UI that the file type check state is dirty. If the file is open and visible then // the UI will sooner or later request a typecheck of the file, recording errors and intellisense information. - builder.BeforeTypeCheckFile.Add (beforeFileChecked.Trigger) - builder.FileParsed.Add (fileParsed.Trigger) - builder.FileChecked.Add (fileChecked.Trigger) - builder.ProjectChecked.Add (fun () -> projectChecked.Trigger options.ProjectFileName) + builder.BeforeFileChecked.Add (fun file -> beforeFileChecked.Trigger(file, options.ExtraProjectInfo)) + builder.FileParsed.Add (fun file -> fileParsed.Trigger(file, options.ExtraProjectInfo)) + builder.FileChecked.Add (fun file -> fileChecked.Trigger(file, options.ExtraProjectInfo)) + builder.ProjectChecked.Add (fun () -> projectChecked.Trigger (options.ProjectFileName, options.ExtraProjectInfo)) (builderOpt, errorsAndWarnings, decrement) @@ -2438,7 +2439,7 @@ type BackgroundCompiler(referenceResolver, projectCacheSize, keepAssemblyContent member bc.ParseAndCheckProject(options) = reactor.EnqueueAndAwaitOpAsync("ParseAndCheckProject " + options.ProjectFileName, fun ct -> bc.ParseAndCheckProjectImpl(options, ct)) - member bc.GetProjectOptionsFromScript(filename, source, ?loadedTimeStamp, ?otherFlags, ?useFsiAuxLib, ?assumeDotNetFramework) = + member bc.GetProjectOptionsFromScript(filename, source, ?loadedTimeStamp, ?otherFlags, ?useFsiAuxLib, ?assumeDotNetFramework, ?extraProjectInfo: obj) = reactor.EnqueueAndAwaitOpAsync ("GetProjectOptionsFromScript " + filename, fun _ct -> // Do we add a reference to FSharp.Compiler.Interactive.Settings by default? let useFsiAuxLib = defaultArg useFsiAuxLib true @@ -2473,6 +2474,7 @@ type BackgroundCompiler(referenceResolver, projectCacheSize, keepAssemblyContent UseScriptResolutionRules = true LoadTime = loadedTimeStamp UnresolvedReferences = Some (UnresolvedReferencesSet(fas.UnresolvedReferences)) + ExtraProjectInfo=extraProjectInfo } scriptClosureCache.Set(co,fas) // Save the full load closure for later correlation. co) @@ -2664,10 +2666,10 @@ type FSharpChecker(referenceResolver, projectCacheSize, keepAssemblyContents, ke backgroundCompiler.KeepProjectAlive(options) /// For a given script file, get the ProjectOptions implied by the #load closure - member ic.GetProjectOptionsFromScript(filename, source, ?loadedTimeStamp, ?otherFlags, ?useFsiAuxLib) = - backgroundCompiler.GetProjectOptionsFromScript(filename,source,?loadedTimeStamp=loadedTimeStamp, ?otherFlags=otherFlags, ?useFsiAuxLib=useFsiAuxLib) + member ic.GetProjectOptionsFromScript(filename, source, ?loadedTimeStamp, ?otherFlags, ?useFsiAuxLib, ?extraProjectInfo: obj) = + backgroundCompiler.GetProjectOptionsFromScript(filename,source,?loadedTimeStamp=loadedTimeStamp, ?otherFlags=otherFlags, ?useFsiAuxLib=useFsiAuxLib, ?extraProjectInfo=extraProjectInfo) - member ic.GetProjectOptionsFromCommandLineArgs(projectFileName, argv, ?loadedTimeStamp) = + member ic.GetProjectOptionsFromCommandLineArgs(projectFileName, argv, ?loadedTimeStamp, ?extraProjectInfo: obj) = let loadedTimeStamp = defaultArg loadedTimeStamp DateTime.MaxValue // Not 'now', we don't want to force reloading { ProjectFileName = projectFileName ProjectFileNames = [| |] // the project file names will be inferred from the ProjectOptions @@ -2676,7 +2678,8 @@ type FSharpChecker(referenceResolver, projectCacheSize, keepAssemblyContents, ke IsIncompleteTypeCheckEnvironment = false UseScriptResolutionRules = false LoadTime = loadedTimeStamp - UnresolvedReferences = None } + UnresolvedReferences = None + ExtraProjectInfo=extraProjectInfo } /// Begin background parsing the given project. member ic.StartBackgroundCompile(options) = backgroundCompiler.CheckProjectInBackground(options) diff --git a/src/fsharp/vs/service.fsi b/src/fsharp/vs/service.fsi index d978cafc41e..e844410f2d1 100755 --- a/src/fsharp/vs/service.fsi +++ b/src/fsharp/vs/service.fsi @@ -318,6 +318,8 @@ type internal FSharpProjectOptions = LoadTime : DateTime /// Unused in this API and should be 'None' UnresolvedReferences : UnresolvedReferencesSet option + /// Extra information passed back on event trigger + ExtraProjectInfo : obj option } @@ -473,7 +475,7 @@ type internal FSharpChecker = /// Indicates when the script was loaded into the editing environment, /// so that an 'unload' and 'reload' action will cause the script to be considered as a new project, /// so that references are re-resolved. - member GetProjectOptionsFromScript : filename: string * source: string * ?loadedTimeStamp: DateTime * ?otherFlags: string[] * ?useFsiAuxLib: bool -> Async + member GetProjectOptionsFromScript : filename: string * source: string * ?loadedTimeStamp: DateTime * ?otherFlags: string[] * ?useFsiAuxLib: bool * ?extraProjectInfo: obj -> Async /// /// Get the FSharpProjectOptions implied by a set of command line arguments. @@ -484,7 +486,7 @@ type internal FSharpChecker = /// Indicates when the script was loaded into the editing environment, /// so that an 'unload' and 'reload' action will cause the script to be considered as a new project, /// so that references are re-resolved. - member GetProjectOptionsFromCommandLineArgs : projectFileName: string * argv: string[] * ?loadedTimeStamp: DateTime -> FSharpProjectOptions + member GetProjectOptionsFromCommandLineArgs : projectFileName: string * argv: string[] * ?loadedTimeStamp: DateTime * ?extraProjectInfo: obj -> FSharpProjectOptions /// /// Like ParseFileInProject, but uses results from the background builder. @@ -558,17 +560,17 @@ type internal FSharpChecker = /// and that the file has become eligible to be re-typechecked for errors. /// /// The event will be raised on a background thread. - member BeforeBackgroundFileCheck : IEvent + member BeforeBackgroundFileCheck : IEvent /// Raised after a parse of a file in the background analysis. /// /// The event will be raised on a background thread. - member FileParsed : IEvent + member FileParsed : IEvent /// Raised after a check of a file in the background analysis. /// /// The event will be raised on a background thread. - member FileChecked : IEvent + member FileChecked : IEvent /// Get or set a flag which controls if background work is started implicitly. /// @@ -583,7 +585,7 @@ type internal FSharpChecker = /// Notify the host that a project has been fully checked in the background (using file contents provided by the file system API) /// /// The event may be raised on a background thread. - member ProjectChecked : IEvent + member ProjectChecked : IEvent // For internal use only member internal ReactorOps : IReactorOperations diff --git a/tests/service/FileSystemTests.fs b/tests/service/FileSystemTests.fs index e335125eb16..b5e492e6960 100644 --- a/tests/service/FileSystemTests.fs +++ b/tests/service/FileSystemTests.fs @@ -101,7 +101,8 @@ let ``FileSystem compilation test``() = IsIncompleteTypeCheckEnvironment = false UseScriptResolutionRules = true LoadTime = System.DateTime.Now // Not 'now', we don't want to force reloading - UnresolvedReferences = None } + UnresolvedReferences = None + ExtraProjectInfo = None } let results = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously diff --git a/vsintegration/src/FSharp.Editor/BraceMatchingService.fs b/vsintegration/src/FSharp.Editor/BraceMatchingService.fs index 359fcf4b3d1..72ca9500fdb 100644 --- a/vsintegration/src/FSharp.Editor/BraceMatchingService.fs +++ b/vsintegration/src/FSharp.Editor/BraceMatchingService.fs @@ -23,7 +23,7 @@ type internal FSharpBraceMatchingService() = interface IBraceMatcher with member this.FindBracesAsync(document, position, cancellationToken) = async { - match FSharpLanguageService.GetOptions(document.Project.Id) with + match FSharpLanguageService.TryGetOptionsForEditingDocumentOrProject(document) with | Some(options) -> let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! result = FSharpBraceMatchingService.GetBraceMatchingResult(sourceText, document.Name, options, position) diff --git a/vsintegration/src/FSharp.Editor/BreakpointResolutionService.fs b/vsintegration/src/FSharp.Editor/BreakpointResolutionService.fs index db7e405d799..4ab50fe1a81 100644 --- a/vsintegration/src/FSharp.Editor/BreakpointResolutionService.fs +++ b/vsintegration/src/FSharp.Editor/BreakpointResolutionService.fs @@ -48,7 +48,7 @@ type internal FSharpBreakpointResolutionService() = interface IBreakpointResolutionService with member this.ResolveBreakpointAsync(document: Document, textSpan: TextSpan, cancellationToken: CancellationToken): Task = async { - match FSharpLanguageService.GetOptions(document.Project.Id) with + match FSharpLanguageService.TryGetOptionsForEditingDocumentOrProject(document) with | Some(options) -> let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! location = FSharpBreakpointResolutionService.GetBreakpointLocation(sourceText, document.Name, textSpan, options) diff --git a/vsintegration/src/FSharp.Editor/ColorizationService.fs b/vsintegration/src/FSharp.Editor/ColorizationService.fs index 9060eb0b249..72a3c689e44 100644 --- a/vsintegration/src/FSharp.Editor/ColorizationService.fs +++ b/vsintegration/src/FSharp.Editor/ColorizationService.fs @@ -36,18 +36,14 @@ type internal FSharpColorizationService() = member this.AddSyntacticClassificationsAsync(document: Document, textSpan: TextSpan, result: List, cancellationToken: CancellationToken) = async { + let defines = FSharpLanguageService.GetCompilationDefinesForEditingDocument(document) let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask - match FSharpLanguageService.GetOptions(document.Project.Id) with - | Some(options) -> - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList) - result.AddRange(CommonHelpers.getColorizationData( - document.Id, sourceText, textSpan, Some(document.FilePath), defines, cancellationToken)) - | None -> () + result.AddRange(CommonHelpers.getColorizationData(document.Id, sourceText, textSpan, Some(document.FilePath), defines, cancellationToken)) } |> CommonRoslynHelpers.StartAsyncUnitAsTask(cancellationToken) member this.AddSemanticClassificationsAsync(document: Document, textSpan: TextSpan, result: List, cancellationToken: CancellationToken) = async { - match FSharpLanguageService.GetOptions(document.Project.Id) with + match FSharpLanguageService.TryGetOptionsForEditingDocumentOrProject(document) with | Some(options) -> let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask diff --git a/vsintegration/src/FSharp.Editor/CommonHelpers.fs b/vsintegration/src/FSharp.Editor/CommonHelpers.fs index 7ebf0c54173..c193082aee7 100644 --- a/vsintegration/src/FSharp.Editor/CommonHelpers.fs +++ b/vsintegration/src/FSharp.Editor/CommonHelpers.fs @@ -152,7 +152,9 @@ module CommonHelpers = | None -> () result - with ex -> + with + | :? System.OperationCanceledException -> reraise() + | ex -> Assert.Exception(ex) List() diff --git a/vsintegration/src/FSharp.Editor/CompletionProvider.fs b/vsintegration/src/FSharp.Editor/CompletionProvider.fs index 819eec560b1..e94d9442983 100644 --- a/vsintegration/src/FSharp.Editor/CompletionProvider.fs +++ b/vsintegration/src/FSharp.Editor/CompletionProvider.fs @@ -136,18 +136,14 @@ type internal FSharpCompletionProvider(workspace: Workspace, serviceProvider: SV let getInfo() = let documentId = workspace.GetDocumentIdInCurrentContext(sourceText.Container) let document = workspace.CurrentSolution.GetDocument(documentId) - - let defines = - match FSharpLanguageService.GetOptions(document.Project.Id) with - | None -> [] - | Some(options) -> CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList) - document.Id, document.FilePath, defines + let defines = FSharpLanguageService.GetCompilationDefinesForEditingDocument(document) + (documentId, document.FilePath, defines) FSharpCompletionProvider.ShouldTriggerCompletionAux(sourceText, caretPosition, trigger.Kind, getInfo) override this.ProvideCompletionsAsync(context: Microsoft.CodeAnalysis.Completion.CompletionContext) = async { - match FSharpLanguageService.GetOptions(context.Document.Project.Id) with + match FSharpLanguageService.TryGetOptionsForEditingDocumentOrProject(context.Document) with | Some(options) -> let! sourceText = context.Document.GetTextAsync(context.CancellationToken) |> Async.AwaitTask let! textVersion = context.Document.GetTextVersionAsync(context.CancellationToken) |> Async.AwaitTask diff --git a/vsintegration/src/FSharp.Editor/DocumentDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/DocumentDiagnosticAnalyzer.fs index 3de82d3f625..be8ae5b75be 100644 --- a/vsintegration/src/FSharp.Editor/DocumentDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/DocumentDiagnosticAnalyzer.fs @@ -25,6 +25,8 @@ type internal FSharpDocumentDiagnosticAnalyzer() = inherit DocumentDiagnosticAnalyzer() static member GetDiagnostics(filePath: string, sourceText: SourceText, textVersionHash: int, options: FSharpProjectOptions, addSemanticErrors: bool) = async { + + let! parseResults = FSharpLanguageService.Checker.ParseFileInProject(filePath, sourceText.ToString(), options) let! errors = async { if addSemanticErrors then @@ -57,7 +59,7 @@ type internal FSharpDocumentDiagnosticAnalyzer() = override this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task> = async { - match FSharpLanguageService.GetOptions(document.Project.Id) with + match FSharpLanguageService.TryGetOptionsForEditingDocumentOrProject(document) with | Some(options) -> let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask @@ -68,7 +70,8 @@ type internal FSharpDocumentDiagnosticAnalyzer() = override this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task> = async { - match FSharpLanguageService.GetOptions(document.Project.Id) with + let! optionsOpt = FSharpLanguageService.TryGetOptionsForDocumentOrProject(document) + match optionsOpt with | Some(options) -> let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask diff --git a/vsintegration/src/FSharp.Editor/GoToDefinitionService.fs b/vsintegration/src/FSharp.Editor/GoToDefinitionService.fs index d6611c0445a..632a9dfc6f0 100644 --- a/vsintegration/src/FSharp.Editor/GoToDefinitionService.fs +++ b/vsintegration/src/FSharp.Editor/GoToDefinitionService.fs @@ -79,7 +79,7 @@ type internal FSharpGoToDefinitionService [] ([() - match FSharpLanguageService.GetOptions(document.Project.Id) with + match FSharpLanguageService.TryGetOptionsForEditingDocumentOrProject(document) with | Some(options) -> let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask diff --git a/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs b/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs index dab7714df06..bc1292b6734 100644 --- a/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs +++ b/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs @@ -66,16 +66,15 @@ type internal FSharpLanguageDebugInfoService() = member this.GetDataTipInfoAsync(document: Document, position: int, cancellationToken: CancellationToken): Task = async { - match FSharpLanguageService.GetOptions(document.Project.Id) with - | Some(options) -> - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList) - let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask - let textSpan = TextSpan.FromBounds(0, sourceText.Length) - let tokens = CommonHelpers.getColorizationData(document.Id, sourceText, textSpan, Some(document.Name), defines, cancellationToken) - return match FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, position, tokens) with - | None -> Unchecked.defaultof - | Some(textSpan) -> new DebugDataTipInfo(textSpan, sourceText.GetSubText(textSpan).ToString()) - | None -> return Unchecked.defaultof + let defines = FSharpLanguageService.GetCompilationDefinesForEditingDocument(document) + let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask + let textSpan = TextSpan.FromBounds(0, sourceText.Length) + let tokens = CommonHelpers.getColorizationData(document.Id, sourceText, textSpan, Some(document.Name), defines, cancellationToken) + let result = + match FSharpLanguageDebugInfoService.GetDataTipInformation(sourceText, position, tokens) with + | None -> DebugDataTipInfo() + | Some(textSpan) -> DebugDataTipInfo(textSpan, sourceText.GetSubText(textSpan).ToString()) + return result } |> CommonRoslynHelpers.StartAsyncAsTask cancellationToken \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/LanguageService.fs b/vsintegration/src/FSharp.Editor/LanguageService.fs index 81cf5743ded..84eaab6fcf0 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService.fs @@ -3,6 +3,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System +open System.Collections.Concurrent open System.Collections.Generic open System.Runtime.InteropServices open System.Linq @@ -48,20 +49,95 @@ type internal SVsSettingsPersistenceManager = class end type internal FSharpLanguageService(package : FSharpPackage) = inherit AbstractLanguageService(package) - static let optionsCache = Dictionary() - static let checker = lazy FSharpChecker.Create() - static member Checker with get() = checker.Value - - static member GetOptions(projectId: ProjectId) = - if optionsCache.ContainsKey(projectId) then - Some(optionsCache.[projectId]) + // A table of information about projects, excluding single-file projects. + static let projectTable = ConcurrentDictionary() + + // A table of information about single-file projects. Currently we only need the load time of each such file, plus + // the original options for editing + static let singleFileProjectTable = ConcurrentDictionary() + + static let checker = lazy FSharpChecker.Create() + + + /// Update the info for a proejct in the project table + static let UpdateProjectInfo(projectId: ProjectId, site: IProjectSite, workspace: Workspace) = + let extraProjectInfo = Some(box workspace) + let options = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site, site.ProjectFileName(), extraProjectInfo) + checker.Value.InvalidateConfiguration(options) + projectTable.[projectId] <- options + + /// Clear a project from the project table + static let ClearProjectInfo(projectId: ProjectId) = + projectTable.TryRemove(projectId) |> ignore + + /// Get the exact options for a single-file script + static let ComputeSingleFileOptions (fileName, loadTime, fileContents, workspace: Workspace) = async { + let extraProjectInfo = Some(box workspace) + if SourceFile.MustBeSingleFileProject(fileName) then + let! options = checker.Value.GetProjectOptionsFromScript(fileName, fileContents, loadTime, [| |], ?extraProjectInfo=extraProjectInfo) + let site = ProjectSitesAndFiles.CreateProjectSiteForScript(fileName, options) + return ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site,fileName,options.ExtraProjectInfo) + else + let site = ProjectSitesAndFiles.ProjectSiteOfSingleFile(fileName) + return ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site,fileName,extraProjectInfo) + } + + /// Get the options for a project + static member TryGetOptionsForProject(projectId: ProjectId) = + if projectTable.ContainsKey(projectId) then + Some(projectTable.[projectId]) else None - static member UpdateOptions(projectId: ProjectId, options: FSharpProjectOptions) = - optionsCache.[projectId] <- options + /// Get the exact options for a document or project + static member TryGetOptionsForDocumentOrProject(document: Document) = async { + let projectId = document.Project.Id + + // The options for a single-file script project are re-requested each time the file is analyzed. This is because the + // single-file project may contain #load and #r references which are changing as the user edits, and we may need to re-analyze + // to determine the latest settings. FCS keeps a cache to help ensure these are up-to-date. + if singleFileProjectTable.ContainsKey(projectId) then + try + let loadTime,_ = singleFileProjectTable.[projectId] + let fileName = document.FilePath + let! cancellationToken = Async.CancellationToken + let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask + let! options = ComputeSingleFileOptions (fileName, loadTime, sourceText.ToString(), document.Project.Solution.Workspace) + singleFileProjectTable.[projectId] <- (loadTime, options) + return Some options + with ex -> + Assert.Exception(ex) + return None + else return FSharpLanguageService.TryGetOptionsForProject(projectId) + } + + /// Get the options for a document or project relevant for syntax processing. + /// Quicker then TryGetOptionsForDocumentOrProject as it doesn't need to recompute the exact project options for a script. + static member TryGetOptionsForEditingDocumentOrProject(document: Document) = + let projectId = document.Project.Id + if singleFileProjectTable.ContainsKey(projectId) then + let _loadTime, originalOptions = singleFileProjectTable.[projectId] + Some originalOptions + else + FSharpLanguageService.TryGetOptionsForProject(projectId) + + /// Get compilation defines relevant for syntax processing. + /// Quicker then TryGetOptionsForDocumentOrProject as it doesn't need to recompute the exact project + /// options for a script. + static member GetCompilationDefinesForEditingDocument(document: Document) = + let projectOptionsOpt = FSharpLanguageService.TryGetOptionsForProject(document.Project.Id) + let otherOptions = + match projectOptionsOpt with + | None -> [] + | Some(options) -> options.OtherOptions |> Array.toList + CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, otherOptions) + + /// Get the global FSharpChecker component + static member Checker with get() = checker.Value + /// Sync the information for the project member this.SyncProject(project: AbstractProject, projectContext: IWorkspaceProjectContext, site: IProjectSite) = + let hashSetIgnoreCase x = new HashSet(x, StringComparer.OrdinalIgnoreCase) let updatedFiles = site.SourceFilesOnDisk() |> hashSetIgnoreCase let workspaceFiles = project.GetCurrentDocuments() |> Seq.map(fun file -> file.FilePath) |> hashSetIgnoreCase @@ -78,39 +154,7 @@ type internal FSharpLanguageService(package : FSharpPackage) = // update the cached options if updated then - let checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site, "") - FSharpLanguageService.UpdateOptions(project.Id, checkOptions) - - override this.ContentTypeName = FSharpCommonConstants.FSharpContentTypeName - override this.LanguageName = FSharpCommonConstants.FSharpLanguageName - override this.RoslynLanguageName = FSharpCommonConstants.FSharpLanguageName - - override this.LanguageServiceId = new Guid(FSharpCommonConstants.languageServiceGuidString) - override this.DebuggerLanguageId = DebuggerEnvironment.GetLanguageID() - - override this.CreateContext(_,_,_,_,_) = raise(System.NotImplementedException()) - - override this.SetupNewTextView(textView) = - base.SetupNewTextView(textView) - let workspace = this.Package.ComponentModel.GetService() - - // FSROSLYNTODO: Hide navigation bars for now. Enable after adding tests - workspace.Options <- workspace.Options.WithChangedOption(NavigationBarOptions.ShowNavigationBar, FSharpCommonConstants.FSharpLanguageName, false) - - match textView.GetBuffer() with - | (VSConstants.S_OK, textLines) -> - let filename = VsTextLines.GetFilename textLines - match VsRunningDocumentTable.FindDocumentWithoutLocking(package.RunningDocumentTable,filename) with - | Some (hier, _) -> - match hier with - | :? IProvideProjectSite as siteProvider when not (IsScript(filename)) -> - this.SetupProjectFile(siteProvider, workspace) - | _ -> - let editorAdapterFactoryService = this.Package.ComponentModel.GetService() - let fileContents = VsTextLines.GetFileContents(textLines, editorAdapterFactoryService) - this.SetupStandAloneFile(filename, fileContents, workspace, hier) - | _ -> () - | _ -> () + UpdateProjectInfo(project.Id, site, project.Workspace) member this.SetupProjectFile(siteProvider: IProvideProjectSite, workspace: VisualStudioWorkspaceImpl) = let site = siteProvider.GetProjectSite() @@ -118,8 +162,7 @@ type internal FSharpLanguageService(package : FSharpPackage) = let projectFileName = site.ProjectFileName() let projectId = workspace.ProjectTracker.GetOrCreateProjectIdForPath(projectFileName, projectFileName) - let options = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site, site.ProjectFileName()) - FSharpLanguageService.UpdateOptions(projectId, options) + UpdateProjectInfo(projectId, site, workspace) match workspace.ProjectTracker.GetProject(projectId) with | null -> @@ -131,14 +174,16 @@ type internal FSharpLanguageService(package : FSharpPackage) = this.SyncProject(project, projectContext, site) site.AdviseProjectSiteChanges(FSharpCommonConstants.FSharpLanguageServiceCallbackName, AdviseProjectSiteChanges(fun () -> this.SyncProject(project, projectContext, site))) - site.AdviseProjectSiteClosed(FSharpCommonConstants.FSharpLanguageServiceCallbackName, AdviseProjectSiteChanges(fun () -> project.Disconnect())) + site.AdviseProjectSiteClosed(FSharpCommonConstants.FSharpLanguageServiceCallbackName, AdviseProjectSiteChanges(fun () -> ClearProjectInfo(project.Id); project.Disconnect())) | _ -> () member this.SetupStandAloneFile(fileName: string, fileContents: string, workspace: VisualStudioWorkspaceImpl, hier: IVsHierarchy) = - let options = FSharpLanguageService.Checker.GetProjectOptionsFromScript(fileName, fileContents, DateTime.Now, [| |]) |> Async.RunSynchronously - let projectId = workspace.ProjectTracker.GetOrCreateProjectIdForPath(options.ProjectFileName, options.ProjectFileName) - FSharpLanguageService.UpdateOptions(projectId, options) + let loadTime = DateTime.Now + let options = ComputeSingleFileOptions (fileName, loadTime, fileContents, workspace) |> Async.RunSynchronously + + let projectId = workspace.ProjectTracker.GetOrCreateProjectIdForPath(options.ProjectFileName, options.ProjectFileName) + singleFileProjectTable.[projectId] <- (loadTime, options) if obj.ReferenceEquals(workspace.ProjectTracker.GetProject(projectId), null) then let projectContextFactory = this.Package.ComponentModel.GetService(); @@ -150,7 +195,40 @@ type internal FSharpLanguageService(package : FSharpPackage) = let project = projectContext :?> AbstractProject let document = project.GetCurrentDocumentFromPath(fileName) - document.Closing.Add(fun _ -> project.Disconnect()) + document.Closing.Add(fun _ -> + singleFileProjectTable.TryRemove(projectId) |> ignore; + project.Disconnect()) + + override this.ContentTypeName = FSharpCommonConstants.FSharpContentTypeName + override this.LanguageName = FSharpCommonConstants.FSharpLanguageName + override this.RoslynLanguageName = FSharpCommonConstants.FSharpLanguageName + + override this.LanguageServiceId = new Guid(FSharpCommonConstants.languageServiceGuidString) + override this.DebuggerLanguageId = DebuggerEnvironment.GetLanguageID() + + override this.CreateContext(_,_,_,_,_) = raise(System.NotImplementedException()) + + override this.SetupNewTextView(textView) = + base.SetupNewTextView(textView) + let workspace = this.Package.ComponentModel.GetService() + + // FSROSLYNTODO: Hide navigation bars for now. Enable after adding tests + workspace.Options <- workspace.Options.WithChangedOption(NavigationBarOptions.ShowNavigationBar, FSharpCommonConstants.FSharpLanguageName, false) + + match textView.GetBuffer() with + | (VSConstants.S_OK, textLines) -> + let filename = VsTextLines.GetFilename textLines + match VsRunningDocumentTable.FindDocumentWithoutLocking(package.RunningDocumentTable,filename) with + | Some (hier, _) -> + match hier with + | :? IProvideProjectSite as siteProvider when not (IsScript(filename)) -> + this.SetupProjectFile(siteProvider, workspace) + | _ -> + let editorAdapterFactoryService = this.Package.ComponentModel.GetService() + let fileContents = VsTextLines.GetFileContents(textLines, editorAdapterFactoryService) + this.SetupStandAloneFile(filename, fileContents, workspace, hier) + | _ -> () + | _ -> () and [] diff --git a/vsintegration/src/FSharp.Editor/ProjectDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/ProjectDiagnosticAnalyzer.fs index 8fe4f65157e..ff6ca2d40bc 100644 --- a/vsintegration/src/FSharp.Editor/ProjectDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/ProjectDiagnosticAnalyzer.fs @@ -47,7 +47,7 @@ type internal FSharpProjectDiagnosticAnalyzer() = override this.AnalyzeProjectAsync(project: Project, cancellationToken: CancellationToken): Task> = async { - match FSharpLanguageService.GetOptions(project.Id) with + match FSharpLanguageService.GetOptionsForProject(project.Id) with | Some(options) -> return! FSharpProjectDiagnosticAnalyzer.GetDiagnostics(options) | None -> return ImmutableArray.Empty } |> CommonRoslynHelpers.StartAsyncAsTask cancellationToken diff --git a/vsintegration/src/FSharp.Editor/QuickInfoProvider.fs b/vsintegration/src/FSharp.Editor/QuickInfoProvider.fs index bfa1360a34e..bc3919d7678 100644 --- a/vsintegration/src/FSharp.Editor/QuickInfoProvider.fs +++ b/vsintegration/src/FSharp.Editor/QuickInfoProvider.fs @@ -100,14 +100,14 @@ type internal FSharpQuickInfoProvider [ = async { - match FSharpLanguageService.GetOptions(document.Project.Id) with - | Some(options) -> - let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, options.OtherOptions |> Seq.toList) - let classification = CommonHelpers.tryClassifyAtPosition(document.Id, sourceText, document.FilePath, defines, position, cancellationToken) + let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask + let defines = FSharpLanguageService.GetCompilationDefinesForEditingDocument(document) + let classification = CommonHelpers.tryClassifyAtPosition(document.Id, sourceText, document.FilePath, defines, position, cancellationToken) - match classification with - | Some _ -> + match classification with + | Some _ -> + match FSharpLanguageService.TryGetOptionsForEditingDocumentOrProject(document) with + | Some(options) -> let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask let! quickInfoResult = FSharpQuickInfoProvider.ProvideQuickInfo(document.Id, sourceText, document.FilePath, position, options, textVersion.GetHashCode(), cancellationToken) match quickInfoResult with diff --git a/vsintegration/src/FSharp.Editor/SignatureHelp.fs b/vsintegration/src/FSharp.Editor/SignatureHelp.fs index 0fb66c3f768..1f971427ab5 100644 --- a/vsintegration/src/FSharp.Editor/SignatureHelp.fs +++ b/vsintegration/src/FSharp.Editor/SignatureHelp.fs @@ -190,7 +190,7 @@ type FSharpSignatureHelpProvider [] (serviceProvider: SVs member this.GetItemsAsync(document, position, triggerInfo, cancellationToken) = async { try - match FSharpLanguageService.GetOptions(document.Project.Id) with + match FSharpLanguageService.TryGetOptionsForEditingDocumentOrProject(document) with | Some(options) -> let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask diff --git a/vsintegration/src/FSharp.LanguageService/BackgroundRequests.fs b/vsintegration/src/FSharp.LanguageService/BackgroundRequests.fs index 82dc1cb1d37..2efc61fc17a 100644 --- a/vsintegration/src/FSharp.LanguageService/BackgroundRequests.fs +++ b/vsintegration/src/FSharp.LanguageService/BackgroundRequests.fs @@ -84,7 +84,7 @@ type internal FSharpLanguageServiceBackgroundRequests // This portion is executed on the UI thread. let rdt = getServiceProvider().RunningDocumentTable let projectSite = getProjectSitesAndFiles().FindOwningProject(rdt,fileName) - let checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite, fileName) + let checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite, fileName, None) let projectFileName = projectSite.ProjectFileName() let data = { ProjectSite = projectSite diff --git a/vsintegration/src/FSharp.LanguageService/FSharpSource.fs b/vsintegration/src/FSharp.LanguageService/FSharpSource.fs index a8fcea047f6..04957099d16 100644 --- a/vsintegration/src/FSharp.LanguageService/FSharpSource.fs +++ b/vsintegration/src/FSharp.LanguageService/FSharpSource.fs @@ -328,7 +328,8 @@ type internal FSharpSource(service:LanguageService, textLines, colorizer, vsFile IsIncompleteTypeCheckEnvironment = true UseScriptResolutionRules = false LoadTime = new System.DateTime(2000,1,1) // dummy data, just enough to get a parse - UnresolvedReferences = None } + UnresolvedReferences = None + ExtraProjectInfo=None } ic.ParseFileInProject(fileName, source.GetText(), co) |> Async.RunSynchronously diff --git a/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs b/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs index 99ca0951f93..079bfd9e385 100644 --- a/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs +++ b/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs @@ -161,7 +161,7 @@ type internal ProjectSitesAndFiles() = | None -> ProjectSitesAndFiles.ProjectSiteOfSingleFile(filename) /// Create project options for this project site. - static member GetProjectOptionsForProjectSite(projectSite:IProjectSite,filename)= + static member GetProjectOptionsForProjectSite(projectSite:IProjectSite,filename,extraProjectInfo) = match projectSite with | :? IHaveCheckOptions as hco -> hco.OriginalCheckOptions() @@ -173,7 +173,8 @@ type internal ProjectSitesAndFiles() = IsIncompleteTypeCheckEnvironment = projectSite.IsIncompleteTypeCheckEnvironment UseScriptResolutionRules = SourceFile.MustBeSingleFileProject(filename) LoadTime = projectSite.LoadTime - UnresolvedReferences = None } + UnresolvedReferences = None + ExtraProjectInfo=extraProjectInfo } /// Create project site for these project options static member CreateProjectSiteForScript (filename, checkOptions) = ProjectSiteOfScriptFile (filename, checkOptions) :> IProjectSite diff --git a/vsintegration/tests/Salsa/FSharpLanguageServiceTestable.fs b/vsintegration/tests/Salsa/FSharpLanguageServiceTestable.fs index 42d97060e91..c0e00f89897 100644 --- a/vsintegration/tests/Salsa/FSharpLanguageServiceTestable.fs +++ b/vsintegration/tests/Salsa/FSharpLanguageServiceTestable.fs @@ -69,7 +69,7 @@ type internal FSharpLanguageServiceTestable() as this = if this.Unhooked then raise Error.UseOfUnhookedLanguageServiceState artifacts <- Some (ProjectSitesAndFiles()) let checker = FSharpChecker.Create() - checker.BeforeBackgroundFileCheck.Add (fun filename -> UIThread.Run(fun () -> this.NotifyFileTypeCheckStateIsDirty(filename))) + checker.BeforeBackgroundFileCheck.Add (fun (filename,_) -> UIThread.Run(fun () -> this.NotifyFileTypeCheckStateIsDirty(filename))) checkerContainerOpt <- Some (checker) serviceProvider <- Some sp isInitialized <- true @@ -126,7 +126,7 @@ type internal FSharpLanguageServiceTestable() as this = /// Respond to project being cleaned/rebuilt (any live type providers in the project should be refreshed) member this.OnProjectCleaned(projectSite:IProjectSite) = - let checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite, "") + let checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite, "",None) this.FSharpChecker.NotifyProjectCleaned(checkOptions) member this.OnActiveViewChanged(textView) = @@ -168,7 +168,7 @@ type internal FSharpLanguageServiceTestable() as this = interface IDependencyFileChangeNotify with member this.DependencyFileCreated projectSite = // Invalidate the configuration if we notice any add for any DependencyFiles - let checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite, "") + let checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite, "", None) this.FSharpChecker.InvalidateConfiguration(checkOptions) member this.DependencyFileChanged (filename) = diff --git a/vsintegration/tests/unittests/BraceMatchingServiceTests.fs b/vsintegration/tests/unittests/BraceMatchingServiceTests.fs index ca598388809..b1d78351770 100644 --- a/vsintegration/tests/unittests/BraceMatchingServiceTests.fs +++ b/vsintegration/tests/unittests/BraceMatchingServiceTests.fs @@ -25,6 +25,7 @@ type BraceMatchingServiceTests() = UseScriptResolutionRules = false LoadTime = DateTime.MaxValue UnresolvedReferences = None + ExtraProjectInfo = None } member private this.VerifyNoBraceMatch(fileContents: string, marker: string) = diff --git a/vsintegration/tests/unittests/BreakpointResolutionService.fs b/vsintegration/tests/unittests/BreakpointResolutionService.fs index 630d4e414e9..24690503fde 100644 --- a/vsintegration/tests/unittests/BreakpointResolutionService.fs +++ b/vsintegration/tests/unittests/BreakpointResolutionService.fs @@ -29,6 +29,7 @@ type BreakpointResolutionServiceTests() = UseScriptResolutionRules = false LoadTime = DateTime.MaxValue UnresolvedReferences = None + ExtraProjectInfo = None } let code = " // This is a comment diff --git a/vsintegration/tests/unittests/CompletionProviderTests.fs b/vsintegration/tests/unittests/CompletionProviderTests.fs index b80a738f7c4..4dd8348cc44 100644 --- a/vsintegration/tests/unittests/CompletionProviderTests.fs +++ b/vsintegration/tests/unittests/CompletionProviderTests.fs @@ -49,6 +49,7 @@ let internal options = { UseScriptResolutionRules = false LoadTime = DateTime.MaxValue UnresolvedReferences = None + ExtraProjectInfo = None } let VerifyCompletionList(fileContents: string, marker: string, expected: string list, unexpected: string list) = diff --git a/vsintegration/tests/unittests/DocumentDiagnosticAnalyzerTests.fs b/vsintegration/tests/unittests/DocumentDiagnosticAnalyzerTests.fs index f0c6eed2883..c768bf06899 100644 --- a/vsintegration/tests/unittests/DocumentDiagnosticAnalyzerTests.fs +++ b/vsintegration/tests/unittests/DocumentDiagnosticAnalyzerTests.fs @@ -31,6 +31,7 @@ type DocumentDiagnosticAnalyzerTests() = UseScriptResolutionRules = false LoadTime = DateTime.MaxValue UnresolvedReferences = None + ExtraProjectInfo = None } member private this.VerifyNoErrors(fileContents: string, ?additionalFlags: string[]) = diff --git a/vsintegration/tests/unittests/GoToDefinitionServiceTests.fs b/vsintegration/tests/unittests/GoToDefinitionServiceTests.fs index be5e8444401..646dfd1e754 100644 --- a/vsintegration/tests/unittests/GoToDefinitionServiceTests.fs +++ b/vsintegration/tests/unittests/GoToDefinitionServiceTests.fs @@ -91,6 +91,7 @@ let _ = Module1.foo 1 UseScriptResolutionRules = false LoadTime = DateTime.MaxValue UnresolvedReferences = None + ExtraProjectInfo = None } File.WriteAllText(filePath, fileContents) diff --git a/vsintegration/tests/unittests/QuickInfoProviderTests.fs b/vsintegration/tests/unittests/QuickInfoProviderTests.fs index abe339bde75..dde438bb460 100644 --- a/vsintegration/tests/unittests/QuickInfoProviderTests.fs +++ b/vsintegration/tests/unittests/QuickInfoProviderTests.fs @@ -47,6 +47,7 @@ let internal options = { UseScriptResolutionRules = false LoadTime = DateTime.MaxValue UnresolvedReferences = None + ExtraProjectInfo = None } let private normalizeLineEnds (s: string) = s.Replace("\r\n", "\n").Replace("\n\n", "\n") diff --git a/vsintegration/tests/unittests/SignatureHelpProviderTests.fs b/vsintegration/tests/unittests/SignatureHelpProviderTests.fs index 954926b5e58..43bdba99d95 100644 --- a/vsintegration/tests/unittests/SignatureHelpProviderTests.fs +++ b/vsintegration/tests/unittests/SignatureHelpProviderTests.fs @@ -18,7 +18,6 @@ // Technique 3: // // Use F# Interactive. This only works for FSharp.Compiler.Service.dll which has a public API - module Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn.SignatureHelpProvider open System @@ -59,6 +58,7 @@ let internal options = { UseScriptResolutionRules = false LoadTime = DateTime.MaxValue UnresolvedReferences = None + ExtraProjectInfo = None } []