Skip to content

Commit 46d4e06

Browse files
authored
Merge pull request #636 from zvirja/enable-nullability
Add .NET 5 target and arrange nullability attributes
2 parents 0daeb85 + 4c488c3 commit 46d4e06

File tree

113 files changed

+642
-366
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+642
-366
lines changed

.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
root = true
22

3+
[*]
4+
trim_trailing_whitespace = true
5+
36
[*.{cs,fs,fsx}]
47
indent_size = 4
58
indent_style = space

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
language: csharp
22
dist: xenial
3-
dotnet: 2.1.502
3+
dotnet: 5.0.100
44
mono: none
5-
env: CONFIGURATION=Release FRAMEWORK=netcoreapp2.1
5+
env: CONFIGURATION=Release FRAMEWORK=net5.0
66

77
before_script:
88
- dotnet --info

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
### unreleased
2+
* [NEW] Add .NET 5 support
23

34
### 4.2.2 (Jun 2020)
45

Directory.Build.props

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<Project>
22

33
<!-- Contains global properties for all projects in the solution.
4-
These can be overridden in inner folders, if necessary.
4+
These can be overridden in inner folders, if necessary.
55
See more here https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2019 -->
6-
6+
77
<PropertyGroup>
88
<TargetIsNetFx Condition="$(TargetFramework.StartsWith('net4'))">true</TargetIsNetFx>
9+
<TargetIsNet5 Condition="'$(TargetFramework)' == 'net5.0'">true</TargetIsNet5>
910
<LangVersion>latest</LangVersion>
1011
</PropertyGroup>
1112

appveyor.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
os: Visual Studio 2017
1+
os: Visual Studio 2019
22
build: off
33

44
environment:
55
CONFIGURATION: Release
66

77
install:
8-
- set PATH=C:\Ruby22\bin;%PATH%
8+
- set PATH=C:\Ruby25\bin;%PATH%
99
- bundle install
1010

1111
before_test:

src/NSubstitute/Arg.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
using System.Linq.Expressions;
33
using NSubstitute.Core.Arguments;
44

5+
// Disable nullability for client API, so it does not affect clients.
6+
#nullable disable annotations
7+
58
namespace NSubstitute
69
{
710
/// <summary>
@@ -89,7 +92,7 @@ public static ref TDelegate InvokeDelegate<TDelegate>(params object[] arguments)
8992
/// </summary>
9093
public static ref T Do<T>(Action<T> useArgument)
9194
{
92-
return ref ArgumentMatcher.Enqueue<T>(new AnyArgumentMatcher(typeof(T)), x => useArgument((T) x));
95+
return ref ArgumentMatcher.Enqueue<T>(new AnyArgumentMatcher(typeof(T)), x => useArgument((T) x!));
9396
}
9497

9598
/// <summary>

src/NSubstitute/Callback.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
using NSubstitute.Callbacks;
44
using NSubstitute.Core;
55

6+
// Disable nullability for client API, so it does not affect clients.
7+
#nullable disable annotations
8+
69
namespace NSubstitute
710
{
811
/// <summary>
@@ -72,7 +75,8 @@ public static Callback AlwaysThrow<TException>(TException exception) where TExce
7275
return AlwaysThrow(info => exception);
7376
}
7477

75-
protected static Action<CallInfo> ToCallback<TException>(Func<CallInfo, TException> throwThis) where TException : Exception
78+
protected static Action<CallInfo> ToCallback<TException>(Func<CallInfo, TException> throwThis)
79+
where TException : notnull, Exception
7680
{
7781
return ci => { if (throwThis != null) throw throwThis(ci); };
7882
}
@@ -111,8 +115,7 @@ public void Call(CallInfo callInfo)
111115

112116
private void CallFromStack(CallInfo callInfo)
113117
{
114-
Action<CallInfo> callback;
115-
if (callbackQueue.TryDequeue(out callback))
118+
if (callbackQueue.TryDequeue(out var callback))
116119
{
117120
callback(callInfo);
118121
}

src/NSubstitute/Callbacks/ConfiguredCallback.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System;
22
using NSubstitute.Core;
33

4+
// Disable nullability for client API, so it does not affect clients.
5+
#nullable disable annotations
6+
47
namespace NSubstitute.Callbacks
58
{
69
public class ConfiguredCallback : EndCallbackChain

src/NSubstitute/Compatibility/CompatArg.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System;
22
using System.Linq.Expressions;
33

4+
// Disable nullability for client API, so it does not affect clients.
5+
#nullable disable annotations
6+
47
namespace NSubstitute.Compatibility
58
{
69
/// <summary>
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#if !SYSTEM_DIAGNOSTICS_CODEANALYSIS_NULLABILITY
2+
3+
// This was copied from https://github.com/dotnet/runtime/blob/39b9607807f29e48cae4652cd74735182b31182e/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
4+
// and updated to have the scope of the attributes be internal.
5+
namespace System.Diagnostics.CodeAnalysis
6+
{
7+
8+
/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
9+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
10+
internal sealed class AllowNullAttribute : Attribute { }
11+
12+
/// <summary>Specifies that null is disallowed as an input even if the corresponding type allows it.</summary>
13+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
14+
internal sealed class DisallowNullAttribute : Attribute { }
15+
16+
/// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>
17+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
18+
internal sealed class MaybeNullAttribute : Attribute { }
19+
20+
/// <summary>Specifies that an output will not be null even if the corresponding type allows it.</summary>
21+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
22+
internal sealed class NotNullAttribute : Attribute { }
23+
24+
/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter may be null even if the corresponding type disallows it.</summary>
25+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
26+
internal sealed class MaybeNullWhenAttribute : Attribute
27+
{
28+
/// <summary>Initializes the attribute with the specified return value condition.</summary>
29+
/// <param name="returnValue">
30+
/// The return value condition. If the method returns this value, the associated parameter may be null.
31+
/// </param>
32+
public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
33+
34+
/// <summary>Gets the return value condition.</summary>
35+
public bool ReturnValue { get; }
36+
}
37+
38+
/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter will not be null even if the corresponding type allows it.</summary>
39+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
40+
internal sealed class NotNullWhenAttribute : Attribute
41+
{
42+
/// <summary>Initializes the attribute with the specified return value condition.</summary>
43+
/// <param name="returnValue">
44+
/// The return value condition. If the method returns this value, the associated parameter will not be null.
45+
/// </param>
46+
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
47+
48+
/// <summary>Gets the return value condition.</summary>
49+
public bool ReturnValue { get; }
50+
}
51+
52+
/// <summary>Specifies that the output will be non-null if the named parameter is non-null.</summary>
53+
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
54+
internal sealed class NotNullIfNotNullAttribute : Attribute
55+
{
56+
/// <summary>Initializes the attribute with the associated parameter name.</summary>
57+
/// <param name="parameterName">
58+
/// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
59+
/// </param>
60+
public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
61+
62+
/// <summary>Gets the associated parameter name.</summary>
63+
public string ParameterName { get; }
64+
}
65+
66+
/// <summary>Applied to a method that will never return under any circumstance.</summary>
67+
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
68+
internal sealed class DoesNotReturnAttribute : Attribute { }
69+
70+
/// <summary>Specifies that the method will not return if the associated Boolean parameter is passed the specified value.</summary>
71+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
72+
internal sealed class DoesNotReturnIfAttribute : Attribute
73+
{
74+
/// <summary>Initializes the attribute with the specified parameter value.</summary>
75+
/// <param name="parameterValue">
76+
/// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to
77+
/// the associated parameter matches this value.
78+
/// </param>
79+
public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
80+
81+
/// <summary>Gets the condition parameter value.</summary>
82+
public bool ParameterValue { get; }
83+
}
84+
85+
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values.</summary>
86+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
87+
internal sealed class MemberNotNullAttribute : Attribute
88+
{
89+
/// <summary>Initializes the attribute with a field or property member.</summary>
90+
/// <param name="member">
91+
/// The field or property member that is promised to be not-null.
92+
/// </param>
93+
public MemberNotNullAttribute(string member) => Members = new[] { member };
94+
95+
/// <summary>Initializes the attribute with the list of field and property members.</summary>
96+
/// <param name="members">
97+
/// The list of field and property members that are promised to be not-null.
98+
/// </param>
99+
public MemberNotNullAttribute(params string[] members) => Members = members;
100+
101+
/// <summary>Gets field or property member names.</summary>
102+
public string[] Members { get; }
103+
}
104+
105+
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition.</summary>
106+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
107+
internal sealed class MemberNotNullWhenAttribute : Attribute
108+
{
109+
/// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
110+
/// <param name="returnValue">
111+
/// The return value condition. If the method returns this value, the associated parameter will not be null.
112+
/// </param>
113+
/// <param name="member">
114+
/// The field or property member that is promised to be not-null.
115+
/// </param>
116+
public MemberNotNullWhenAttribute(bool returnValue, string member)
117+
{
118+
ReturnValue = returnValue;
119+
Members = new[] { member };
120+
}
121+
122+
/// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
123+
/// <param name="returnValue">
124+
/// The return value condition. If the method returns this value, the associated parameter will not be null.
125+
/// </param>
126+
/// <param name="members">
127+
/// The list of field and property members that are promised to be not-null.
128+
/// </param>
129+
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
130+
{
131+
ReturnValue = returnValue;
132+
Members = members;
133+
}
134+
135+
/// <summary>Gets the return value condition.</summary>
136+
public bool ReturnValue { get; }
137+
138+
/// <summary>Gets field or property member names.</summary>
139+
public string[] Members { get; }
140+
}
141+
}
142+
#endif

0 commit comments

Comments
 (0)