Skip to content

Commit

Permalink
Disable partial type checking when getting full results for a file or…
Browse files Browse the repository at this point in the history
… project (dotnet#10448)
  • Loading branch information
TIHan authored and nosami committed Feb 22, 2021
1 parent b7cd6eb commit 5d0b983
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 9 deletions.
35 changes: 34 additions & 1 deletion src/fsharp/service/IncrementalBuild.fs
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
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
Expand Up @@ -718,7 +718,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 @@ -772,9 +772,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 @@ -788,9 +787,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 @@ -810,7 +808,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

0 comments on commit 5d0b983

Please sign in to comment.