@@ -52,6 +52,7 @@ open Microsoft.FSharp.Compiler.TypeChecker
5252//-------------------------------------------------------------------------
5353
5454type internal TcResult = TcEnv * TopAttribs * TypedImplFile option * ModuleOrNamespaceType
55+ type internal TcErrors = FSharpErrorInfo[]
5556
5657type InteractiveChecker internal ( tcConfig , tcGlobals , tcImports , tcInitialState , ctok , reactorOps , parseCache , checkCache ) =
5758 let userOpName = " Unknown"
@@ -289,7 +290,7 @@ type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState
289290 // parse cache, keyed on file name and source hash
290291 let parseCache = ConcurrentDictionary< string * int, FSharpParseFileResults>( HashIdentity.Structural)
291292 // type check cache, keyed on file name
292- let checkCache = ConcurrentDictionary< string, TcResult * ( TcState * ModuleNamesDict)>( HashIdentity.Structural)
293+ let checkCache = ConcurrentDictionary< string, ( TcResult * TcErrors ) * ( TcState * ModuleNamesDict)>( HashIdentity.Structural)
293294
294295 InteractiveChecker ( tcConfig, tcGlobals, tcImports, tcInitialState, ctok, reactorOps, parseCache, checkCache)
295296
@@ -326,32 +327,40 @@ type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState
326327 let dependencyFiles = [||] // interactions have no dependencies
327328 FSharpParseFileResults ( parseErrors, parseTreeOpt, anyErrors, dependencyFiles) )
328329
330+ member private x.TypeCheckOneInput ( parseResults : FSharpParseFileResults , tcSink : TcResultsSink , tcState : TcState , moduleNamesDict : ModuleNamesDict ) =
331+ let input = parseResults.ParseTree.Value
332+ let capturingErrorLogger = CompilationErrorLogger( " TypeCheckFile" , tcConfig.errorSeverityOptions)
333+ let errorLogger = GetErrorLoggerFilteringByScopedPragmas( false , GetScopedPragmasForInput( input), capturingErrorLogger)
334+ use _errorScope = new CompilationGlobalsScope ( errorLogger, BuildPhase.TypeCheck)
335+
336+ let checkForErrors () = parseResults.ParseHadErrors || errorLogger.ErrorCount > 0
337+ let prefixPathOpt = None
338+
339+ let input , moduleNamesDict = input |> DeduplicateParsedInputModuleName moduleNamesDict
340+ let tcResult , tcState =
341+ TypeCheckOneInputEventually ( checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input)
342+ |> Eventually.force ctok
343+
344+ let fileName = parseResults.FileName
345+ let tcErrors = ErrorHelpers.CreateErrorInfos ( tcConfig.errorSeverityOptions, false , fileName, ( capturingErrorLogger.GetErrors()))
346+ ( tcResult, tcErrors), ( tcState, moduleNamesDict)
347+
329348 member private x.CheckFile ( projectFileName : string , parseResults : FSharpParseFileResults , tcState : TcState , moduleNamesDict : ModuleNamesDict ) =
330349 match parseResults.ParseTree with
331350 | Some input ->
332- let capturingErrorLogger = CompilationErrorLogger( " TypeCheckFile" , tcConfig.errorSeverityOptions)
333- let errorLogger = GetErrorLoggerFilteringByScopedPragmas( false , GetScopedPragmasForInput( input), capturingErrorLogger)
334- use _errorScope = new CompilationGlobalsScope ( errorLogger, BuildPhase.TypeCheck)
335-
336351 let sink = TcResultsSinkImpl( tcGlobals)
337352 let tcSink = TcResultsSink.WithSink sink
338- let checkForErrors () = parseResults.ParseHadErrors || errorLogger.ErrorCount > 0
339- let prefixPathOpt = None
340-
341- let input , moduleNamesDict = input |> DeduplicateParsedInputModuleName moduleNamesDict
342- let ( tcEnvAtEnd , topAttrs , implFile , ccuSigForFile ), tcState =
343- TypeCheckOneInputEventually ( checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input)
344- |> Eventually.force ctok
345-
353+ let ( tcResult , tcErrors ), ( tcState , moduleNamesDict ) =
354+ x.TypeCheckOneInput ( parseResults, tcSink, tcState, moduleNamesDict)
346355 let fileName = parseResults.FileName
347- checkCache.[ fileName] <- (( tcEnvAtEnd , topAttrs , implFile , ccuSigForFile ), ( tcState, moduleNamesDict))
356+ checkCache.[ fileName] <- (( tcResult , tcErrors ), ( tcState, moduleNamesDict))
348357
349358 let loadClosure = None
350359 let checkAlive () = true
351360 let textSnapshotInfo = None
352361 let keepAssemblyContents = true
353362
354- let tcErrors = ErrorHelpers.CreateErrorInfos ( tcConfig.errorSeverityOptions , false , fileName , ( capturingErrorLogger.GetErrors ()))
363+ let tcEnvAtEnd , _topAttrs , implFile , ccuSigForFile = tcResult
355364 let errors = Array.append parseResults.Errors tcErrors
356365
357366 let scope = TypeCheckInfo ( tcConfig, tcGlobals, ccuSigForFile, tcState.Ccu, tcImports, tcEnvAtEnd.AccessRights,
@@ -362,24 +371,19 @@ type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState
362371 | None ->
363372 None
364373
365- member private x.TypeCheckClosedInputSet ( ctok , checkForErrors , tcConfig , tcImports , tcGlobals , prefixPathOpt , tcState , inputs ) =
366- let fileNameOf = function
367- | ParsedInput.SigFile ( ParsedSigFileInput( fileName,_,_,_,_)) -> fileName
368- | ParsedInput.ImplFile ( ParsedImplFileInput( fileName,_,_,_,_,_,_)) -> fileName
369- let cachedTypeCheck ( tcState , moduleNamesDict ) ( input : ParsedInput ) =
370- let checkCacheKey = fileNameOf input
374+ member private x.TypeCheckClosedInputSet ( parseResults : FSharpParseFileResults [], tcConfig , tcImports , tcGlobals , tcState ) =
375+ let cachedTypeCheck ( tcState , moduleNamesDict ) ( parseRes : FSharpParseFileResults ) =
376+ let checkCacheKey = parseRes.FileName
371377 let typeCheckOneInput _fileName =
372- let input , moduleNamesDict = input |> DeduplicateParsedInputModuleName moduleNamesDict
373- let tcResults , tcState =
374- TypeCheckOneInput ( ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt) tcState input
375- tcResults, ( tcState, moduleNamesDict)
378+ x.TypeCheckOneInput ( parseRes, TcResultsSink.NoSink, tcState, moduleNamesDict)
376379 checkCache.GetOrAdd( checkCacheKey, typeCheckOneInput)
377380 let results , ( tcState , moduleNamesDict ) =
378- (( tcState, Map.empty), inputs) ||> List.mapFold cachedTypeCheck
381+ (( tcState, Map.empty), parseResults) ||> Array.mapFold cachedTypeCheck
382+ let tcResults , tcErrors = Array.unzip results
379383 let ( tcEnvAtEndOfLastFile , topAttrs , implFiles , _ccuSigsForFiles ), tcState =
380- TypeCheckMultipleInputsFinish( results , tcState)
384+ TypeCheckMultipleInputsFinish( tcResults |> Array.toList , tcState)
381385 let tcState , declaredImpls = TypeCheckClosedInputSetFinish ( implFiles, tcState)
382- tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile, moduleNamesDict
386+ tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile, moduleNamesDict, tcErrors
383387
384388 /// Errors grouped by file, sorted by line, column
385389 member private x.ErrorsByFile ( fileNames : string [], errorList : FSharpErrorInfo [] list ) =
@@ -427,20 +431,14 @@ type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState
427431 let parsingOptions = FSharpParsingOptions.FromTcConfig( tcConfig, fileNames, false )
428432 let parseFile ( fileName , source ) = x.ParseFile ( fileName, source, parsingOptions)
429433 let parseResults = Array.zip fileNames sources |> Array.map parseFile
430- let parseHadErrors = parseResults |> Array.exists ( fun p -> p.ParseHadErrors)
431- let parsedInputs = parseResults |> Array.choose ( fun p -> p.ParseTree) |> Array.toList
432434
433435 // type check files
434- use errorScope = new ErrorScope()
435- let hasTypedErrors () = errorScope.Diagnostics |> List.exists ( fun e -> e.Severity = FSharpErrorSeverity.Error)
436- let checkForErrors () = parseHadErrors || hasTypedErrors ()
437- let prefixPathOpt = None
438- let tcState , topAttrs , tcImplFiles , _tcEnvAtEnd , _moduleNamesDict =
439- x.TypeCheckClosedInputSet ( ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcInitialState, parsedInputs)
436+ let tcState , topAttrs , tcImplFiles , _tcEnvAtEnd , _moduleNamesDict , tcErrors =
437+ x.TypeCheckClosedInputSet ( parseResults, tcConfig, tcImports, tcGlobals, tcInitialState)
440438
441439 // make project results
442440 let parseErrors = parseResults |> Array.collect ( fun p -> p.Errors)
443- let typedErrors = errorScope.Diagnostics |> List.toArray
441+ let typedErrors = tcErrors |> Array.concat
444442 let errors = x.ErrorsByFile ( fileNames, [ parseErrors; typedErrors ])
445443 let symbolUses = [] //TODO:
446444 let projectResults = x.MakeProjectResults ( projectFileName, parseResults, tcState, errors, symbolUses, Some topAttrs, Some tcImplFiles)
@@ -461,26 +459,20 @@ type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState
461459 let parsingOptions = FSharpParsingOptions.FromTcConfig( tcConfig, fileNames, false )
462460 let parseFile ( fileName , source ) = x.ParseFile ( fileName, source, parsingOptions)
463461 let parseResults = Array.zip fileNamesBeforeFile sourcesBeforeFile |> Array.map parseFile
464- let parseHadErrors = parseResults |> Array.exists ( fun p -> p.ParseHadErrors)
465- let parsedInputs = parseResults |> Array.choose ( fun p -> p.ParseTree) |> Array.toList
466462
467463 // type check files before file
468- use errorScope = new ErrorScope()
469- let hasTypedErrors () = errorScope.Diagnostics |> List.exists ( fun e -> e.Severity = FSharpErrorSeverity.Error)
470- let checkForErrors () = parseHadErrors || hasTypedErrors ()
471- let prefixPathOpt = None
472- let tcState , topAttrs , tcImplFiles , _tcEnvAtEnd , moduleNamesDict =
473- x.TypeCheckClosedInputSet ( ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcInitialState, parsedInputs)
464+ let tcState , topAttrs , tcImplFiles , _tcEnvAtEnd , moduleNamesDict , tcErrors =
465+ x.TypeCheckClosedInputSet ( parseResults, tcConfig, tcImports, tcGlobals, tcInitialState)
474466
475467 // parse and type check file
476468 let parseFileResults = parseFile ( fileName, sources.[ fileIndex])
477469 let checkFileResults = x.CheckFile ( projectFileName, parseFileResults, tcState, moduleNamesDict)
478- let ( _tcEnvAtEndFile , topAttrsFile , implFile , _ccuSigForFile ), ( tcState , _moduleNamesDict ) =
479- checkCache .[ fileName ]
470+ let ( tcResult , _tcErrors ), ( tcState , _moduleNamesDict ) = checkCache .[ fileName ]
471+ let _tcEnvAtEndFile , topAttrsFile , implFile , _ccuSigForFile = tcResult
480472
481473 // collect errors
482474 let parseErrorsBefore = parseResults |> Array.collect ( fun p -> p.Errors)
483- let typedErrorsBefore = errorScope.Diagnostics |> List.toArray
475+ let typedErrorsBefore = tcErrors |> Array.concat
484476 let newErrors = match checkFileResults with | Some res -> res.Errors | None -> [||]
485477 let errors = x.ErrorsByFile ( fileNames, [ parseErrorsBefore; typedErrorsBefore; newErrors ])
486478
0 commit comments