Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable partial type checking when getting full results for a file or project #10448

Merged
merged 1 commit into from
Nov 25, 2020
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
35 changes: 34 additions & 1 deletion src/fsharp/service/IncrementalBuild.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -1578,6 +1586,8 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
let importsInvalidatedByTypeProvider = new Event<string>()
#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))
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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())

Expand All @@ -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
Expand Down
22 changes: 22 additions & 0 deletions src/fsharp/service/IncrementalBuild.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<PartialCheckResults>

/// 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<PartialCheckResults>

/// 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.
///
Expand All @@ -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<PartialCheckResults * IL.ILAssemblyRef * IRawFSharpAssemblyData option * TypedImplFile list option>

/// 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<PartialCheckResults * IL.ILAssemblyRef * IRawFSharpAssemblyData option * TypedImplFile list option>

/// 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

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

Expand Down Expand Up @@ -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
Expand All @@ -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) =
Expand All @@ -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

Expand Down