Skip to content

Fixed Guard APIs CS8777 warnings #3296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Microsoft.Toolkit/Diagnostics/Attributes/DoesNotReturnAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#if !NETSTANDARD2_1

namespace System.Diagnostics.CodeAnalysis
{
/// <summary>
/// Applied to a method that will never return under any circumstance.
/// </summary>
/// <remarks>Internal copy of the .NET Standard 2.1 attribute.</remarks>
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
internal sealed class DoesNotReturnAttribute : Attribute
{
}
}

#endif
6 changes: 0 additions & 6 deletions Microsoft.Toolkit/Diagnostics/Attributes/NotNullAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ namespace System.Diagnostics.CodeAnalysis
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)]
internal sealed class NotNullAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="NotNullAttribute"/> class.
/// </summary>
public NotNullAttribute()
{
}
}
}

Expand Down

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions Microsoft.Toolkit/Diagnostics/Generated/ThrowHelper.Collection.tt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<#@include file="TypeInfo.ttinclude" #>
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.Extensions;

Expand All @@ -24,6 +25,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsEmpty{T}(T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsEmpty<T>(<#=item.Type#> <#=item.Name#>, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must be empty, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
Expand All @@ -33,6 +35,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size equal to {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
Expand All @@ -42,6 +45,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeNotEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeNotEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size not equal to {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
Expand All @@ -51,6 +55,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThan{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeGreaterThan<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size over {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
Expand All @@ -60,6 +65,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeGreaterThanOrEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeGreaterThanOrEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size of at least {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
Expand All @@ -69,6 +75,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThan{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeLessThan<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size less than {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
Expand All @@ -78,6 +85,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo{T}(T[],int,string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo<T>(<#=item.Type#> <#=item.Name#>, int size, string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size less than or equal to {size}, had a size of {<#=item.Name#>.<#=item.Size#>.ToAssertString()}");
Expand All @@ -87,6 +95,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeEqualTo{T}(T[],T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeEqualTo<T>(<#=item.Type#> source, <#=item.DestinationType#> destination, string name)
{
ThrowArgumentException(name, $"The source {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size equal to {destination.<#=item.Size#>.ToAssertString()} (the destination), had a size of {source.<#=item.Size#>.ToAssertString()}");
Expand All @@ -96,6 +105,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentException"/> when <see cref="Guard.HasSizeLessThanOrEqualTo{T}(T[],T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForHasSizeLessThanOrEqualTo<T>(<#=item.Type#> source, <#=item.DestinationType#> destination, string name)
{
ThrowArgumentException(name, $"The source {name.ToAssertString()} ({typeof(<#=item.Type#>).ToTypeString()}) must have a size less than or equal to {destination.<#=item.Size#>.ToAssertString()} (the destination), had a size of {source.<#=item.Size#>.ToAssertString()}");
Expand All @@ -105,6 +115,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsInRangeFor{T}(int,T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsInRangeFor<T>(int index, <#=item.Type#> <#=item.Name#>, string name)
{
ThrowArgumentOutOfRangeException(name, $"Parameter {name.ToAssertString()} (int) must be in the range given by <0> and {<#=item.Name#>.<#=item.Size#>.ToAssertString()} to be a valid index for the target collection ({typeof(<#=item.Type#>).ToTypeString()}), was {index.ToAssertString()}");
Expand All @@ -114,6 +125,7 @@ GenerateTextForItems(EnumerableTypes, item =>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when <see cref="Guard.IsNotInRangeFor{T}(int,T[],string)"/> (or an overload) fails.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentOutOfRangeExceptionForIsNotInRangeFor<T>(int index, <#=item.Type#> <#=item.Name#>, string name)
{
ThrowArgumentOutOfRangeException(name, $"Parameter {name.ToAssertString()} (int) must not be in the range given by <0> and {<#=item.Name#>.<#=item.Size#>.ToAssertString()} to be an invalid index for the target collection ({typeof(<#=item.Type#>).ToTypeString()}), was {index.ToAssertString()}");
Expand Down
4 changes: 4 additions & 0 deletions Microsoft.Toolkit/Diagnostics/Guard.String.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ public static void IsNotNullOrEmpty([NotNull] string? text, string name)
{
ThrowHelper.ThrowArgumentExceptionForIsNotNullOrEmpty(text, name);
}
#pragma warning disable CS8777 // Does not return when text is null (.NET Standard 2.0 string.IsNullOrEmpty lacks flow attribute)
}
#pragma warning restore CS8777

/// <summary>
/// Asserts that the input <see cref="string"/> instance must be <see langword="null"/> or whitespace.
Expand Down Expand Up @@ -73,7 +75,9 @@ public static void IsNotNullOrWhitespace([NotNull] string? text, string name)
{
ThrowHelper.ThrowArgumentExceptionForIsNotNullOrWhitespace(text, name);
}
#pragma warning disable CS8777 // Does not return when text is null
}
#pragma warning restore CS8777

/// <summary>
/// Asserts that the input <see cref="string"/> instance must be empty.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.Extensions;

Expand All @@ -21,6 +22,7 @@ internal static partial class ThrowHelper
/// <typeparam name="T">The item of items in the input <see cref="Span{T}"/> instance.</typeparam>
/// <remarks>This method is needed because <see cref="Span{T}"/> can't be used as a generic type parameter.</remarks>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotEmptyWithSpan<T>(string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(Span<T>).ToTypeString()}) must not be empty");
Expand All @@ -32,6 +34,7 @@ public static void ThrowArgumentExceptionForIsNotEmptyWithSpan<T>(string name)
/// <typeparam name="T">The item of items in the input <see cref="ReadOnlySpan{T}"/> instance.</typeparam>
/// <remarks>This method is needed because <see cref="ReadOnlySpan{T}"/> can't be used as a generic type parameter.</remarks>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotEmptyWithReadOnlySpan<T>(string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(ReadOnlySpan<T>).ToTypeString()}) must not be empty");
Expand All @@ -42,6 +45,7 @@ public static void ThrowArgumentExceptionForIsNotEmptyWithReadOnlySpan<T>(string
/// </summary>
/// <typeparam name="T">The item of items in the input collection.</typeparam>
[MethodImpl(MethodImplOptions.NoInlining)]
[DoesNotReturn]
public static void ThrowArgumentExceptionForIsNotEmpty<T>(string name)
{
ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(T).ToTypeString()}) must not be empty");
Expand Down
Loading