@@ -1383,8 +1383,13 @@ let CheckOneInput
13831383 )
13841384 }
13851385
1386+ type FsiBackedInfo =
1387+ Import.ImportMap * string list option * ModuleOrNamespaceType *
1388+ bool * ParsedImplFileInput * TcState * ModuleOrNamespaceType
13861389
1390+ let mutable asts = Dictionary< string, ParsedInput>()
13871391
1392+ let mutable fsiBackedInfos = Dictionary< string, FsiBackedInfo>()
13881393
13891394/// Typecheck a single file (or interactive entry into F# Interactive)
13901395let CheckOneInputAux '
@@ -1438,74 +1443,162 @@ let CheckOneInputAux'
14381443 tcState.tcsTcSigEnv
14391444 file
14401445
1446+ // Open the prefixPath for fsi.exe
1447+ let tcEnv , _openDecls1 =
1448+ match prefixPathOpt with
1449+ | None -> tcEnv, []
1450+ | Some prefixPath ->
1451+ let m = qualNameOfFile.Range
1452+ TcOpenModuleOrNamespaceDecl tcSink tcGlobals amap m tcEnv ( prefixPath, m)
1453+
14411454 return fun tcState ->
1442- let rootSigs = Zmap.add qualNameOfFile sigFileType tcState.tcsRootSigs
1443-
1444- // Add the signature to the signature env (unless it had an explicit signature)
1445- let ccuSigForFile = CombineCcuContentFragments [ sigFileType; tcState.tcsCcuSig ]
1446-
1447- // Open the prefixPath for fsi.exe
1448- let tcEnv , _openDecls1 =
1449- match prefixPathOpt with
1450- | None -> tcEnv, []
1451- | Some prefixPath ->
1452- let m = qualNameOfFile.Range
1453- TcOpenModuleOrNamespaceDecl tcSink tcGlobals amap m tcEnv ( prefixPath, m)
1454-
1455- let partialResult = tcEnv, EmptyTopAttrs, None, ccuSigForFile
1455+ let fsiPartialResult , tcState =
1456+ let rootSigs = Zmap.add qualNameOfFile sigFileType tcState.tcsRootSigs
1457+
1458+ // Add the signature to the signature env (unless it had an explicit signature)
1459+ let ccuSigForFile = CombineCcuContentFragments [ sigFileType; tcState.tcsCcuSig ]
1460+
1461+ let partialResult = tcEnv, EmptyTopAttrs, None, ccuSigForFile
1462+
1463+ let tcState =
1464+ { tcState with
1465+ tcsTcSigEnv = tcEnv
1466+ tcsTcImplEnv = tcState.tcsTcImplEnv
1467+ tcsRootSigs = rootSigs
1468+ tcsCreatesGeneratedProvidedTypes = tcState.tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes
1469+ }
1470+ partialResult, tcState
14561471
1457- let tcState =
1458- { tcState with
1459- tcsTcSigEnv = tcEnv
1460- tcsTcImplEnv = tcState.tcsTcImplEnv
1461- tcsRootSigs = rootSigs
1462- tcsCreatesGeneratedProvidedTypes = tcState.tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes
1463- }
1464-
1465- partialResult, tcState
1472+ // Create dedicated state & some data for the .fs file type-checking later on - save it in a dict
1473+ let fsTcState =
1474+ let hadSig = true
1475+ // Add dummy .fs results
1476+ // Adjust the TcState as if it has been checked, which makes the signature for the file available later
1477+ // in the compilation order.
1478+ let tcStateForImplFile = tcState
1479+ let fsName = file.FileName.TrimEnd( 'i' )
1480+ let fsQualifiedName = asts[ fsName]. QualifiedName
1481+ let qualNameOfFile = fsQualifiedName
1482+ let priorErrors = checkForErrors ()
1483+
1484+ // Add dummy TcState so that others can use this file through the .fsi stuff, without type-checking .fs
1485+ // Don't use it for this file's type-checking - it will cause duplicates
1486+ let ccuSigForFile , tcState =
1487+ AddCheckResultsToTcState
1488+ ( tcGlobals, amap, hadSig, prefixPathOpt, tcSink, tcState.tcsTcImplEnv, qualNameOfFile, sigFileType)
1489+ tcState
1490+
1491+ // Save info needed for type-checking .fs file later on
1492+ let fsiBackedInfo : FsiBackedInfo =
1493+ let ast = asts[ fsName]
1494+ let file =
1495+ match ast with
1496+ | ParsedInput.ImplFile parsedImplFileInput -> parsedImplFileInput
1497+ | ParsedInput.SigFile _ -> failwith " Unexpected SigFile"
1498+ amap, conditionalDefines, sigFileType, priorErrors, file, tcStateForImplFile, ccuSigForFile
1499+
1500+ fsiBackedInfos[ fsName] <- fsiBackedInfo
1501+
1502+ tcState
1503+ //
1504+ // let _, finalTcState =
1505+ // match dummyFsPartialResult with
1506+ // | amap, _conditionalDefines, rootSig, _priorErrors, file, tcStateForImplFile, _ccuSigForFile ->
1507+ // AddDummyCheckResultsToTcState(
1508+ // tcGlobals,
1509+ // amap,
1510+ // file.QualifiedName,
1511+ // prefixPathOpt,
1512+ // tcSink,
1513+ // fsTcState,
1514+ // tcStateForImplFile,
1515+ // rootSig
1516+ // )
1517+
1518+ fsiPartialResult, fsTcState
14661519
14671520 | ParsedInput.ImplFile file ->
14681521 let qualNameOfFile = file.QualifiedName
14691522
14701523 // Check if we've got an interface for this fragment
14711524 let rootSigOpt = tcState.tcsRootSigs.TryFind qualNameOfFile
14721525
1473- // Check if we've already seen an implementation for this fragment
1474- if Zset.contains qualNameOfFile tcState.tcsRootImpls then
1475- errorR ( Error( FSComp.SR.buildImplementationAlreadyGiven ( qualNameOfFile.Text), m))
1476-
1477- let hadSig = rootSigOpt.IsSome
1478-
1479- // Typecheck the implementation file
1480- let! topAttrs , implFile , tcEnvAtEnd , createsGeneratedProvidedTypes =
1481- CheckOneImplFile(
1482- tcGlobals,
1483- amap,
1484- tcState.tcsCcu,
1485- tcState.tcsImplicitOpenDeclarations,
1486- checkForErrors,
1487- conditionalDefines,
1488- tcSink,
1489- tcConfig.internalTestSpanStackReferring,
1490- tcState.tcsTcImplEnv,
1491- rootSigOpt,
1492- file
1493- )
1526+ match rootSigOpt with
1527+ | Some _ ->
1528+ // Type-check an implementation file backed by a signature file
1529+ let info = fsiBackedInfos[ file.FileName]
1530+ match info with
1531+ | amap, conditionalDefines, rootSig, priorErrors, file, tcStateForImplFile, ccuSigForFile ->
1532+
1533+ // Check if we've already seen an implementation for this fragment
1534+ if Zset.contains qualNameOfFile tcStateForImplFile.tcsRootImpls then
1535+ errorR ( Error( FSComp.SR.buildImplementationAlreadyGiven ( qualNameOfFile.Text), m))
1536+
1537+ // In the first linear part of parallel checking, we use a 'checkForErrors' that checks either for errors
1538+ // somewhere in the files processed prior to this one, including from the first phase, or in the processing
1539+ // of this particular file.
1540+ // TODO: Are we handling the commented out code somewhere else?
1541+ let checkForErrors2 () = priorErrors // || (logger.ErrorCount > 0)
1542+
1543+ let topAttrs , implFile , tcEnvAtEnd , createsGeneratedProvidedTypes =
1544+ CheckOneImplFile(
1545+ tcGlobals,
1546+ amap,
1547+ tcStateForImplFile.tcsCcu,
1548+ tcStateForImplFile.tcsImplicitOpenDeclarations,
1549+ checkForErrors2,
1550+ conditionalDefines,
1551+ TcResultsSink.NoSink,
1552+ tcConfig.internalTestSpanStackReferring,
1553+ tcStateForImplFile.tcsTcImplEnv,
1554+ Some rootSig,
1555+ file
1556+ )
1557+ |> Cancellable.runWithoutCancellation
1558+
1559+ let result = ( tcEnvAtEnd, topAttrs, Some implFile, ccuSigForFile)
1560+
1561+ // Type-check .fs file using dedicated stuff, not the main tcState as that will cause duplicates.
1562+ // Do not return resuling tcState - it shouldn't be used for anything.
1563+ // Return old tcState, with the exception of one flag.
1564+ return fun tcState ->
1565+ result, { tcState with tcsCreatesGeneratedProvidedTypes = tcState.CreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes }
1566+ | None ->
1567+ // Typecheck the implementation file not backed by a signature file
1568+
1569+ // Check if we've already seen an implementation for this fragment
1570+ if Zset.contains qualNameOfFile tcState.tcsRootImpls then
1571+ errorR ( Error( FSComp.SR.buildImplementationAlreadyGiven ( qualNameOfFile.Text), m))
1572+
1573+ let! topAttrs , implFile , tcEnvAtEnd , createsGeneratedProvidedTypes =
1574+ CheckOneImplFile(
1575+ tcGlobals,
1576+ amap,
1577+ tcState.tcsCcu,
1578+ tcState.tcsImplicitOpenDeclarations,
1579+ checkForErrors,
1580+ conditionalDefines,
1581+ tcSink,
1582+ tcConfig.internalTestSpanStackReferring,
1583+ tcState.tcsTcImplEnv,
1584+ None,
1585+ file
1586+ )
14941587
1495- return fun tcState ->
1496- let ccuSigForFile , tcState =
1497- AddCheckResultsToTcState
1498- ( tcGlobals, amap, hadSig , prefixPathOpt, tcSink, tcState.tcsTcImplEnv, qualNameOfFile, implFile.Signature)
1499- tcState
1588+ return fun tcState ->
1589+ let ccuSigForFile , fsTcState =
1590+ AddCheckResultsToTcState
1591+ ( tcGlobals, amap, false , prefixPathOpt, tcSink, tcState.tcsTcImplEnv, qualNameOfFile, implFile.Signature)
1592+ tcState
15001593
1501- let partialResult = tcEnvAtEnd, topAttrs, Some implFile, ccuSigForFile
1502-
1503- let tcState =
1504- { tcState with
1505- tcsCreatesGeneratedProvidedTypes = tcState .tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes
1506- }
1594+ let partialResult = tcEnvAtEnd, topAttrs, Some implFile, ccuSigForFile
1595+
1596+ let tcState =
1597+ { fsTcState with
1598+ tcsCreatesGeneratedProvidedTypes = fsTcState .tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes
1599+ }
15071600
1508- partialResult, tcState
1601+ partialResult, tcState
15091602
15101603 with e ->
15111604 errorRecovery e range0
0 commit comments