From a761703d965cb7c1976c04ad0a2d936418e11d06 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 4 Jun 2026 11:36:34 +0200 Subject: [PATCH 1/5] Unused analyzers: disable in VS when file has errors --- src/Compiler/Service/FSharpCheckerResults.fs | 3 +++ src/Compiler/Service/FSharpCheckerResults.fsi | 2 ++ .../Diagnostics/UnusedDeclarationsAnalyzer.fs | 15 +++++++++------ .../Diagnostics/UnusedOpensDiagnosticAnalyzer.fs | 9 ++++++--- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index 6e9c1ced079..9b090020113 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -3404,6 +3404,9 @@ type FSharpCheckFileResults member _.Diagnostics = errors + member _.HasErrors = + errors |> Array.exists (fun d -> d.Severity = FSharpDiagnosticSeverity.Error) + member _.HasFullTypeCheckInfo = details.IsSome member _.TryGetCurrentTcImports() = diff --git a/src/Compiler/Service/FSharpCheckerResults.fsi b/src/Compiler/Service/FSharpCheckerResults.fsi index 22779fc7d6e..9b5a95c28a9 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fsi +++ b/src/Compiler/Service/FSharpCheckerResults.fsi @@ -253,6 +253,8 @@ type public FSharpCheckFileResults = /// The errors returned by parsing a source file. member Diagnostics: FSharpDiagnostic[] + member HasErrors: bool + /// Get a view of the contents of the assembly up to and including the file just checked member PartialAssemblySignature: FSharpAssemblySignature diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs index f8de2140da1..577354d6dda 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs @@ -33,11 +33,14 @@ type internal UnusedDeclarationsAnalyzer [] () = let! unusedRanges = UnusedDeclarations.getUnusedDeclarations (checkResults, (isScriptFile document.FilePath)) - let! sourceText = document.GetTextAsync() - - return - unusedRanges - |> Seq.map (fun m -> Diagnostic.Create(descriptor, RoslynHelpers.RangeToLocation(m, sourceText, document.FilePath))) - |> Seq.toImmutableArray + if checkResults.HasErrors then + return ImmutableArray.Empty + else + let! sourceText = document.GetTextAsync() + + return + unusedRanges + |> Seq.map (fun m -> Diagnostic.Create(descriptor, RoslynHelpers.RangeToLocation(m, sourceText, document.FilePath))) + |> Seq.toImmutableArray } |> CancellableTask.start cancellationToken diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs index eca26429312..79e853c32af 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs @@ -29,10 +29,13 @@ type internal UnusedOpensDiagnosticAnalyzer [] () = let! _, checkResults = document.GetFSharpParseAndCheckResultsAsync(nameof UnusedOpensDiagnosticAnalyzer) - let! unusedOpens = - UnusedOpens.getUnusedOpens (checkResults, (fun lineNumber -> sourceText.Lines[Line.toZ lineNumber].ToString())) + if checkResults.HasErrors then + return ValueNone + else + let! unusedOpens = + UnusedOpens.getUnusedOpens (checkResults, (fun lineNumber -> sourceText.Lines[Line.toZ lineNumber].ToString())) - return (ValueSome unusedOpens) + return (ValueSome unusedOpens) } interface IFSharpUnusedOpensDiagnosticAnalyzer with From f2e2fa33bb0da46004f588cd3dc8a78bbf6e4349 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 4 Jun 2026 11:50:23 +0200 Subject: [PATCH 2/5] Fantomas --- .../FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs index 577354d6dda..899fb151a7a 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs @@ -40,7 +40,8 @@ type internal UnusedDeclarationsAnalyzer [] () = return unusedRanges - |> Seq.map (fun m -> Diagnostic.Create(descriptor, RoslynHelpers.RangeToLocation(m, sourceText, document.FilePath))) + |> Seq.map (fun m -> + Diagnostic.Create(descriptor, RoslynHelpers.RangeToLocation(m, sourceText, document.FilePath))) |> Seq.toImmutableArray } |> CancellableTask.start cancellationToken From b94b81d141510f3b543b0dc775dbe856ba7a4d4d Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 4 Jun 2026 14:43:59 +0200 Subject: [PATCH 3/5] Surface area --- .../FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl | 2 ++ 1 file changed, 2 insertions(+) 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 9b33caf5d71..df378a6c47a 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 @@ -2085,8 +2085,10 @@ FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Int32 GetHashCode(System.Col FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Int32 Tag FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Int32 get_Tag() FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: System.String ToString() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Boolean HasErrors FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Boolean HasFullTypeCheckInfo FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Boolean IsRelativeNameResolvableFromSymbol(FSharp.Compiler.Text.Position, Microsoft.FSharp.Collections.FSharpList`1[System.String], FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Boolean get_HasErrors() FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Boolean get_HasFullTypeCheckInfo() FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.CodeAnalysis.FSharpProjectContext ProjectContext FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.CodeAnalysis.FSharpProjectContext get_ProjectContext() From bd10574e8649f9d6cca651baf27c13ad9fb7fa7d Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 4 Jun 2026 14:46:06 +0200 Subject: [PATCH 4/5] Release notes --- docs/release-notes/.VisualStudio/18.vNext.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.VisualStudio/18.vNext.md b/docs/release-notes/.VisualStudio/18.vNext.md index a7a62a728f8..ccdcdb76426 100644 --- a/docs/release-notes/.VisualStudio/18.vNext.md +++ b/docs/release-notes/.VisualStudio/18.vNext.md @@ -9,3 +9,4 @@ ### Changed * Rename "inline hints" to "inlay hints" in VS options for consistency with industry terminology. ([PR #19318](https://github.com/dotnet/fsharp/pull/19318)) +* Unused analyzers: disable in VS when file has errors ([PR #19892](https://github.com/dotnet/fsharp/pull/19892)) From 74e06143a5d0f8f49b6c488558f23b247cefe7d0 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 4 Jun 2026 14:49:14 +0200 Subject: [PATCH 5/5] Release notes --- docs/release-notes/.FSharp.Compiler.Service/11.0.100.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index 793bf71982f..90535239f30 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -75,6 +75,7 @@ * Added warning FS3884 when a function or delegate value is used as an interpolated string argument. ([PR #19289](https://github.com/dotnet/fsharp/pull/19289)) * Symbols: add ObsoleteDiagnosticInfo ([PR #19359](https://github.com/dotnet/fsharp/pull/19359)) +* FCS: add FSharpCheckFileResults.HasErrors ([PR #19892](https://github.com/dotnet/fsharp/pull/19892)) * Add `#version;;` directive to F# Interactive to display version and environment information. ([Issue #13307](https://github.com/dotnet/fsharp/issues/13307), [PR #19332](https://github.com/dotnet/fsharp/pull/19332)) ### Changed