Skip to content

F# analyzers provide extra checks for common mistakes

Notifications You must be signed in to change notification settings

criipto/fsharp-analyzers

Repository files navigation

Idura.FSharp.Analyzers

A set of F# analyzers which warn against code issues previously encountered by Idura.

Build

You should be able to build the project by simply running dotnet build.

Test

You can test the analyzers by running dotnet test.

The test suite works by running each analyzer on a number of test programs. There are two kinds of tests for the analyzers: positive and negative.

Positive tests check that the analyzer reports issues correctly when presented with a faulty program. Positive tests run the analyzer on each test program and record the messages generated by the analyzer. They then check that there is at least one message, and compare the generated messages with a snapshot to check that the analyzer does not change its behavior unintentionally. If the snapshot does not match, the test suite will fail and generate a __mismatch__ directory containing the new messages so you can compare them with the snapshots while debugging your code. If you are intentionally changing the behaviour of an analyzer and want to update the snapshots to reflect this, overwrite the old snapshots with the new snapshots generated in the __mismatch__ directory after running the test suite.

Negative tests check that the analyzer does not report issues on correct programs. Negative tests run the analyzer on each test program and check that the analyzer does not produce any messages.

Usage

Run dotnet pack --configuration Release to generate a NuGet package (in the bin/Release directory). You can then use the NuGet package like any other F# analyzer.

Development

FSharp.Tree.Viewer

The FSharp.Tree.Viewer project contains a small command-line utility which allows you to view the syntax tree and typed declarations as parsed by the F# compiler. This can be useful to figure out what to look for when traversing the abstract syntax tree to find a specific construct. From the src/FSharp.Tree.Viewer directory, the tool can be run with e.g. dotnet run -- Program.fs. Run dotnet run -- Program.fs -- --help to get an overview of the options.

Analyzers

Missing type annotations in XUnit InlineData argument

Xunit only supports literals in InlineData. If you provide a non-literal type as input to an InlineData test, the test will silently be skipped by Xunit. This can cause surprising behavior when refactoring tests and accidentally changing test input to a non-literal. This can be somewhat mitigated by annotating the types of all input parameters supplied via InlineData.

This analyzer detects missing type annotations in parameters supplied via InlineData.

About this analyzer
 Code IDURA-XUNIT-001
 Message Arguments with data supplied via the InlineData annotation must have type annotations
Severity  Warning
Works in  CLI, Ionide

Missing unit argument in XUnit Fact tests

XUnit will silently skip any tests tagged with the Fact attribute if they don't have a unit argument. This is an easy way to accidentally disable a test, and it is also easy to forget to add the unit argument.

This analyzer detects missing unit arguments in functions that have the Fact attribute.

About this analyzer
 Code IDURA-XUNIT-002
 Message Test functions tagged with the XUnit [Fact] attribute must have a unit argument or the test runner will not execute them
Severity  Warning
Works in  CLI, Ionide

Do not use your own random generator instance

The random number generator instances in .NET sometimes fail with cryptographic exceptions for no observable reason. We have observed that this can cause the entire generator instance to permanently fail. For this reason, you should never use your own instances of random number generators.

In non-legacy code, the solution is to use the static methods on the RandomNumberGenerator class, which are not bound to a specific instance.

In legacy code where these are not available, you should maintain a pool of random number generator instances which replaces failed generators automatically. At Idura, we have implemented this in our legacy products at Idura by injecting such a pool as a dependency for every module that needs a random number generator.

This analyzer detects use of the constructors and Create methods of the RandomNumberGenerator and RNGCryptoServiceProvider classes.

About this analyzer
 Code IDURA-CRYPTO-001
 Message Do not use your own instance of RNGCryptoServiceProvider. Depend on a global RNG pool to ensure stability of the generator.
Severity  Warning
Works in  CLI, Ionide
About this analyzer
 Code IDURA-CRYPTO-002
 Message Do not use your own instance of RandomNumberGenerator. Depend on a global RNG pool to ensure stability of the generator.
Severity  Warning
Works in  CLI, Ionide

About

F# analyzers provide extra checks for common mistakes

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages