@@ -2189,17 +2189,17 @@ module Helpers =
21892189 && FSharpProjectOptions.UseSameProject( o1, o2)
21902190
21912191 /// Determine whether two (fileName,sourceText,options) keys should be identical w.r.t. parsing
2192- let AreSameForParsing (( fileName1 : string , source1 : ISourceText , options1 ), ( fileName2 , source2 , options2 )) =
2193- fileName1 = fileName2 && options1 = options2 && source1.ContentEquals ( source2 )
2192+ let AreSameForParsing (( fileName1 : string , source1Hash : int , options1 ), ( fileName2 , source2Hash , options2 )) =
2193+ fileName1 = fileName2 && options1 = options2 && source1Hash = source2Hash
21942194
21952195 let AreSimilarForParsing (( fileName1 , _ , _ ), ( fileName2 , _ , _ )) =
21962196 fileName1 = fileName2
21972197
21982198 /// Determine whether two (fileName,sourceText,options) keys should be identical w.r.t. checking
2199- let AreSameForChecking3 (( fileName1 : string , source1 : ISourceText , options1 : FSharpProjectOptions ), ( fileName2 , source2 , options2 )) =
2199+ let AreSameForChecking3 (( fileName1 : string , source1Hash : int , options1 : FSharpProjectOptions ), ( fileName2 , source2Hash , options2 )) =
22002200 ( fileName1 = fileName2)
22012201 && FSharpProjectOptions.AreSameForChecking( options1, options2)
2202- && source1.ContentEquals ( source2 )
2202+ && source1Hash = source2Hash
22032203
22042204 /// Determine whether two (fileName,sourceText,options) keys should be identical w.r.t. resource usage
22052205 let AreSubsumable3 (( fileName1 : string , _ , o1 : FSharpProjectOptions ),( fileName2 : string , _ , o2 : FSharpProjectOptions )) =
@@ -2315,7 +2315,7 @@ module CompileHelpers =
23152315 System.Console.SetError error
23162316 | None -> ()
23172317
2318-
2318+ type SourceTextHash = int
23192319type FileName = string
23202320type FilePath = string
23212321type ProjectPath = string
@@ -2461,7 +2461,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
24612461
24622462 // Also keyed on source. This can only be out of date if the antecedent is out of date
24632463 let checkFileInProjectCache =
2464- MruCache< ParseCacheLockToken, FileName * ISourceText * FSharpProjectOptions, FSharpParseFileResults * FSharpCheckFileResults * FileVersion * DateTime>
2464+ MruCache< ParseCacheLockToken, FileName * SourceTextHash * FSharpProjectOptions, FSharpParseFileResults * FSharpCheckFileResults * FileVersion * DateTime>
24652465 ( keepStrongly= checkFileInProjectCacheSize,
24662466 areSame= AreSameForChecking3,
24672467 areSimilar= AreSubsumable3)
@@ -2512,13 +2512,14 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
25122512
25132513 member bc.ParseFile ( filename : string , sourceText : ISourceText , options : FSharpParsingOptions , userOpName : string ) =
25142514 async {
2515- match parseCacheLock.AcquireLock( fun ltok -> parseFileCache.TryGet( ltok, ( filename, sourceText, options))) with
2515+ let hash = sourceText.GetHashCode()
2516+ match parseCacheLock.AcquireLock( fun ltok -> parseFileCache.TryGet( ltok, ( filename, hash, options))) with
25162517 | Some res -> return res
25172518 | None ->
25182519 foregroundParseCount <- foregroundParseCount + 1
25192520 let parseErrors , parseTreeOpt , anyErrors = Parser.parseFile( sourceText, filename, options, userOpName, suggestNamesForErrors)
25202521 let res = FSharpParseFileResults( parseErrors, parseTreeOpt, anyErrors, options.SourceFiles)
2521- parseCacheLock.AcquireLock( fun ltok -> parseFileCache.Set( ltok, ( filename, sourceText , options), res))
2522+ parseCacheLock.AcquireLock( fun ltok -> parseFileCache.Set( ltok, ( filename, hash , options), res))
25222523 return res
25232524 }
25242525
@@ -2537,9 +2538,9 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
25372538 }
25382539 )
25392540
2540- member bc.GetCachedCheckFileResult ( builder : IncrementalBuilder , filename , sourceText , options ) =
2541+ member bc.GetCachedCheckFileResult ( builder : IncrementalBuilder , filename , sourceText : ISourceText , options ) =
25412542 // Check the cache. We can only use cached results when there is no work to do to bring the background builder up-to-date
2542- let cachedResults = parseCacheLock.AcquireLock ( fun ltok -> checkFileInProjectCache.TryGet( ltok, ( filename, sourceText, options)))
2543+ let cachedResults = parseCacheLock.AcquireLock ( fun ltok -> checkFileInProjectCache.TryGet( ltok, ( filename, sourceText.GetHashCode () , options)))
25432544
25442545 match cachedResults with
25452546// | Some (parseResults, checkResults, _, _) when builder.AreCheckResultsBeforeFileInProjectReady(filename) ->
@@ -2599,7 +2600,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
25992600 tcPrior.TcState, loadClosure, tcPrior.TcErrors, reactorOps, ( fun () -> builder.IsAlive), textSnapshotInfo, userOpName, suggestNamesForErrors)
26002601 let parsingOptions = FSharpParsingOptions.FromTcConfig( tcPrior.TcConfig, Array.ofList builder.SourceFiles, options.UseScriptResolutionRules)
26012602 let checkAnswer = MakeCheckFileAnswer( fileName, tcFileResult, options, builder, Array.ofList tcPrior.TcDependencyFiles, creationErrors, parseResults.Errors, tcErrors)
2602- bc.RecordTypeCheckFileInProjectResults( fileName, options, parsingOptions, parseResults, fileVersion, tcPrior.TimeStamp, Some checkAnswer, sourceText)
2603+ bc.RecordTypeCheckFileInProjectResults( fileName, options, parsingOptions, parseResults, fileVersion, tcPrior.TimeStamp, Some checkAnswer, sourceText.GetHashCode () )
26032604 return checkAnswer
26042605 finally
26052606 let dummy = ref ()
@@ -2615,7 +2616,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
26152616 }
26162617
26172618 /// Type-check the result obtained by parsing, but only if the antecedent type checking context is available.
2618- member bc.CheckFileInProjectAllowingStaleCachedResults ( parseResults : FSharpParseFileResults , filename , fileVersion , sourceText , options , textSnapshotInfo : obj option , userOpName ) =
2619+ member bc.CheckFileInProjectAllowingStaleCachedResults ( parseResults : FSharpParseFileResults , filename , fileVersion , sourceText : ISourceText , options , textSnapshotInfo : obj option , userOpName ) =
26192620 let execWithReactorAsync action = reactor.EnqueueAndAwaitOpAsync( userOpName, " CheckFileInProjectAllowingStaleCachedResults " , filename, action)
26202621 async {
26212622 try
@@ -2658,7 +2659,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
26582659 }
26592660
26602661 /// Type-check the result obtained by parsing. Force the evaluation of the antecedent type checking context if needed.
2661- member bc.CheckFileInProject ( parseResults : FSharpParseFileResults , filename , fileVersion , sourceText , options , textSnapshotInfo , userOpName ) =
2662+ member bc.CheckFileInProject ( parseResults : FSharpParseFileResults , filename , fileVersion , sourceText : ISourceText , options , textSnapshotInfo , userOpName ) =
26622663 let execWithReactorAsync action = reactor.EnqueueAndAwaitOpAsync( userOpName, " CheckFileInProject" , filename, action)
26632664 async {
26642665 try
@@ -2686,7 +2687,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
26862687 }
26872688
26882689 /// Parses and checks the source file and returns untyped AST and check results.
2689- member bc.ParseAndCheckFileInProject ( filename : string , fileVersion , sourceText , options : FSharpProjectOptions , textSnapshotInfo , userOpName ) =
2690+ member bc.ParseAndCheckFileInProject ( filename : string , fileVersion , sourceText : ISourceText , options : FSharpProjectOptions , textSnapshotInfo , userOpName ) =
26902691 let execWithReactorAsync action = reactor.EnqueueAndAwaitOpAsync( userOpName, " ParseAndCheckFileInProject" , filename, action)
26912692 async {
26922693 try
@@ -2773,7 +2774,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
27732774 match sourceText with
27742775 | Some sourceText ->
27752776 parseCacheLock.AcquireLock ( fun ltok ->
2776- match checkFileInProjectCache.TryGet( ltok,( filename, sourceText, options)) with
2777+ match checkFileInProjectCache.TryGet( ltok,( filename, sourceText.GetHashCode () , options)) with
27772778 | Some ( a, b, c,_) -> Some ( a, b, c)
27782779 | None -> parseCacheLock.AcquireLock ( fun ltok -> checkFileInProjectCachePossiblyStale.TryGet( ltok,( filename, options))))
27792780 | None -> parseCacheLock.AcquireLock ( fun ltok -> checkFileInProjectCachePossiblyStale.TryGet( ltok,( filename, options)))
@@ -3010,14 +3011,15 @@ type FSharpChecker(legacyReferenceResolver, projectCacheSize, keepAssemblyConten
30103011
30113012 member ic.ReferenceResolver = legacyReferenceResolver
30123013
3013- member ic.MatchBraces ( filename , sourceText , options : FSharpParsingOptions , ? userOpName : string ) =
3014+ member ic.MatchBraces ( filename , sourceText : ISourceText , options : FSharpParsingOptions , ? userOpName : string ) =
30143015 let userOpName = defaultArg userOpName " Unknown"
3016+ let hash = sourceText.GetHashCode()
30153017 async {
3016- match braceMatchCache.TryGet( AssumeAnyCallerThreadWithoutEvidence(), ( filename, sourceText , options)) with
3018+ match braceMatchCache.TryGet( AssumeAnyCallerThreadWithoutEvidence(), ( filename, hash , options)) with
30173019 | Some res -> return res
30183020 | None ->
30193021 let res = Parser.matchBraces( sourceText, filename, options, userOpName, suggestNamesForErrors)
3020- braceMatchCache.Set( AssumeAnyCallerThreadWithoutEvidence(), ( filename, sourceText , options), res)
3022+ braceMatchCache.Set( AssumeAnyCallerThreadWithoutEvidence(), ( filename, hash , options), res)
30213023 return res
30223024 }
30233025
0 commit comments