From 4e6ebb923f20a5280ada67aad1fa7478f45c44cc Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 18 Aug 2019 17:18:55 +0200 Subject: [PATCH 1/6] add shared Guard classes --- Helpers/DebugGuard.cs | 308 +++++++++++++++++++++++++++++++++++++++++ Helpers/Guard.cs | 309 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 617 insertions(+) create mode 100644 Helpers/DebugGuard.cs create mode 100644 Helpers/Guard.cs diff --git a/Helpers/DebugGuard.cs b/Helpers/DebugGuard.cs new file mode 100644 index 0000000..31d7d23 --- /dev/null +++ b/Helpers/DebugGuard.cs @@ -0,0 +1,308 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace SixLabors +{ + /// + /// Provides methods to protect against invalid parameters for a DEBUG build. + /// + [DebuggerStepThrough] + internal static class DebugGuard + { + /// + /// Ensures that the value is not null. + /// + /// The target object, which cannot be null. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// is null. + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void NotNull(TValue value, string parameterName) + where TValue : class + { + if (value is null) + { + ThrowArgumentNullException(parameterName); + } + } + + /// + /// Ensures that the target value is not null, empty, or whitespace. + /// + /// The target string, which should be checked against being null or empty. + /// Name of the parameter. + /// is null. + /// is empty or contains only blanks. + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void NotNullOrWhiteSpace(string value, string parameterName) + { + if (value is null) + { + ThrowArgumentNullException(parameterName); + } + + if (string.IsNullOrWhiteSpace(value)) + { + ThrowArgumentException("Must not be empty or whitespace.", parameterName); + } + } + + /// + /// Ensures that the specified value is less than a maximum value. + /// + /// The target value, which should be validated. + /// The maximum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is greater than the maximum value. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void MustBeLessThan(TValue value, TValue max, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(max) >= 0) + { + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be less than {max}."); + } + } + + /// + /// Verifies that the specified value is less than or equal to a maximum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The maximum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is greater than the maximum value. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(max) > 0) + { + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be less than or equal to {max}."); + } + } + + /// + /// Verifies that the specified value is greater than a minimum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The minimum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is less than the minimum value. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(min) <= 0) + { + ThrowArgumentOutOfRangeException( + parameterName, + $"Value {value} must be greater than {min}."); + } + } + + /// + /// Verifies that the specified value is greater than or equal to a minimum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The minimum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is less than the minimum value. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(min) < 0) + { + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min}."); + } + } + + /// + /// Verifies that the specified value is greater than or equal to a minimum value and less than + /// or equal to a maximum value and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The minimum value. + /// The maximum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is less than the minimum value of greater than the maximum value. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0) + { + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min} and less than or equal to {max}."); + } + } + + /// + /// Verifies, that the method parameter with specified target value is true + /// and throws an exception if it is found to be so. + /// + /// The target value, which cannot be false. + /// The name of the parameter that is to be checked. + /// The error message, if any to add to the exception. + /// + /// is false. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void IsTrue(bool target, string parameterName, string message) + { + if (!target) + { + ThrowArgumentException(message, parameterName); + } + } + + /// + /// Verifies, that the method parameter with specified target value is false + /// and throws an exception if it is found to be so. + /// + /// The target value, which cannot be true. + /// The name of the parameter that is to be checked. + /// The error message, if any to add to the exception. + /// + /// is true. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void IsFalse(bool target, string parameterName, string message) + { + if (target) + { + ThrowArgumentException(message, parameterName); + } + } + + /// + /// Verifies, that the `source` span has the length of 'minLength', or longer. + /// + /// The element type of the spans. + /// The source span. + /// The minimum length. + /// The name of the parameter that is to be checked. + /// + /// has less than items. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, string parameterName) + { + if (source.Length < minLength) + { + ThrowArgumentException($"Span-s must be at least of length {minLength}!", parameterName); + } + } + + /// + /// Verifies, that the `source` span has the length of 'minLength', or longer. + /// + /// The element type of the spans. + /// The target span. + /// The minimum length. + /// The name of the parameter that is to be checked. + /// + /// has less than items. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) + { + if (source.Length < minLength) + { + ThrowArgumentException($"The size must be at least {minLength}.", parameterName); + } + } + + /// + /// Verifies that the 'destination' span is not shorter than 'source'. + /// + /// The source element type. + /// The destination element type. + /// The source span. + /// The destination span. + /// The name of the argument for 'destination'. + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void DestinationShouldNotBeTooShort( + ReadOnlySpan source, + Span destination, + string destinationParamName) + { + if (destination.Length < source.Length) + { + ThrowArgumentException($"Destination span is too short!", destinationParamName); + } + } + + /// + /// Verifies that the 'destination' span is not shorter than 'source'. + /// + /// The source element type. + /// The destination element type. + /// The source span. + /// The destination span. + /// The name of the argument for 'destination'. + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void DestinationShouldNotBeTooShort( + Span source, + Span destination, + string destinationParamName) + { + if (destination.Length < source.Length) + { + ThrowArgumentException($"Destination span is too short!", destinationParamName); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowArgumentException(string message, string parameterName) + { + throw new ArgumentException(message, parameterName); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowArgumentOutOfRangeException(string parameterName, string message) + { + throw new ArgumentOutOfRangeException(parameterName, message); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowArgumentNullException(string parameterName) + { + throw new ArgumentNullException(parameterName); + } + } +} \ No newline at end of file diff --git a/Helpers/Guard.cs b/Helpers/Guard.cs new file mode 100644 index 0000000..09c8675 --- /dev/null +++ b/Helpers/Guard.cs @@ -0,0 +1,309 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace SixLabors +{ + /// + /// Provides methods to protect against invalid parameters. + /// + [DebuggerStepThrough] + internal static class Guard + { + /// + /// Ensures that the value is not null. + /// + /// The target object, which cannot be null. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// is null. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void NotNull(TValue value, string parameterName) + where TValue : class + { + if (value is null) + { + ThrowArgumentNullException(parameterName); + } + } + + /// + /// Ensures that the target value is not null, empty, or whitespace. + /// + /// The target string, which should be checked against being null or empty. + /// Name of the parameter. + /// is null. + /// is empty or contains only blanks. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void NotNullOrWhiteSpace(string value, string parameterName) + { + if (value is null) + { + ThrowArgumentNullException(parameterName); + } + + if (string.IsNullOrWhiteSpace(value)) + { + ThrowArgumentException("Must not be empty or whitespace.", parameterName); + } + } + + /// + /// Ensures that the specified value is less than a maximum value. + /// + /// The target value, which should be validated. + /// The maximum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is greater than the maximum value. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void MustBeLessThan(TValue value, TValue max, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(max) >= 0) + { + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be less than {max}."); + } + } + + /// + /// Verifies that the specified value is less than or equal to a maximum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The maximum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is greater than the maximum value. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(max) > 0) + { + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be less than or equal to {max}."); + } + } + + /// + /// Verifies that the specified value is greater than a minimum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The minimum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is less than the minimum value. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(min) <= 0) + { + ThrowArgumentOutOfRangeException( + parameterName, + $"Value {value} must be greater than {min}."); + } + } + + /// + /// Verifies that the specified value is greater than or equal to a minimum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The minimum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is less than the minimum value. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(min) < 0) + { + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min}."); + } + } + + /// + /// Verifies that the specified value is greater than or equal to a minimum value and less than + /// or equal to a maximum value and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The minimum value. + /// The maximum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is less than the minimum value of greater than the maximum value. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0) + { + ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min} and less than or equal to {max}."); + } + } + + /// + /// Verifies, that the method parameter with specified target value is true + /// and throws an exception if it is found to be so. + /// + /// The target value, which cannot be false. + /// The name of the parameter that is to be checked. + /// The error message, if any to add to the exception. + /// + /// is false. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void IsTrue(bool target, string parameterName, string message) + { + if (!target) + { + ThrowArgumentException(message, parameterName); + } + } + + /// + /// Verifies, that the method parameter with specified target value is false + /// and throws an exception if it is found to be so. + /// + /// The target value, which cannot be true. + /// The name of the parameter that is to be checked. + /// The error message, if any to add to the exception. + /// + /// is true. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void IsFalse(bool target, string parameterName, string message) + { + if (target) + { + ThrowArgumentException(message, parameterName); + } + } + + /// + /// Verifies, that the `source` span has the length of 'minLength', or longer. + /// + /// The element type of the spans. + /// The source span. + /// The minimum length. + /// The name of the parameter that is to be checked. + /// + /// has less than items. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, string parameterName) + { + if (source.Length < minLength) + { + ThrowArgumentException($"Span-s must be at least of length {minLength}!", parameterName); + } + } + + /// + /// Verifies, that the `source` span has the length of 'minLength', or longer. + /// + /// The element type of the spans. + /// The target span. + /// The minimum length. + /// The name of the parameter that is to be checked. + /// + /// has less than items. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) + { + if (source.Length < minLength) + { + ThrowArgumentException($"The size must be at least {minLength}.", parameterName); + } + } + + /// + /// Verifies that the 'destination' span is not shorter than 'source'. + /// + /// The source element type. + /// The destination element type. + /// The source span. + /// The destination span. + /// The name of the argument for 'destination'. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void DestinationShouldNotBeTooShort( + ReadOnlySpan source, + Span destination, + string destinationParamName) + { + if (destination.Length < source.Length) + { + ThrowArgumentException($"Destination span is too short!", destinationParamName); + } + } + + /// + /// Verifies that the 'destination' span is not shorter than 'source'. + /// + /// The source element type. + /// The destination element type. + /// The source span. + /// The destination span. + /// The name of the argument for 'destination'. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [DebuggerStepThrough] + public static void DestinationShouldNotBeTooShort( + Span source, + Span destination, + string destinationParamName) + { + if (destination.Length < source.Length) + { + ThrowArgumentException($"Destination span is too short!", destinationParamName); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowArgumentException(string message, string parameterName) + { + throw new ArgumentException(message, parameterName); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowArgumentOutOfRangeException(string parameterName, string message) + { + throw new ArgumentOutOfRangeException(parameterName, message); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowArgumentNullException(string parameterName) + { + throw new ArgumentNullException(parameterName); + } + } +} From 948a02984c6b62dca1c40b02b289f6d1c13d79b1 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 18 Aug 2019 17:40:30 +0200 Subject: [PATCH 2/6] make guards partial --- Helpers/DebugGuard.cs | 2 +- Helpers/Guard.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Helpers/DebugGuard.cs b/Helpers/DebugGuard.cs index 31d7d23..1515381 100644 --- a/Helpers/DebugGuard.cs +++ b/Helpers/DebugGuard.cs @@ -11,7 +11,7 @@ namespace SixLabors /// Provides methods to protect against invalid parameters for a DEBUG build. /// [DebuggerStepThrough] - internal static class DebugGuard + internal static partial class DebugGuard { /// /// Ensures that the value is not null. diff --git a/Helpers/Guard.cs b/Helpers/Guard.cs index 09c8675..acc0835 100644 --- a/Helpers/Guard.cs +++ b/Helpers/Guard.cs @@ -12,7 +12,7 @@ namespace SixLabors /// Provides methods to protect against invalid parameters. /// [DebuggerStepThrough] - internal static class Guard + internal static partial class Guard { /// /// Ensures that the value is not null. From 30e6fe889dd8005634496c4d8aac85ab01f62c1d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 18 Aug 2019 20:33:58 +0200 Subject: [PATCH 3/6] Drop redundant [DebuggerStepThrough] + apply formatting --- Helpers/DebugGuard.cs | 31 ++++++------------------------- Helpers/Guard.cs | 18 ++++++------------ 2 files changed, 12 insertions(+), 37 deletions(-) diff --git a/Helpers/DebugGuard.cs b/Helpers/DebugGuard.cs index 1515381..bf8ac6b 100644 --- a/Helpers/DebugGuard.cs +++ b/Helpers/DebugGuard.cs @@ -13,7 +13,7 @@ namespace SixLabors [DebuggerStepThrough] internal static partial class DebugGuard { - /// + /// /// Ensures that the value is not null. /// /// The target object, which cannot be null. @@ -21,7 +21,6 @@ internal static partial class DebugGuard /// The type of the value. /// is null. [Conditional("DEBUG")] - [DebuggerStepThrough] public static void NotNull(TValue value, string parameterName) where TValue : class { @@ -39,7 +38,6 @@ public static void NotNull(TValue value, string parameterName) /// is null. /// is empty or contains only blanks. [Conditional("DEBUG")] - [DebuggerStepThrough] public static void NotNullOrWhiteSpace(string value, string parameterName) { if (value is null) @@ -64,9 +62,8 @@ public static void NotNullOrWhiteSpace(string value, string parameterName) /// is greater than the maximum value. /// [Conditional("DEBUG")] - [DebuggerStepThrough] public static void MustBeLessThan(TValue value, TValue max, string parameterName) - where TValue : IComparable + where TValue : IComparable { if (value.CompareTo(max) >= 0) { @@ -86,9 +83,8 @@ public static void MustBeLessThan(TValue value, TValue max, string param /// is greater than the maximum value. /// [Conditional("DEBUG")] - [DebuggerStepThrough] public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) - where TValue : IComparable + where TValue : IComparable { if (value.CompareTo(max) > 0) { @@ -108,7 +104,6 @@ public static void MustBeLessThanOrEqualTo(TValue value, TValue max, str /// is less than the minimum value. /// [Conditional("DEBUG")] - [DebuggerStepThrough] public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) where TValue : IComparable { @@ -132,7 +127,6 @@ public static void MustBeGreaterThan(TValue value, TValue min, string pa /// is less than the minimum value. /// [Conditional("DEBUG")] - [DebuggerStepThrough] public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) where TValue : IComparable { @@ -155,7 +149,6 @@ public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, /// is less than the minimum value of greater than the maximum value. /// [Conditional("DEBUG")] - [DebuggerStepThrough] public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName) where TValue : IComparable { @@ -176,7 +169,6 @@ public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TVal /// is false. /// [Conditional("DEBUG")] - [DebuggerStepThrough] public static void IsTrue(bool target, string parameterName, string message) { if (!target) @@ -196,7 +188,6 @@ public static void IsTrue(bool target, string parameterName, string message) /// is true. /// [Conditional("DEBUG")] - [DebuggerStepThrough] public static void IsFalse(bool target, string parameterName, string message) { if (target) @@ -216,7 +207,6 @@ public static void IsFalse(bool target, string parameterName, string message) /// has less than items. /// [Conditional("DEBUG")] - [DebuggerStepThrough] public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, string parameterName) { if (source.Length < minLength) @@ -236,7 +226,6 @@ public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, /// has less than items. /// [Conditional("DEBUG")] - [DebuggerStepThrough] public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) { if (source.Length < minLength) @@ -254,7 +243,6 @@ public static void MustBeSizedAtLeast(Span source, int minLength, string p /// The destination span. /// The name of the argument for 'destination'. [Conditional("DEBUG")] - [DebuggerStepThrough] public static void DestinationShouldNotBeTooShort( ReadOnlySpan source, Span destination, @@ -275,7 +263,6 @@ public static void DestinationShouldNotBeTooShort( /// The destination span. /// The name of the argument for 'destination'. [Conditional("DEBUG")] - [DebuggerStepThrough] public static void DestinationShouldNotBeTooShort( Span source, Span destination, @@ -288,21 +275,15 @@ public static void DestinationShouldNotBeTooShort( } [MethodImpl(MethodImplOptions.NoInlining)] - private static void ThrowArgumentException(string message, string parameterName) - { + private static void ThrowArgumentException(string message, string parameterName) => throw new ArgumentException(message, parameterName); - } [MethodImpl(MethodImplOptions.NoInlining)] - private static void ThrowArgumentOutOfRangeException(string parameterName, string message) - { + private static void ThrowArgumentOutOfRangeException(string parameterName, string message) => throw new ArgumentOutOfRangeException(parameterName, message); - } [MethodImpl(MethodImplOptions.NoInlining)] - private static void ThrowArgumentNullException(string parameterName) - { + private static void ThrowArgumentNullException(string parameterName) => throw new ArgumentNullException(parameterName); - } } } \ No newline at end of file diff --git a/Helpers/Guard.cs b/Helpers/Guard.cs index acc0835..95fc2c7 100644 --- a/Helpers/Guard.cs +++ b/Helpers/Guard.cs @@ -67,7 +67,7 @@ public static void NotNullOrWhiteSpace(string value, string parameterName) [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void MustBeLessThan(TValue value, TValue max, string parameterName) - where TValue : IComparable + where TValue : IComparable { if (value.CompareTo(max) >= 0) { @@ -89,7 +89,7 @@ public static void MustBeLessThan(TValue value, TValue max, string param [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) - where TValue : IComparable + where TValue : IComparable { if (value.CompareTo(max) > 0) { @@ -289,21 +289,15 @@ public static void DestinationShouldNotBeTooShort( } [MethodImpl(MethodImplOptions.NoInlining)] - private static void ThrowArgumentException(string message, string parameterName) - { + private static void ThrowArgumentException(string message, string parameterName) => throw new ArgumentException(message, parameterName); - } [MethodImpl(MethodImplOptions.NoInlining)] - private static void ThrowArgumentOutOfRangeException(string parameterName, string message) - { + private static void ThrowArgumentOutOfRangeException(string parameterName, string message) => throw new ArgumentOutOfRangeException(parameterName, message); - } [MethodImpl(MethodImplOptions.NoInlining)] - private static void ThrowArgumentNullException(string parameterName) - { + private static void ThrowArgumentNullException(string parameterName) => throw new ArgumentNullException(parameterName); - } } -} +} \ No newline at end of file From 10fa2a5d9f3e16ff01faa857b6eaf7833a7163ca Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 18 Aug 2019 20:42:18 +0200 Subject: [PATCH 4/6] remove redundant [DebuggerStepThrough] --- Helpers/Guard.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Helpers/Guard.cs b/Helpers/Guard.cs index 95fc2c7..2eee4a5 100644 --- a/Helpers/Guard.cs +++ b/Helpers/Guard.cs @@ -22,7 +22,6 @@ internal static partial class Guard /// The type of the value. /// is null. [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void NotNull(TValue value, string parameterName) where TValue : class { @@ -40,7 +39,6 @@ public static void NotNull(TValue value, string parameterName) /// is null. /// is empty or contains only blanks. [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void NotNullOrWhiteSpace(string value, string parameterName) { if (value is null) @@ -65,7 +63,6 @@ public static void NotNullOrWhiteSpace(string value, string parameterName) /// is greater than the maximum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void MustBeLessThan(TValue value, TValue max, string parameterName) where TValue : IComparable { @@ -87,7 +84,6 @@ public static void MustBeLessThan(TValue value, TValue max, string param /// is greater than the maximum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) where TValue : IComparable { @@ -109,7 +105,6 @@ public static void MustBeLessThanOrEqualTo(TValue value, TValue max, str /// is less than the minimum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) where TValue : IComparable { @@ -133,7 +128,6 @@ public static void MustBeGreaterThan(TValue value, TValue min, string pa /// is less than the minimum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) where TValue : IComparable { @@ -156,7 +150,6 @@ public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, /// is less than the minimum value of greater than the maximum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName) where TValue : IComparable { @@ -177,7 +170,6 @@ public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TVal /// is false. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void IsTrue(bool target, string parameterName, string message) { if (!target) @@ -197,7 +189,6 @@ public static void IsTrue(bool target, string parameterName, string message) /// is true. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void IsFalse(bool target, string parameterName, string message) { if (target) @@ -217,7 +208,6 @@ public static void IsFalse(bool target, string parameterName, string message) /// has less than items. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, string parameterName) { if (source.Length < minLength) @@ -237,7 +227,6 @@ public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, /// has less than items. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) { if (source.Length < minLength) @@ -255,7 +244,6 @@ public static void MustBeSizedAtLeast(Span source, int minLength, string p /// The destination span. /// The name of the argument for 'destination'. [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void DestinationShouldNotBeTooShort( ReadOnlySpan source, Span destination, @@ -276,7 +264,6 @@ public static void DestinationShouldNotBeTooShort( /// The destination span. /// The name of the argument for 'destination'. [MethodImpl(MethodImplOptions.AggressiveInlining)] - [DebuggerStepThrough] public static void DestinationShouldNotBeTooShort( Span source, Span destination, From 2ba1e5219a15e29ef2aa4e51f3439884f9d98479 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Aug 2019 23:17:33 +0200 Subject: [PATCH 5/6] change README.md according to the new purpose of the repository --- README.md | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 27e629f..d7f5896 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,17 @@

-SixLabors.Standards +SixLabors.SharedInfrastructure
-SixLabors.Standards +SixLabors.SharedInfrastructure

-This repository contains the configuration and guidelines for automated linting of C# projects. It is designed to be installed as a [git submodule](https://blog.github.com/2016-02-01-working-with-submodules/) into your solution. +This repository contains: +- Configuration and guidelines for automated linting of C# projects. +- Standardized internal C# utility classes to be reused across SixLabors projects (like `Guard`) +- SixLabors.snk to support strong-name signing of SixLabors assemblies +- Centralized msbuild configuration and utilities for SixLabors projects (*Coming soon*) + +It is designed to be installed as a [git submodule](https://blog.github.com/2016-02-01-working-with-submodules/) into your solution. ## Installation. @@ -41,21 +47,21 @@ If the solution does not conform to this structure you will have to update it to ### Adding the Submodule -To add SixLabors.Standards as a submodule of your project. In the project repository type: +To add SixLabors.SharedInfrastructure as a submodule of your project. In the project repository type: ``` bash -git submodule add https://github.com/SixLabors/Standards standards +git submodule add https://github.com/SixLabors/SharedInfrastructure shared-infrastructure ``` -At this point, you’ll have a **standards** folder inside your project, but if you were to peek inside that folder, depending on your version of Git, you might see… nothing. +At this point, you’ll have a **shared-infrastructure** folder inside your project, but if you were to peek inside that folder, depending on your version of Git, you might see… nothing. -Newer versions of Git will do this automatically, but older versions will require you to explicitly tell Git to download the contents of **standards**: +Newer versions of Git will do this automatically, but older versions will require you to explicitly tell Git to download the contents of **shared-infrastructure**: ``` bash git submodule update --init --recursive ``` -If everything looks good, you can commit this change and you’ll have a **standards** folder in your project repository with all the content from the SixLabors.Standards repository. +If everything looks good, you can commit this change and you’ll have a **shared-infrastructure** folder in your project repository with all the content from the SixLabors.SharedInfrastructure repository. ### Updating the Submodule. @@ -113,12 +119,24 @@ These files tell StyleCop what rules to enforce and will have to be manually add ``` xml - ..\..\standards\SixLabors.ruleset + ..\..\shared-infrastructure\SixLabors.ruleset - + + +``` + +An up-to-date list of which StyleCop rules are implemented and which have code fixes can be found [here](https://dotnetanalyzers.github.io/StyleCopAnalyzers/). + +### Using internal C# utility classes + +To include internals like `Guard.cs` into your project you should add the following line to your `.csproj`: + +``` xml + + ``` -An up-to-date list of which StyleCop rules are implemented and which have code fixes can be found [here](https://dotnetanalyzers.github.io/StyleCopAnalyzers/). \ No newline at end of file +*Note:* This might change as soon as we include shared msbuild infrastructure elements (`.props` and `.targets`) \ No newline at end of file From a75a7ac4cbce8e100f0e8052540a893a9aca599a Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 31 Aug 2019 13:13:09 +1000 Subject: [PATCH 6/6] Update shared linting config and readme --- .editorconfig | 408 ++++++++++++++++++++++++++++++++++------ .gitattributes | 105 ++++++++++- README.md | 37 ++-- SixLabors.Tests.ruleset | 54 ++++++ SixLabors.ruleset | 15 +- 5 files changed, 538 insertions(+), 81 deletions(-) create mode 100644 SixLabors.Tests.ruleset diff --git a/.editorconfig b/.editorconfig index a235835..b0d0662 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,88 +1,372 @@ -# You can learn more about editorconfig here: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference -# top-most EditorConfig file -root = true -[*.cs] +############################################################################### +# EditorConfig is awesome: http://EditorConfig.org +############################################################################### -#Core editorconfig formatting - indentation +############################################################################### +# Top-most EditorConfig file +############################################################################### +root = true -#use soft tabs (spaces) for indentation +############################################################################### +# Set default behavior to: +# a UTF-8 encoding, +# Unix-style line endings, +# a newline ending the file, +# 4 space indentation, and +# trimming of trailing whitespace +############################################################################### +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true indent_style = space indent_size = 4 -csharp_style_var_for_built_in_types = false:warning -csharp_style_var_elsewhere = false:warning -csharp_style_var_when_type_is_apparent = true:warning +trim_trailing_whitespace = true + +############################################################################### +# Set file behavior to: +# 2 space indentation +############################################################################### +[*.{cmd,config,csproj,json,props,ps1,resx,sh,targets}] +indent_size = 2 + +############################################################################### +# Set file behavior to: +# Windows-style line endings, and +# tabular indentation +############################################################################### +[*.sln] end_of_line = crlf +indent_style = tab + +############################################################################### +# Set dotnet naming rules to: +# suggest async members be pascal case suffixed with Async +# suggest const declarations be pascal case +# suggest interfaces be pascal case prefixed with I +# suggest parameters be camel case +# suggest private and internal static fields be camel case +# suggest private and internal fields be camel case +# suggest public and protected declarations be pascal case +# suggest static readonly declarations be pascal case +# suggest type parameters be prefixed with T +############################################################################### +[*.cs] +dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.severity = suggestion +dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.style = pascal_case_suffixed_with_async +dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.symbols = async_members + +dotnet_naming_rule.const_declarations_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.const_declarations_should_be_pascal_case.style = pascal_case +dotnet_naming_rule.const_declarations_should_be_pascal_case.symbols = const_declarations + +dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.severity = suggestion +dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.style = pascal_case_prefixed_with_i +dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.symbols = interfaces + +dotnet_naming_rule.parameters_should_be_camel_case.severity = suggestion +dotnet_naming_rule.parameters_should_be_camel_case.style = camel_case +dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameters + +dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.severity = suggestion +dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.style = camel_case +dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.symbols = private_and_internal_static_fields + +dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.severity = suggestion +dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.style = camel_case +dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.symbols = private_and_internal_fields + +dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.style = pascal_case +dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.symbols = public_and_protected_declarations +dotnet_naming_symbols.public_and_protected_declarations.applicable_kinds = method, field, event, property + +dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.style = pascal_case +dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.symbols = static_readonly_declarations + +dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.severity = suggestion +dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.style = pascal_case_prefixed_with_t +dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.symbols = type_parameters + +############################################################################### +# Set dotnet naming styles to define: +# camel case +# pascal case +# pascal case suffixed with Async +# pascal case prefixed with I +# pascal case prefixed with T +############################################################################### +[*.cs] +dotnet_naming_style.camel_case.capitalization = camel_case + +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.pascal_case_suffixed_with_async.capitalization = pascal_case +dotnet_naming_style.pascal_case_suffixed_with_async.required_suffix = Async + +dotnet_naming_style.pascal_case_prefixed_with_i.capitalization = pascal_case +dotnet_naming_style.pascal_case_prefixed_with_i.required_prefix = I + +dotnet_naming_style.pascal_case_prefixed_with_t.capitalization = pascal_case +dotnet_naming_style.pascal_case_prefixed_with_t.required_prefix = T + +############################################################################### +# Set dotnet naming symbols to: +# async members +# const declarations +# interfaces +# private and internal fields +# private and internal static fields +# public and protected declarations +# static readonly declarations +# type parameters +############################################################################### +[*.cs] +dotnet_naming_symbols.async_members.required_modifiers = async + +dotnet_naming_symbols.const_declarations.required_modifiers = const + +dotnet_naming_symbols.interfaces.applicable_kinds = interface + +dotnet_naming_symbols.parameters.applicable_kinds = parameter + +dotnet_naming_symbols.private_and_internal_fields.applicable_accessibilities = private, internal +dotnet_naming_symbols.private_and_internal_fields.applicable_kinds = field + +dotnet_naming_symbols.private_and_internal_static_fields.applicable_accessibilities = private, internal +dotnet_naming_symbols.private_and_internal_static_fields.applicable_kinds = field +dotnet_naming_symbols.private_and_internal_static_fields.required_modifiers = static + +dotnet_naming_symbols.public_and_protected_declarations.applicable_accessibilities = public, protected + +dotnet_naming_symbols.static_readonly_declarations.required_modifiers = static, readonly + +dotnet_naming_symbols.type_parameters.applicable_kinds = type_parameter + +############################################################################### +# Set dotnet sort options to: +# do not separate import directives into groups, and +# sort system directives first +############################################################################### +[*.cs] +dotnet_separate_import_directive_groups = false dotnet_sort_system_directives_first = true -#Formatting - spacing options +############################################################################### +# Set dotnet style options to: +# suggest null-coalescing expressions, +# suggest collection-initializers, +# suggest explicit tuple names, +# suggest null-propogation +# suggest object-initializers, +# generate parentheses in arithmetic binary operators for clarity, +# generate parentheses in other binary operators for clarity, +# don't generate parentheses in other operators if unnecessary, +# generate parentheses in relational binary operators for clarity, +# warn when not using predefined-types for locals, parameters, and members, +# generate predefined-types of type names for member access, +# generate auto properties, +# suggest compound assignment, +# generate conditional expression over assignment, +# generate conditional expression over return, +# suggest inferred anonymous types, +# suggest inferred tuple names, +# suggest 'is null' checks over '== null', +# don't generate 'this.' and 'Me.' for events, +# warn when not using 'this.' and 'Me.' for fields, +# warn when not using 'this.' and 'Me.' for methods, +# warn when not using 'this.' and 'Me.' for properties, +# suggest readonly fields, and +# generate accessibility modifiers for non interface members +############################################################################### +[*.cs] +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion + +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent -#require NO space between a cast and the value +dotnet_style_predefined_type_for_locals_parameters_members = true:warning +dotnet_style_predefined_type_for_member_access = true:silent + +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion + +dotnet_style_qualification_for_event = false:silent +dotnet_style_qualification_for_field = true:warning +dotnet_style_qualification_for_method = true:warning +dotnet_style_qualification_for_property = true:warning + +dotnet_style_readonly_field = true:suggestion +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +############################################################################### +# Set dotnet style options to: +# suggest removing all unused parameters +############################################################################### +[*.cs] +dotnet_code_quality_unused_parameters = all:suggestion + +############################################################################### +# Set csharp indent options to: +# indent block contents, +# not indent braces, +# indent case contents, +# not indent case contents when block, +# indent labels one less than the current, and +# indent switch labels +############################################################################### +[*.cs] +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = false +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +############################################################################### +# Set csharp new-line options to: +# insert a new-line before "catch", +# insert a new-line before "else", +# insert a new-line before "finally", +# insert a new-line before members in anonymous-types, +# insert a new-line before members in object-initializers, and +# insert a new-line before all open braces +############################################################################### +[*.cs] +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true + +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true + +csharp_new_line_before_open_brace = all + +############################################################################### +# Set csharp preserve options to: +# preserve single-line blocks, and +# preserve single-line statements +############################################################################### +[*.cs] +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +############################################################################### +# Set csharp space options to: +# remove any space after a cast, +# add a space after the colon in an inheritance clause, +# add a space after a comma, +# remove any space after a dot, +# add a space after keywords in control flow statements, +# add a space after a semicolon in a "for" statement, +# add a space before and after binary operators, +# remove space around declaration statements, +# add a space before the colon in an inheritance clause, +# remove any space before a comma, +# remove any space before a dot, +# remove any space before an open square-bracket, +# remove any space before a semicolon in a "for" statement, +# remove any space between empty square-brackets, +# remove any space between a method call's empty parameter list parenthesis, +# remove any space between a method call's name and its opening parenthesis, +# remove any space between a method call's parameter list parenthesis, +# remove any space between a method declaration's empty parameter list parenthesis, +# remove any space between a method declaration's name and its openening parenthesis, +# remove any space between a method declaration's parameter list parenthesis, +# remove any space between parentheses, and +# remove any space between square brackets +############################################################################### +[*.cs] csharp_space_after_cast = false -#require a space before the colon for bases or interfaces in a type declaration csharp_space_after_colon_in_inheritance_clause = true -#require a space after a keyword in a control flow statement such as a for loop +csharp_space_after_comma = true +csharp_space_after_dot = false csharp_space_after_keywords_in_control_flow_statements = true -#require a space before the colon for bases or interfaces in a type declaration +csharp_space_after_semicolon_in_for_statement = true + +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = do_not_ignore + csharp_space_before_colon_in_inheritance_clause = true -#remove space within empty argument list parentheses +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false + +csharp_space_between_empty_square_brackets = false csharp_space_between_method_call_empty_parameter_list_parentheses = false -#remove space between method call name and opening parenthesis csharp_space_between_method_call_name_and_opening_parenthesis = false -#do not place space characters after the opening parenthesis and before the closing parenthesis of a method call csharp_space_between_method_call_parameter_list_parentheses = false -#remove space within empty parameter list parentheses for a method declaration csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -#place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list. +csharp_space_between_method_declaration_name_and_open_parenthesis = false csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false -#Formatting - wrapping options - -#leave code block on single line -csharp_preserve_single_line_blocks = true -#leave statements and member declarations on the same line -csharp_preserve_single_line_statements = true - -#Style - expression bodied member options +############################################################################### +# Set csharp style options to: +# generate braces, +# suggest simple default expressions, +# generate a preferred modifier order, +# suggest conditional delegate calls, +# suggest deconstructed variable declarations, +# generate expression-bodied accessors, +# generate expression-bodied constructors, +# generate expression-bodied indexers, +# generate expression-bodied lambdas, +# generate expression-bodied methods, +# generate expression-bodied operators, +# generate expression-bodied properties, +# suggest inlined variable declarations, +# suggest local over anonymous functions, +# suggest pattern-matching over "as" with "null" check, +# suggest pattern-matching over "is" with "cast" check, +# suggest throw expressions, +# generate a discard variable for unused value expression statements, +# suggest a discard variable for unused assignments, +# warn when using var for built-in types, +# warn when using var when the type is not apparent, and +# warn when not using var when the type is apparent +############################################################################### +[*.cs] +csharp_prefer_braces = true:silent +csharp_prefer_simple_default_expression = true:suggestion +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent -#prefer expression-bodied members for accessors -csharp_style_expression_bodied_accessors = true:suggestion -#prefer block bodies for constructors -csharp_style_expression_bodied_constructors = false:suggestion -#prefer expression-bodied members for indexers -csharp_style_expression_bodied_indexers = true:suggestion -#prefer expression-bodied members for methods -csharp_style_expression_bodied_methods = true:suggestion -#prefer block bodies for operators -csharp_style_expression_bodied_operators = false:suggestion -#prefer expression-bodied members for properties -csharp_style_expression_bodied_properties = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion -#Style - expression level options +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_methods = true:silent +csharp_style_expression_bodied_operators = true:silent +csharp_style_expression_bodied_properties = true:silent -#prefer out variables to be declared inline in the argument list of a method call when possible csharp_style_inlined_variable_declaration = true:suggestion -#prefer tuple names to ItemX properties -dotnet_style_explicit_tuple_names = true:suggestion -#prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them -dotnet_style_predefined_type_for_member_access = true:suggestion -#Style - implicit and explicit types +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -#prefer explicit type over var to declare variables with built-in system types such as int -csharp_style_var_for_built_in_types = false:suggestion -#prefer var when the type is already mentioned on the right-hand side of a declaration expression -csharp_style_var_when_type_is_apparent = true:suggestion +csharp_style_throw_expression = true:suggestion -#Style - language keyword and framework type options +csharp_style_unused_value_expression_statement_preference = discard_variable:silent +csharp_style_unused_value_assignment_preference = discard_variable:suggestion -#prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them -dotnet_style_predefined_type_for_locals_parameters_members = true:warning - -#Style - qualification options - -#prefer fields to be prefaced with this. in C# or Me. in Visual Basic -dotnet_style_qualification_for_field = true:warning -#prefer methods to be prefaced with this. in C# or Me. in Visual Basic -dotnet_style_qualification_for_method = true:warning -#prefer properties to be prefaced with this. in C# or Me. in Visual Basic -dotnet_style_qualification_for_property = true:warning +csharp_style_var_for_built_in_types = false:warning +csharp_style_var_elsewhere = false:warning +csharp_style_var_when_type_is_apparent = true:warning diff --git a/.gitattributes b/.gitattributes index 5dcc417..537d9ce 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,108 @@ +############################################################################### +# Set default behavior to: +# treat as text and +# normalize to Unix-style line endings +############################################################################### +* text eol=lf + +############################################################################### +# Set explicit file behavior to: +# treat as text and +# normalize to Unix-style line endings +############################################################################### +*.asm text eol=lf +*.c text eol=lf +*.clj text eol=lf +*.cmd text eol=lf +*.cpp text eol=lf +*.css text eol=lf +*.cxx text eol=lf +*.config text eol=lf +*.DotSettings text eol=lf +*.erl text eol=lf +*.fs text eol=lf +*.fsx text eol=lf +*.h text eol=lf +*.htm text eol=lf +*.html text eol=lf +*.hs text eol=lf +*.hxx text eol=lf +*.java text eol=lf +*.js text eol=lf +*.json text eol=lf +*.less text eol=lf +*.lisp text eol=lf +*.lua text eol=lf +*.m text eol=lf +*.md text eol=lf +*.php text eol=lf +*.props text eol=lf +*.ps1 text eol=lf +*.py text eol=lf +*.rb text eol=lf +*.resx text eol=lf +*.runsettings text eol=lf +*.ruleset text eol=lf +*.sass text eol=lf +*.scss text eol=lf +*.sh text eol=lf +*.sql text eol=lf +*.svg text eol=lf +*.targets text eol=lf +*.tt text eol=crlf +*.ttinclude text eol=crlf +*.txt text eol=lf +*.vb text eol=lf +*.yml text eol=lf + +############################################################################### +# Set explicit file behavior to: +# treat as text +# normalize to Unix-style line endings and +# diff as csharp +############################################################################### +*.cs text eol=lf diff=csharp + +############################################################################### +# Set explicit file behavior to: +# treat as text +# normalize to Unix-style line endings and +# use a union merge when resoling conflicts +############################################################################### +*.csproj text eol=lf merge=union +*.dbproj text eol=lf merge=union +*.fsproj text eol=lf merge=union +*.ncrunchproject text eol=lf merge=union +*.vbproj text eol=lf merge=union + +############################################################################### +# Set explicit file behavior to: +# treat as text +# normalize to Windows-style line endings and +# use a union merge when resoling conflicts +############################################################################### +*.sln text eol=crlf merge=union + ############################################################################### # Set explicit file behavior to: # treat as binary ############################################################################### -*.snk binary +*.bmp binary +*.dll binary +*.exe binary +*.gif binary +*.jpg binary +*.png binary +*.ttf binary +*.snk binary + +############################################################################### +# Set explicit file behavior to: +# diff as plain text +############################################################################### +*.doc diff=astextplain +*.docx diff=astextplain +*.dot diff=astextplain +*.pdf diff=astextplain +*.pptx diff=astextplain +*.rtf diff=astextplain diff --git a/README.md b/README.md index d7f5896..da075aa 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,9 @@ It is designed to be installed as a [git submodule](https://blog.github.com/2016 This installation guide assumes that your solution conforms to the following structure: -``` txt +``` bash solution.sln readme.md -.gitattributes .gitignore +---> src + + @@ -65,32 +64,40 @@ If everything looks good, you can commit this change and you’ll have a **share ### Updating the Submodule. -Since the submodule is stored in a separate repository you may find at times updates have been made to the linting rules that require you to update your copy. The same command as above will allow you to do so: +Since the submodule is stored in a separate repository you may find at times updates have been made to the linting rules that require you to update your copy. The command below will allow you to do so: ``` bash git submodule update --init --recursive +git submodule foreach git pull origin master ``` ### Wiring up the Linting Tools -There are two tools contained within the submodule that will help to automatically promote and enforce coding standards and consistancy: - -- [EditorConfig](https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2017) +There are three tools contained within the submodule that will help to automatically promote and enforce coding standards and consistancy: +- [.gitattributes](https://git-scm.com/docs/gitattributes) +- [.editorconfig](https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2017) - [StyleCop Analyzers](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) -#### Editor Config +### Gitattributes +`.gitattributes` files are used to do things like specify separate merge strategies for individual files or directories in your project, tell Git how to diff non-text files, or have Git filter content before you check it into or out of Git. The default attributes are configured to safely allow cross platform development. + +>**Note: `.gitattributes` relies on a [physical file path hierarchy](https://git-scm.com/docs/gitattributes) to work so after installing or updating the submodule you need to copy the `.gitattributes` file to the solution root before adding to Visual Studio.** + +#### EditorConfig + +Settings in `.editorconfig` files enable you to maintain consistent coding styles and settings in a codebase, such as indent style, tab width, end of line characters, encoding, and more, regardless of the editor or IDE you use. For example, when coding in C#, if your codebase has a convention to prefer that indents always consist of five space characters, documents use UTF-8 encoding, and each line always ends with a CR/LF, you can configure an `.editorconfig` file to do that. -Settings in EditorConfig files enable you to maintain consistent coding styles and settings in a codebase, such as indent style, tab width, end of line characters, encoding, and more, regardless of the editor or IDE you use. For example, when coding in C#, if your codebase has a convention to prefer that indents always consist of five space characters, documents use UTF-8 encoding, and each line always ends with a CR/LF, you can configure an .editorconfig file to do that. +Adding an `.editorconfig` file to your project or codebase does not convert existing styles to the new ones. For example, if you have indents in your file that are formatted with tabs, and you add an `.editorconfig` file that indents with spaces, the indent characters are not automatically converted to spaces. However, any new lines of code are formatted according to the `.editorconfig` file. Additionally, if you format the document using Ctrl+K, Ctrl+E), the settings in the `.editorconfig` file are applied to existing lines of code. -Adding an EditorConfig file to your project or codebase does not convert existing styles to the new ones. For example, if you have indents in your file that are formatted with tabs, and you add an EditorConfig file that indents with spaces, the indent characters are not automatically converted to spaces. However, any new lines of code are formatted according to the EditorConfig file. Additionally, if you format the document (**Edit > Advanced > Format Document** or Ctrl+K, Ctrl+D), the settings in the EditorConfig file are applied to existing lines of code. +>**Note: `.editorconfig` relies on a [physical file path hierarchy](https://editorconfig.org/#file-location) to work so after installing or updating the submodule you need to copy the `.editorconfig` file to the solution root before adding to Visual Studio.** -To add an EditorConfig file to your solution open the solution in Visual Studio. Select the solution node and right-click. +To add an `.editorconfig` file to your solution open the solution in Visual Studio. Select the solution node and right-click. From the menu bar, choose **Project > Add Existing Item**, or press Shift+Alt+A. -The Add Existing Item dialog box opens. Use this to navigate to your new **standards** folder and select the .editorconfig file. +The Add Existing Item dialog box opens. Use this to navigate to your new **shared-infrastructure** folder and select the `.editorconfig` file. -An .editorconfig file appears in Solution Explorer, and it opens in the editor. +An `.editorconfig` file appears in Solution Explorer, and it opens in the editor. ![EditorConfig file in solution explorer.](images/editorconfig-in-solution-explorer.png) @@ -98,7 +105,7 @@ An .editorconfig file appears in Solution Explorer, and it opens in the editor. StyleCop Analyzers are Roslyn Analyzer that contain an implementation of the StyleCop rules using the .NET Compiler Platform. Where possible, code fixes are also provided to simplify the process of correcting violations. -StyleCopAnalyzers can be installed using the NuGet command line or the NuGet Package Manager in Visual Studio 2017. +StyleCopAnalyzers can be installed using the NuGet command line or the NuGet Package Manager in Visual Studio 2019. Install using the command line: @@ -110,14 +117,16 @@ Installing via the package manager: ![stylecop analyzers-via-nuget](images/stylecop-analyzers-via-nuget.png) -Once the Nuget package is installed you will should add the following configuration files to the **Solution Items** folder you created when installing the .editorconfig file so you can easily view the contents. +Once the Nuget package is installed you will should add the following configuration files to the **Solution Items** folder you created when installing the `.editorconfig` file so you can easily view the contents. - `SixLabors.ruleset` +- `SixLabors.Tests.ruleset` - `stylecop.json` These files tell StyleCop what rules to enforce and will have to be manually added to each project. **right-click > Edit [YOUR_PROJECT_NAME].csproj** ``` xml + ..\..\shared-infrastructure\SixLabors.ruleset diff --git a/SixLabors.Tests.ruleset b/SixLabors.Tests.ruleset new file mode 100644 index 0000000..04d97c5 --- /dev/null +++ b/SixLabors.Tests.ruleset @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SixLabors.ruleset b/SixLabors.ruleset index ced5c71..45fc548 100644 --- a/SixLabors.ruleset +++ b/SixLabors.ruleset @@ -5,16 +5,23 @@ - - + + - - + + + + + + + + + \ No newline at end of file