Skip to content

Commit

Permalink
Fix a false negative in LoggingTemplateMissingValuesAnalyzer (#80)
Browse files Browse the repository at this point in the history
* fix a false negative caused by not diving into match clauses

* add changelog entry and release 0.9.1

* Update CHANGELOG.md

Co-authored-by: Florian Verdonck <[email protected]>

* remove test file from item group

* add comment about non-tailrec function

* detect template strings constructed by functions like sprintf

* add changelog entry and release

---------

Co-authored-by: Florian Verdonck <[email protected]>
  • Loading branch information
dawedawe and nojaf authored Feb 16, 2024
1 parent 6932c8d commit ac234ce
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.9.2 - 2024-02-16

### Fixed
* Fixed a false negative of LoggingTemplateMissingValuesAnalyzer. [#79](https://github.com/G-Research/fsharp-analyzers/issues/79)

## 0.9.1 - 2024-02-15

### Fixed
Expand Down
32 changes: 28 additions & 4 deletions src/FSharp.Analyzers/LoggingTemplateMissingValuesAnalyzer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,38 @@ open FSharp.Compiler.Text
[<Literal>]
let Code = "GRA-LOGTEMPLMISSVALS-001"

let (|StringConst|_|) (e : FSharpExpr) =
let rec (|StringFormat|_|) (e : FSharpExpr) =
match e with
| Call (_exprOption, _mfv, _types, _l, exprs) ->
match exprs with
| Coerce (targetType, expr) :: _ when
targetType.BasicQualifiedName = "Microsoft.FSharp.Core.PrintfModule+StringFormat`1"
->
match expr with
| NewObject (_mfv, _types, [ StringConst s ]) -> Some s
| _ -> None
| exprs ->
exprs
|> List.tryPick (
function
| StringConst s -> Some s
| _ -> None
)
| _ -> None
| _ -> None

and (|StringConst|_|) (e : FSharpExpr) =
let name = e.Type.ErasedType.TypeDefinition.TryGetFullName ()

match name, e with
| Some "System.String", Const (o, _type) when not (isNull o) -> Some (string o)
| Some "System.String", Application (expr, _, _) ->
match expr with
| Let ((_mfv, StringFormat s, _debugPointAtBinding), _expr) -> Some s
| _ -> None
| _, StringFormat s -> Some s
| _ -> None


let analyze (typedTree : FSharpImplementationFileContents) =
let state = ResizeArray<range * string> ()

Expand Down Expand Up @@ -51,7 +75,7 @@ let analyze (typedTree : FSharpImplementationFileContents) =
else
0

let expected =
let calcExpected () =
let logString =
args
|> List.tryPick (
Expand Down Expand Up @@ -80,7 +104,7 @@ let analyze (typedTree : FSharpImplementationFileContents) =
if
m.Assembly.SimpleName = assemblyName
&& Set.contains name namesToWarnAbout
&& provided <> expected
&& provided <> calcExpected ()
then
state.Add (range, m.DisplayName)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module M

open Microsoft.Extensions.Logging

let testlog () =
use factory = LoggerFactory.Create(fun b -> b.AddConsole() |> ignore)
let logger: ILogger = factory.CreateLogger("Program")
let timeWasteString = "time waste"

logger.LogWarning(id "Foo {Wasted}\n{Result}", timeWasteString)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GRA-LOGTEMPLMISSVALS-001 | Warning | (10,8 - 10,71) | The given values in your call to ILogger.LogWarning don't match the expected templated args. | []
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module M

open Microsoft.Extensions.Logging

let testlog () =
use factory = LoggerFactory.Create(fun b -> b.AddConsole() |> ignore)
let logger: ILogger = factory.CreateLogger("Program")
let timespan = System.TimeSpan()
let timeWasteString = "time waste"

logger.LogWarning(sprintf "Foo %dm %ds {Wasted}\n{Result}" (int timespan.TotalMinutes) timespan.Seconds, timeWasteString)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GRA-LOGTEMPLMISSVALS-001 | Warning | (11,8 - 11,129) | The given values in your call to ILogger.LogWarning don't match the expected templated args. | []
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module M

open Microsoft.Extensions.Logging

let testlog () =
use factory = LoggerFactory.Create(fun b -> b.AddConsole() |> ignore)
let logger: ILogger = factory.CreateLogger("Program")
let timeWasteString = "time waste"

logger.LogWarning(sprintf "Foo {Wasted}\n{Result}", timeWasteString)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GRA-LOGTEMPLMISSVALS-001 | Warning | (10,8 - 10,76) | The given values in your call to ILogger.LogWarning don't match the expected templated args. | []
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module M

open Microsoft.Extensions.Logging

let testlog () =
use factory = LoggerFactory.Create(fun b -> b.AddConsole() |> ignore)
let logger: ILogger = factory.CreateLogger("Program")
let timespan = System.TimeSpan()
let timeWasteString = "time waste"
let result = "result"

logger.LogWarning(id "Foo {Wasted}\n{Result}", timeWasteString, result)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module M

open Microsoft.Extensions.Logging

let testlog () =
use factory = LoggerFactory.Create(fun b -> b.AddConsole() |> ignore)
let logger: ILogger = factory.CreateLogger("Program")
let timespan = System.TimeSpan()
let timeWasteString = "time waste"
let result = "result"

logger.LogWarning(sprintf "Foo %dm %ds {Wasted}\n{Result}" (int timespan.TotalMinutes) timespan.Seconds, timeWasteString, result)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module M

open Microsoft.Extensions.Logging

let testlog () =
use factory = LoggerFactory.Create(fun b -> b.AddConsole() |> ignore)
let logger: ILogger = factory.CreateLogger("Program")
let timespan = System.TimeSpan()
let timeWasteString = "time waste"
let result = "result"

logger.LogWarning(sprintf "Foo {Wasted}\n{Result}", timeWasteString, result)

0 comments on commit ac234ce

Please sign in to comment.