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

Add a general analyzer for postfix generics #39

Merged
merged 8 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
## Unreleased

### Changed
* Reworks `ReplaceOptionGetWithGracefulHandlingAnalyzer` to handle ValueOption's and `.Value` member access.
* Reworks `ReplaceOptionGetWithGracefulHandlingAnalyzer` to handle ValueOption's and `.Value` member access. [#33](https://github.com/ionide/ionide-analyzers/pull/33)
* Reworks `SquareBracketArrayAnalyzer` to handle all generic types that should be postfixed. [#39](https://github.com/ionide/ionide-analyzers/pull/39)

## 0.4.0 - 2023-11-15

Expand Down
16 changes: 13 additions & 3 deletions docs/style/002.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
---
title: SquareBracketArrayAnalyzer
title: PostfixGenericsAnalyzer
category: style
categoryindex: 3
index: 1
---

# SquareBracketArrayAnalyzer
# PostfixGenericsAnalyzer

## Problem

Using the older array type syntax (`string[]`) is discouraged by the [style guide](https://learn.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#for-types-prefer-prefix-syntax-for-generics-foot-with-some-specific-exceptions).
Generally, the .NET style should be used for generics. However, it is suggested to use the postfix syntax for arrays, lists, sequences, options, value options, and reference cells in the F# [style guide](https://learn.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#for-types-prefer-prefix-syntax-for-generics-foot-with-some-specific-exceptions).

```fsharp
// Triggers analyzer
let a: string[] = Array.empty
let b: list<string> = List.empty
let c: seq<string> = Seq.empty
let d: option<string> = None
let e: voption<string> = ValueNone
let f: ref<string> = ref ""
```

## Fix
Expand All @@ -22,4 +27,9 @@ The `postfix` syntax is preferred:

```fsharp
let a: string array = Array.empty
let b: string list = List.empty
let c: string seq = Seq.empty
let d: string option = None
let e: string voption = ValueNone
let f: string ref = ref ""
```
2 changes: 1 addition & 1 deletion src/Ionide.Analyzers/Ionide.Analyzers.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<Compile Include="Suggestion\UnnamedDiscriminatedUnionFieldAnalyzer.fs"/>
<Compile Include="Suggestion\EmptyStringAnalyzer.fs"/>
<Compile Include="Suggestion\HandleOptionGracefullyAnalyzer.fs"/>
<Compile Include="Style\SquareBracketArrayAnalyzer.fs"/>
<Compile Include="Style\PostfixGenericsAnalyzer.fs"/>
</ItemGroup>

<ItemGroup Condition="'$(UseLocalAnalyzersSDK)' == 'true'">
Expand Down
52 changes: 52 additions & 0 deletions src/Ionide.Analyzers/Style/PostfixGenericsAnalyzer.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
module Ionide.Analyzers.Style.PostfixGenericsAnalyzer

open FSharp.Compiler.Text
open FSharp.Compiler.Syntax
open FSharp.Analyzers.SDK
open FSharp.Analyzers.SDK.ASTCollecting

[<CliAnalyzer("PostfixGenericsAnalyzer",
"Detect if generic type should be in the postfix position.",
"https://ionide.io/ionide-analyzers/style/002.html")>]
let postfixGenericsAnalyzer: Analyzer<CliContext> =
fun (context: CliContext) ->
async {
let ts = ResizeArray<string * range>()

let collector =
{ new SyntaxCollectorBase() with
override x.WalkType(t: SynType) =
match t with
| SynType.Array _ -> ts.Add("Prefer postfix syntax for arrays.", t.Range)
| SynType.App(typeName = SynType.LongIdent synLongIdent; isPostfix = false) ->
match synLongIdent.LongIdent with
| [ ident ] ->
match ident.idText with
| "array" -> ts.Add("Prefer postfix syntax for arrays.", t.Range)
| "seq" -> ts.Add("Prefer postfix syntax for sequences.", t.Range)
| "list" -> ts.Add("Prefer postfix syntax for lists.", t.Range)
| "option" -> ts.Add("Prefer postfix syntax for options.", t.Range)
| "voption" -> ts.Add("Prefer postfix syntax for value options.", t.Range)
| "Ref"
| "ref" -> ts.Add("Prefer postfix syntax for reference cells.", t.Range)
| _ -> ()
| _ -> ()
| _ -> ()
}

walkAst collector context.ParseFileResults.ParseTree

return
ts
|> Seq.map (fun (message, range) ->
{
Type = "PostfixGenericsAnalyzer"
Message = message
Code = "IONIDE-002"
Severity = Info
Range = range
Fixes = []
}
)
|> Seq.toList
}
39 changes: 0 additions & 39 deletions src/Ionide.Analyzers/Style/SquareBracketArrayAnalyzer.fs

This file was deleted.

2 changes: 1 addition & 1 deletion tests/Ionide.Analyzers.Tests/Ionide.Analyzers.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<Compile Include="Suggestion\UnnamedDiscriminatedUnionFieldAnalyzerTests.fs" />
<Compile Include="Suggestion\EmptyStringAnalyzerTests.fs" />
<Compile Include="Suggestion\HandleOptionGracefullyAnalyzerTests.fs" />
<Compile Include="Style\SquareBracketArrayAnalyzerTests.fs" />
<Compile Include="Style\PostfixGenericsAnalyzerTests.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

Expand Down
Loading