Skip to content

Commit

Permalink
Merge pull request #768 from polyadic/primary-constructor
Browse files Browse the repository at this point in the history
Use Primary Constructors
  • Loading branch information
bash authored Nov 29, 2023
2 parents 24c536c + 6b07623 commit e627042
Show file tree
Hide file tree
Showing 34 changed files with 139 additions and 335 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,42 +43,27 @@ private static IdentifierNameSyntax DiagnosticIdToMethodName(string diagnosticId
_ => throw new NotSupportedException("Internal error: This branch should be unreachable"),
};

private sealed class GetOrElseCodeFixAction : CodeAction
private sealed class GetOrElseCodeFixAction(
Document document,
InvocationExpressionSyntax invocationExpression,
MemberAccessExpressionSyntax memberAccessExpression,
int errorStateArgumentIndex,
IdentifierNameSyntax methodName) : CodeAction
{
private readonly Document _document;
private readonly InvocationExpressionSyntax _invocationExpression;
private readonly MemberAccessExpressionSyntax _memberAccessExpression;
private readonly int _errorStateArgumentIndex;
private readonly IdentifierNameSyntax _methodName;

public GetOrElseCodeFixAction(
Document document,
InvocationExpressionSyntax invocationExpression,
MemberAccessExpressionSyntax memberAccessExpression,
int errorStateArgumentIndex,
IdentifierNameSyntax methodName)
{
_document = document;
_invocationExpression = invocationExpression;
_memberAccessExpression = memberAccessExpression;
_errorStateArgumentIndex = errorStateArgumentIndex;
_methodName = methodName;
}

public override string Title => $"Replace {MatchMethodName} with {_methodName.Identifier}";
public override string Title => $"Replace {MatchMethodName} with {methodName.Identifier}";

public override string? EquivalenceKey => nameof(MatchToOrElseCodeFix);

protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
{
var editor = await DocumentEditor.CreateAsync(_document, cancellationToken).ConfigureAwait(false);
var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

editor.ReplaceNode(
_invocationExpression,
_invocationExpression.WithExpression(_memberAccessExpression
.WithName(_methodName))
invocationExpression,
invocationExpression.WithExpression(memberAccessExpression
.WithName(methodName))
.WithArgumentList(ArgumentList(SingletonSeparatedList(
Argument(_invocationExpression.ArgumentList.Arguments[_errorStateArgumentIndex].Expression)))));
Argument(invocationExpression.ArgumentList.Arguments[errorStateArgumentIndex].Expression)))));

return editor.GetChangedDocument();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,20 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
private static Diagnostic GetDiagnostic(CodeFixContext context)
=> context.Diagnostics.First();

private sealed class ToEnumerableEmptyCodeAction : CodeAction
private sealed class ToEnumerableEmptyCodeAction(
Document document,
InvocationExpressionSyntax invocationExpression,
int valueParameterIndex) : CodeAction
{
private readonly Document _document;
private readonly InvocationExpressionSyntax _invocationExpression;
private readonly int _valueParameterIndex;

public ToEnumerableEmptyCodeAction(Document document, InvocationExpressionSyntax invocationExpression, int valueParameterIndex)
{
_document = document;
_invocationExpression = invocationExpression;
_valueParameterIndex = valueParameterIndex;
}

public override string Title => EnumerableRepeatNeverCodeFixTitle;

public override string EquivalenceKey => nameof(ToEnumerableEmptyCodeAction);

protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
{
var editor = await DocumentEditor.CreateAsync(_document, cancellationToken).ConfigureAwait(false);
var valueParameter = _invocationExpression.ArgumentList.Arguments[_valueParameterIndex];
editor.ReplaceNode(_invocationExpression, CreateEnumerableReturnRoot(valueParameter, editor.SemanticModel, editor.Generator));
var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
var valueParameter = invocationExpression.ArgumentList.Arguments[valueParameterIndex];
editor.ReplaceNode(invocationExpression, CreateEnumerableReturnRoot(valueParameter, editor.SemanticModel, editor.Generator));
return editor.GetChangedDocument();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,17 @@

namespace Funcky.Analyzers;

internal sealed class ReplaceParameterReferenceRewriter : CSharpSyntaxRewriter
internal sealed class ReplaceParameterReferenceRewriter(
SemanticModel semanticModel,
string parameterName,
ExpressionSyntax replacement)
: CSharpSyntaxRewriter(visitIntoStructuredTrivia: false)
{
private readonly SemanticModel _semanticModel;
private readonly string _parameterName;
private readonly ExpressionSyntax _replacement;

public ReplaceParameterReferenceRewriter(SemanticModel semanticModel, string parameterName, ExpressionSyntax replacement)
: base(visitIntoStructuredTrivia: false)
{
_semanticModel = semanticModel;
_parameterName = parameterName;
_replacement = replacement;
}

public override SyntaxNode? VisitIdentifierName(IdentifierNameSyntax node)
{
if (_semanticModel.GetOperation(node) is IParameterReferenceOperation { Parameter.Name: var name } && name == _parameterName)
if (semanticModel.GetOperation(node) is IParameterReferenceOperation { Parameter.Name: var name } && name == parameterName)
{
return _replacement.WithTriviaFrom(node);
return replacement.WithTriviaFrom(node);
}

return node;
Expand Down
13 changes: 2 additions & 11 deletions Funcky.Async.Test/TestUtilities/OptionProducer.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
namespace Funcky.Async.Test.TestUtilities;

internal sealed class OptionProducer<T>
internal sealed class OptionProducer<T>(int retriesNeeded, T result)
where T : notnull
{
private readonly T _result;
private readonly int _retriesNeeded;

public OptionProducer(int retriesNeeded, T result)
{
_retriesNeeded = retriesNeeded;
_result = result;
}

public int Called { get; private set; }

public ValueTask<Option<T>> ProduceAsync()
{
Called += 1;

return ValueTask.FromResult(Option.FromBoolean(_retriesNeeded == (Called - 1), _result));
return ValueTask.FromResult(Option.FromBoolean(retriesNeeded == (Called - 1), result));
}
}
14 changes: 5 additions & 9 deletions Funcky.Async/AsyncSequence/AsyncSequence.CycleRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,13 @@ public static AsyncCycleBuffer<TSource> Create<TSource>(IAsyncEnumerable<TSource
=> new(source, maxCycles);
}

private sealed class AsyncCycleBuffer<T> : IAsyncBuffer<T>
private sealed class AsyncCycleBuffer<T>(IAsyncEnumerable<T> source, Option<int> maxCycles = default) : IAsyncBuffer<T>
{
private readonly List<T> _buffer = new();
private readonly IAsyncEnumerator<T> _source;
private readonly Option<int> _maxCycles;
private readonly IAsyncEnumerator<T> _source = source.GetAsyncEnumerator();

private bool _disposed;

public AsyncCycleBuffer(IAsyncEnumerable<T> source, Option<int> maxCycles = default)
=> (_source, _maxCycles) = (source.GetAsyncEnumerator(), maxCycles);

public async ValueTask DisposeAsync()
{
if (!_disposed)
Expand Down Expand Up @@ -74,7 +70,7 @@ private async IAsyncEnumerator<T> GetEnumeratorInternal()

if (_buffer.Count is 0)
{
if (_maxCycles.Match(none: true, some: False))
if (maxCycles.Match(none: true, some: False))
{
throw new InvalidOperationException("you cannot cycle an empty enumerable");
}
Expand All @@ -99,10 +95,10 @@ private async IAsyncEnumerator<T> GetEnumeratorInternal()
}

private bool HasNoCycles()
=> _maxCycles.Match(none: false, some: maxCycles => maxCycles is 0);
=> maxCycles.Match(none: false, some: maxCycles => maxCycles is 0);

private bool IsCycling(int cycle)
=> _maxCycles.Match(
=> maxCycles.Match(
none: true,
some: maxCycles => cycle < maxCycles);

Expand Down
14 changes: 4 additions & 10 deletions Funcky.Async/Extensions/AsyncEnumerableExtensions/Memoize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,14 @@ public static MemoizedAsyncBuffer<TSource> Create<TSource>(IAsyncEnumerable<TSou
=> new(source);
}

private sealed class BorrowedAsyncBuffer<T> : IAsyncBuffer<T>
private sealed class BorrowedAsyncBuffer<T>(IAsyncBuffer<T> inner) : IAsyncBuffer<T>
{
private readonly IAsyncBuffer<T> _inner;
private bool _disposed;

public BorrowedAsyncBuffer(IAsyncBuffer<T> inner) => _inner = inner;

public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
ThrowIfDisposed();
return _inner.GetAsyncEnumerator(cancellationToken);
return inner.GetAsyncEnumerator(cancellationToken);
}

public ValueTask DisposeAsync()
Expand All @@ -52,16 +49,13 @@ private void ThrowIfDisposed()
}
}

private sealed class MemoizedAsyncBuffer<T> : IAsyncBuffer<T>
private sealed class MemoizedAsyncBuffer<T>(IAsyncEnumerable<T> source) : IAsyncBuffer<T>
{
private readonly List<T> _buffer = new();
private readonly IAsyncEnumerator<T> _source;
private readonly IAsyncEnumerator<T> _source = source.GetAsyncEnumerator();

private bool _disposed;

public MemoizedAsyncBuffer(IAsyncEnumerable<T> source)
=> _source = source.GetAsyncEnumerator();

public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
ThrowIfDisposed();
Expand Down
9 changes: 3 additions & 6 deletions Funcky.Async/Extensions/AsyncEnumerableExtensions/Sequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,10 @@ private static async ValueTask<UnsafeEither<TLeft, IReadOnlyList<TRight>>> Trave
return UnsafeEither<TLeft, IReadOnlyList<TRight>>.Right(builder.ToImmutable());
}

private sealed class SequenceLazyInternal<[DynamicallyAccessedMembers(PublicParameterlessConstructor)] TSource>
private sealed class SequenceLazyInternal<[DynamicallyAccessedMembers(PublicParameterlessConstructor)] TSource>(
IAsyncEnumerable<Lazy<TSource>> source)
{
private readonly IAsyncEnumerable<Lazy<TSource>> _source;

public SequenceLazyInternal(IAsyncEnumerable<Lazy<TSource>> source) => _source = source;

// Workaround for https://github.com/dotnet/linker/issues/1416
public IAsyncEnumerable<TSource> Invoke() => _source.Select(lazy => lazy.Value);
public IAsyncEnumerable<TSource> Invoke() => source.Select(lazy => lazy.Value);
}
}
7 changes: 2 additions & 5 deletions Funcky.Test.Internal/Data/Person.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
namespace Funcky.Test.Internal.Data;

public sealed class Person : IComparable<Person>, IEquatable<Person>
public sealed class Person(int age) : IComparable<Person>, IEquatable<Person>
{
public Person(int age)
=> Age = age;

public int Age { get; }
public int Age { get; } = age;

public int CompareTo(Person? other)
=> other != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,17 @@

namespace Funcky.Test.Extensions.EnumerableExtensions;

internal sealed class FailOnEnumerationList : IList<int>
internal sealed class FailOnEnumerationList(int length) : IList<int>
{
private readonly int _length;

public FailOnEnumerationList(int length)
=> _length = length;

public int Count
=> _length;
=> length;

public bool IsReadOnly
=> true;

public int this[int index]
{
get => index >= 0 && index < _length ? index : throw new IndexOutOfRangeException();
get => index >= 0 && index < length ? index : throw new IndexOutOfRangeException();
set => throw new NotSupportedException();
}

Expand Down
5 changes: 1 addition & 4 deletions Funcky.Test/Extensions/SideEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ namespace Funcky.Test.Extensions;

internal sealed class SideEffect
{
private string _string;

public SideEffect()
=> _string = string.Empty;
private string _string = string.Empty;

public void Store(string s)
=> _string = s;
Expand Down
11 changes: 2 additions & 9 deletions Funcky.Test/Extensions/StringExtensions/IndexOfTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Funcky.Test.Extensions.StringExtensions;

public sealed class IndexOfTest
public sealed class IndexOfTest(ITestOutputHelper testOutputHelper)
{
private const int NumberOfThisParametersInExtensionMethods = 1;

Expand All @@ -14,13 +14,6 @@ public sealed class IndexOfTest
private const char ExistingNeedleChar = 'y';
private const int NeedlePosition = 2;

private readonly ITestOutputHelper _testOutputHelper;

public IndexOfTest(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}

[Theory]
[MemberData(nameof(InvalidIndexes))]
public void ReturnsNoneIfNeedleIsNotFound(Option<int> index)
Expand Down Expand Up @@ -117,7 +110,7 @@ public void AllOverloadsOfIndexOfAreSupported()
private static IEnumerable<MethodInfo> GetIndexOfMethods()
=> typeof(string).GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(IsIndexOfMethod);

private void WriteToTestOutput(object value) => _testOutputHelper.WriteLine(value.ToString());
private void WriteToTestOutput(object value) => testOutputHelper.WriteLine(value.ToString());

private static Option<MethodInfo> GetMatchingExtensionMethod(MethodInfo originalMethod)
{
Expand Down
8 changes: 2 additions & 6 deletions Funcky.Test/Monads/OptionEqualityComparerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,9 @@ private sealed class ThrowingEqualityComparer<T> : EqualityComparer<T>
public override int GetHashCode(T obj) => throw new NotSupportedException();
}

private sealed class ConstantEqualityComparer<T> : EqualityComparer<T>
private sealed class ConstantEqualityComparer<T>(bool areEqual) : EqualityComparer<T>
{
private readonly bool _areEqual;

public ConstantEqualityComparer(bool areEqual) => _areEqual = areEqual;

public override bool Equals(T? x, T? y) => _areEqual;
public override bool Equals(T? x, T? y) => areEqual;

public override int GetHashCode(T obj) => throw new NotSupportedException();
}
Expand Down
13 changes: 2 additions & 11 deletions Funcky.Test/TestUtils/OptionProducer.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
namespace Funcky.Test.TestUtils;

internal sealed class OptionProducer<T>
internal sealed class OptionProducer<T>(int retriesNeeded, T result)
where T : notnull
{
private readonly T _result;
private readonly int _retriesNeeded;

public OptionProducer(int retriesNeeded, T result)
{
_retriesNeeded = retriesNeeded;
_result = result;
}

public int Called { get; private set; }

public Option<T> Produce()
{
Called += 1;

return Option.FromBoolean(_retriesNeeded == (Called - 1), _result);
return Option.FromBoolean(retriesNeeded == (Called - 1), result);
}
}
Loading

0 comments on commit e627042

Please sign in to comment.