Skip to content

Commit 57c1bfd

Browse files
committed
Use seq instead of resize array
1 parent 0b202e3 commit 57c1bfd

File tree

1 file changed

+68
-59
lines changed

1 file changed

+68
-59
lines changed

src/Compiler/Driver/CompilerDiagnostics.fs

Lines changed: 68 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,7 +2246,7 @@ type PhasedDiagnostic with
22462246

22472247
/// used by fsc.exe and fsi.exe, but not by VS
22482248
/// prints error and related errors to the specified StringBuilder
2249-
member diagnostic.Output(buf, tcConfig: TcConfig, severity) =
2249+
member diagnostic.Output(buf: StringBuilder, tcConfig: TcConfig, severity: FSharpDiagnosticSeverity) =
22502250

22512251
// 'true' for "canSuggestNames" is passed last here because we want to report suggestions in fsc.exe and fsi.exe, just not in regular IDE usage.
22522252
let diagnostics = CollectFormattedDiagnostics(tcConfig, severity, diagnostic, true)
@@ -2260,66 +2260,75 @@ type PhasedDiagnostic with
22602260
| FSharpDiagnosticSeverity.Hidden -> "Info"
22612261

22622262
let codeText = sprintf "FS%04d" details.Canonical.ErrorNumber
2263-
let lines = ResizeArray<string>()
2264-
2265-
// For multi-line messages, the first line with number and severity, the rest are indented
2266-
let messageLines = details.Message.Split([| '\n' |], StringSplitOptions.None)
2267-
if messageLines.Length > 0 then
2268-
lines.Add(sprintf "[%s] %s: %s" codeText severityText messageLines[0])
2269-
for i in 1 .. messageLines.Length - 1 do
2270-
lines.Add(sprintf "%s" messageLines[i])
2271-
else
2272-
lines.Add(sprintf "[%s] %s" codeText details.Message)
2273-
2274-
let addLocationAndSnippet (l: FormattedDiagnosticLocation) =
2275-
let range = l.Range
2276-
let fileDisplay = if String.IsNullOrWhiteSpace l.File then "unknown" else l.File
2277-
lines.Add(sprintf "└─ [%s:(%d,%d)]" fileDisplay range.StartLine range.StartColumn)
2278-
lines.Add("")
2279-
2280-
let tryRenderSnippet () =
2281-
try
2282-
let fullPath =
2283-
l.File
2284-
|> FileSystem.GetFullFilePathInDirectoryShim tcConfig.implicitIncludeDir
2285-
2286-
if FileSystem.FileExistsShim fullPath then
2287-
let content = File.ReadAllLines fullPath
2288-
2289-
if content.Length > 0 then
2290-
let startLine = max 1 (range.StartLine - 1)
2291-
let endLine = min content.Length (range.StartLine)
2292-
let snippetLines =
2293-
[ for ln in startLine .. min content.Length (endLine + 1) do
2294-
yield ln, content[ln - 1] ]
2295-
2296-
let lineNoWidth =
2297-
snippetLines
2298-
|> List.map fst
2299-
|> List.map string
2300-
|> List.map String.length
2301-
|> List.max
2302-
2303-
let caretStart = max 0 (range.StartColumn - 1)
2304-
let caretWidth = max 1 (max 0 (range.EndColumn - range.StartColumn))
2305-
let caretLine = String.make caretStart ' ' + String.make caretWidth '^'
2263+
let messageSentences =
2264+
details.Message.Split([| '\n' |], StringSplitOptions.None)
2265+
|> Seq.collect (fun line ->
2266+
let parts = line.Split([| '.' |], StringSplitOptions.None)
23062267

2307-
for (ln, text) in snippetLines do
2308-
lines.Add(sprintf " %*d | %s" lineNoWidth ln text)
2268+
parts
2269+
|> Seq.mapi (fun idx part ->
2270+
let trimmed = part.Trim()
23092271

2310-
lines.Add(sprintf " %s | %s" (String.make lineNoWidth ' ') caretLine)
2311-
with _ ->
2312-
()
2313-
2314-
tryRenderSnippet ()
2315-
2316-
match details.Location with
2317-
| Some l when not l.IsEmpty -> addLocationAndSnippet l
2318-
| _ -> ()
2319-
2320-
for i = 0 to lines.Count - 1 do
2321-
buf.AppendString lines[i]
2322-
if i < lines.Count - 1 then buf.AppendString "\n"
2272+
if trimmed = "" then
2273+
None
2274+
else
2275+
let hasDot = idx < parts.Length - 1 || line.EndsWith(".")
2276+
Some(if hasDot then trimmed + "." else trimmed)))
2277+
|> Seq.choose id
2278+
|> Seq.toList
2279+
2280+
let messageLines =
2281+
match messageSentences with
2282+
| head :: tail ->
2283+
seq {
2284+
yield sprintf "[%s] %s: %s" codeText severityText head
2285+
yield! tail |> Seq.map (fun s -> sprintf "%s" s)
2286+
}
2287+
| [] -> seq { yield sprintf "[%s] %s" codeText details.Message }
2288+
2289+
let locationAndSnippet =
2290+
match details.Location with
2291+
| Some l when not l.IsEmpty ->
2292+
seq {
2293+
let range = l.Range
2294+
let fileDisplay = if String.IsNullOrWhiteSpace l.File then "unknown" else l.File
2295+
yield sprintf "└─ [%s:(%d,%d)]" fileDisplay range.StartLine range.StartColumn
2296+
yield ""
2297+
2298+
try
2299+
let fullPath = l.File |> FileSystem.GetFullFilePathInDirectoryShim tcConfig.implicitIncludeDir
2300+
2301+
if FileSystem.FileExistsShim fullPath then
2302+
let content = File.ReadAllLines fullPath
2303+
2304+
if content.Length > 0 then
2305+
let startLine = max 1 (range.StartLine - 1)
2306+
let endLine = min content.Length range.StartLine
2307+
let snippetLines =
2308+
[ for ln in startLine .. min content.Length (endLine + 1) -> ln, content[ln - 1] ]
2309+
2310+
let lineNoWidth =
2311+
snippetLines
2312+
|> List.map fst
2313+
|> List.map string
2314+
|> List.map String.length
2315+
|> List.max
2316+
2317+
let caretStart = max 0 (range.StartColumn - 1)
2318+
let caretWidth = max 1 (max 0 (range.EndColumn - range.StartColumn))
2319+
let caretLine = String.make caretStart ' ' + String.make caretWidth '^'
2320+
2321+
for (ln, text) in snippetLines do
2322+
yield sprintf " %*d | %s" lineNoWidth ln text
2323+
if ln = range.StartLine then
2324+
yield sprintf " %s | %s" (String.make lineNoWidth ' ') caretLine
2325+
with _ -> ()
2326+
}
2327+
| _ -> Seq.empty
2328+
2329+
Seq.append messageLines locationAndSnippet
2330+
|> String.concat "\n"
2331+
|> fun rendered -> buf.Append(rendered) |> ignore
23232332

23242333
for e in diagnostics do
23252334
Printf.bprintf buf "\n"

0 commit comments

Comments
 (0)