@@ -8,6 +8,7 @@ open System.Diagnostics
88open System.IO
99open System.Collections .Generic
1010
11+ open System.Threading
1112open Internal.Utilities .Collections
1213open Internal.Utilities .Library
1314open Internal.Utilities .Library .Extras
@@ -1558,21 +1559,96 @@ type WorkInput =
15581559
15591560/// Use parallel checking of implementation files that have signature files
15601561let CheckMultipleInputsInParallel2
1561- (
1562- ctok ,
1563- checkForErrors ,
1562+ (( ctok : CancellationToken ,
1563+ checkForErrors : unit -> bool ,
15641564 tcConfig : TcConfig ,
15651565 tcImports : TcImports ,
1566- tcGlobals ,
1566+ tcGlobals : TcGlobals ,
15671567 prefixPathOpt ,
15681568 tcState ,
15691569 eagerFormat ,
1570- inputs
1571- ) : PartialResult list * TcState =
1570+ inputs ): CancellationToken * ( unit -> bool ) * TcConfig * TcImports * TcGlobals * LongIdent option * TcState * ( PhasedDiagnostic -> PhasedDiagnostic ) * ParsedInput list )
1571+ : PartialResult list * TcState =
15721572
15731573 let _ = ctok // TODO Use
15741574 let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger
15751575
1576+ // In the first linear part of parallel checking, we use a 'checkForErrors' that checks either for errors
1577+ // somewhere in the files processed prior to each one, or in the processing of this particular file.
1578+ let priorErrors = checkForErrors ()
1579+ let amap = tcImports.GetImportMap()
1580+ let conditionalDefines =
1581+ if tcConfig.noConditionalErasure then
1582+ None
1583+ else
1584+ Some tcConfig.conditionalDefines
1585+
1586+ let processFile
1587+ ( currentTcState : TcState )
1588+ (( input , logger ) : ParsedInput * DiagnosticsLogger )
1589+ : State -> PartialResult * State =
1590+ cancellable {
1591+ use _ = UseDiagnosticsLogger logger
1592+ // Is it OK that we don't update 'priorErrors' after processing batches?
1593+ let checkForErrors2 () = priorErrors || ( logger.ErrorCount > 0 )
1594+
1595+ // this is taken mostly from CheckOneInputAux, the case where the impl has no signature file
1596+ let file =
1597+ match input with
1598+ | ParsedInput.ImplFile file -> file
1599+ | ParsedInput.SigFile _ -> failwith " not expecting a signature file for now"
1600+
1601+ let tcSink = TcResultsSink.NoSink
1602+
1603+ // Typecheck the implementation file
1604+ let! topAttrs , implFile , tcEnvAtEnd , createsGeneratedProvidedTypes =
1605+ CheckOneImplFile(
1606+ tcGlobals,
1607+ amap,
1608+ currentTcState.tcsCcu,
1609+ currentTcState.tcsImplicitOpenDeclarations,
1610+ checkForErrors2,
1611+ conditionalDefines,
1612+ TcResultsSink.NoSink,
1613+ tcConfig.internalTestSpanStackReferring,
1614+ currentTcState.tcsTcImplEnv,
1615+ None,
1616+ file
1617+ )
1618+
1619+ return
1620+ ( fun ( state : State ) ->
1621+ let tcState , _priorErrors = state
1622+ let tcState =
1623+ { tcState with
1624+ tcsCreatesGeneratedProvidedTypes =
1625+ tcState.tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes
1626+ }
1627+
1628+ let ccuSigForFile , updatedTcState =
1629+ let results =
1630+ tcGlobals,
1631+ amap,
1632+ false ,
1633+ prefixPathOpt,
1634+ tcSink,
1635+ tcState.tcsTcImplEnv,
1636+ input.QualifiedName,
1637+ implFile.Signature
1638+
1639+ AddCheckResultsToTcState results tcState
1640+
1641+ let partialResult : PartialResult = tcEnvAtEnd, topAttrs, Some implFile, ccuSigForFile
1642+ let hasErrors = logger.ErrorCount > 0
1643+ let priorOrCurrentErrors = priorErrors || hasErrors
1644+ let state : State = updatedTcState, priorOrCurrentErrors
1645+
1646+ partialResult, state
1647+ )
1648+ }
1649+ |> Cancellable.runWithoutCancellation
1650+
1651+
15761652 // We create one CapturingDiagnosticLogger for each file we are processing and
15771653 // ensure the diagnostics are presented in deterministic order.
15781654 //
@@ -1617,13 +1693,6 @@ let CheckMultipleInputsInParallel2
16171693
16181694 let partialResults , ( state : State ) =
16191695 let lastIndex = inputsWithLoggers.Length - 1
1620- let amap = tcImports.GetImportMap()
1621-
1622- let conditionalDefines =
1623- if tcConfig.noConditionalErasure then
1624- None
1625- else
1626- Some tcConfig.conditionalDefines
16271696
16281697 // This function will type check all the files where it knows all the dependent file have already been seen.
16291698 // The `freeFiles` are a set of file indexes that have been type checked in a previous run.
@@ -1649,72 +1718,9 @@ let CheckMultipleInputsInParallel2
16491718 else
16501719 None)
16511720 |> Seq.toArray
1652-
1653- let processFile (( input , logger ) : ParsedInput * _ )
1654- : State -> PartialResult * State =
1655- cancellable {
1656- use _ = UseDiagnosticsLogger logger
1657- // Is it OK that we don't update 'priorErrors' after processing batches?
1658- let checkForErrors2 () = priorErrors || ( logger.ErrorCount > 0 )
1659-
1660- // this is taken mostly from CheckOneInputAux, the case where the impl has no signature file
1661- let file =
1662- match input with
1663- | ParsedInput.ImplFile file -> file
1664- | ParsedInput.SigFile _ -> failwith " not expecting a signature file for now"
1665-
1666- let tcSink = TcResultsSink.NoSink
1667-
1668- // Typecheck the implementation file
1669- let! topAttrs , implFile , tcEnvAtEnd , createsGeneratedProvidedTypes =
1670- CheckOneImplFile(
1671- tcGlobals,
1672- amap,
1673- currentTcState.tcsCcu,
1674- currentTcState.tcsImplicitOpenDeclarations,
1675- checkForErrors2,
1676- conditionalDefines,
1677- TcResultsSink.NoSink,
1678- tcConfig.internalTestSpanStackReferring,
1679- currentTcState.tcsTcImplEnv,
1680- None,
1681- file
1682- )
1683-
1684- return
1685- ( fun ( state : State ) ->
1686- let tcState , _priorErrors = state
1687- let tcState =
1688- { tcState with
1689- tcsCreatesGeneratedProvidedTypes =
1690- tcState.tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes
1691- }
1692-
1693- let ccuSigForFile , updatedTcState =
1694- let results =
1695- tcGlobals,
1696- amap,
1697- false ,
1698- prefixPathOpt,
1699- tcSink,
1700- tcState.tcsTcImplEnv,
1701- input.QualifiedName,
1702- implFile.Signature
1703-
1704- AddCheckResultsToTcState results tcState
1705-
1706- let partialResult : PartialResult = tcEnvAtEnd, topAttrs, Some implFile, ccuSigForFile
1707- let hasErrors = logger.ErrorCount > 0
1708- let priorOrCurrentErrors = priorErrors || hasErrors
1709- let state : State = updatedTcState, priorOrCurrentErrors
1710-
1711- partialResult, state
1712- )
1713- }
1714- |> Cancellable.runWithoutCancellation
17151721
17161722 let go ( fileIndex : int , ( input , logger )) : State -> int * ( PartialResult * State ) =
1717- let r = processFile ( input, logger)
1723+ let r = processFile currentTcState ( input, logger)
17181724 fun state ->
17191725 fileIndex, r state
17201726
0 commit comments