@@ -305,10 +305,18 @@ type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState
305305
306306 member private x.ClearStaleCache ( fileName : string , parsingOptions : FSharpParsingOptions ) =
307307 let fileIndex = parsingOptions.SourceFiles |> Array.findIndex ((=) fileName)
308+ let filesAbove = parsingOptions.SourceFiles |> Array.take fileIndex
309+ // backup all cached typecheck entries above file
310+ let cachedAbove = filesAbove |> Array.choose ( fun key ->
311+ match checkCache.TryGetValue( key) with
312+ | true , value -> Some ( key, value)
313+ | false , _ -> None)
314+ // remove all parse cache entries with the same file name
308315 let staleParseKeys = parseCache.Keys |> Seq.filter ( fun ( n , _ ) -> n = fileName) |> Seq.toArray
309- let staleCheckKeys = parsingOptions.SourceFiles |> Array.skip fileIndex
310316 staleParseKeys |> Array.iter ( fun key -> parseCache.Remove( key) |> ignore)
311- staleCheckKeys |> Array.iter ( fun key -> checkCache.Remove( key) |> ignore)
317+ checkCache.Clear(); // clear all typecheck cache
318+ // restore all cached typecheck entries above file
319+ cachedAbove |> Array.iter ( fun ( key , value ) -> checkCache.TryAdd( key, value) |> ignore)
312320
313321 member private x.ParseFile ( fileName : string , source : string , parsingOptions : FSharpParsingOptions ) =
314322 let parseCacheKey = fileName, hash source
@@ -373,6 +381,13 @@ type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState
373381 let tcState , declaredImpls = TypeCheckClosedInputSetFinish ( implFiles, tcState)
374382 tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile, moduleNamesDict
375383
384+ /// Errors grouped by file, sorted by line, column
385+ member private x.ErrorsByFile ( fileNames : string [], errorList : FSharpErrorInfo [] list ) =
386+ let errorMap = errorList |> Array.concat |> Array.groupBy ( fun x -> x.FileName) |> Map.ofArray
387+ let errors = fileNames |> Array.choose errorMap.TryFind
388+ errors |> Array.iter ( Array.sortInPlaceBy ( fun x -> x.StartLineAlternate, x.StartColumn))
389+ errors |> Array.concat
390+
376391 /// Clears parse and typecheck caches.
377392 member x.ClearCache () =
378393 parseCache.Clear()
@@ -426,7 +441,7 @@ type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState
426441 // make project results
427442 let parseErrors = parseResults |> Array.collect ( fun p -> p.Errors)
428443 let typedErrors = errorScope.Diagnostics |> List.toArray
429- let errors = Array.append parseErrors typedErrors //TODO: order by file
444+ let errors = x.ErrorsByFile ( fileNames , [ parseErrors; typedErrors ])
430445 let symbolUses = [] //TODO:
431446 let projectResults = x.MakeProjectResults ( projectFileName, parseResults, tcState, errors, symbolUses, Some topAttrs, Some tcImplFiles)
432447
@@ -467,7 +482,7 @@ type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState
467482 let parseErrorsBefore = parseResults |> Array.collect ( fun p -> p.Errors)
468483 let typedErrorsBefore = errorScope.Diagnostics |> List.toArray
469484 let newErrors = match checkFileResults with | Some res -> res.Errors | None -> [||]
470- let errors = [| yield ! parseErrorsBefore; yield ! typedErrorsBefore; yield ! newErrors |] //TODO: order by file
485+ let errors = x.ErrorsByFile ( fileNames , [ parseErrorsBefore; typedErrorsBefore; newErrors ])
471486
472487 // make partial project results
473488 let parseResults = Array.append parseResults [| parseFileResults |]
0 commit comments