Skip to content

Commit

Permalink
doc: document AvoidEnumParametersAnalyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
kryptt committed Mar 14, 2023
1 parent 31bac65 commit 6327d53
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Documentation/Diagnostics/PH2138.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Ultimately we will need to execute changes onto the code's environment. For thes

## Example

Code that triggers 2 diagnostics:
Code that triggers the diagnostic:
``` cs
class MyClass
{
Expand Down
95 changes: 95 additions & 0 deletions Documentation/Diagnostics/PH2140.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# PH2138: Avoid enum parameters

| Property | Value |
|--|--|
| Package | [Philips.CodeAnalysis.MaintainabilityAnalyzers](https://www.nuget.org/packages/Philips.CodeAnalysis.MaintainabilityAnalyzers) |
| Diagnostic ID | PH2140 |
| Category | [Functional Programming](../FunctionalProgramming.md) |
| Analyzer | [AvoidEnumParametersAnalyzer](https://github.com/philips-software/roslyn-analyzers/blob/main/Philips.CodeAnalysis.MaintainabilityAnalyzers/Cardinality/AvoidEnumParametersAnalyzer.cs)
| CodeFix | No |
| Severity | Error |
| Enabled By Default | No |

## Introduction

This analyzer warns about methods or functions that have enums as parameters. Whenever a method takes in a known subset of values there is an opportunity to invert the control flow and reduce the complexity of the call site.

Often times the method does not apply to all values in the enum, but only a subset of them. In these cases it is better to define the method only for those values.

Otherwise, when all values are addressable it is often the case each individual value has its own particular set of rules it follows. In these cases it is better to isolate each different ruleset to its relevant enum value.

## How to solve

Upgrade the enum to a record and have each value implement its own particular version.
If that is not possible, create an extension method that performs the relevant pattern matching.
See this [blog post](https://spencerfarley.com/2021/03/26/unions-in-csharp/) for some more details.

## Example

Code that triggeres the diagnostic:
```cs
class MyClass
{
public ResultCode processFilename(String filename)
{
var envConfig = Config.FromEnvironment();
return processSysConfig(filename, envConfig);
}
public ResultCode processSysConfig(String filename, ConfigEnum config)
{
if (config == ReadOnUpdate)
{
...
}
else if (config == ReadWeekly || config == ReadMonthly)
{
...
}
else
{
...
}
}
}

enum ConfigEnum {
ReadOnUpdate, ReadMonthly, ReadWeekly, ReadNever
}
```

And the corrected code:
```cs
class MyClass
{
public ResultCode processFilename(String filename)
{
var envConfig = Config.FromEnvironment();
return envConfig.process(filename);
}

}

public abstract record ConfigRecord
{
public abstract long ProcessFile(string filename);

public record ReadOnUpdate() : ConfigRecord()
{
public override long ProcessFile(string filename) { ... }
};

public record ReadWeekly() : ConfigRecord()
{
public override long ProcessFile(string filename) { ... }
}

public record ReadMonthly() : ConfigRecord()
{
public override long ProcessFile(string filename) { ... }
}

public record ReadNever() : ConfigRecord() {
public override long ProcessFile(string filename) { ... }
}
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -97,31 +97,33 @@
* Introduce PH2114: Avoid empty statement.
* Introduce PH2115: Every Lambda expression on separate line.
* Introduce PH2116: Avoid ArrayList, use List<T> instead.
* Introduce PH2117: Avoid unnecessary Where.
* Introduce PH2118: Avoid magic numbers.
* PH2006 now supports folders in namespace
* Introduce PH2119: Cast complete object.
* Introduce PH2120: Document thrown exceptions.
* Introduce PH2121: Throw informational exceptions.
* Introduce PH2122: Avoid throwing exceptions from unexpected locations.
* Introduce PH2123: Pass sender to EventHandler.
* Introduce PH2124: Document unhandled exceptions.
* Introduce PH2125: Align number of + and == operators.
* Introduce PH2126: Avoid using Parameters as temporary variables.
* Introduce PH2127: Avoid changing loop variables.
* Introduce PH2128: Split multi-line conditions on logical operators.
* Introduce PH2129: Return immutable collections.
* Increased the test coverage.
* Introduce PH2130: Avoid implementing finalizers.
* Introduce PH2131: Align filename and class name.
* Introduce PH2131: Remove commented code.
* Introduce PH2133: Unmanaged objects need disposing.
* Introduce PH2134: Set properties in any order.
* PH2090 now also uses an AdditionalFile on top of the existing .editorconfig option to configure allowed methods.
* Introduce PH2135: Match namespace and Assembly Name. This extends the functionality that was previously claimed by PH2006 but never enforced.
* Introduce PH2136: Avoid duplicate strings.
* Introduce PH2139: Enable documentation creation.
</PackageReleaseNotes>
* Introduce PH2117: Avoid unnecessary Where.
* Introduce PH2118: Avoid magic numbers.
* PH2006 now supports folders in namespace
* Introduce PH2119: Cast complete object.
* Introduce PH2120: Document thrown exceptions.
* Introduce PH2121: Throw informational exceptions.
* Introduce PH2122: Avoid throwing exceptions from unexpected locations.
* Introduce PH2123: Pass sender to EventHandler.
* Introduce PH2124: Document unhandled exceptions.
* Introduce PH2125: Align number of + and == operators.
* Introduce PH2126: Avoid using Parameters as temporary variables.
* Introduce PH2127: Avoid changing loop variables.
* Introduce PH2128: Split multi-line conditions on logical operators.
* Introduce PH2129: Return immutable collections.
* Increased the test coverage.
* Introduce PH2130: Avoid implementing finalizers.
* Introduce PH2131: Align filename and class name.
* Introduce PH2131: Remove commented code.
* Introduce PH2133: Unmanaged objects need disposing.
* Introduce PH2134: Set properties in any order.
* PH2090 now also uses an AdditionalFile on top of the existing .editorconfig option to configure allowed methods.
* Introduce PH2135: Match namespace and Assembly Name. This extends the functionality that was previously claimed by PH2006 but never enforced.
* Introduce PH2136: Avoid duplicate strings.
* Introduce PH2138: Avoid void return.
* Introduce PH2139: Enable documentation creation.
* Introduce PH2140: Avoid enum parameters.
</PackageReleaseNotes>
<Copyright>© 2019-2023 Koninklijke Philips N.V.</Copyright>
<PackageTags>CSharp Maintainability Roslyn CodeAnalysis analyzers Philips</PackageTags>
<NoPackageAnalysis>true</NoPackageAnalysis>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,4 @@
| [PH2136](../Documentation/Diagnostics/PH2136.md) | Avoid duplicate strings | Duplicate strings are less maintainable. |
| [PH2138](../Documentation/Diagnostics/PH2138.md) | Avoid void returns | Methods that return void are mysterious. |
| [PH2139](../Documentation/Diagnostics/PH2139.md) | Enable documentation creation | Add XML documentation generation to the project file, to be able to see Diagnostics for XML documentation. |
| [PH2140](../Documentation/Diagnostics/PH2140.md) | Avoid enum parameters | Methods that take enums as parameters should be factored out the enum parameter it receives as either an extension method or in the relevant enum instances. |

0 comments on commit 6327d53

Please sign in to comment.