Skip to content

Commit

Permalink
Merge pull request #123 from JohannesMoersch/AddNullableSupport
Browse files Browse the repository at this point in the history
Add nullable support
  • Loading branch information
RyanMarcotte authored Aug 8, 2021
2 parents d3edea5 + e6b4b86 commit da4b860
Show file tree
Hide file tree
Showing 23 changed files with 56 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Authors>Johannes Moersch + contributors</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>Copyright © 2020 Johannes Moersch</Copyright>
<Version>2.10.0</Version>
<Version>2.11.0</Version>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
<Description>This package depends on all other packages in the Functional suite.</Description>
<PackageTags>functional</PackageTags>
<IncludeBuildOutput>false</IncludeBuildOutput>
<AssemblyName>Functional.All</AssemblyName>
<PackageId>Functional.All.NetStandard2</PackageId>
<AssemblyName>Functional.All</AssemblyName>
<PackageId>Functional.All.NetStandard2</PackageId>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions Functional.All/Functional.All.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<Description>This package depends on all other packages in the Functional suite.</Description>
<PackageTags>functional</PackageTags>
<IncludeBuildOutput>false</IncludeBuildOutput>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
<Title>Functional.AsyncEnumerables.NetStandard2</Title>
<Description>This package contains a framework and extension methods for asynchronous enumerables.</Description>
<PackageTags>functional</PackageTags>
<AssemblyName>Functional.AsyncEnumerables</AssemblyName>
<PackageId>Functional.AsyncEnumerables.NetStandard2</PackageId>
<AssemblyName>Functional.AsyncEnumerables</AssemblyName>
<PackageId>Functional.AsyncEnumerables.NetStandard2</PackageId>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Title>Functional.AsyncEnumerables</Title>
<Description>This package contains a framework and extension methods for asynchronous enumerables.</Description>
<PackageTags>functional</PackageTags>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Title>Functional.Common.Extensions</Title>
<Description>This package contains extension methods for .NET types.</Description>
<PackageTags>functional</PackageTags>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Title>Functional.Enumerables.Extensions</Title>
<Description>This package contains extension methods for IEnumerable&lt;T&gt; and extension methods that add support for Task&lt;IEnumerable&lt;T&gt;&gt; to LINQ.</Description>
<PackageTags>functional</PackageTags>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
<Title>Functional.Primitives.AsyncEnumerables.NetStandard2</Title>
<Description>This package contains a extension methods for primitives and async enumerables.</Description>
<PackageTags>functional</PackageTags>
<AssemblyName>Functional.Primitives.AsyncEnumerables</AssemblyName>
<PackageId>Functional.Primitives.AsyncEnumerables.NetStandard2</PackageId>
<AssemblyName>Functional.Primitives.AsyncEnumerables</AssemblyName>
<PackageId>Functional.Primitives.AsyncEnumerables.NetStandard2</PackageId>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Title>Functional.Primitives.AsyncEnumerables</Title>
<Description>This package contains a extension methods for primitives and async enumerables.</Description>
<PackageTags>functional</PackageTags>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Title>Functional.Primitives.Extensions</Title>
<Description>This package contains a suite of extension methods for working with Option and Result types.</Description>
<PackageTags>functional</PackageTags>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Functional.Primitives\Functional.Primitives.csproj" />
Expand Down
1 change: 1 addition & 0 deletions Functional.Primitives/Functional.Primitives.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Title>Functional.Primitives</Title>
<Description>This package contains allocation free Option and Result discriminated union types and associated factory methods.</Description>
<PackageTags>functional</PackageTags>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
4 changes: 4 additions & 0 deletions Functional.Primitives/Option.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ internal Option(bool hasValue, TValue value)
_value = value;
}

#pragma warning disable CS8618, CS8601 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. Possible null reference assignment.
private Option(SerializationInfo info, StreamingContext context)
{
_hasValue = info.GetBoolean(nameof(_hasValue));
Expand All @@ -28,6 +29,7 @@ private Option(SerializationInfo info, StreamingContext context)
else
_value = default;
}
#pragma warning restore CS8618, CS8601 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. Possible null reference assignment.

[AllowAllocations]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
Expand All @@ -51,8 +53,10 @@ public TResult Match<TResult>(Func<TValue, TResult> some, Func<TResult> none)
public bool Equals(Option<TValue> other)
=> _hasValue == other._hasValue && (!_hasValue || EqualityComparer<TValue>.Default.Equals(_value, other._value));

#pragma warning disable CS8602 // Dereference of a possibly null reference.
public override int GetHashCode()
=> _hasValue ? _value.GetHashCode() * 31 : 0;
#pragma warning restore CS8602 // Dereference of a possibly null reference.

public override bool Equals(object obj)
=> obj is Option<TValue> option && Equals(option);
Expand Down
8 changes: 5 additions & 3 deletions Functional.Primitives/OptionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,23 @@ public static async Task<Option<T>> SomeAsync<T>(Task<T> value)
=> Some(await value);

public static Option<T> None<T>()
#pragma warning disable CS8604 // Possible null reference argument.
=> new Option<T>(false, default);
#pragma warning restore CS8604 // Possible null reference argument.

public static Option<T> FromNullable<T>(T value)
public static Option<T> FromNullable<T>(T? value)
where T : class
=> value != null
? Some(value)
: None<T>();

[Obsolete("Please use .FromNullableAsync() instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public static Task<Option<T>> FromNullable<T>(Task<T> value)
public static Task<Option<T>> FromNullable<T>(Task<T?> value)
where T : class
=> FromNullableAsync(value);

public static async Task<Option<T>> FromNullableAsync<T>(Task<T> value)
public static async Task<Option<T>> FromNullableAsync<T>(Task<T?> value)
where T : class
=> FromNullable(await value);

Expand Down
4 changes: 4 additions & 0 deletions Functional.Primitives/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal Result(bool isSuccess, TSuccess success, TFailure failure)
_failure = failure;
}

#pragma warning disable CS8618, CS8601 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. Possible null reference assignment.
private Result(SerializationInfo info, StreamingContext context)
{
var isSuccess = info.GetBoolean(nameof(_isSuccess));
Expand All @@ -39,6 +40,7 @@ private Result(SerializationInfo info, StreamingContext context)
_failure = (TFailure)info.GetValue(nameof(_failure), typeof(TFailure));
}
}
#pragma warning restore CS8618, CS8601 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. Possible null reference assignment.

[AllowAllocations]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
Expand Down Expand Up @@ -70,8 +72,10 @@ public bool Equals(Result<TSuccess, TFailure> other)
=> IsSuccess() == other.IsSuccess()
&& (IsSuccess() ? EqualityComparer<TSuccess>.Default.Equals(_success, other._success) : EqualityComparer<TFailure>.Default.Equals(_failure, other._failure));

#pragma warning disable CS8602 // Dereference of a possibly null reference.
public override int GetHashCode()
=> IsSuccess() ? _success.GetHashCode() * 31 : _failure.GetHashCode() * 31;
#pragma warning restore CS8602 // Dereference of a possibly null reference.

public override bool Equals(object obj)
=> obj is Result<TSuccess, TFailure> result && Equals(result);
Expand Down
4 changes: 4 additions & 0 deletions Functional.Primitives/ResultFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public static Result<TSuccess, TFailure> Success<TSuccess, TFailure>(TSuccess su
if (success == null)
throw new ArgumentNullException(nameof(success));

#pragma warning disable CS8604 // Possible null reference argument.
return new Result<TSuccess, TFailure>(true, success, default);
#pragma warning restore CS8604 // Possible null reference argument.
}

[Obsolete("Please use .SuccessAsync() instead.")]
Expand All @@ -30,7 +32,9 @@ public static Result<TSuccess, TFailure> Failure<TSuccess, TFailure>(TFailure fa
if (failure == null)
throw new ArgumentNullException(nameof(failure));

#pragma warning disable CS8604 // Possible null reference argument.
return new Result<TSuccess, TFailure>(false, default, failure);
#pragma warning restore CS8604 // Possible null reference argument.
}

[Obsolete("Please use .FailureAsync() instead.")]
Expand Down
1 change: 1 addition & 0 deletions Functional.Tests/AllocationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ private static bool ContainsAllowAllocations(IEnumerable<Attribute> attributes)
private static IEnumerable<ParsedMethodBody> GetMethodBodiesInAssembly(Assembly assembly)
=> assembly
.GetTypes()
.Where(t => t.FullName != "System.Runtime.CompilerServices.NullableAttribute")
.SelectMany(GetMethodBodiesFromType);

private static IEnumerable<ParsedMethodBody> GetMethodBodiesFromType(Type type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
<Title>Functional.Unions.AsyncEnumerables.NetStandard2</Title>
<Description>This package contains a extension methods for unions and async enumerables.</Description>
<PackageTags>functional</PackageTags>
<AssemblyName>Functional.Unions.AsyncEnumerables</AssemblyName>
<PackageId>Functional.Unions.AsyncEnumerables.NetStandard2</PackageId>
<AssemblyName>Functional.Unions.AsyncEnumerables</AssemblyName>
<PackageId>Functional.Unions.AsyncEnumerables.NetStandard2</PackageId>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Title>Functional.Unions.AsyncEnumerables</Title>
<Description>This package contains a extension methods for unions and async enumerables.</Description>
<PackageTags>functional</PackageTags>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public ValueTask DisposeAsync()
_complete = true;
}

#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type.
return (false, default);
#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type.
}
}

Expand All @@ -48,8 +50,10 @@ internal class ReplayableAsyncEnumerator<T> : IAsyncEnumerator<T>

private int _index = 0;

#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public ReplayableAsyncEnumerator(ReplayableAsyncEnumerableData<T> data)
=> _data = data;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

public ValueTask DisposeAsync()
=> _data.DisposeAsync();
Expand All @@ -63,7 +67,9 @@ public async ValueTask<bool> MoveNextAsync()
return true;
}

#pragma warning disable CS8601 // Possible null reference assignment.
Current = default;
#pragma warning restore CS8601 // Possible null reference assignment.
return false;
}

Expand Down
8 changes: 7 additions & 1 deletion Functional.Unions.AsyncEnumerables/ReplayableEnumerable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public bool TryGetValue(int index, out T value)
_complete = true;
}

#pragma warning disable CS8601 // Possible null reference assignment.
value = default;
#pragma warning restore CS8601 // Possible null reference assignment.
return false;
}
}
Expand All @@ -45,14 +47,16 @@ internal class ReplayableEnumerator<T> : IEnumerator<T>
{
public T Current { get; private set; }

object IEnumerator.Current => Current;
object? IEnumerator.Current => Current;

private readonly ReplayableEnumerableData<T> _data;

private int _index = 0;

#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public ReplayableEnumerator(ReplayableEnumerableData<T> data)
=> _data = data;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

public void Dispose() { }

Expand All @@ -64,7 +68,9 @@ public bool MoveNext()
return true;
}

#pragma warning disable CS8601 // Possible null reference assignment.
Current = default;
#pragma warning restore CS8601 // Possible null reference assignment.
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Functional
[EditorBrowsable(EditorBrowsableState.Never)]
public static class UnionEnumerableWhereExtensions
{
#pragma warning disable CS8603 // Possible null reference return.
public static IEnumerable<TOne> WhereOne<TUnionType, TUnionDefinition, TOne>(this IEnumerable<IUnionValue<UnionDefinitionBase<TUnionType, TUnionDefinition, TOne>>> source)
where TUnionType : struct
where TUnionDefinition : UnionDefinitionBase<TUnionType, TUnionDefinition, TOne>
Expand Down Expand Up @@ -369,5 +370,6 @@ public static IAsyncEnumerable<TEight> WhereEight<TUnionType, TUnionDefinition,
where TUnionType : struct
where TUnionDefinition : UnionDefinitionBase<TUnionType, TUnionDefinition, TOne, TTwo, TThree, TFour, TFive, TSix, TSeven, TEight>
=> source.Where(union => union.Match(_ => false, _ => false, _ => false, _ => false, _ => false, _ => false, _ => false, _ => true)).Select(union => union.Match(_ => default, _ => default, _ => default, _ => default, _ => default, _ => default, _ => default, _ => _));
#pragma warning restore CS8603 // Possible null reference return.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Title>Functional.Unions.Extensions</Title>
<Description>This package contains extension methods for working with Union types.</Description>
<PackageTags>functional</PackageTags>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions Functional.Unions/Functional.Unions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Title>Functional.Unions</Title>
<Description>This package contains discriminated union types for arbitrary unions of 2 to 8 types and associated factory methods.</Description>
<PackageTags>functional</PackageTags>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

0 comments on commit da4b860

Please sign in to comment.