diff --git a/src/fsharp/service/IncrementalBuild.fs b/src/fsharp/service/IncrementalBuild.fs index e5470c5df49..0a02759b70b 100755 --- a/src/fsharp/service/IncrementalBuild.fs +++ b/src/fsharp/service/IncrementalBuild.fs @@ -1516,6 +1516,14 @@ type PartialCheckResults private (semanticModel: SemanticModel, timeStamp: DateT member _.TcInfoWithOptional ctok = semanticModel.TcInfoWithOptional |> eval ctok + member _.TryGetItemKeyStore ctok = + let _, info = semanticModel.TcInfoWithOptional |> eval ctok + info.itemKeyStore + + member _.GetSemanticClassification ctok = + let _, info = semanticModel.TcInfoWithOptional |> eval ctok + info.semanticClassification + static member Create (semanticModel: SemanticModel, timestamp) = PartialCheckResults(semanticModel, timestamp) @@ -1578,6 +1586,8 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput let importsInvalidatedByTypeProvider = new Event() #endif let mutable currentTcImportsOpt = None + let defaultPartialTypeChecking = enablePartialTypeChecking + let mutable enablePartialTypeChecking = enablePartialTypeChecking // Check for the existence of loaded sources and prepend them to the sources list if present. let sourceFiles = tcConfig.GetAvailableLoadedSources() @ (sourceFiles |>List.map (fun s -> rangeStartup, s)) @@ -1718,7 +1728,7 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput maxTimeShareMilliseconds, keepAllBackgroundSymbolUses, enableBackgroundItemKeyStoreAndSemanticClassification, - enablePartialTypeChecking, + defaultPartialTypeChecking, beforeFileChecked, fileChecked, tcInfo, Eventually.Done (Some tcInfoOptional), None) } /// This is a build task function that gets placed into the build rules as the computation for a Vector.ScanLeft @@ -1944,6 +1954,17 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput let slotOfFile = builder.GetSlotOfFileName filename + 1 builder.GetCheckResultsBeforeSlotInProject (ctok, slotOfFile) + member builder.GetFullCheckResultsAfterFileInProject (ctok: CompilationThreadToken, filename) = + enablePartialTypeChecking <- false + cancellable { + try + let! result = builder.GetCheckResultsAfterFileInProject(ctok, filename) + result.TcInfoWithOptional ctok |> ignore // Make sure we forcefully evaluate the info + return result + finally + enablePartialTypeChecking <- defaultPartialTypeChecking + } + member builder.GetCheckResultsAfterLastFileInProject (ctok: CompilationThreadToken) = builder.GetCheckResultsBeforeSlotInProject(ctok, builder.GetSlotsCount()) @@ -1965,6 +1986,18 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput let msg = sprintf "Build was not evaluated, expected the results to be ready after 'Eval' (GetCheckResultsAndImplementationsForProject, data = %A)." data return! failwith msg } + + member this.GetFullCheckResultsAndImplementationsForProject(ctok: CompilationThreadToken) = + enablePartialTypeChecking <- false + cancellable { + try + let! result = this.GetCheckResultsAndImplementationsForProject(ctok) + let results, _, _, _ = result + results.TcInfoWithOptional ctok |> ignore // Make sure we forcefully evaluate the info + return result + finally + enablePartialTypeChecking <- defaultPartialTypeChecking + } member __.GetLogicalTimeStampForProject(cache, ctok: CompilationThreadToken) = let t1 = MaxTimeStampInDependencies cache ctok stampedFileNamesNode diff --git a/src/fsharp/service/IncrementalBuild.fsi b/src/fsharp/service/IncrementalBuild.fsi index 1730f23c106..729c258add4 100755 --- a/src/fsharp/service/IncrementalBuild.fsi +++ b/src/fsharp/service/IncrementalBuild.fsi @@ -110,6 +110,14 @@ type internal PartialCheckResults = /// Only use when it's absolutely necessary to get rich information on a file. member TcInfoWithOptional: CompilationThreadToken -> TcInfo * TcInfoOptional + /// Can cause a second type-check if `enablePartialTypeChecking` is true in the checker. + /// Only use when it's absolutely necessary to get rich information on a file. + member TryGetItemKeyStore: CompilationThreadToken -> ItemKeyStore option + + /// Can cause a second type-check if `enablePartialTypeChecking` is true in the checker. + /// Only use when it's absolutely necessary to get rich information on a file. + member GetSemanticClassification: CompilationThreadToken -> struct(range * SemanticClassificationType) [] + member TimeStamp: DateTime /// Manages an incremental build graph for the build of an F# project @@ -177,6 +185,13 @@ type internal IncrementalBuilder = // TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled) member GetCheckResultsAfterFileInProject : CompilationThreadToken * filename:string -> Cancellable + /// Get the typecheck state after checking a file. Compute the entire type check of the project up + /// to the necessary point if the result is not available. This may be a long-running operation. + /// This will get full type-check info for the file, meaning no partial type-checking. + /// + // TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled) + member GetFullCheckResultsAfterFileInProject : CompilationThreadToken * filename:string -> Cancellable + /// Get the typecheck result after the end of the last file. The typecheck of the project is not 'completed'. /// This may be a long-running operation. /// @@ -189,6 +204,13 @@ type internal IncrementalBuilder = // TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled) member GetCheckResultsAndImplementationsForProject : CompilationThreadToken -> Cancellable + /// Get the final typecheck result. If 'generateTypedImplFiles' was set on Create then the TypedAssemblyAfterOptimization will contain implementations. + /// This may be a long-running operation. + /// This will get full type-check info for the project, meaning no partial type-checking. + /// + // TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled) + member GetFullCheckResultsAndImplementationsForProject : CompilationThreadToken -> Cancellable + /// Get the logical time stamp that is associated with the output of the project if it were gully built immediately member GetLogicalTimeStampForProject: TimeStampCache * CompilationThreadToken -> DateTime diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs index 24c5cd08ea7..244f4d7e0a1 100644 --- a/src/fsharp/service/service.fs +++ b/src/fsharp/service/service.fs @@ -722,7 +722,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC return (parseResults, typedResults) | Some builder -> let! (parseTreeOpt, _, _, untypedErrors) = builder.GetParseResultsForFile (ctok, filename) - let! tcProj = builder.GetCheckResultsAfterFileInProject (ctok, filename) + let! tcProj = builder.GetFullCheckResultsAfterFileInProject (ctok, filename) let tcInfo, tcInfoOptional = tcProj.TcInfoWithOptional ctok @@ -775,9 +775,8 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC | None -> return Seq.empty | Some builder -> if builder.ContainsFile filename then - let! checkResults = builder.GetCheckResultsAfterFileInProject (ctok, filename) - let _, tcInfoOptional = checkResults.TcInfoWithOptional ctok - match tcInfoOptional.itemKeyStore with + let! checkResults = builder.GetFullCheckResultsAfterFileInProject (ctok, filename) + match checkResults.TryGetItemKeyStore ctok with | None -> return Seq.empty | Some reader -> return reader.FindAll symbol.Item else @@ -791,9 +790,8 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC match builderOpt with | None -> return [||] | Some builder -> - let! checkResults = builder.GetCheckResultsAfterFileInProject (ctok, filename) - let _, tcInfoOptional = checkResults.TcInfoWithOptional ctok - return tcInfoOptional.semanticClassification }) + let! checkResults = builder.GetFullCheckResultsAfterFileInProject (ctok, filename) + return checkResults.GetSemanticClassification ctok }) /// Try to get recent approximate type check results for a file. member __.TryGetRecentCheckResultsForFile(filename: string, options:FSharpProjectOptions, sourceText: ISourceText option, _userOpName: string) = @@ -813,7 +811,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC | None -> return FSharpCheckProjectResults (options.ProjectFileName, None, keepAssemblyContents, creationErrors, None) | Some builder -> - let! (tcProj, ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt) = builder.GetCheckResultsAndImplementationsForProject(ctok) + let! (tcProj, ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt) = builder.GetFullCheckResultsAndImplementationsForProject(ctok) let errorOptions = tcProj.TcConfig.errorSeverityOptions let fileName = TcGlobals.DummyFileNameForRangesWithoutASpecificLocation