diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.200.md index 03c30d64d6c..b647952d09c 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.200.md @@ -2,6 +2,10 @@ * Type relations cache: optimize key generation ([Issue #19116](https://github.com/dotnet/fsharp/issues/18767)) ([PR #19120](https://github.com/dotnet/fsharp/pull/19120)) +### Added + +* FSharpDiagnostic: add default severity ([#19152](https://github.com/dotnet/fsharp/pull/19152)) + ### Breaking Changes * `SynExpr.LetOrUse` holds `SynLetOrUse`. ([PR #19090](https://github.com/dotnet/fsharp/pull/19090)) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md index 4d9542cf94e..c8bbf2156ce 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md @@ -20,6 +20,7 @@ * Add FSharpCodeCompletionOptions ([PR #19030](https://github.com/dotnet/fsharp/pull/19030)) * Type checker: recover on checking binding parameter constraints ([#19046](https://github.com/dotnet/fsharp/pull/19046)) * Debugger: provide breakpoint ranges for short lambdas ([#19067](https://github.com/dotnet/fsharp/pull/19067)) +* FSharpDiagnostic: add default severity ([#19152](https://github.com/dotnet/fsharp/pull/19152)) ### Changed diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 71b0ba0eb2c..875d21c3bdb 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -405,7 +405,8 @@ type PhasedDiagnostic with (severity = FSharpDiagnosticSeverity.Info && level > 0) || (severity = FSharpDiagnosticSeverity.Warning && level >= x.WarningLevel) - member x.AdjustSeverity(options, severity) = + member x.AdjustSeverity(options) = + let severity = x.Severity let n = x.Number let localWarnon () = WarnScopes.IsWarnon options n x.Range @@ -2007,7 +2008,7 @@ type PhasedDiagnostic with x.Exception.Output(buf, suggestNames) let message = buf.ToString() let exn = DiagnosticWithText(x.Number, message, m) - { Exception = exn; Phase = x.Phase } + { x with Exception = exn } | None -> x let SanitizeFileName fileName implicitIncludeDir = @@ -2313,15 +2314,15 @@ type DiagnosticsLoggerFilteringByScopedNowarn(diagnosticOptions: FSharpDiagnosti let mutable realErrorPresent = false - override _.DiagnosticSink(diagnostic: PhasedDiagnostic, severity) = + override _.DiagnosticSink(diagnostic: PhasedDiagnostic) = - if severity = FSharpDiagnosticSeverity.Error then + if diagnostic.Severity = FSharpDiagnosticSeverity.Error then realErrorPresent <- true - diagnosticsLogger.DiagnosticSink(diagnostic, severity) + diagnosticsLogger.DiagnosticSink(diagnostic) else - match diagnostic.AdjustSeverity(diagnosticOptions, severity) with + match diagnostic.AdjustSeverity(diagnosticOptions) with | FSharpDiagnosticSeverity.Hidden -> () - | s -> diagnosticsLogger.DiagnosticSink(diagnostic, s) + | s -> diagnosticsLogger.DiagnosticSink({ diagnostic with Severity = s }) override _.ErrorCount = diagnosticsLogger.ErrorCount diff --git a/src/Compiler/Driver/CompilerDiagnostics.fsi b/src/Compiler/Driver/CompilerDiagnostics.fsi index dc9bccc3362..0cf57b81e8c 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fsi +++ b/src/Compiler/Driver/CompilerDiagnostics.fsi @@ -61,7 +61,7 @@ type PhasedDiagnostic with member FormatCore: flattenErrors: bool * suggestNames: bool -> string /// Compute new severity according to the various diagnostics options - member AdjustSeverity: FSharpDiagnosticOptions * FSharpDiagnosticSeverity -> FSharpDiagnosticSeverity + member AdjustSeverity: FSharpDiagnosticOptions -> FSharpDiagnosticSeverity /// Output all of a diagnostic to a buffer, including range member Output: buf: StringBuilder * tcConfig: TcConfig * severity: FSharpDiagnosticSeverity -> unit diff --git a/src/Compiler/Driver/ScriptClosure.fs b/src/Compiler/Driver/ScriptClosure.fs index 2f3778bb1db..7f25c7b826d 100644 --- a/src/Compiler/Driver/ScriptClosure.fs +++ b/src/Compiler/Driver/ScriptClosure.fs @@ -29,8 +29,8 @@ type LoadClosureInput = { FileName: string SyntaxTree: ParsedInput option - ParseDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list - MetaCommandDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + ParseDiagnostics: PhasedDiagnostic list + MetaCommandDiagnostics: PhasedDiagnostic list } [] @@ -64,13 +64,13 @@ type LoadClosure = OriginalLoadReferences: (range * string * string) list /// Diagnostics seen while processing resolutions - ResolutionDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + ResolutionDiagnostics: PhasedDiagnostic list /// Diagnostics seen while parsing root of closure - AllRootFileDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + AllRootFileDiagnostics: PhasedDiagnostic list /// Diagnostics seen while processing the compiler options implied root of closure - LoadClosureRootFileDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + LoadClosureRootFileDiagnostics: PhasedDiagnostic list } [] @@ -91,8 +91,8 @@ module ScriptPreprocessClosure = fileName: string * range: range * parsedInput: ParsedInput option * - parseDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list * - metaDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + parseDiagnostics: PhasedDiagnostic list * + metaDiagnostics: PhasedDiagnostic list type Observed() = let seen = Dictionary<_, bool>() @@ -594,7 +594,7 @@ module ScriptPreprocessClosure = | None -> true // Filter out non-root errors and warnings - let allRootDiagnostics = allRootDiagnostics |> List.filter (fst >> isRootRange) + let allRootDiagnostics = allRootDiagnostics |> List.filter isRootRange { SourceFiles = List.groupBy fst sourceFiles |> List.map (map2Of2 (List.map snd)) diff --git a/src/Compiler/Driver/ScriptClosure.fsi b/src/Compiler/Driver/ScriptClosure.fsi index b54b9b2f0d0..b14bf1fd465 100644 --- a/src/Compiler/Driver/ScriptClosure.fsi +++ b/src/Compiler/Driver/ScriptClosure.fsi @@ -26,9 +26,9 @@ type LoadClosureInput = SyntaxTree: ParsedInput option - ParseDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + ParseDiagnostics: PhasedDiagnostic list - MetaCommandDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list } + MetaCommandDiagnostics: PhasedDiagnostic list } [] type LoadClosure = @@ -61,13 +61,13 @@ type LoadClosure = OriginalLoadReferences: (range * string * string) list /// Diagnostics seen while processing resolutions - ResolutionDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + ResolutionDiagnostics: PhasedDiagnostic list /// Diagnostics to show for root of closure (used by fsc.fs) - AllRootFileDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + AllRootFileDiagnostics: PhasedDiagnostic list /// Diagnostics seen while processing the compiler options implied root of closure - LoadClosureRootFileDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + LoadClosureRootFileDiagnostics: PhasedDiagnostic list } /// Analyze a script text and find the closure of its references. diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 198b74601c4..1c31bdbe379 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -74,10 +74,10 @@ type DiagnosticsLoggerUpToMaxErrors(tcConfigB: TcConfigBuilder, exiter: Exiter, override _.ErrorCount = errors - override x.DiagnosticSink(diagnostic, severity) = + override x.DiagnosticSink(diagnostic) = let tcConfig = TcConfig.Create(tcConfigB, validate = false) - match diagnostic.AdjustSeverity(tcConfig.diagnosticsOptions, severity) with + match diagnostic.AdjustSeverity(tcConfig.diagnosticsOptions) with | FSharpDiagnosticSeverity.Error -> if errors >= tcConfig.maxErrors then x.HandleTooManyErrors(FSComp.SR.fscTooManyErrors ()) @@ -89,9 +89,8 @@ type DiagnosticsLoggerUpToMaxErrors(tcConfigB: TcConfigBuilder, exiter: Exiter, match diagnostic.Exception, tcConfigB.simulateException with | InternalError(msg, _), None - | Failure msg, None -> Debug.Assert(false, sprintf "Bug in compiler: %s\n%s" msg (diagnostic.Exception.ToString())) - | :? KeyNotFoundException, None -> - Debug.Assert(false, sprintf "Lookup exception in compiler: %s" (diagnostic.Exception.ToString())) + | Failure msg, None -> Debug.Assert(false, sprintf "Bug in compiler: %s\n%s" msg (diagnostic.ToString())) + | :? KeyNotFoundException, None -> Debug.Assert(false, sprintf "Lookup exception in compiler: %s" (diagnostic.ToString())) | _ -> () | FSharpDiagnosticSeverity.Hidden -> () diff --git a/src/Compiler/Driver/fsc.fsi b/src/Compiler/Driver/fsc.fsi index 377f82992a2..7a62da16911 100644 --- a/src/Compiler/Driver/fsc.fsi +++ b/src/Compiler/Driver/fsc.fsi @@ -39,7 +39,7 @@ type DiagnosticsLoggerUpToMaxErrors = override ErrorCount: int - override DiagnosticSink: diagnostic: PhasedDiagnostic * severity: FSharpDiagnosticSeverity -> unit + override DiagnosticSink: diagnostic: PhasedDiagnostic -> unit /// The main (non-incremental) compilation entry point used by fsc.exe val CompileFromCommandLineArguments: diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fs b/src/Compiler/Facilities/DiagnosticsLogger.fs index 58d24ddaaa7..91128beff8a 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fs +++ b/src/Compiler/Facilities/DiagnosticsLogger.fs @@ -286,10 +286,18 @@ type PhasedDiagnostic = { Exception: exn Phase: BuildPhase + Severity: FSharpDiagnosticSeverity + DefaultSeverity: FSharpDiagnosticSeverity } /// Construct a phased error - static member Create(exn: exn, phase: BuildPhase) : PhasedDiagnostic = { Exception = exn; Phase = phase } + static member Create(exn: exn, phase: BuildPhase, severity: FSharpDiagnosticSeverity) : PhasedDiagnostic = + { + Exception = exn + Phase = phase + Severity = severity + DefaultSeverity = severity + } member this.DebugDisplay() = sprintf "%s: %s" (this.Subcategory()) this.Exception.Message @@ -355,7 +363,7 @@ type DiagnosticsLogger(nameForDebugging: string) = // The 'Impl' factoring enables a developer to place a breakpoint at the non-Impl // code just below and get a breakpoint for all error logger implementations. - abstract DiagnosticSink: diagnostic: PhasedDiagnostic * severity: FSharpDiagnosticSeverity -> unit + abstract DiagnosticSink: diagnostic: PhasedDiagnostic -> unit member x.CheckForErrors() = (x.ErrorCount > 0) @@ -367,14 +375,14 @@ type DiagnosticsLogger(nameForDebugging: string) = let DiscardErrorsLogger = { new DiagnosticsLogger("DiscardErrorsLogger") with - member _.DiagnosticSink(diagnostic, severity) = () + member _.DiagnosticSink(diagnostic) = () member _.ErrorCount = 0 } let AssertFalseDiagnosticsLogger = { new DiagnosticsLogger("AssertFalseDiagnosticsLogger") with // TODO: reenable these asserts in the compiler service - member _.DiagnosticSink(diagnostic, severity) = (* assert false; *) () + member _.DiagnosticSink(diagnostic) = (* assert false; *) () member _.ErrorCount = (* assert false; *) 0 } @@ -383,16 +391,16 @@ type CapturingDiagnosticsLogger(nm, ?eagerFormat) = let mutable errorCount = 0 let diagnostics = ResizeArray() - override _.DiagnosticSink(diagnostic, severity) = + override _.DiagnosticSink(diagnostic) = let diagnostic = match eagerFormat with | None -> diagnostic | Some f -> f diagnostic - if severity = FSharpDiagnosticSeverity.Error then + if diagnostic.Severity = FSharpDiagnosticSeverity.Error then errorCount <- errorCount + 1 - diagnostics.Add(diagnostic, severity) + diagnostics.Add(diagnostic) override _.ErrorCount = errorCount @@ -457,7 +465,7 @@ module DiagnosticsLoggerExtensions = | ReportedError _ -> PreserveStackTrace exn raise exn - | _ -> x.DiagnosticSink(PhasedDiagnostic.Create(exn, DiagnosticsThreadStatics.BuildPhase), severity) + | _ -> x.DiagnosticSink(PhasedDiagnostic.Create(exn, DiagnosticsThreadStatics.BuildPhase, severity)) member x.ErrorR exn = x.EmitDiagnostic(exn, FSharpDiagnosticSeverity.Error) @@ -472,8 +480,8 @@ module DiagnosticsLoggerExtensions = x.ErrorR exn raise (ReportedError(Some exn)) - member x.SimulateError diagnostic = - x.DiagnosticSink(diagnostic, FSharpDiagnosticSeverity.Error) + member x.SimulateError(diagnostic) = + x.DiagnosticSink(diagnostic) raise (ReportedError(Some diagnostic.Exception)) member x.ErrorRecovery (exn: exn) (m: range) = @@ -580,17 +588,11 @@ let error exn = DiagnosticsThreadStatics.DiagnosticsLogger.Error exn /// Simulates an error. For test purposes only. -let simulateError (diagnostic: PhasedDiagnostic) = - DiagnosticsThreadStatics.DiagnosticsLogger.SimulateError diagnostic - -let diagnosticSink (diagnostic, severity) = - DiagnosticsThreadStatics.DiagnosticsLogger.DiagnosticSink(diagnostic, severity) - -let errorSink diagnostic = - diagnosticSink (diagnostic, FSharpDiagnosticSeverity.Error) +let simulateError diagnostic = + DiagnosticsThreadStatics.DiagnosticsLogger.SimulateError(diagnostic) -let warnSink diagnostic = - diagnosticSink (diagnostic, FSharpDiagnosticSeverity.Warning) +let diagnosticSink diagnostic = + DiagnosticsThreadStatics.DiagnosticsLogger.DiagnosticSink(diagnostic) let errorRecovery exn m = DiagnosticsThreadStatics.DiagnosticsLogger.ErrorRecovery exn m @@ -623,7 +625,7 @@ let suppressErrorReporting f = try let diagnosticsLogger = { new DiagnosticsLogger("suppressErrorReporting") with - member _.DiagnosticSink(_phasedError, _isError) = () + member _.DiagnosticSink(_diagnostic) = () member _.ErrorCount = 0 } diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fsi b/src/Compiler/Facilities/DiagnosticsLogger.fsi index 7a083efae7e..9b8bb20c7b6 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fsi +++ b/src/Compiler/Facilities/DiagnosticsLogger.fsi @@ -178,10 +178,12 @@ module BuildPhaseSubcategory = type PhasedDiagnostic = { Exception: exn - Phase: BuildPhase } + Phase: BuildPhase + Severity: FSharpDiagnosticSeverity + DefaultSeverity: FSharpDiagnosticSeverity } /// Construct a phased error - static member Create: exn: exn * phase: BuildPhase -> PhasedDiagnostic + static member Create: exn: exn * phase: BuildPhase * severity: FSharpDiagnosticSeverity -> PhasedDiagnostic /// Return true if the textual phase given is from the compile part of the build process. /// This set needs to be equal to the set of subcategories that the language service can produce. @@ -208,7 +210,7 @@ type DiagnosticsLogger = member DebugDisplay: unit -> string /// Emit a diagnostic to the logger - abstract DiagnosticSink: diagnostic: PhasedDiagnostic * severity: FSharpDiagnosticSeverity -> unit + abstract DiagnosticSink: diagnostic: PhasedDiagnostic -> unit /// Get the number of error diagnostics reported abstract ErrorCount: int @@ -235,9 +237,9 @@ type CapturingDiagnosticsLogger = member CommitDelayedDiagnostics: diagnosticsLogger: DiagnosticsLogger -> unit - override DiagnosticSink: diagnostic: PhasedDiagnostic * severity: FSharpDiagnosticSeverity -> unit + override DiagnosticSink: diagnostic: PhasedDiagnostic -> unit - member Diagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + member Diagnostics: PhasedDiagnostic list override ErrorCount: int @@ -313,11 +315,7 @@ val informationalWarning: exn: exn -> unit val simulateError: diagnostic: PhasedDiagnostic -> 'T -val diagnosticSink: diagnostic: PhasedDiagnostic * severity: FSharpDiagnosticSeverity -> unit - -val errorSink: diagnostic: PhasedDiagnostic -> unit - -val warnSink: diagnostic: PhasedDiagnostic -> unit +val diagnosticSink: diagnostic: PhasedDiagnostic -> unit val errorRecovery: exn: exn -> m: range -> unit diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index ca96324426a..5dd3b97f4a7 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -897,10 +897,10 @@ type internal DiagnosticsLoggerThatStopsOnFirstError member _.ResetErrorCount() = errorCount <- 0 - override _.DiagnosticSink(diagnostic, severity) = + override _.DiagnosticSink(diagnostic) = let tcConfig = TcConfig.Create(tcConfigB, validate = false) - match diagnostic.AdjustSeverity(tcConfig.diagnosticsOptions, severity) with + match diagnostic.AdjustSeverity(tcConfig.diagnosticsOptions) with | FSharpDiagnosticSeverity.Error -> fsiStdinSyphon.PrintDiagnostic(tcConfig, diagnostic) errorCount <- errorCount + 1 @@ -913,7 +913,7 @@ type internal DiagnosticsLoggerThatStopsOnFirstError | FSharpDiagnosticSeverity.Info as adjustedSeverity -> DoWithDiagnosticColor adjustedSeverity (fun () -> fsiConsoleOutput.Error.WriteLine() - diagnostic.WriteWithContext(fsiConsoleOutput.Error, " ", fsiStdinSyphon.GetLine, tcConfig, severity) + diagnostic.WriteWithContext(fsiConsoleOutput.Error, " ", fsiStdinSyphon.GetLine, tcConfig, diagnostic.Severity) fsiConsoleOutput.Error.WriteLine() fsiConsoleOutput.Error.WriteLine() fsiConsoleOutput.Error.Flush()) diff --git a/src/Compiler/Service/BackgroundCompiler.fs b/src/Compiler/Service/BackgroundCompiler.fs index 8c910806ede..9e0e32bd7e7 100644 --- a/src/Compiler/Service/BackgroundCompiler.fs +++ b/src/Compiler/Service/BackgroundCompiler.fs @@ -1352,7 +1352,7 @@ type internal BackgroundCompiler let flatErrors = options.OtherOptions |> Array.contains "--flaterrors" loadClosure.LoadClosureRootFileDiagnostics - |> List.map (fun (exn, isError) -> FSharpDiagnostic.CreateFromException(exn, isError, false, flatErrors, None)) + |> List.map (fun diagnostic -> FSharpDiagnostic.CreateFromException(diagnostic, false, flatErrors, None)) return options, (diags @ diagnostics.Diagnostics) } diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index 584591c059c..873d688c17f 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -2870,20 +2870,20 @@ module internal ParseAndCheckFile = let diagnosticsCollector = ResizeArray<_>() let mutable errorCount = 0 - let collectOne severity diagnostic = + let collectOne diagnostic = // 1. Extended diagnostic data should be created after typechecking because it requires a valid SymbolEnv // 2. Diagnostic message should be created during the diagnostic sink, because after typechecking // the formatting of types in it may change (for example, 'a to obj) // // So we'll create a diagnostic later, but cache the FormatCore message now diagnostic.Exception.Data["CachedFormatCore"] <- diagnostic.FormatCore(flatErrors, suggestNamesForErrors) - diagnosticsCollector.Add(struct (diagnostic, severity)) + diagnosticsCollector.Add(diagnostic) - if severity = FSharpDiagnosticSeverity.Error then + if diagnostic.Severity = FSharpDiagnosticSeverity.Error then errorCount <- errorCount + 1 // This function gets called whenever an error happens during parsing or checking - let diagnosticSink severity (diagnostic: PhasedDiagnostic) = + let diagnosticSink (diagnostic: PhasedDiagnostic) = // Sanity check here. The phase of an error should be in a phase known to the language service. let diagnostic = if not (diagnostic.IsPhaseInCompile()) then @@ -2906,13 +2906,13 @@ module internal ParseAndCheckFile = #if !NO_TYPEPROVIDERS | { Exception = :? TypeProviderError as tpe - } -> tpe.Iter(fun exn -> collectOne severity { diagnostic with Exception = exn }) + } -> tpe.Iter(fun exn -> collectOne { diagnostic with Exception = exn }) #endif - | _ -> collectOne severity diagnostic + | _ -> collectOne diagnostic let diagnosticsLogger = { new DiagnosticsLogger("DiagnosticsHandler") with - member _.DiagnosticSink(exn, severity) = diagnosticSink severity exn + member _.DiagnosticSink(diagnostic) = diagnosticSink diagnostic member _.ErrorCount = errorCount } @@ -2926,21 +2926,17 @@ module internal ParseAndCheckFile = member _.AnyErrors = errorCount > 0 - member _.CollectedPhasedDiagnostics = - [| - for struct (diagnostic, severity) in diagnosticsCollector -> diagnostic, severity - |] + member _.CollectedPhasedDiagnostics = diagnosticsCollector.ToArray() member _.CollectedDiagnostics(symbolEnv: SymbolEnv option) = [| - for struct (diagnostic, severity) in diagnosticsCollector do + for diagnostic in diagnosticsCollector do yield! DiagnosticHelpers.ReportDiagnostic( options, false, mainInputFileName, diagnostic, - severity, suggestNamesForErrors, flatErrors, symbolEnv @@ -3177,7 +3173,7 @@ module internal ParseAndCheckFile = // If there was a loadClosure, replay the errors and warnings from resolution, excluding parsing loadClosure.LoadClosureRootFileDiagnostics |> List.iter diagnosticSink - let fileOfBackgroundError (diagnostic: PhasedDiagnostic, _) = + let fileOfBackgroundError (diagnostic: PhasedDiagnostic) = match diagnostic.Range with | Some m -> Some m.FileName | None -> None @@ -3211,28 +3207,28 @@ module internal ParseAndCheckFile = for file, errorGroupedByFileName in hashLoadBackgroundDiagnosticsGroupedByFileName do if sameFile file fileOfHashLoad then for rangeOfHashLoad in rangesOfHashLoad do // Handle the case of two #loads of the same file - let diagnostics = - errorGroupedByFileName |> Array.map (fun (_, (pe, f)) -> pe.Exception, f) // Strip the build phase here. It will be replaced, in total, with TypeCheck + let diagnostics = errorGroupedByFileName |> Array.map snd + // Strip the build phase here. It will be replaced, in total, with TypeCheck let errors = [ - for err, severity in diagnostics do - if severity = FSharpDiagnosticSeverity.Error then - err + for err in diagnostics do + if err.Severity = FSharpDiagnosticSeverity.Error then + err.Exception ] let warnings = [ - for err, severity in diagnostics do - if severity = FSharpDiagnosticSeverity.Warning then - err + for err in diagnostics do + if err.Severity = FSharpDiagnosticSeverity.Warning then + err.Exception ] let infos = [ - for err, severity in diagnostics do - if severity = FSharpDiagnosticSeverity.Info then - err + for err in diagnostics do + if err.Severity = FSharpDiagnosticSeverity.Info then + err.Exception ] let message = HashLoadedSourceHasIssues(infos, warnings, errors, rangeOfHashLoad) @@ -3242,8 +3238,8 @@ module internal ParseAndCheckFile = else errorR message // Replay other background errors. - for diagnostic, severity in otherBackgroundDiagnostics do - match severity with + for diagnostic in otherBackgroundDiagnostics do + match diagnostic.Severity with | FSharpDiagnosticSeverity.Info -> informationalWarning diagnostic.Exception | FSharpDiagnosticSeverity.Warning -> warning diagnostic.Exception | FSharpDiagnosticSeverity.Error -> errorR diagnostic.Exception @@ -3273,7 +3269,7 @@ module internal ParseAndCheckFile = tcState: TcState, moduleNamesDict: ModuleNamesDict, loadClosure: LoadClosure option, - backgroundDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity)[], + backgroundDiagnostics: PhasedDiagnostic[], suggestNamesForErrors: bool ) = @@ -3341,10 +3337,10 @@ module internal ParseAndCheckFile = // Play background errors and warnings for this file. do - for err, severity in backgroundDiagnostics do - match err.AdjustSeverity(tcConfig.diagnosticsOptions, severity) with + for diagnostic in backgroundDiagnostics do + match diagnostic.AdjustSeverity(tcConfig.diagnosticsOptions) with | FSharpDiagnosticSeverity.Hidden -> () - | s -> diagnosticSink (err, s) + | s -> diagnosticSink { diagnostic with Severity = s } let (tcEnvAtEnd, _, implFiles, ccuSigsForFiles), tcState = resOpt @@ -3745,7 +3741,7 @@ type FSharpCheckFileResults tcState: TcState, moduleNamesDict: ModuleNamesDict, loadClosure: LoadClosure option, - backgroundDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity)[], + backgroundDiagnostics: PhasedDiagnostic[], isIncompleteTypeCheckEnvironment: bool, projectOptions: FSharpProjectOptions, builder: IncrementalBuilder option, diff --git a/src/Compiler/Service/FSharpCheckerResults.fsi b/src/Compiler/Service/FSharpCheckerResults.fsi index 28deec6804a..7417aacb82a 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fsi +++ b/src/Compiler/Service/FSharpCheckerResults.fsi @@ -499,7 +499,7 @@ type public FSharpCheckFileResults = tcState: TcState * moduleNamesDict: ModuleNamesDict * loadClosure: LoadClosure option * - backgroundDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity)[] * + backgroundDiagnostics: PhasedDiagnostic[] * isIncompleteTypeCheckEnvironment: bool * projectOptions: FSharpProjectOptions * builder: IncrementalBuilder option * @@ -612,7 +612,7 @@ module internal ParseAndCheckFile = member AnyErrors: bool - member CollectedPhasedDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) array + member CollectedPhasedDiagnostics: PhasedDiagnostic array member CollectedDiagnostics: symbolEnv: SymbolEnv option -> FSharpDiagnostic array diff --git a/src/Compiler/Service/FSharpProjectSnapshot.fs b/src/Compiler/Service/FSharpProjectSnapshot.fs index 2183ca75e87..e385cfda204 100644 --- a/src/Compiler/Service/FSharpProjectSnapshot.fs +++ b/src/Compiler/Service/FSharpProjectSnapshot.fs @@ -151,13 +151,8 @@ type internal FSharpFileSnapshotWithSource /// A source file snapshot with parsed syntax tree type internal FSharpParsedFile - ( - FileName: string, - SyntaxTreeHash: byte array, - SourceText: ISourceText, - ParsedInput: ParsedInput, - ParseDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity)[] - ) = + (FileName: string, SyntaxTreeHash: byte array, SourceText: ISourceText, ParsedInput: ParsedInput, ParseDiagnostics: PhasedDiagnostic[]) + = member _.FileName = FileName member _.SourceText = SourceText diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs index 6db19653f9a..ba635d17cb8 100644 --- a/src/Compiler/Service/IncrementalBuild.fs +++ b/src/Compiler/Service/IncrementalBuild.fs @@ -104,7 +104,7 @@ type internal FSharpFile = { [] module IncrementalBuildSyntaxTree = - type ParseResult = ParsedInput * range * string * (PhasedDiagnostic * FSharpDiagnosticSeverity) array + type ParseResult = ParsedInput * range * string * PhasedDiagnostic array /// Information needed to lazily parse a file to get a ParsedInput. Internally uses a weak cache. [] @@ -198,7 +198,7 @@ type TcInfo = latestCcuSigForFile: ModuleOrNamespaceType option /// Accumulated diagnostics, last file first - tcDiagnosticsRev:(PhasedDiagnostic * FSharpDiagnosticSeverity)[] list + tcDiagnosticsRev:PhasedDiagnostic[] list tcDependencyFiles: string list @@ -229,7 +229,7 @@ type TcInfoExtras = member x.TcSymbolUses = x.tcSymbolUses -type private SingleFileDiagnostics = (PhasedDiagnostic * FSharpDiagnosticSeverity) array +type private SingleFileDiagnostics = PhasedDiagnostic array type private TypeCheck = TcInfo * TcResultsSinkImpl * CheckedImplFile option * string * SingleFileDiagnostics /// Bound model of an underlying syntax and typed tree. @@ -1665,8 +1665,8 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc | _ -> Array.ofList delayedLogger.Diagnostics, false diagnostics - |> Array.map (fun (diagnostic, severity) -> - FSharpDiagnostic.CreateFromException(diagnostic, severity, suggestNamesForErrors, flatErrors, None)) + |> Array.map (fun (diagnostic) -> + FSharpDiagnostic.CreateFromException(diagnostic, suggestNamesForErrors, flatErrors, None)) return builderOpt, diagnostics } diff --git a/src/Compiler/Service/IncrementalBuild.fsi b/src/Compiler/Service/IncrementalBuild.fsi index 915f21196a7..cced43ea44b 100644 --- a/src/Compiler/Service/IncrementalBuild.fsi +++ b/src/Compiler/Service/IncrementalBuild.fsi @@ -70,7 +70,7 @@ type internal TcInfo = latestCcuSigForFile: ModuleOrNamespaceType option /// Accumulated errors, last file first - tcDiagnosticsRev: (PhasedDiagnostic * FSharpDiagnosticSeverity)[] list + tcDiagnosticsRev: PhasedDiagnostic[] list tcDependencyFiles: string list @@ -78,7 +78,7 @@ type internal TcInfo = } /// Accumulated diagnostics - member TcDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity)[] + member TcDiagnostics: PhasedDiagnostic[] /// Accumulated results of type checking. Optional data that isn't needed to type-check a file, but needed for more information for in tooling. [] @@ -267,8 +267,7 @@ type internal IncrementalBuilder = /// Await the untyped parse results for a particular slot in the vector of parse results. /// /// This may be a marginally long-running operation (parses are relatively quick, only one file needs to be parsed) - member GetParseResultsForFile: - fileName: string -> ParsedInput * range * string * (PhasedDiagnostic * FSharpDiagnosticSeverity)[] + member GetParseResultsForFile: fileName: string -> ParsedInput * range * string * PhasedDiagnostic[] member NotifyFileChanged: fileName: string * timeStamp: DateTime -> Async diff --git a/src/Compiler/Service/ServiceDeclarationLists.fs b/src/Compiler/Service/ServiceDeclarationLists.fs index 9e55016aea5..98312a69306 100644 --- a/src/Compiler/Service/ServiceDeclarationLists.fs +++ b/src/Compiler/Service/ServiceDeclarationLists.fs @@ -102,7 +102,7 @@ module DeclarationListHelpers = let FormatOverloadsToList (infoReader: InfoReader) m denv (item: ItemWithInst) minfos symbol (width: int option) : ToolTipElement = ToolTipFault |> Option.iter (fun msg -> let exn = Error((0, msg), range0) - let ph = PhasedDiagnostic.Create(exn, BuildPhase.TypeCheck) + let ph = PhasedDiagnostic.Create(exn, BuildPhase.TypeCheck, FSharpDiagnosticSeverity.Error) simulateError ph) let layouts = diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs index fc049da736a..3d08f9663df 100644 --- a/src/Compiler/Service/TransparentCompiler.fs +++ b/src/Compiler/Service/TransparentCompiler.fs @@ -60,7 +60,7 @@ type internal TcInfo = latestCcuSigForFile: ModuleOrNamespaceType option /// Accumulated diagnostics, last file first - tcDiagnosticsRev: (PhasedDiagnostic * FSharpDiagnosticSeverity)[] list + tcDiagnosticsRev: PhasedDiagnostic[] list tcDependencyFiles: string list @@ -85,7 +85,7 @@ type internal TcIntermediate = moduleNamesDict: ModuleNamesDict /// Accumulated diagnostics, last file first - tcDiagnosticsRev: (PhasedDiagnostic * FSharpDiagnosticSeverity)[] list + tcDiagnosticsRev: PhasedDiagnostic[] list tcDependencyFiles: string list @@ -1120,13 +1120,13 @@ type internal TransparentCompiler delayedLogger.CommitDelayedDiagnostics diagnosticsLogger diagnosticsLogger.GetDiagnostics() | _ -> Array.ofList delayedLogger.Diagnostics - |> Array.map (fun (diagnostic, severity) -> + |> Array.map (fun (diagnostic) -> let flatErrors = bootstrapInfoOpt |> Option.map (fun bootstrapInfo -> bootstrapInfo.TcConfig.flatErrors) |> Option.defaultValue false // TODO: do we need to figure this out? - FSharpDiagnostic.CreateFromException(diagnostic, severity, suggestNamesForErrors, flatErrors, None)) + FSharpDiagnostic.CreateFromException(diagnostic, suggestNamesForErrors, flatErrors, None)) return bootstrapInfoOpt, diagnostics } @@ -1407,7 +1407,7 @@ type internal TransparentCompiler let hadParseErrors = file.ParseDiagnostics - |> Array.exists (snd >> (=) FSharpDiagnosticSeverity.Error) + |> Array.exists (fun diagnostic -> diagnostic.Severity = FSharpDiagnosticSeverity.Error) let input, moduleNamesDict = DeduplicateParsedInputModuleName prevTcInfo.moduleNamesDict input @@ -2478,7 +2478,7 @@ type internal TransparentCompiler let flaterrors = otherFlags |> List.contains "--flaterrors" loadClosure.LoadClosureRootFileDiagnostics - |> List.map (fun (exn, isError) -> FSharpDiagnostic.CreateFromException(exn, isError, false, flaterrors, None)) + |> List.map (fun diagnostic -> FSharpDiagnostic.CreateFromException(diagnostic, false, flaterrors, None)) return snapshot, (diags @ diagnostics.Diagnostics) } diff --git a/src/Compiler/Service/TransparentCompiler.fsi b/src/Compiler/Service/TransparentCompiler.fsi index 2eb1786dc74..7e947fe81e9 100644 --- a/src/Compiler/Service/TransparentCompiler.fsi +++ b/src/Compiler/Service/TransparentCompiler.fsi @@ -37,7 +37,7 @@ type internal TcInfo = latestCcuSigForFile: ModuleOrNamespaceType option /// Accumulated diagnostics, last file first - tcDiagnosticsRev: (PhasedDiagnostic * FSharpDiagnosticSeverity)[] list + tcDiagnosticsRev: PhasedDiagnostic[] list tcDependencyFiles: string list @@ -59,7 +59,7 @@ type internal TcIntermediate = moduleNamesDict: ModuleNamesDict /// Accumulated diagnostics, last file first - tcDiagnosticsRev: (PhasedDiagnostic * FSharpDiagnosticSeverity) array list + tcDiagnosticsRev: PhasedDiagnostic array list tcDependencyFiles: string list sink: TcResultsSinkImpl } diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs index 75d6c137087..de3635f516f 100644 --- a/src/Compiler/Service/service.fs +++ b/src/Compiler/Service/service.fs @@ -30,8 +30,8 @@ module CompileHelpers = let diagnosticsLogger = { new DiagnosticsLogger("CompileAPI") with - member _.DiagnosticSink(diag, isError) = - diagnostics.Add(FSharpDiagnostic.CreateFromException(diag, isError, true, flatErrors, None)) // Suggest names for errors + member _.DiagnosticSink(diagnostic) = + diagnostics.Add(FSharpDiagnostic.CreateFromException(diagnostic, true, flatErrors, None)) // Suggest names for errors member _.ErrorCount = diagnostics diff --git a/src/Compiler/Symbols/FSharpDiagnostic.fs b/src/Compiler/Symbols/FSharpDiagnostic.fs index 24ea614cc16..0e322386f02 100644 --- a/src/Compiler/Symbols/FSharpDiagnostic.fs +++ b/src/Compiler/Symbols/FSharpDiagnostic.fs @@ -129,10 +129,10 @@ module ExtendedData = open ExtendedData -type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: string, subcategory: string, errorNum: int, - numberPrefix: string, extendedData: IFSharpDiagnosticExtendedData option) = +type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, defaultSeverity: FSharpDiagnosticSeverity, message: string, subcategory: string, errorNum: int, numberPrefix: string, extendedData: IFSharpDiagnosticExtendedData option) = member _.Range = m member _.Severity = severity + member _.DefaultSeverity = defaultSeverity member _.Message = message member _.Subcategory = subcategory member _.ErrorNumber = errorNum @@ -150,11 +150,11 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str member _.WithStart newStart = let m = mkFileIndexRange m.FileIndex newStart m.End - FSharpDiagnostic(m, severity, message, subcategory, errorNum, numberPrefix, extendedData) + FSharpDiagnostic(m, severity, defaultSeverity, message, subcategory, errorNum, numberPrefix, extendedData) member _.WithEnd newEnd = let m = mkFileIndexRange m.FileIndex m.Start newEnd - FSharpDiagnostic(m, severity, message, subcategory, errorNum, numberPrefix, extendedData) + FSharpDiagnostic(m, severity, defaultSeverity, message, subcategory, errorNum, numberPrefix, extendedData) override _.ToString() = let fileName = m.FileName @@ -169,7 +169,7 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str sprintf "%s (%d,%d)-(%d,%d) %s %s %s" fileName s.Line (s.Column + 1) e.Line (e.Column + 1) subcategory severity message /// Decompose a warning or error into parts: position, severity, message, error number - static member CreateFromException(diagnostic: PhasedDiagnostic, severity, suggestNames: bool, flatErrors: bool, symbolEnv: SymbolEnv option) = + static member CreateFromException(diagnostic: PhasedDiagnostic, suggestNames: bool, flatErrors: bool, symbolEnv: SymbolEnv option) = let extendedData: IFSharpDiagnosticExtendedData option = match symbolEnv with | None -> None @@ -231,7 +231,7 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str let errorNum = diagnostic.Number let m = match diagnostic.Range with Some m -> m.ApplyLineDirectives() | None -> range0 - FSharpDiagnostic(m, severity, msg, diagnostic.Subcategory(), errorNum, "FS", extendedData) + FSharpDiagnostic(m, diagnostic.Severity, diagnostic.DefaultSeverity, msg, diagnostic.Subcategory(), errorNum, "FS", extendedData) static member NewlineifyErrorString(message) = NewlineifyErrorString(message) @@ -240,7 +240,7 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str static member Create(severity, message, number, range, ?numberPrefix, ?subcategory) = let subcategory = defaultArg subcategory BuildPhaseSubcategory.TypeCheck let numberPrefix = defaultArg numberPrefix "FS" - FSharpDiagnostic(range, severity, message, subcategory, number, numberPrefix, None) + FSharpDiagnostic(range, severity, severity, message, subcategory, number, numberPrefix, None) /// Use to reset error and warning handlers [] @@ -251,8 +251,8 @@ type DiagnosticsScope(flatErrors: bool) = UseDiagnosticsLogger { new DiagnosticsLogger("DiagnosticsScope") with - member _.DiagnosticSink(diagnostic, severity) = - let diagnostic = FSharpDiagnostic.CreateFromException(diagnostic, severity, false, flatErrors, None) + member _.DiagnosticSink(diagnostic) = + let diagnostic = FSharpDiagnostic.CreateFromException(diagnostic, false, flatErrors, None) diags <- diagnostic :: diags member _.ErrorCount = diags.Length } @@ -307,18 +307,18 @@ type internal CompilationDiagnosticLogger(debugName: string, options: FSharpDiag let mutable errorCount = 0 let diagnostics = ResizeArray<_>() - override _.DiagnosticSink(diagnostic, severity) = + override _.DiagnosticSink(diagnostic) = let diagnostic = match preprocess with | Some f -> f diagnostic | None -> diagnostic - match diagnostic.AdjustSeverity(options, severity) with + match diagnostic.AdjustSeverity(options) with | FSharpDiagnosticSeverity.Error -> - diagnostics.Add(diagnostic, FSharpDiagnosticSeverity.Error) + diagnostics.Add({ diagnostic with Severity = FSharpDiagnosticSeverity.Error }) errorCount <- errorCount + 1 | FSharpDiagnosticSeverity.Hidden -> () - | sev -> diagnostics.Add(diagnostic, sev) + | sev -> diagnostics.Add({ diagnostic with Severity = sev }) override _.ErrorCount = errorCount @@ -326,20 +326,20 @@ type internal CompilationDiagnosticLogger(debugName: string, options: FSharpDiag module DiagnosticHelpers = - let ReportDiagnostic (options: FSharpDiagnosticOptions, allErrors, mainInputFileName, diagnostic: PhasedDiagnostic, severity, suggestNames, flatErrors, symbolEnv) = - match diagnostic.AdjustSeverity(options, severity) with + let ReportDiagnostic (options: FSharpDiagnosticOptions, allErrors, mainInputFileName, diagnostic: PhasedDiagnostic, suggestNames, flatErrors, symbolEnv) = + match diagnostic.AdjustSeverity(options) with | FSharpDiagnosticSeverity.Hidden -> [] | adjustedSeverity -> - + let diagnostic = { diagnostic with Severity = adjustedSeverity } let fileName = match diagnostic.Range with | Some r -> r.FileName | None -> TcGlobals.DummyFileNameForRangesWithoutASpecificLocation - let fDiagnostic = FSharpDiagnostic.CreateFromException (diagnostic, adjustedSeverity, suggestNames, flatErrors, symbolEnv) + let fDiagnostic = FSharpDiagnostic.CreateFromException (diagnostic, suggestNames, flatErrors, symbolEnv) if allErrors || fileName = mainInputFileName || fileName = TcGlobals.DummyFileNameForRangesWithoutASpecificLocation then [fDiagnostic] else [] let CreateDiagnostics (options, allErrors, mainInputFileName, diagnostics, suggestNames, flatErrors, symbolEnv) = - [| for diagnostic, severity in diagnostics do - yield! ReportDiagnostic (options, allErrors, mainInputFileName, diagnostic, severity, suggestNames, flatErrors, symbolEnv) |] + [| for diagnostic in diagnostics do + yield! ReportDiagnostic (options, allErrors, mainInputFileName, diagnostic, suggestNames, flatErrors, symbolEnv) |] diff --git a/src/Compiler/Symbols/FSharpDiagnostic.fsi b/src/Compiler/Symbols/FSharpDiagnostic.fsi index 12500623916..35b96efe629 100644 --- a/src/Compiler/Symbols/FSharpDiagnostic.fsi +++ b/src/Compiler/Symbols/FSharpDiagnostic.fsi @@ -196,6 +196,9 @@ type FSharpDiagnostic = /// Gets the severity for the diagnostic member Severity: FSharpDiagnosticSeverity + /// Gets the original severity prior to adjustments via compiler flags, #nowarn and other features + member DefaultSeverity: FSharpDiagnosticSeverity + /// Gets the message for the diagnostic member Message: string @@ -226,11 +229,7 @@ type FSharpDiagnostic = FSharpDiagnostic static member internal CreateFromException: - diagnostic: PhasedDiagnostic * - severity: FSharpDiagnosticSeverity * - suggestNames: bool * - flatErrors: bool * - symbolEnv: SymbolEnv option -> + diagnostic: PhasedDiagnostic * suggestNames: bool * flatErrors: bool * symbolEnv: SymbolEnv option -> FSharpDiagnostic /// Newlines are recognized and replaced with (ASCII 29, the 'group separator'), @@ -266,7 +265,7 @@ type internal CompilationDiagnosticLogger = CompilationDiagnosticLogger /// Get the captured diagnostics - member GetDiagnostics: unit -> (PhasedDiagnostic * FSharpDiagnosticSeverity)[] + member GetDiagnostics: unit -> PhasedDiagnostic[] module internal DiagnosticHelpers = @@ -275,7 +274,6 @@ module internal DiagnosticHelpers = allErrors: bool * mainInputFileName: string * diagnostic: PhasedDiagnostic * - severity: FSharpDiagnosticSeverity * suggestNames: bool * flatErrors: bool * symbolEnv: SymbolEnv option -> @@ -285,7 +283,7 @@ module internal DiagnosticHelpers = FSharpDiagnosticOptions * allErrors: bool * mainInputFileName: string * - seq * + seq * suggestNames: bool * flatErrors: bool * symbolEnv: SymbolEnv option -> diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs index 77e8f4b2137..3b50cd9fe25 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs @@ -520,7 +520,7 @@ let ``Preserve thread static diagnostics`` () = Assert.Equal<(int * int) list>([4, 100], diagnosticCounts) - let diagnosticMessages = results |> Seq.map snd |> Seq.map (Array.map (fun (d, _) -> d.Exception.Message) >> Array.toList) |> Set + let diagnosticMessages = results |> Seq.map snd |> Seq.map (Array.map _.Exception.Message >> Array.toList) |> Set Assert.Equal>(Set [["task error"; "job2 error 1"; "job1 error"; "job2 error 2"; ]], diagnosticMessages) @@ -550,7 +550,7 @@ let ``Preserve thread static diagnostics already completed job`` () = let! _ = cache.Get(key, job "1" ) let! _ = cache.Get(key, job "2" ) - let diagnosticMessages = diagnosticsLogger.GetDiagnostics() |> Array.map (fun (d, _) -> d.Exception.Message) |> Array.toList + let diagnosticMessages = diagnosticsLogger.GetDiagnostics() |> Array.map _.Exception.Message |> Array.toList Assert.Equal<_ list>(["job 1 error"; "job 1 error"], diagnosticMessages) @@ -582,7 +582,7 @@ let ``We get diagnostics from the job that failed`` () = do! cache.Get(key, job ) |> Async.Catch |> Async.Ignore - let messages = logger.Diagnostics |> List.map fst |> List.map _.Exception.Message + let messages = logger.Diagnostics |> List.map _.Exception.Message Assert.Equal<_ list>(["job error"], messages) } diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/FSharpDiagnosticTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/FSharpDiagnosticTests.fs new file mode 100644 index 00000000000..90122709185 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/FSharpDiagnosticTests.fs @@ -0,0 +1,55 @@ +module ErrorMessages.FSharpDiagnosticTests + +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Test.Assert +open FSharp.Test.Compiler +open Xunit + +let checkDiagnostics diagnostics (checkResults: FSharpCheckFileResults) = + checkResults.Diagnostics + |> Array.map (fun e -> + {| Number = e.ErrorNumber + Severity = e.Severity + DefaultSeverity = e.DefaultSeverity |}) + |> shouldEqual diagnostics + +[] +let ``FSharpDiagnostic: warning default severity`` () = + FSharp " +module Test +5 +" + |> typecheckResults + |> checkDiagnostics [| + {| Number = 20 + Severity = FSharpDiagnosticSeverity.Warning + DefaultSeverity = FSharpDiagnosticSeverity.Warning |} + |] + +[] +let ``FSharpDiagnostic: warning as error default severity`` () = + FSharp " +module M +5 +" + |> withOptions [ "--warnaserror+" ] + |> typecheckResults + |> checkDiagnostics [| + {| Number = 20 + Severity = FSharpDiagnosticSeverity.Error + DefaultSeverity = FSharpDiagnosticSeverity.Warning |} + |] + +[] +let ``FSharpDiagnostic: error default severity`` () = + FSharp " +module M +x +" + |> typecheckResults + |> checkDiagnostics [| + {| Number = 39 + Severity = FSharpDiagnosticSeverity.Error + DefaultSeverity = FSharpDiagnosticSeverity.Error |} + |] diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 8f5ace7aade..0bc7df3c9fa 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -231,6 +231,7 @@ + diff --git a/tests/FSharp.Compiler.Service.Tests/BuildGraphTests.fs b/tests/FSharp.Compiler.Service.Tests/BuildGraphTests.fs index 61140c40c33..ccae1bdc140 100644 --- a/tests/FSharp.Compiler.Service.Tests/BuildGraphTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/BuildGraphTests.fs @@ -260,7 +260,7 @@ module BuildGraphTests = use _ = new CompilationGlobalsScope(logger, phase) let! _ = Seq.init n (job phase) |> MultipleDiagnosticsLoggers.Parallel - let diags = logger.Diagnostics |> List.map fst + let diags = logger.Diagnostics diags |> List.map _.Phase |> List.distinct |> Assert.shouldBe [ phase ] diags |> List.map _.Exception.Message @@ -296,8 +296,8 @@ module BuildGraphTests = let mutable errorCount = 0 - override _.DiagnosticSink(d, s) = - if s = FSharpDiagnosticSeverity.Error then Interlocked.Increment(&errorCount) |> ignore + override _.DiagnosticSink(e) = + if e.Severity = FSharpDiagnosticSeverity.Error then Interlocked.Increment(&errorCount) |> ignore override this.ErrorCount = errorCount @@ -341,8 +341,8 @@ module BuildGraphTests = type internal DiagnosticsLoggerWithCallback(callback) = inherit CapturingDiagnosticsLogger("test") - override _.DiagnosticSink(e, s) = - base.DiagnosticSink(e, s) + override _.DiagnosticSink(e) = + base.DiagnosticSink(e) callback e.Exception.Message |> ignore [] diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl index bd46be604f5..e98b4ec609e 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl @@ -2900,7 +2900,9 @@ FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedDa FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnostic Create(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity, System.String, Int32, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity DefaultSeverity FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Severity +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_DefaultSeverity() FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Severity() FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Text.Position End FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Text.Position Start diff --git a/tests/FSharp.Compiler.Service.Tests/HashIfExpression.fs b/tests/FSharp.Compiler.Service.Tests/HashIfExpression.fs index 2032b625f3e..0854397d9de 100644 --- a/tests/FSharp.Compiler.Service.Tests/HashIfExpression.fs +++ b/tests/FSharp.Compiler.Service.Tests/HashIfExpression.fs @@ -53,7 +53,7 @@ type public HashIfExpression() = let diagnosticsLogger = { new DiagnosticsLogger("TestDiagnosticsLogger") with - member _.DiagnosticSink(e, sev) = if sev = FSharpDiagnosticSeverity.Error then errors.Add e else warnings.Add e + member _.DiagnosticSink(e) = if e.Severity = FSharpDiagnosticSeverity.Error then errors.Add e else warnings.Add e member _.ErrorCount = errors.Count }