From 7fd128c1bc1f7259b1d663dd19360997dde0c43a Mon Sep 17 00:00:00 2001 From: Will Smith Date: Tue, 26 Oct 2021 10:29:36 -0700 Subject: [PATCH 1/3] Adding new parse functions --- src/fsharp/ParseAndCheckInputs.fs | 32 ++++++++++++++++++++++++++++++ src/fsharp/ParseAndCheckInputs.fsi | 7 +++++++ 2 files changed, 39 insertions(+) diff --git a/src/fsharp/ParseAndCheckInputs.fs b/src/fsharp/ParseAndCheckInputs.fs index d6b690a8ad7..4003fb5fc79 100644 --- a/src/fsharp/ParseAndCheckInputs.fs +++ b/src/fsharp/ParseAndCheckInputs.fs @@ -420,6 +420,22 @@ let checkInputFile (tcConfig: TcConfig) filename = else error(Error(FSComp.SR.buildInvalidSourceFileExtension(SanitizeFileName filename tcConfig.implicitIncludeDir), rangeStartup)) +let parseInputStreamAux (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, retryLocked, stream: Stream) = + use reader = stream.GetReader(tcConfig.inputCodePage, retryLocked) + + // Set up the LexBuffer for the file + let lexbuf = UnicodeLexing.StreamReaderAsLexbuf(not tcConfig.compilingFslib, tcConfig.langVersion, reader) + + // Parse the file drawing tokens from the lexbuf + ParseOneInputLexbuf(tcConfig, lexResourceManager, conditionalCompilationDefines, lexbuf, filename, isLastCompiland, errorLogger) + +let parseInputSourceTextAux (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, sourceText: ISourceText) = + // Set up the LexBuffer for the file + let lexbuf = UnicodeLexing.SourceTextAsLexbuf(not tcConfig.compilingFslib, tcConfig.langVersion, sourceText) + + // Parse the file drawing tokens from the lexbuf + ParseOneInputLexbuf(tcConfig, lexResourceManager, conditionalCompilationDefines, lexbuf, filename, isLastCompiland, errorLogger) + let parseInputFileAux (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, retryLocked) = // Get a stream reader for the file use fileStream = FileSystem.OpenFileForReadShim(filename) @@ -431,6 +447,22 @@ let parseInputFileAux (tcConfig: TcConfig, lexResourceManager, conditionalCompil // Parse the file drawing tokens from the lexbuf ParseOneInputLexbuf(tcConfig, lexResourceManager, conditionalCompilationDefines, lexbuf, filename, isLastCompiland, errorLogger) +/// Parse an input from stream +let ParseOneInputStream (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, retryLocked, stream: Stream) = + try + parseInputStreamAux(tcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, retryLocked, stream) + with e -> + errorRecovery e rangeStartup + EmptyParsedInput(filename, isLastCompiland) + +/// Parse an input from source text +let ParseOneInputSourceText (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, sourceText: ISourceText) = + try + parseInputSourceTextAux(tcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, sourceText) + with e -> + errorRecovery e rangeStartup + EmptyParsedInput(filename, isLastCompiland) + /// Parse an input from disk let ParseOneInputFile (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, retryLocked) = try diff --git a/src/fsharp/ParseAndCheckInputs.fsi b/src/fsharp/ParseAndCheckInputs.fsi index d1074191899..d0906edbf27 100644 --- a/src/fsharp/ParseAndCheckInputs.fsi +++ b/src/fsharp/ParseAndCheckInputs.fsi @@ -3,6 +3,7 @@ /// Contains logic to coordinate the parsing and checking of one or a group of files module internal FSharp.Compiler.ParseAndCheckInputs +open System.IO open Internal.Utilities.Library open FSharp.Compiler.CheckExpressions open FSharp.Compiler.CheckDeclarations @@ -46,6 +47,12 @@ val ApplyMetaCommandsFromInputToTcConfig: TcConfig * ParsedInput * string * Depe /// Process the #nowarn in an input and integrate them into the TcConfig val ApplyNoWarnsToTcConfig: TcConfig * ParsedInput * string -> TcConfig +/// Parse one input stream +val ParseOneInputStream: TcConfig * Lexhelp.LexResourceManager * conditionalCompilationDefines: string list * string * isLastCompiland: (bool * bool) * ErrorLogger * retryLocked: bool * stream: Stream -> ParsedInput + +/// Parse one input source text +val ParseOneInputSourceText: TcConfig * Lexhelp.LexResourceManager * conditionalCompilationDefines: string list * string * isLastCompiland: (bool * bool) * ErrorLogger * sourceText: ISourceText -> ParsedInput + /// Parse one input file val ParseOneInputFile: TcConfig * Lexhelp.LexResourceManager * conditionalCompilationDefines: string list * string * isLastCompiland: (bool * bool) * ErrorLogger * retryLocked: bool -> ParsedInput From 0c1d6ace51444a175457861d297a2e5c74ebf898 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Tue, 26 Oct 2021 10:53:29 -0700 Subject: [PATCH 2/3] Added FSharpDocument --- .../FSharp.Compiler.Service.fsproj | 6 ++ src/fsharp/service/FSharpDocument.fs | 102 ++++++++++++++++++ src/fsharp/service/FSharpDocument.fsi | 36 +++++++ 3 files changed, 144 insertions(+) create mode 100644 src/fsharp/service/FSharpDocument.fs create mode 100644 src/fsharp/service/FSharpDocument.fsi diff --git a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj index d972271f2b0..f6354b073ee 100644 --- a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj +++ b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj @@ -843,6 +843,12 @@ Service/SemanticClassificationKey.fs + + Service/FSharpDocument.fsi + + + Service/FSharpDocument.fs + Service/IncrementalBuild.fsi diff --git a/src/fsharp/service/FSharpDocument.fs b/src/fsharp/service/FSharpDocument.fs new file mode 100644 index 00000000000..2f096734d28 --- /dev/null +++ b/src/fsharp/service/FSharpDocument.fs @@ -0,0 +1,102 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.CodeAnalysis + +open System +open System.IO +open Internal.Utilities.Library +open FSharp.Compiler.IO +open FSharp.Compiler.Text + +[] +type DocumentText = + | OnDisk + | Stream of Stream + | SourceText of ISourceText + + interface IDisposable with + + member this.Dispose() = + match this with + | Stream stream -> stream.Dispose() + | _ -> () + +[] +type FSharpDocument internal () = + + abstract FilePath : string + + abstract TimeStamp : DateTime + + abstract IsOpen : bool + + abstract GetText : unit -> DocumentText + +type private FSharpDocumentMemoryMappedFile(filePath: string, timeStamp: DateTime, isOpen, openStream: unit -> Stream) = + inherit FSharpDocument() + + override _.FilePath = filePath + + override _.TimeStamp = timeStamp + + override _.IsOpen = isOpen + + override _.GetText() = + openStream () |> DocumentText.Stream + +type private FSharpDocumentByteArray(filePath: string, timeStamp: DateTime, isOpen, bytes: byte[]) = + inherit FSharpDocument() + + override _.FilePath = filePath + + override _.TimeStamp = timeStamp + + override _.IsOpen = isOpen + + override _.GetText() = + DocumentText.Stream(new MemoryStream(bytes, 0, bytes.Length, false) :> Stream) + +type private FSharpDocumentFromFile(filePath: string) = + inherit FSharpDocument() + + override _.FilePath = filePath + + override _.TimeStamp = FileSystem.GetLastWriteTimeShim(filePath) + + override _.IsOpen = false + + override _.GetText() = + DocumentText.OnDisk + +type private FSharpDocumentCustom(filePath: string, isOpen, getTimeStamp, getSourceText) = + inherit FSharpDocument() + + override _.FilePath = filePath + + override _.TimeStamp = getTimeStamp() + + override _.IsOpen = isOpen + + override _.GetText() = + DocumentText.SourceText(getSourceText()) + +type FSharpDocument with + + static member Create(filePath, isOpen, getTimeStamp, getSourceText) = + FSharpDocumentCustom(filePath, isOpen, getTimeStamp, getSourceText) :> FSharpDocument + + static member CreateFromFile(filePath: string) = + FSharpDocumentFromFile(filePath) :> FSharpDocument + + static member CreateCopyFromFile(filePath: string, isOpen) = + let timeStamp = FileSystem.GetLastWriteTimeShim(filePath) + + // We want to use mmaped documents only when + // not running on mono, since its MemoryMappedFile implementation throws when "mapName" is not provided (is null), (see: https://github.com/mono/mono/issues/10245) + if runningOnMono then + let bytes = FileSystem.OpenFileForReadShim(filePath, useMemoryMappedFile = false).ReadAllBytes() + FSharpDocumentByteArray(filePath, timeStamp, isOpen, bytes) :> FSharpDocument + else + let openStream = fun () -> + FileSystem.OpenFileForReadShim(filePath, useMemoryMappedFile = true, shouldShadowCopy = true) + FSharpDocumentMemoryMappedFile(filePath, timeStamp, isOpen, openStream) :> FSharpDocument \ No newline at end of file diff --git a/src/fsharp/service/FSharpDocument.fsi b/src/fsharp/service/FSharpDocument.fsi new file mode 100644 index 00000000000..b0b227f4f82 --- /dev/null +++ b/src/fsharp/service/FSharpDocument.fsi @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.CodeAnalysis + +open System +open System.IO +open FSharp.Compiler.Text + +[] +type internal DocumentText = + | OnDisk + | Stream of Stream + | SourceText of ISourceText + + interface IDisposable + +[] +type FSharpDocument = + + /// The file path of the source. + abstract FilePath : string + + /// The timestamp of the source. + abstract TimeStamp : DateTime + + /// Is the document open in an editor? + /// This is used to allow the background build to provide rich information on the document. + abstract IsOpen : bool + + abstract internal GetText : unit -> DocumentText + + static member internal CreateFromFile : filePath: string -> FSharpDocument + + static member CreateCopyFromFile : filePath: string * isOpen: bool -> FSharpDocument + + static member Create : filePath: string * isOpen: bool * getTimeStamp: (unit -> DateTime) * getSourceText: (unit -> ISourceText) -> FSharpDocument \ No newline at end of file From 208f423620faef43b45dd0deee91ebbaa0798d86 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Tue, 26 Oct 2021 16:28:04 -0700 Subject: [PATCH 3/3] Rename FSharpDocument to FSharpSource --- .../FSharp.Compiler.Service.fsproj | 8 +-- src/fsharp/service/FSharpDocument.fsi | 36 ----------- .../{FSharpDocument.fs => FSharpSource.fs} | 62 ++++++++----------- src/fsharp/service/FSharpSource.fsi | 38 ++++++++++++ src/fsharp/service/IncrementalBuild.fs | 38 ++++++++---- 5 files changed, 94 insertions(+), 88 deletions(-) delete mode 100644 src/fsharp/service/FSharpDocument.fsi rename src/fsharp/service/{FSharpDocument.fs => FSharpSource.fs} (50%) create mode 100644 src/fsharp/service/FSharpSource.fsi diff --git a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj index f6354b073ee..2cee1ba5a9c 100644 --- a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj +++ b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj @@ -843,11 +843,11 @@ Service/SemanticClassificationKey.fs - - Service/FSharpDocument.fsi + + Service/FSharpSource.fsi - - Service/FSharpDocument.fs + + Service/FSharpSource.fs Service/IncrementalBuild.fsi diff --git a/src/fsharp/service/FSharpDocument.fsi b/src/fsharp/service/FSharpDocument.fsi deleted file mode 100644 index b0b227f4f82..00000000000 --- a/src/fsharp/service/FSharpDocument.fsi +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.CodeAnalysis - -open System -open System.IO -open FSharp.Compiler.Text - -[] -type internal DocumentText = - | OnDisk - | Stream of Stream - | SourceText of ISourceText - - interface IDisposable - -[] -type FSharpDocument = - - /// The file path of the source. - abstract FilePath : string - - /// The timestamp of the source. - abstract TimeStamp : DateTime - - /// Is the document open in an editor? - /// This is used to allow the background build to provide rich information on the document. - abstract IsOpen : bool - - abstract internal GetText : unit -> DocumentText - - static member internal CreateFromFile : filePath: string -> FSharpDocument - - static member CreateCopyFromFile : filePath: string * isOpen: bool -> FSharpDocument - - static member Create : filePath: string * isOpen: bool * getTimeStamp: (unit -> DateTime) * getSourceText: (unit -> ISourceText) -> FSharpDocument \ No newline at end of file diff --git a/src/fsharp/service/FSharpDocument.fs b/src/fsharp/service/FSharpSource.fs similarity index 50% rename from src/fsharp/service/FSharpDocument.fs rename to src/fsharp/service/FSharpSource.fs index 2f096734d28..1f1d12373a9 100644 --- a/src/fsharp/service/FSharpDocument.fs +++ b/src/fsharp/service/FSharpSource.fs @@ -9,7 +9,7 @@ open FSharp.Compiler.IO open FSharp.Compiler.Text [] -type DocumentText = +type TextContainer = | OnDisk | Stream of Stream | SourceText of ISourceText @@ -22,81 +22,71 @@ type DocumentText = | _ -> () [] -type FSharpDocument internal () = +type FSharpSource internal () = abstract FilePath : string abstract TimeStamp : DateTime - abstract IsOpen : bool + abstract GetTextContainer: unit -> TextContainer - abstract GetText : unit -> DocumentText - -type private FSharpDocumentMemoryMappedFile(filePath: string, timeStamp: DateTime, isOpen, openStream: unit -> Stream) = - inherit FSharpDocument() +type private FSharpSourceMemoryMappedFile(filePath: string, timeStamp: DateTime, openStream: unit -> Stream) = + inherit FSharpSource() override _.FilePath = filePath override _.TimeStamp = timeStamp - override _.IsOpen = isOpen - - override _.GetText() = - openStream () |> DocumentText.Stream + override _.GetTextContainer() = + openStream () |> TextContainer.Stream -type private FSharpDocumentByteArray(filePath: string, timeStamp: DateTime, isOpen, bytes: byte[]) = - inherit FSharpDocument() +type private FSharpSourceByteArray(filePath: string, timeStamp: DateTime, bytes: byte[]) = + inherit FSharpSource() override _.FilePath = filePath override _.TimeStamp = timeStamp - override _.IsOpen = isOpen - - override _.GetText() = - DocumentText.Stream(new MemoryStream(bytes, 0, bytes.Length, false) :> Stream) + override _.GetTextContainer() = + TextContainer.Stream(new MemoryStream(bytes, 0, bytes.Length, false) :> Stream) -type private FSharpDocumentFromFile(filePath: string) = - inherit FSharpDocument() +type private FSharpSourceFromFile(filePath: string) = + inherit FSharpSource() override _.FilePath = filePath override _.TimeStamp = FileSystem.GetLastWriteTimeShim(filePath) - override _.IsOpen = false + override _.GetTextContainer() = + TextContainer.OnDisk - override _.GetText() = - DocumentText.OnDisk - -type private FSharpDocumentCustom(filePath: string, isOpen, getTimeStamp, getSourceText) = - inherit FSharpDocument() +type private FSharpSourceCustom(filePath: string, getTimeStamp, getSourceText) = + inherit FSharpSource() override _.FilePath = filePath override _.TimeStamp = getTimeStamp() - override _.IsOpen = isOpen - - override _.GetText() = - DocumentText.SourceText(getSourceText()) + override _.GetTextContainer() = + TextContainer.SourceText(getSourceText()) -type FSharpDocument with +type FSharpSource with - static member Create(filePath, isOpen, getTimeStamp, getSourceText) = - FSharpDocumentCustom(filePath, isOpen, getTimeStamp, getSourceText) :> FSharpDocument + static member Create(filePath, getTimeStamp, getSourceText) = + FSharpSourceCustom(filePath, getTimeStamp, getSourceText) :> FSharpSource static member CreateFromFile(filePath: string) = - FSharpDocumentFromFile(filePath) :> FSharpDocument + FSharpSourceFromFile(filePath) :> FSharpSource - static member CreateCopyFromFile(filePath: string, isOpen) = + static member CreateCopyFromFile(filePath: string) = let timeStamp = FileSystem.GetLastWriteTimeShim(filePath) // We want to use mmaped documents only when // not running on mono, since its MemoryMappedFile implementation throws when "mapName" is not provided (is null), (see: https://github.com/mono/mono/issues/10245) if runningOnMono then let bytes = FileSystem.OpenFileForReadShim(filePath, useMemoryMappedFile = false).ReadAllBytes() - FSharpDocumentByteArray(filePath, timeStamp, isOpen, bytes) :> FSharpDocument + FSharpSourceByteArray(filePath, timeStamp, bytes) :> FSharpSource else let openStream = fun () -> FileSystem.OpenFileForReadShim(filePath, useMemoryMappedFile = true, shouldShadowCopy = true) - FSharpDocumentMemoryMappedFile(filePath, timeStamp, isOpen, openStream) :> FSharpDocument \ No newline at end of file + FSharpSourceMemoryMappedFile(filePath, timeStamp, openStream) :> FSharpSource \ No newline at end of file diff --git a/src/fsharp/service/FSharpSource.fsi b/src/fsharp/service/FSharpSource.fsi new file mode 100644 index 00000000000..c8738342046 --- /dev/null +++ b/src/fsharp/service/FSharpSource.fsi @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.CodeAnalysis + +open System +open System.IO +open FSharp.Compiler.Text + +[] +type internal TextContainer = + | OnDisk + | Stream of Stream + | SourceText of ISourceText + + interface IDisposable + +/// The storage container for a F# source item that could either be on-disk or in-memory. +/// TODO: Make this public. +[] +type internal FSharpSource = + + /// The file path of the source. + abstract FilePath : string + + /// The timestamp of the source. + abstract TimeStamp : DateTime + + /// Gets the internal text container. Text may be on-disk, in a stream, or a source text. + abstract internal GetTextContainer : unit -> TextContainer + + /// Creates a FSharpSource from disk. Only used internally. + static member internal CreateFromFile : filePath: string -> FSharpSource + + /// Creates a FSharpSource from the specified file path by shadow-copying the file. + static member CreateCopyFromFile : filePath: string -> FSharpSource + + /// Creates a FSharpSource. + static member Create : filePath: string * getTimeStamp: (unit -> DateTime) * getSourceText: (unit -> ISourceText) -> FSharpSource \ No newline at end of file diff --git a/src/fsharp/service/IncrementalBuild.fs b/src/fsharp/service/IncrementalBuild.fs index ebb94f18398..8a5c531534d 100644 --- a/src/fsharp/service/IncrementalBuild.fs +++ b/src/fsharp/service/IncrementalBuild.fs @@ -96,8 +96,9 @@ module IncrementalBuildSyntaxTree = /// Information needed to lazily parse a file to get a ParsedInput. Internally uses a weak cache. [] - type SyntaxTree (tcConfig: TcConfig, fileParsed: Event, lexResourceManager, sourceRange: range, filename: string, isLastCompiland) = + type SyntaxTree (tcConfig: TcConfig, fileParsed: Event, lexResourceManager, sourceRange: range, source: FSharpSource, isLastCompiland) = + let filename = source.FilePath let mutable weakCache: WeakReference<_> option = None let parse(sigNameOpt: QualifiedNameOfFile option) = @@ -123,7 +124,14 @@ module IncrementalBuildSyntaxTree = ) ) else - ParseOneInputFile(tcConfig, lexResourceManager, [], filename, isLastCompiland, errorLogger, (*retryLocked*)true) + use text = source.GetTextContainer() + match text with + | TextContainer.Stream(stream) -> + ParseOneInputStream(tcConfig, lexResourceManager, [], filename, isLastCompiland, errorLogger, (*retryLocked*)false, stream) + | TextContainer.SourceText(sourceText) -> + ParseOneInputSourceText(tcConfig, lexResourceManager, [], filename, isLastCompiland, errorLogger, sourceText) + | TextContainer.OnDisk -> + ParseOneInputFile(tcConfig, lexResourceManager, [], filename, isLastCompiland, errorLogger, (*retryLocked*)true) fileParsed.Trigger filename @@ -147,7 +155,7 @@ module IncrementalBuildSyntaxTree = | _ -> parse sigNameOpt member _.Invalidate() = - SyntaxTree(tcConfig, fileParsed, lexResourceManager, sourceRange, filename, isLastCompiland) + SyntaxTree(tcConfig, fileParsed, lexResourceManager, sourceRange, source, isLastCompiland) member _.FileName = filename @@ -703,8 +711,8 @@ type RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, generate module IncrementalBuilderHelpers = /// Get the timestamp of the given file name. - let StampFileNameTask (cache: TimeStampCache) (_m: range, filename: string, _isLastCompiland) = - cache.GetFileTimeStamp filename + let StampFileNameTask (cache: TimeStampCache) (_m: range, source: FSharpSource, _isLastCompiland) = + cache.GetFileTimeStamp source.FilePath /// Timestamps of referenced assemblies are taken from the file's timestamp. let StampReferencedAssemblyTask (cache: TimeStampCache) (_ref, timeStamper) = @@ -911,8 +919,8 @@ module IncrementalBuilderHelpers = return ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt, finalBoundModelWithErrors } - let GetSyntaxTree tcConfig fileParsed lexResourceManager (sourceRange: range, filename: string, isLastCompiland) = - SyntaxTree(tcConfig, fileParsed, lexResourceManager, sourceRange, filename, isLastCompiland) + let GetSyntaxTree tcConfig fileParsed lexResourceManager (sourceRange: range, source, isLastCompiland) = + SyntaxTree(tcConfig, fileParsed, lexResourceManager, sourceRange, source, isLastCompiland) [] type IncrementalBuilderInitialState = @@ -924,7 +932,7 @@ type IncrementalBuilderInitialState = outfile: string assemblyName: string lexResourceManager: Lexhelp.LexResourceManager - fileNames: block + fileNames: block enablePartialTypeChecking: bool beforeFileChecked: Event fileChecked: Event @@ -1332,10 +1340,10 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc member _.TryGetSlotOfFileName(filename: string) = // Get the slot of the given file and force it to build. - let CompareFileNames (_, f2, _) = + let CompareFileNames (_, f2: FSharpSource, _) = let result = - String.Compare(filename, f2, StringComparison.CurrentCultureIgnoreCase)=0 - || String.Compare(FileSystem.GetFullPathShim filename, FileSystem.GetFullPathShim f2, StringComparison.CurrentCultureIgnoreCase)=0 + String.Compare(filename, f2.FilePath, StringComparison.CurrentCultureIgnoreCase)=0 + || String.Compare(FileSystem.GetFullPathShim filename, FileSystem.GetFullPathShim f2.FilePath, StringComparison.CurrentCultureIgnoreCase)=0 result match fileNames |> Block.tryFindIndex CompareFileNames with | Some slot -> Some slot @@ -1358,7 +1366,7 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc let syntaxTree = GetSyntaxTree initialState.tcConfig initialState.fileParsed initialState.lexResourceManager fileInfo syntaxTree.Parse None - member _.SourceFiles = fileNames |> Seq.map (fun (_, f, _) -> f) |> List.ofSeq + member _.SourceFiles = fileNames |> Seq.map (fun (_, f, _) -> f.FilePath) |> List.ofSeq /// CreateIncrementalBuilder (for background type checking). Note that fsc.fs also /// creates an incremental builder used by the command line compiler. @@ -1584,6 +1592,12 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc importsInvalidatedByTypeProvider ) + let sourceFiles = + sourceFiles + |> List.map (fun (m, filename, isLastCompiland) -> + (m, FSharpSource.CreateFromFile(filename), isLastCompiland) + ) + let initialState = IncrementalBuilderInitialState.Create( initialBoundModel,