Skip to content

Releases: ShaharPrishMSFT/SubtleEngineering

Add SE106X - Force usage of static lambdas

04 Oct 12:00
578aee0
Compare
Choose a tag to compare

Code quality: Warn against using non-static lambdas (SE106X)

For performance-sensitive code, it's sometimes useful for the developer to prevent misuse of a method or class to protect the developer.

Using the [UseStaticLambda] on a field, property or parameter will cause the analyzer to emit a warning if a non-static lambda is passed in.

public ref struct MyOptimizedNonAllocUtility
{
	public MyOptimizedNonAllocUtility([UseStaticLambda] Func<int> myDelegate)
	{
		_myDelegate = myDelegate;
	}
}

// Code using the struct
var s = new MyOptimizedNonAllocUtility(() => 42); // This will emit SE1060

// Fixed code:
var s = new MyOptimizedNonAllocUtility(static () => 42); // This will emit SE1060

SE1060/SE1061

What it looks for: Passing in non-static delegates to methods that expect to get a static.

Why: For performance-sensitive code that uses delegates, it's easy to sometimes forget that creating a capturing delegate can be expensive. This will remind the developer to use a delegate that will not allocate or allocate less.

How it helps engineers: Reduces the chance of making such mistakes.

The [RequireUsing] attribute now works with ref structs

04 Oct 07:58
28746f7
Compare
Choose a tag to compare

When using ref structs, the [RequireUsing] attribute will now work properly and not emit a warning that it's assigned to an incorrect method/type

Before, when having a ref struct with Dispose (which is usable in a using statement) would have complained that it does not support IDisposable.

Fix issue with SE1050 (Exhaustive switches) + another fix option for SE1040

29 Sep 08:34
fbdecfe
Compare
Choose a tag to compare

SE1050

Fixed an issue when switch arms contain a call to a static method with an enum as an argument

SE1040

Added a code fix that keeps the elements visible for intellisense.

Support for SE1050 - Exhaustive Switch expressions/statements

28 Sep 13:34
0170c09
Compare
Choose a tag to compare

SE1050 allows switch statements and expressions to be checked for exhaustiveness.

var x = myEnum.ForceExhaustive() switch
{
// All options must be mentioned
}

Fixes to SE1040 - correct placement of namespace declaration

27 Sep 12:42
Compare
Choose a tag to compare
0.2.7

Fix issue with adding the namespace if it already exists, as well as …

Fix issue with SE1040 where code fix has to be applied twice.

26 Sep 12:50
Compare
Choose a tag to compare
0.2.6

Merge branch 'main' of https://github.com/ShaharPrishMSFT/SubtleEngin…

Add SE1040 - hiding obsoleted entities.

26 Sep 12:19
58a63a5
Compare
Choose a tag to compare
Update README.md

Add SE1040

Add fix for default record primary constructor arguments.

30 Jun 07:24
c1ffd66
Compare
Choose a tag to compare

Added another warning + codefix.

SE1034: PrimaryDefaultConstructorValuesNotAllowed

What it looks for: Primary constructors are not allowed to have default values on implicit constructor properties.

Why: Default arguments on the primary constructor are not allowed on exhauste initialization types.

How it helps engineering: See SE1030

Add support for Exhaustive initialization types.

29 Jun 14:12
1ae3cf9
Compare
Choose a tag to compare

Code Quality Analyzer: Define and protect Exhaustive initialization types
Applies to types decorated with the ExhaustiveInitializationAttribute attribute.

This analyzer verifies that all properties in the type are initialized in the constructor or have the required modifier.

Example
[ExhaustiveInitialization]
public class MyClass
{
public int MyProperty { get; set; } // This will raise a warning because it's not initialized in the constructor or marked as required
}
SE1030: TypeInitializationIsNonExhaustive
What it looks for: This analyzer checks for types that are not designed to be exhaustively initialized.

Why: In certain cases, it's advantageous to ensure that all properties of a type are initialized in the constructor or marked as required. This can help prevent omission bugs and make the code more robust. A good example for this are types that are used as DTOs or models where they need to be converted to and from - marking both class as ExhaustiveInitialization can help ensure that all properties are properly initialized.

How it helps engineering: By enforcing exhaustive initialization, it helps to ensure that all properties of a type are properly initialized, which can help prevent bugs and make the code more robust.

SE1031: PropertyInitializationIsNonExhaustive
What it looks for: This is a warning on specific properties that are not required, or otherwise initialized in the constructor.

Why: See SE1030

How it helps engineering: See SE1030

SE1032: OnlyOneConstructorAllowed
What it looks for: When a class (not record) or a struct (not a record struct) contains multiple constructors, and not all properties are required, the analyzer will raise a warning that it does not know how to handle it.

Why: Reduce chances of mis-creating the class.

How it helps engineering: See SE1030

SE1033: NotAllowedOnType
What it looks for: Primary constructors are not allowed on classes and structs that are not records.

Why: There's no good way to inspect what the primary constructor is doing, and so exhaustiveness cannot be enforced.

How it helps engineering: See SE1030

Code fix available
A code fix is available for SE1030 and SE1031 - will add required to properties that are missing it.

Downgrade code analysis assemblies to support more SDKs

05 Jun 08:29
Compare
Choose a tag to compare
0.2.2

Downgrade libraries to make it work with c#6