Skip to content

Commit

Permalink
Merge pull request #80 from nojaf/use-fantomas
Browse files Browse the repository at this point in the history
Use fantomas for formatting
  • Loading branch information
TheAngryByrd committed Sep 8, 2023
2 parents ba8ce4f + 0a1377c commit 16321ec
Show file tree
Hide file tree
Showing 9 changed files with 423 additions and 319 deletions.
9 changes: 8 additions & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {}
"tools": {
"fantomas": {
"version": "6.2.0",
"commands": [
"fantomas"
]
}
}
}
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root = true

[*.{fs,fsi,fsx}]
end_of_line = lf
fsharp_keep_max_number_of_blank_lines = 1
fsharp_multi_line_lambda_closing_newline = true
fsharp_alternative_long_member_definitions = true
fsharp_align_function_signature_to_indentation = true
fsharp_experimental_keep_indent_in_branch = true
fsharp_bar_before_discriminated_union_declaration = true
fsharp_multiline_bracket_style = aligned
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
# Automatically normalize line endings
* text=auto

# Always use lf for F# files
*.fs text eol=lf
*.fsx text eol=lf
*.fsi text eol=lf
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Restore tools
run: dotnet tool restore

- name: Check format
run: dotnet fantomas . --check

- name: Restore dependencies
run: dotnet restore --locked-mode

Expand Down
6 changes: 4 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,13 @@ in order to craft an excellent pull request:
[interactive rebase](https://help.github.com/articles/about-git-rebase/)
feature to tidy up your commits before making them public.

5. Make sure all the tests are still passing.
5. Ensure the code is formatted and the sample still works.

```bash
dotnet tool restore
dotnet fake build
dotnet fantomas .
dotnet build -c Release
dotnet run --project src/FSharp.Analyzers.Cli/FSharp.Analyzers.Cli.fsproj -- --project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./samples/OptionAnalyzer/bin/Release --verbose
```

6. Push your topic branch up to your fork:
Expand Down
159 changes: 78 additions & 81 deletions samples/OptionAnalyzer/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,134 +6,131 @@ open FSharp.Compiler.Symbols
open FSharp.Compiler.Symbols.FSharpExprPatterns
open FSharp.Compiler.Text

let rec visitExpr memberCallHandler (e:FSharpExpr) =
let rec visitExpr memberCallHandler (e: FSharpExpr) =
match e with
| AddressOf(lvalueExpr) ->
visitExpr memberCallHandler lvalueExpr
| AddressOf(lvalueExpr) -> visitExpr memberCallHandler lvalueExpr
| AddressSet(lvalueExpr, rvalueExpr) ->
visitExpr memberCallHandler lvalueExpr; visitExpr memberCallHandler rvalueExpr
visitExpr memberCallHandler lvalueExpr
visitExpr memberCallHandler rvalueExpr
| Application(funcExpr, typeArgs, argExprs) ->
visitExpr memberCallHandler funcExpr; visitExprs memberCallHandler argExprs
visitExpr memberCallHandler funcExpr
visitExprs memberCallHandler argExprs
| Call(objExprOpt, memberOrFunc, typeArgs1, typeArgs2, argExprs) ->
memberCallHandler e.Range memberOrFunc
visitObjArg memberCallHandler objExprOpt; visitExprs memberCallHandler argExprs
| Coerce(targetType, inpExpr) ->
visitExpr memberCallHandler inpExpr
| FastIntegerForLoop(startExpr, limitExpr, consumeExpr, isUp, debugPointAtFor, debugPointAtInOrTo) ->
visitExpr memberCallHandler startExpr; visitExpr memberCallHandler limitExpr; visitExpr memberCallHandler consumeExpr
| ILAsm(asmCode, typeArgs, argExprs) ->
visitExprs memberCallHandler argExprs
| ILFieldGet (objExprOpt, fieldType, fieldName) ->
visitObjArg memberCallHandler objExprOpt
| ILFieldSet (objExprOpt, fieldType, fieldName, valueExpr) ->
visitObjArg memberCallHandler objExprOpt
| IfThenElse (guardExpr, thenExpr, elseExpr) ->
visitExpr memberCallHandler guardExpr; visitExpr memberCallHandler thenExpr; visitExpr memberCallHandler elseExpr
| Lambda(lambdaVar, bodyExpr) ->
visitExpr memberCallHandler bodyExpr
visitExprs memberCallHandler argExprs
| Coerce(targetType, inpExpr) -> visitExpr memberCallHandler inpExpr
| FastIntegerForLoop(startExpr, limitExpr, consumeExpr, isUp, debugPointAtFor, debugPointAtInOrTo) ->
visitExpr memberCallHandler startExpr
visitExpr memberCallHandler limitExpr
visitExpr memberCallHandler consumeExpr
| ILAsm(asmCode, typeArgs, argExprs) -> visitExprs memberCallHandler argExprs
| ILFieldGet(objExprOpt, fieldType, fieldName) -> visitObjArg memberCallHandler objExprOpt
| ILFieldSet(objExprOpt, fieldType, fieldName, valueExpr) -> visitObjArg memberCallHandler objExprOpt
| IfThenElse(guardExpr, thenExpr, elseExpr) ->
visitExpr memberCallHandler guardExpr
visitExpr memberCallHandler thenExpr
visitExpr memberCallHandler elseExpr
| Lambda(lambdaVar, bodyExpr) -> visitExpr memberCallHandler bodyExpr
| Let((bindingVar, bindingExpr, debugPointAtBinding), bodyExpr) ->
visitExpr memberCallHandler bindingExpr; visitExpr memberCallHandler bodyExpr
visitExpr memberCallHandler bindingExpr
visitExpr memberCallHandler bodyExpr
| LetRec(recursiveBindings, bodyExpr) ->
let recursiveBindings' = recursiveBindings |> List.map (fun (mfv, expr, dp) -> (mfv, expr))
List.iter (snd >> visitExpr memberCallHandler) recursiveBindings'; visitExpr memberCallHandler bodyExpr
| NewArray(arrayType, argExprs) ->
visitExprs memberCallHandler argExprs
| NewDelegate(delegateType, delegateBodyExpr) ->
visitExpr memberCallHandler delegateBodyExpr
| NewObject(objType, typeArgs, argExprs) ->
visitExprs memberCallHandler argExprs
| NewRecord(recordType, argExprs) ->
visitExprs memberCallHandler argExprs
| NewTuple(tupleType, argExprs) ->
visitExprs memberCallHandler argExprs
| NewUnionCase(unionType, unionCase, argExprs) ->
visitExprs memberCallHandler argExprs
| Quote(quotedExpr) ->
visitExpr memberCallHandler quotedExpr
| FSharpFieldGet(objExprOpt, recordOrClassType, fieldInfo) ->
visitObjArg memberCallHandler objExprOpt
let recursiveBindings' =
recursiveBindings |> List.map (fun (mfv, expr, dp) -> (mfv, expr))

List.iter (snd >> visitExpr memberCallHandler) recursiveBindings'
visitExpr memberCallHandler bodyExpr
| NewArray(arrayType, argExprs) -> visitExprs memberCallHandler argExprs
| NewDelegate(delegateType, delegateBodyExpr) -> visitExpr memberCallHandler delegateBodyExpr
| NewObject(objType, typeArgs, argExprs) -> visitExprs memberCallHandler argExprs
| NewRecord(recordType, argExprs) -> visitExprs memberCallHandler argExprs
| NewTuple(tupleType, argExprs) -> visitExprs memberCallHandler argExprs
| NewUnionCase(unionType, unionCase, argExprs) -> visitExprs memberCallHandler argExprs
| Quote(quotedExpr) -> visitExpr memberCallHandler quotedExpr
| FSharpFieldGet(objExprOpt, recordOrClassType, fieldInfo) -> visitObjArg memberCallHandler objExprOpt
| FSharpFieldSet(objExprOpt, recordOrClassType, fieldInfo, argExpr) ->
visitObjArg memberCallHandler objExprOpt; visitExpr memberCallHandler argExpr
visitObjArg memberCallHandler objExprOpt
visitExpr memberCallHandler argExpr
| Sequential(firstExpr, secondExpr) ->
visitExpr memberCallHandler firstExpr; visitExpr memberCallHandler secondExpr
visitExpr memberCallHandler firstExpr
visitExpr memberCallHandler secondExpr
| TryFinally(bodyExpr, finalizeExpr, debugPointAtTry, debugPointAtFinally) ->
visitExpr memberCallHandler bodyExpr; visitExpr memberCallHandler finalizeExpr
visitExpr memberCallHandler bodyExpr
visitExpr memberCallHandler finalizeExpr
| TryWith(bodyExpr, _, _, catchVar, catchExpr, debugPointAtTry, debugPointAtWith) ->
visitExpr memberCallHandler bodyExpr; visitExpr memberCallHandler catchExpr
| TupleGet(tupleType, tupleElemIndex, tupleExpr) ->
visitExpr memberCallHandler tupleExpr
| DecisionTree(decisionExpr, decisionTargets) ->
visitExpr memberCallHandler decisionExpr; List.iter (snd >> visitExpr memberCallHandler) decisionTargets
| DecisionTreeSuccess (decisionTargetIdx, decisionTargetExprs) ->
visitExprs memberCallHandler decisionTargetExprs
| TypeLambda(genericParam, bodyExpr) ->
visitExpr memberCallHandler bodyExpr
| TypeTest(ty, inpExpr) ->
visitExpr memberCallHandler inpExpr
visitExpr memberCallHandler catchExpr
| TupleGet(tupleType, tupleElemIndex, tupleExpr) -> visitExpr memberCallHandler tupleExpr
| DecisionTree(decisionExpr, decisionTargets) ->
visitExpr memberCallHandler decisionExpr
List.iter (snd >> visitExpr memberCallHandler) decisionTargets
| DecisionTreeSuccess(decisionTargetIdx, decisionTargetExprs) -> visitExprs memberCallHandler decisionTargetExprs
| TypeLambda(genericParam, bodyExpr) -> visitExpr memberCallHandler bodyExpr
| TypeTest(ty, inpExpr) -> visitExpr memberCallHandler inpExpr
| UnionCaseSet(unionExpr, unionType, unionCase, unionCaseField, valueExpr) ->
visitExpr memberCallHandler unionExpr; visitExpr memberCallHandler valueExpr
| UnionCaseGet(unionExpr, unionType, unionCase, unionCaseField) ->
visitExpr memberCallHandler unionExpr
| UnionCaseTest(unionExpr, unionType, unionCase) ->
visitExpr memberCallHandler unionExpr
| UnionCaseTag(unionExpr, unionType) ->
visitExpr memberCallHandler unionExpr
visitExpr memberCallHandler valueExpr
| UnionCaseGet(unionExpr, unionType, unionCase, unionCaseField) -> visitExpr memberCallHandler unionExpr
| UnionCaseTest(unionExpr, unionType, unionCase) -> visitExpr memberCallHandler unionExpr
| UnionCaseTag(unionExpr, unionType) -> visitExpr memberCallHandler unionExpr
| ObjectExpr(objType, baseCallExpr, overrides, interfaceImplementations) ->
visitExpr memberCallHandler baseCallExpr
List.iter (visitObjMember memberCallHandler) overrides
List.iter (snd >> List.iter (visitObjMember memberCallHandler)) interfaceImplementations
| TraitCall(sourceTypes, traitName, typeArgs, typeInstantiation, argTypes, argExprs) ->
visitExprs memberCallHandler argExprs
| ValueSet(valToSet, valueExpr) ->
visitExpr memberCallHandler valueExpr
| ValueSet(valToSet, valueExpr) -> visitExpr memberCallHandler valueExpr
| WhileLoop(guardExpr, bodyExpr, debugPointAtWhile) ->
visitExpr memberCallHandler guardExpr; visitExpr memberCallHandler bodyExpr
visitExpr memberCallHandler guardExpr
visitExpr memberCallHandler bodyExpr
| BaseValue baseType -> ()
| DefaultValue defaultType -> ()
| ThisValue thisType -> ()
| Const(constValueObj, constType) -> ()
| Value(valueToGet) -> ()
| _ -> ()

and visitExprs f exprs =
List.iter (visitExpr f) exprs
and visitExprs f exprs = List.iter (visitExpr f) exprs

and visitObjArg f objOpt =
Option.iter (visitExpr f) objOpt
and visitObjArg f objOpt = Option.iter (visitExpr f) objOpt

and visitObjMember f memb =
visitExpr f memb.Body
and visitObjMember f memb = visitExpr f memb.Body

let rec visitDeclaration f d =
match d with
| FSharpImplementationFileDeclaration.Entity (e, subDecls) ->
| FSharpImplementationFileDeclaration.Entity(e, subDecls) ->
for subDecl in subDecls do
visitDeclaration f subDecl
| FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v, vs, e) ->
visitExpr f e
| FSharpImplementationFileDeclaration.InitAction(e) ->
visitExpr f e
| FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v, vs, e) -> visitExpr f e
| FSharpImplementationFileDeclaration.InitAction(e) -> visitExpr f e

let notUsed() =
let option : Option<int> = None
let notUsed () =
let option: Option<int> = None
option.Value

[<Analyzer "OptionAnalyzer">]
let optionValueAnalyzer : Analyzer =
let optionValueAnalyzer: Analyzer =
fun ctx ->
let state = ResizeArray<range>()

let handler (range: range) (m: FSharpMemberOrFunctionOrValue) =
let name = String.Join(".", m.DeclaringEntity.Value.FullName, m.DisplayName)

if name = "Microsoft.FSharp.Core.FSharpOption`1.Value" then
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 = []}
{
Type = "Option.Value analyzer"
Message = "Option.Value shouldn't be used"
Code = "OV001"
Severity = Warning
Range = r
Fixes = []
}
)
|> Seq.toList
|> Seq.toList
Loading

0 comments on commit 16321ec

Please sign in to comment.