Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/fsharp/vs/IncrementalBuild.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1272,10 +1272,10 @@ type IncrementalBuilder(frameworkTcImportsCache: FrameworkImportsCache, tcConfig

let tcConfigP = TcConfigProvider.Constant(tcConfig)
let importsInvalidated = new Event<string>()
let fileParsed = new Event<_>()
let beforeTypeCheckFile = new Event<_>()
let fileChecked = new Event<_>()
let projectChecked = new Event<_>()
let fileParsed = new Event<string>()
let beforeFileChecked = new Event<string>()
let fileChecked = new Event<string>()
let projectChecked = new Event<unit>()

// 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
Expand Down Expand Up @@ -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()))
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/fsharp/vs/IncrementalBuild.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>
member BeforeFileChecked : IEvent<string>

/// Raised just after a file is parsed
member FileParsed : IEvent<string>
Expand Down
29 changes: 16 additions & 13 deletions src/fsharp/vs/service.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<string>()
let fileParsed = Event<string>()
let fileChecked = Event<string>()
let projectChecked = Event<string>()
let beforeFileChecked = Event<string * obj option>()
let fileParsed = Event<string * obj option>()
let fileChecked = Event<string * obj option>()
let projectChecked = Event<string * obj option>()

let mutable implicitlyStartBackgroundWork = true
let reactorOps =
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down
14 changes: 8 additions & 6 deletions src/fsharp/vs/service.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -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
}


Expand Down Expand Up @@ -473,7 +475,7 @@ type internal FSharpChecker =
/// <param name="loadedTimeStamp">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.</param>
member GetProjectOptionsFromScript : filename: string * source: string * ?loadedTimeStamp: DateTime * ?otherFlags: string[] * ?useFsiAuxLib: bool -> Async<FSharpProjectOptions>
member GetProjectOptionsFromScript : filename: string * source: string * ?loadedTimeStamp: DateTime * ?otherFlags: string[] * ?useFsiAuxLib: bool * ?extraProjectInfo: obj -> Async<FSharpProjectOptions>

/// <summary>
/// <para>Get the FSharpProjectOptions implied by a set of command line arguments.</para>
Expand All @@ -484,7 +486,7 @@ type internal FSharpChecker =
/// <param name="loadedTimeStamp">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.</param>
member GetProjectOptionsFromCommandLineArgs : projectFileName: string * argv: string[] * ?loadedTimeStamp: DateTime -> FSharpProjectOptions
member GetProjectOptionsFromCommandLineArgs : projectFileName: string * argv: string[] * ?loadedTimeStamp: DateTime * ?extraProjectInfo: obj -> FSharpProjectOptions

/// <summary>
/// <para>Like ParseFileInProject, but uses results from the background builder.</para>
Expand Down Expand Up @@ -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<string>
member BeforeBackgroundFileCheck : IEvent<string * obj option>

/// Raised after a parse of a file in the background analysis.
///
/// The event will be raised on a background thread.
member FileParsed : IEvent<string>
member FileParsed : IEvent<string * obj option>

/// Raised after a check of a file in the background analysis.
///
/// The event will be raised on a background thread.
member FileChecked : IEvent<string>
member FileChecked : IEvent<string * obj option>

/// Get or set a flag which controls if background work is started implicitly.
///
Expand All @@ -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<string>
member ProjectChecked : IEvent<string * obj option>

// For internal use only
member internal ReactorOps : IReactorOperations
Expand Down
3 changes: 2 additions & 1 deletion tests/service/FileSystemTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion vsintegration/src/FSharp.Editor/BraceMatchingService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type internal FSharpBreakpointResolutionService() =
interface IBreakpointResolutionService with
member this.ResolveBreakpointAsync(document: Document, textSpan: TextSpan, cancellationToken: CancellationToken): Task<BreakpointResolutionResult> =
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)
Expand Down
10 changes: 3 additions & 7 deletions vsintegration/src/FSharp.Editor/ColorizationService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,14 @@ type internal FSharpColorizationService() =

member this.AddSyntacticClassificationsAsync(document: Document, textSpan: TextSpan, result: List<ClassifiedSpan>, 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<ClassifiedSpan>, 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
Expand Down
4 changes: 3 additions & 1 deletion vsintegration/src/FSharp.Editor/CommonHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ module CommonHelpers =
| None -> ()

result
with ex ->
with
| :? System.OperationCanceledException -> reraise()
| ex ->
Assert.Exception(ex)
List<ClassifiedSpan>()

Expand Down
10 changes: 3 additions & 7 deletions vsintegration/src/FSharp.Editor/CompletionProvider.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions vsintegration/src/FSharp.Editor/DocumentDiagnosticAnalyzer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -57,7 +59,7 @@ type internal FSharpDocumentDiagnosticAnalyzer() =

override this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
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
Expand All @@ -68,7 +70,8 @@ type internal FSharpDocumentDiagnosticAnalyzer() =

override this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
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
Expand Down
2 changes: 1 addition & 1 deletion vsintegration/src/FSharp.Editor/GoToDefinitionService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ type internal FSharpGoToDefinitionService [<ImportingConstructor>] ([<ImportMany
member this.FindDefinitionsAsyncAux(document: Document, position: int, cancellationToken: CancellationToken) =
async {
let results = List<INavigableItem>()
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
Expand Down
Loading