diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md index e5c6a408edf..fcd012b8281 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md @@ -28,6 +28,7 @@ * TypeMismatchDiagnosticExtendedData: fix expected and actual types calculation. ([Issue ](https://github.com/dotnet/fsharp/pull/18851)) * Format top-level generic types using a prefix style in inherit/interface declarations and flexible type annotations. ([PR #18897](https://github.com/dotnet/fsharp/pull/18897)) * Parser: fix range for computed binding expressions ([PR #18903](https://github.com/dotnet/fsharp/pull/18903)) +* Tests: set test source for range debug printing ([PR #18879](https://github.com/dotnet/fsharp/pull/18879)) * Checker: fix declaring type for abbreviated types extensions ([PR #18909](https://github.com/dotnet/fsharp/pull/18909)) ### Changed diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs index 647d48e65a2..3a22199c32f 100755 --- a/src/Compiler/Utilities/range.fs +++ b/src/Compiler/Utilities/range.fs @@ -7,6 +7,7 @@ open System open System.IO open System.Collections.Concurrent open System.Collections.Generic +open System.Text open Microsoft.FSharp.Core.Printf open Internal.Utilities.Library open Internal.Utilities.Library.Extras.Bits @@ -261,6 +262,9 @@ module FileIndex = let startupFileName = "startup" let commandLineArgsFileName = "commandLineArgs" + let mutable testSources: ConcurrentDictionary = + ConcurrentDictionary() + [] module internal LineDirectives = @@ -329,6 +333,9 @@ type Range(code1: int64, code2: int64) = member m.FileName = fileOfFileIndex m.FileIndex + member internal m.ShortFileName = + Path.GetFileName(fileOfFileIndex m.FileIndex) |> nonNull + member m.ApplyLineDirectives() = match LineDirectives.store.TryFind m.FileIndex with | None -> m @@ -376,32 +383,42 @@ type Range(code1: int64, code2: int64) = member _.Code2 = code2 member m.DebugCode = - let name = m.FileName + let getRangeSubstring (m: range) (stream: Stream) = + let endCol = m.EndColumn - 1 + let startCol = m.StartColumn - 1 + + stream.ReadLines() + |> Seq.skip (m.StartLine - 1) + |> Seq.take (m.EndLine - m.StartLine + 1) + |> String.concat "\n" + |> fun s -> s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol) + + match testSources.TryGetValue(m.FileName) with + | true, source -> + use stream = new MemoryStream(Encoding.UTF8.GetBytes(source + "\n")) + getRangeSubstring m stream + | _ -> - if - name = unknownFileName - || name = startupFileName - || name = commandLineArgsFileName - then - name - else + let name = m.FileName - try - let endCol = m.EndColumn - 1 - let startCol = m.StartColumn - 1 + if + name = unknownFileName + || name = startupFileName + || name = commandLineArgsFileName + then + name + else - if FileSystem.IsInvalidPathShim m.FileName then - "path invalid: " + m.FileName - elif not (FileSystem.FileExistsShim m.FileName) then - "nonexistent file: " + m.FileName - else - FileSystem.OpenFileForReadShim(m.FileName).ReadLines() - |> Seq.skip (m.StartLine - 1) - |> Seq.take (m.EndLine - m.StartLine + 1) - |> String.concat "\n" - |> fun s -> s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol) - with e -> - e.ToString() + try + if FileSystem.IsInvalidPathShim m.FileName then + "path invalid: " + m.FileName + elif not (FileSystem.FileExistsShim m.FileName) then + "nonexistent file: " + m.FileName + else + use stream = FileSystem.OpenFileForReadShim(m.FileName) + getRangeSubstring m stream + with e -> + e.ToString() member _.Equals(m2: range) = let code2 = code2 &&& ~~~(debugPointKindMask ||| isSyntheticMask) @@ -613,3 +630,6 @@ module Range = | None -> mkRange file (mkPos 1 0) (mkPos 1 80) with _ -> mkRange file (mkPos 1 0) (mkPos 1 80) + + let internal setTestSource path (source: string) = + testSources.GetOrAdd(path, source) |> ignore diff --git a/src/Compiler/Utilities/range.fsi b/src/Compiler/Utilities/range.fsi index b20682e0ad0..0322589dae1 100755 --- a/src/Compiler/Utilities/range.fsi +++ b/src/Compiler/Utilities/range.fsi @@ -100,9 +100,13 @@ type Range = /// The file index for the range member internal FileIndex: int + member internal DebugCode: string + /// The file name for the file of the range member FileName: string - + + member internal ShortFileName: string + /// Apply the line directives to the range. member ApplyLineDirectives: unit -> range @@ -272,6 +276,8 @@ module Range = /// Equality comparer for range. val comparer: IEqualityComparer + val internal setTestSource: path: string -> source: string -> unit + /// Functions related to converting between lines indexed at 0 and 1 module Line = diff --git a/tests/FSharp.Compiler.Service.Tests/Common.fs b/tests/FSharp.Compiler.Service.Tests/Common.fs index 74368c9b1f3..6309a815345 100644 --- a/tests/FSharp.Compiler.Service.Tests/Common.fs +++ b/tests/FSharp.Compiler.Service.Tests/Common.fs @@ -141,11 +141,14 @@ let mkTestFileAndOptions additionalArgs = fileName, options let parseAndCheckFile fileName source options = + Range.setTestSource fileName source + match checker.ParseAndCheckFileInProject(fileName, 0, SourceText.ofString source, options) |> Async.RunImmediate with | parseResults, FSharpCheckFileAnswer.Succeeded(checkResults) -> parseResults, checkResults | _ -> failwithf "Parsing aborted unexpectedly..." let parseAndCheckScriptWithOptions (file:string, input, opts) = + Range.setTestSource file input #if NETCOREAPP let projectOptions = @@ -194,6 +197,7 @@ let parseSourceCode (name: string, code: string) = let args = mkProjectCommandLineArgs(dllPath, [filePath]) let options, _errors = checker.GetParsingOptionsFromCommandLineArgs(List.ofArray args) let parseResults = checker.ParseFile(filePath, SourceText.ofString code, options) |> Async.RunImmediate + Range.setTestSource filePath code parseResults.ParseTree let matchBraces (name: string, code: string) = diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 9e5607b27a1..111f683188e 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -368,6 +368,8 @@ module rec Compiler = let loadSourceFromFile path = getSource(TestType.Path path) let fsFromString (source: SourceCodeFileKind): FSharpCompilationSource = + source.GetSourceText |> Option.iter (Range.setTestSource source.GetSourceFileName) + { Source = source AdditionalSources = [] @@ -1308,7 +1310,7 @@ Actual: /// After compile, rebuild and print FSharpDiagnostic[] exactly as before, /// then diff against your existing .err.bsl files (few lines will shift). let verifyBaseline (cResult: CompilationResult) : CompilationResult = - // 1) Grab the ErrorInfo list from the compile result… + // 1) Grab the ErrorInfo list from the compilation result let errorInfos = match cResult with | CompilationResult.Success o