ExhaustiveMatching icon indicating copy to clipboard operation
ExhaustiveMatching copied to clipboard

Dependency-free builds

Open daiplusplus opened this issue 3 years ago • 4 comments

I'd love to use this ExhaustiveMatching analyzer with a number of NuGet projects that I work on but I understand that even though this is a "private" dependency, it still causes my project to have a reference to the ExhaustiveMatching.dll assembly which then must be referenced by my output NuGet package - this isn't ideal.

It should be possible for the ExhaustiveMatching code-analysis to work by detecting the use of built-in exception types (e.g. ArgumentOutOfRangeException) in a switch block provided they're annotated with a known magic const string for the message: ctor parameter - or allow use to redefine the ExhaustiveMatching exceptions in our own projects - and the analyzer could then look for that without us needing to reference the ExhaustiveMatching.dll assembly.


On a related note, I'd like to have two separate exceptions to : one derived from ArgumentOutOfRangeException for when switching over an enum parameter argument, and another derived from InvalidOperationException when swiching over an enum that isn't a parameter argument.

daiplusplus avatar Mar 26 '21 14:03 daiplusplus

The library already supports exhaustive matching when throwing InvalidEnumArgumentException which inherits from ArgumentOutOfRangeException. It might be possible to split that functionality into a separate analyzer that doesn't add the dependency on ExhaustiveMatching.dll.

The thing is that it isn't just the exception type in the ExhaustiveMatching.dll. There are also the attributes used for closed types. Without that the functionality is severely limited. But it sounds as if you aren't using that functionality? In the future, there will likely be further useful types in there. For example, to configure null handling.

I'm not seeing a good way to support anything but the most basic stuff without the reference to ExhaustiveMatching.dll.

@Jehoel, if ExhaustiveMatching.dll were in a separate NuGet package so your NuGet package could depend on that without depending on ExhaustiveMatching.Analyzer would that be good enough?

Redefining the ExhaustiveMatchFailedException in your own library could make it strange for consumers of your library if it ever throws that exception.

WalkerCodeRanger avatar Aug 27 '21 19:08 WalkerCodeRanger

The library already supports exhaustive matching when throwing InvalidEnumArgumentException which inherits from ArgumentOutOfRangeException

It doesn't. InvalidEnumArgumentException inherits from only ArgumentException.

There are also the attributes used for closed types. Without that the functionality is severely limited

It could be supported by simply requiring the project being analyzed to reimplement those types, just like how you can use C# 8.0 nullable annotations (which only exist in .NET Standard 2.1+ or .NET Core 3.0+) when targeting .NET Standard 2.0 by providing your own System.Diagnostics.CodeAnalysis.AllowNullAttribute .

Redefining the ExhaustiveMatchFailedException in your own library could make it strange for consumers of your library if it ever throws that exception.

Whyso? The analyzer would presumably require that the project's ExhaustiveMatchFailedException implementation must derive from ArgumentOutOfRangeException so that catch(ArgumentException) and catch(ArgumentOutOfRangeException) still work as-expected.

daiplusplus avatar Aug 28 '21 01:08 daiplusplus

I've decided on a plan for handling dependency-free builds. It is mostly described in the Packages and Downloading and Dependency Free Usage sections of the readme.

Additionally, I plan to actually eliminate the ExhaustiveMatchFailedException exception. Instead only standard exceptions will be used. Which one is used will depend on whether the ExahustiveMatch.Failed<T>(string paramName, T value) or ExahustiveMatch.Failed<T>(T value) overload is used.

ExahustiveMatch.Failed<T>(string paramName, T value) throws:

  • InvalidEnumArgumentException for is an invalid enum value
  • InvalidOperationException for null value types (i.e. Nullable<T>) - this should be prevented by the analyzer, if this happens it is not a problem with the argument, but with the matching.
  • ArgumentNullException for null reference types
  • ArgumentOutOfRangeException for all other cases - exception message will explain that exhaustive matching failed

ExahustiveMatch.Failed<T>(T value) throws:

  • InvalidOperationException for all cases - exception message will explain that exhaustive matching failed

I have not started implementing this. We will see how it goes.

WalkerCodeRanger avatar Mar 20 '22 23:03 WalkerCodeRanger

I have this implemented in prototype form in my fork here: https://github.com/daiplusplus/ExhaustiveMatching/tree/dev/2023-11-look-mum-no-assembly-reference-required

daiplusplus avatar Nov 19 '23 12:11 daiplusplus