Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update analyzers support #1217

Merged
merged 10 commits into from
Jan 14, 2024
2 changes: 1 addition & 1 deletion paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ nuget Microsoft.Build.Utilities.Core >= 17.4 copy_local:false
nuget Microsoft.Build.Tasks.Core >= 17.4 copy_local: false
nuget Nuget.Frameworks >= 6.3 copy_local: false
nuget Microsoft.CodeAnalysis 4.5.0
nuget FSharp.Analyzers.SDK
nuget FSharp.Analyzers.SDK 0.22.0
nuget ICSharpCode.Decompiler
nuget Mono.Cecil >= 0.11.4
nuget FSharpLint.Core
Expand Down
26 changes: 13 additions & 13 deletions paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ NUGET
FSharp.Core (>= 4.3.4)
FSharp.Analyzers.Build (0.2)
NETStandard.Library (>= 1.6.1)
FSharp.Analyzers.SDK (0.11)
FSharp.Compiler.Service (>= 41.0.1) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net5.0)) (&& (== netstandard2.1) (>= net5.0))
FSharp.Core (>= 6.0.1) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net5.0)) (&& (== netstandard2.1) (>= net5.0))
McMaster.NETCore.Plugins (>= 1.4) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net5.0)) (&& (== netstandard2.1) (>= net5.0))
FSharp.Analyzers.SDK (0.22)
FSharp.Compiler.Service (43.8.100) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0))
FSharp.Core (8.0.100) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0))
McMaster.NETCore.Plugins (>= 1.4) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0))
Microsoft.Extensions.Logging.Abstractions (>= 8.0) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0))
FSharp.Compiler.Service (43.8.100)
FSharp.Core (8.0.100)
System.Buffers (>= 4.5.1)
Expand Down Expand Up @@ -157,7 +158,7 @@ NUGET
Newtonsoft.Json (>= 13.0.1) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0))
Ionide.ProjInfo.Sln (0.62)
LinkDotNet.StringBuilder (1.18)
McMaster.NETCore.Plugins (1.4) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net5.0)) (&& (== netstandard2.1) (>= net5.0))
McMaster.NETCore.Plugins (1.4) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0))
Microsoft.DotNet.PlatformAbstractions (>= 3.1.6) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp2.1)) (&& (== netstandard2.1) (>= netcoreapp2.1))
Microsoft.Extensions.DependencyModel (>= 5.0) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp2.1)) (&& (== netstandard2.1) (>= netcoreapp2.1))
MessagePack (2.5.108)
Expand All @@ -170,7 +171,7 @@ NUGET
System.Runtime.CompilerServices.Unsafe (>= 6.0)
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net7.0) (< net6.0)) (&& (== net8.0) (< net6.0)) (== netstandard2.0) (== netstandard2.1)
MessagePack.Annotations (2.5.108)
Microsoft.Bcl.AsyncInterfaces (7.0)
Microsoft.Bcl.AsyncInterfaces (8.0)
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net462)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net462)) (&& (== net7.0) (< netstandard2.1)) (&& (== net8.0) (>= net462)) (&& (== net8.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net462))
Microsoft.Bcl.HashCode (1.1) - restriction: || (&& (== net6.0) (< netcoreapp2.1) (< netstandard2.1)) (&& (== net7.0) (< netcoreapp2.1) (< netstandard2.1)) (&& (== net8.0) (< netcoreapp2.1) (< netstandard2.1)) (== netstandard2.0)
Microsoft.Build (17.2) - copy_local: false
Expand Down Expand Up @@ -274,10 +275,10 @@ NUGET
Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0)
System.Runtime.CompilerServices.Unsafe (>= 6.0)
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netstandard2.1)) (&& (== net8.0) (>= net461)) (&& (== net8.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461))
Microsoft.Extensions.DependencyInjection.Abstractions (6.0)
Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netstandard2.1)) (&& (== net8.0) (>= net461)) (&& (== net8.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461))
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netstandard2.1)) (&& (== net8.0) (>= net461)) (&& (== net8.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461))
Microsoft.Extensions.DependencyModel (6.0) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net5.0)) (&& (== netstandard2.1) (>= net5.0))
Microsoft.Extensions.DependencyInjection.Abstractions (8.0)
Microsoft.Bcl.AsyncInterfaces (>= 8.0) - restriction: || (&& (== net6.0) (>= net462)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net462)) (&& (== net7.0) (< netstandard2.1)) (&& (== net8.0) (>= net462)) (&& (== net8.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net462))
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net462)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net462)) (&& (== net7.0) (< netstandard2.1)) (&& (== net8.0) (>= net462)) (&& (== net8.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net462))
Microsoft.Extensions.DependencyModel (6.0) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0))
System.Buffers (>= 4.5.1)
System.Memory (>= 4.5.4)
System.Runtime.CompilerServices.Unsafe (>= 6.0)
Expand All @@ -290,9 +291,8 @@ NUGET
Microsoft.Extensions.Logging.Abstractions (>= 6.0)
Microsoft.Extensions.Options (>= 6.0)
System.Diagnostics.DiagnosticSource (>= 6.0)
Microsoft.Extensions.Logging.Abstractions (6.0.2)
System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< net6.0)) (&& (== net8.0) (>= net461)) (&& (== net8.0) (< net6.0)) (== netstandard2.0) (== netstandard2.1)
System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< net6.0)) (&& (== net8.0) (>= net461)) (&& (== net8.0) (< net6.0)) (== netstandard2.0) (== netstandard2.1)
Microsoft.Extensions.Logging.Abstractions (8.0)
Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0)
Microsoft.Extensions.Logging.Configuration (6.0)
Microsoft.Extensions.Configuration (>= 6.0)
Microsoft.Extensions.Configuration.Abstractions (>= 6.0)
Expand Down
49 changes: 29 additions & 20 deletions src/FsAutoComplete.Core/Commands.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1137,14 +1137,23 @@ module Commands =



let analyzerHandler (file: string<LocalPath>, content, pt, tast, symbols, getAllEntities) =
let ctx: SDK.Context =
let analyzerHandler
(
client: SDK.Client<SDK.EditorAnalyzerAttribute, SDK.EditorContext>,
file: string<LocalPath>,
content: ISourceText,
pt,
tast,
_symbols,
_getAllEntities
) =
let ctx: SDK.EditorContext =
{ FileName = UMX.untag file
Content = content
ParseTree = pt
TypedTree = tast
Symbols = symbols
GetAllEntities = getAllEntities }
SourceText = content
ParseFileResults = pt
CheckFileResults = None
TypedTree = Some tast
CheckProjectResults = None }

let extractResultsFromAnalyzer (r: SDK.AnalysisResult) =
match r.Output with
Expand All @@ -1168,20 +1177,20 @@ module Commands =

[]

try
SDK.Client.runAnalyzersSafely ctx
|> List.collect extractResultsFromAnalyzer
|> List.toArray
with ex ->
Loggers.analyzers.error (
Log.setMessage "Error while processing analyzers for {file}: {message}"
>> Log.addContextDestructured "message" ex.Message
>> Log.addExn ex
>> Log.addContextDestructured "file" file
)

[||]
async {
try
let! r = client.RunAnalyzersSafely ctx
return r |> List.collect extractResultsFromAnalyzer |> List.toArray
with ex ->
Loggers.analyzers.error (
Log.setMessage "Error while processing analyzers for {file}: {message}"
>> Log.addContextDestructured "message" ex.Message
>> Log.addExn ex
>> Log.addContextDestructured "file" file
)

return [||]
}

type Commands() =

Expand Down
10 changes: 10 additions & 0 deletions src/FsAutoComplete/LspHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,8 @@
EnableReferenceCodeLens: bool option
EnableAnalyzers: bool option
AnalyzersPath: string[] option
ExcludeAnalyzers: string[] option
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
IncludeAnalyzers: string[] option
Fixed Show fixed Hide fixed
DisableInMemoryProjectReferences: bool option
LineLens: LineLensConfig option
UseSdkScripts: bool option
Expand Down Expand Up @@ -800,6 +802,8 @@
EnableReferenceCodeLens: bool
EnableAnalyzers: bool
AnalyzersPath: string[]
ExcludeAnalyzers: string[]
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
IncludeAnalyzers: string[]
Fixed Show fixed Hide fixed
DisableInMemoryProjectReferences: bool
LineLens: LineLensConfig
UseSdkScripts: bool
Expand Down Expand Up @@ -846,6 +850,8 @@
EnableReferenceCodeLens = false
EnableAnalyzers = false
AnalyzersPath = [||]
ExcludeAnalyzers = [||]
IncludeAnalyzers = [||]
DisableInMemoryProjectReferences = false
LineLens = { Enabled = "never"; Prefix = "" }
UseSdkScripts = true
Expand Down Expand Up @@ -894,6 +900,8 @@
EnableReferenceCodeLens = defaultArg dto.EnableReferenceCodeLens false
EnableAnalyzers = defaultArg dto.EnableAnalyzers false
AnalyzersPath = defaultArg dto.AnalyzersPath [||]
ExcludeAnalyzers = defaultArg dto.ExcludeAnalyzers [||]
IncludeAnalyzers = defaultArg dto.IncludeAnalyzers [||]
DisableInMemoryProjectReferences = defaultArg dto.DisableInMemoryProjectReferences false
LineLens =
{ Enabled = defaultArg (dto.LineLens |> Option.map (fun n -> n.Enabled)) "never"
Expand Down Expand Up @@ -999,6 +1007,8 @@
EnableReferenceCodeLens = defaultArg dto.EnableReferenceCodeLens x.EnableReferenceCodeLens
EnableAnalyzers = defaultArg dto.EnableAnalyzers x.EnableAnalyzers
AnalyzersPath = defaultArg dto.AnalyzersPath x.AnalyzersPath
ExcludeAnalyzers = defaultArg dto.ExcludeAnalyzers x.ExcludeAnalyzers
IncludeAnalyzers = defaultArg dto.IncludeAnalyzers x.IncludeAnalyzers
DisableInMemoryProjectReferences =
defaultArg dto.DisableInMemoryProjectReferences x.DisableInMemoryProjectReferences
LineLens =
Expand Down
4 changes: 4 additions & 0 deletions src/FsAutoComplete/LspHelpers.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@
EnableReferenceCodeLens: bool option
EnableAnalyzers: bool option
AnalyzersPath: string[] option
ExcludeAnalyzers: string[] option
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
IncludeAnalyzers: string[] option
Fixed Show fixed Hide fixed
DisableInMemoryProjectReferences: bool option
LineLens: LineLensConfig option
UseSdkScripts: bool option
Expand Down Expand Up @@ -389,6 +391,8 @@
EnableReferenceCodeLens: bool
EnableAnalyzers: bool
AnalyzersPath: string[]
ExcludeAnalyzers: string[]
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
IncludeAnalyzers: string[]
Fixed Show fixed Hide fixed
DisableInMemoryProjectReferences: bool
LineLens: LineLensConfig
UseSdkScripts: bool
Expand Down
28 changes: 24 additions & 4 deletions src/FsAutoComplete/LspServers/AdaptiveServerState.fs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@
[| yield! fsiCompilerToolLocations |> Array.map toCompilerToolArgument
yield! fsiExtraParameters |]

let analyzersClient =
FSharp.Analyzers.SDK.Client<FSharp.Analyzers.SDK.EditorAnalyzerAttribute, FSharp.Analyzers.SDK.EditorContext>(
Microsoft.Extensions.Logging.Abstractions.NullLogger.Instance
)

/// <summary>Loads F# Analyzers from the configured directories</summary>
/// <param name="config">The FSharpConfig</param>
/// <param name="rootPath">The RootPath</param>
Expand All @@ -135,6 +140,19 @@
if config.EnableAnalyzers then
Loggers.analyzers.info (Log.setMessageI $"Using analyzer roots of {config.AnalyzersPath:roots}")

let excludeInclude =
match config.ExcludeAnalyzers, config.IncludeAnalyzers with
| [||], [||] -> None
| e, [||] -> Some(FSharp.Analyzers.SDK.ExcludeInclude.Exclude(Set.ofArray e))

Check failure on line 146 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on macos-latest for repo global.json

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

Check failure on line 146 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on macos-latest for 6.0

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

Check failure on line 146 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on windows-latest for repo global.json

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

Check failure on line 146 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on windows-latest for 6.0

The value, constructor, namespace or type 'ExcludeInclude' is not defined.
| [||], i -> Some(FSharp.Analyzers.SDK.ExcludeInclude.Include(Set.ofArray i))

Check failure on line 147 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on macos-latest for repo global.json

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

Check failure on line 147 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on macos-latest for 6.0

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

Check failure on line 147 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on windows-latest for repo global.json

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

Check failure on line 147 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on windows-latest for 6.0

The value, constructor, namespace or type 'ExcludeInclude' is not defined.
| i, _e ->
Loggers.analyzers.warn (
Log.setMessage
"--exclude-analyzers and --include-analyzers are mutually exclusive, ignoring --exclude-analyzers"
)

Some(FSharp.Analyzers.SDK.ExcludeInclude.Include(Set.ofArray i))

Check failure on line 154 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on macos-latest for repo global.json

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

Check failure on line 154 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on macos-latest for 6.0

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

Check failure on line 154 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on windows-latest for repo global.json

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

Check failure on line 154 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on windows-latest for 6.0

The value, constructor, namespace or type 'ExcludeInclude' is not defined.

config.AnalyzersPath
|> Array.iter (fun analyzerPath ->
match rootPath with
Expand All @@ -152,7 +170,7 @@

Loggers.analyzers.info (Log.setMessageI $"Loading analyzers from {dir:dir}")

let (dllCount, analyzerCount) = dir |> FSharp.Analyzers.SDK.Client.loadAnalyzers
let (dllCount, analyzerCount) = analyzersClient.LoadAnalyzers(dir, excludeInclude)

Check failure on line 173 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on macos-latest for repo global.json

Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.

Check failure on line 173 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on macos-latest for 6.0

Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.

Check failure on line 173 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on windows-latest for repo global.json

Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.

Check failure on line 173 in src/FsAutoComplete/LspServers/AdaptiveServerState.fs

View workflow job for this annotation

GitHub Actions / Build on windows-latest for 6.0

Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.

Loggers.analyzers.info (
Log.setMessageI
Expand Down Expand Up @@ -369,11 +387,12 @@
// Since analyzers are not async, we need to switch to a new thread to not block threadpool
do! Async.SwitchToNewThread()

let res =
let! res =
Commands.analyzerHandler (
analyzersClient,
file,
volatileFile.Source.ToString().Split("\n"),
parseAndCheck.GetParseResults.ParseTree,
volatileFile.Source,
parseAndCheck.GetParseResults,
tast,
parseAndCheck.GetCheckResults.PartialAssemblySignature.Entities |> Seq.toList,
parseAndCheck.GetAllEntities
Expand Down Expand Up @@ -552,6 +571,7 @@

let severity =
match m.Severity with
| FSharp.Analyzers.SDK.Hint -> DiagnosticSeverity.Hint
| FSharp.Analyzers.SDK.Info -> DiagnosticSeverity.Information
| FSharp.Analyzers.SDK.Warning -> DiagnosticSeverity.Warning
| FSharp.Analyzers.SDK.Error -> DiagnosticSeverity.Error
Expand Down
2 changes: 2 additions & 0 deletions test/FsAutoComplete.Tests.Lsp/Helpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ let defaultConfigDto: FSharpConfigDto =
EnableReferenceCodeLens = None
EnableAnalyzers = None
AnalyzersPath = None
ExcludeAnalyzers = None
IncludeAnalyzers = None
DisableInMemoryProjectReferences = None
AutomaticWorkspaceInit = Some true
InterfaceStubGeneration = None
Expand Down
59 changes: 32 additions & 27 deletions test/OptionAnalyzer/Analyzer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -117,31 +117,36 @@ let info message items =

let inline (==>) x y = x, box y

[<Analyzer "OptionAnalyzer">]
let optionValueAnalyzer: Analyzer =
[<EditorAnalyzer "OptionAnalyzer">]
let optionValueAnalyzer: Analyzer<EditorContext> =
fun ctx ->
info "analyzing {file} for uses of Option.Value" [ "file" ==> ctx.FileName ]
let state = ResizeArray<Range>()

let handler (range: Range) (m: FSharpMemberOrFunctionOrValue) =
let rangeString =
sprintf "(%d,%d)-(%d,%d)" range.Start.Line range.Start.Column range.End.Line range.End.Column

let name = String.Join(".", m.DeclaringEntity.Value.FullName, m.DisplayName)
info "checking value at {range} with name {name}" [ "range" ==> rangeString; "name" ==> name ]

if name = "Microsoft.FSharp.Core.FSharpOption`1.Value" then
info "matched at range {range}" [ "range" ==> rangeString ]
state.Add range

ctx.TypedTree.Declarations |> List.iter (visitDeclaration handler)

state
|> Seq.map (fun r ->
{ Type = "Option.Value analyzer"
Message = "Option.Value shouldn't be used"
Code = "OV001"
Severity = Warning
Range = r
Fixes = [] })
|> Seq.toList
async {
info "analyzing {file} for uses of Option.Value" [ "file" ==> ctx.FileName ]
let state = ResizeArray<Range>()

let handler (range: Range) (m: FSharpMemberOrFunctionOrValue) =
let rangeString =
sprintf "(%d,%d)-(%d,%d)" range.Start.Line range.Start.Column range.End.Line range.End.Column

let name = String.Join(".", m.DeclaringEntity.Value.FullName, m.DisplayName)
info "checking value at {range} with name {name}" [ "range" ==> rangeString; "name" ==> name ]

if name = "Microsoft.FSharp.Core.FSharpOption`1.Value" then
info "matched at range {range}" [ "range" ==> rangeString ]
state.Add range

match ctx.TypedTree with
| Some tt -> tt.Declarations |> List.iter (visitDeclaration handler)
| None -> ()

return
state
|> Seq.map (fun r ->
{ Type = "Option.Value analyzer"
Message = "Option.Value shouldn't be used"
Code = "OV001"
Severity = Warning
Range = r
Fixes = [] })
|> Seq.toList
}
Loading