Skip to content

Commit

Permalink
Merge pull request #774 from polyadic/use-polysharp
Browse files Browse the repository at this point in the history
Use  PolySharp
  • Loading branch information
FreeApophis authored Dec 5, 2023
2 parents 0cf0448 + b1e3572 commit a1abd3f
Show file tree
Hide file tree
Showing 22 changed files with 52 additions and 76 deletions.
5 changes: 2 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
<PackageVersion Include="System.Linq.Async" Version="[5.0.0, 7)" />
</ItemGroup>
<ItemGroup Label="Build Dependencies">
<PackageVersion Include="IsExternalInit" Version="1.0.2" />
<PackageVersion Include="Messerli.CodeStyle" Version="2.2.0" />
<PackageVersion Include="PolySharp" Version="1.14.0" />
<PackageVersion Include="Messerli.CodeStyle" Version="2.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.3" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<PackageVersion Include="Nullable" Version="1.3.0" />
</ItemGroup>
<ItemGroup Label="Test Dependencies">
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
<PackageReference Include="PolySharp" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
<PackageReference Include="Nullable" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,17 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
private static bool IsWhereInvocation(SyntaxNode syntax, SemanticModel semanticModel, Symbols symbols, [NotNullWhen(true)] out IInvocationOperation? whereInvocation)
{
whereInvocation = null;
return semanticModel.GetOperation(syntax) is IInvocationOperation operation
&& operation.TargetMethod.Name == WhereMethodName
&& SymbolEqualityComparer.Default.Equals(symbols.GenericOptionType, operation.TargetMethod.ContainingType.ConstructedFrom)
&& (whereInvocation = operation) is var _;
return semanticModel.GetOperation(syntax) is IInvocationOperation { TargetMethod.Name: WhereMethodName } operation
&& SymbolEqualityComparer.Default.Equals(symbols.GenericOptionType, operation.TargetMethod.ContainingType.ConstructedFrom)
&& (whereInvocation = operation) is var _;
}

private static bool IsOptionReturnInvocation(IOperation? candidate, Symbols symbols, [NotNullWhen(true)] out IInvocationOperation? returnInvocationOperation)
{
returnInvocationOperation = null;
return candidate is IInvocationOperation operation
&& operation.TargetMethod.Name is MonadReturnMethodName or OptionSomeMethodName
&& SymbolEqualityComparer.Default.Equals(symbols.OptionType, operation.TargetMethod.ContainingType)
&& (returnInvocationOperation = operation) is var _;
return candidate is IInvocationOperation { TargetMethod.Name: MonadReturnMethodName or OptionSomeMethodName } operation
&& SymbolEqualityComparer.Default.Equals(symbols.OptionType, operation.TargetMethod.ContainingType)
&& (returnInvocationOperation = operation) is var _;
}

private static ApplyPredicate? TryGetPredicateApplier(InvocationExpressionSyntax whereInvocation, SemanticModel semanticModel)
Expand All @@ -82,19 +80,19 @@ LambdaExpressionSyntax lambda when
=> lambda switch
{
SimpleLambdaExpressionSyntax { Parameter: var parameter } => parameter,
ParenthesizedLambdaExpressionSyntax { ParameterList.Parameters: { Count: 1 } parameters } => parameters.Single(),
ParenthesizedLambdaExpressionSyntax { ParameterList.Parameters: [var parameter] } => parameter,
_ => null,
};

private static ExpressionSyntax? TryGetLambdaExpression(LambdaExpressionSyntax lambda)
=> lambda switch
{
{ ExpressionBody: { } expressionBody } => expressionBody,
{ Block.Statements: { Count: 1 } statements } when statements.Single() is ReturnStatementSyntax { Expression: var returnExpression } => returnExpression,
{ Block.Statements: [ReturnStatementSyntax { Expression: var returnExpression }] } => returnExpression,
_ => null,
};

private Func<CancellationToken, Task<Document>> ReplaceWithOptionFromBoolean(Document document, Symbols symbols, ApplyPredicate applyPredicate, InvocationExpressionSyntax whereInvocation, InvocationExpressionSyntax returnInvocation)
private static Func<CancellationToken, Task<Document>> ReplaceWithOptionFromBoolean(Document document, Symbols symbols, ApplyPredicate applyPredicate, InvocationExpressionSyntax whereInvocation, InvocationExpressionSyntax returnInvocation)
=> async cancellationToken =>
{
var editor = await DocumentEditor.CreateAsync(document, cancellationToken);
Expand All @@ -112,7 +110,7 @@ private Func<CancellationToken, Task<Document>> ReplaceWithOptionFromBoolean(Doc
return editor.GetChangedDocument();
};

private InvocationExpressionSyntax CreateFromBooleanInvocation(
private static InvocationExpressionSyntax CreateFromBooleanInvocation(
InvocationExpressionSyntax returnInvocation,
Symbols symbols,
SyntaxGenerator generator,
Expand All @@ -127,12 +125,12 @@ private InvocationExpressionSyntax CreateFromBooleanInvocation(
ArgumentList(SeparatedList(new[] { Argument(condition), Argument(returnValue) })))
.WithLeadingTrivia(returnInvocation.GetLeadingTrivia());

private SimpleNameSyntax GetFromBooleanName(InvocationExpressionSyntax returnInvocation)
private static SimpleNameSyntax GetFromBooleanName(InvocationExpressionSyntax returnInvocation)
=> GetMethodName(returnInvocation) is GenericNameSyntax genericNameSyntax
? genericNameSyntax.WithIdentifier(Identifier(OptionFromBooleanMethodName))
: IdentifierName(OptionFromBooleanMethodName);

private SimpleNameSyntax GetMethodName(InvocationExpressionSyntax invocationExpressionSyntax)
private static SimpleNameSyntax GetMethodName(InvocationExpressionSyntax invocationExpressionSyntax)
=> invocationExpressionSyntax.Expression switch
{
SimpleNameSyntax simpleNameSyntax => simpleNameSyntax,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,10 @@ internal sealed class ReplaceParameterReferenceRewriter(
ExpressionSyntax replacement)
: CSharpSyntaxRewriter(visitIntoStructuredTrivia: false)
{
public override SyntaxNode? VisitIdentifierName(IdentifierNameSyntax node)
{
if (semanticModel.GetOperation(node) is IParameterReferenceOperation { Parameter.Name: var name } && name == parameterName)
{
return replacement.WithTriviaFrom(node);
}

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

internal static partial class SyntaxNodeExtensions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ private static bool IsGetOrElseEquivalent(INamedTypeSymbol receiverType, IArgume
private static ITypeSymbol? GetTypeOrDelegateReturnType(IOperation operation)
=> operation switch
{
IDelegateCreationOperation { Target: IAnonymousFunctionOperation { Body.Operations: { Length: 1 } operations } } when operations[0] is IReturnOperation returnOperation => returnOperation.ReturnedValue?.Type,
IDelegateCreationOperation { Target: IAnonymousFunctionOperation { Body.Operations: [IReturnOperation returnOperation] } } => returnOperation.ReturnedValue?.Type,
IDelegateCreationOperation { Target: IAnonymousFunctionOperation { Symbol.ReturnType: var returnType } } => returnType,
IDelegateCreationOperation { Target: IMethodReferenceOperation { Method.ReturnType: var returnType } } => returnType,
_ => operation.Type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,9 @@ private static bool IsMatchInvocation(
{
matchReceiverType = null;
alternativeMonadType = null;
return invocation.TargetMethod.ReceiverType is INamedTypeSymbol receiverType
&& invocation.TargetMethod.Name == MatchMethodName
&& invocation.Arguments.Length == 2
&& alternativeMonadTypes.Value.TryGetValue(receiverType.ConstructedFrom, out alternativeMonadType)
&& (matchReceiverType = receiverType) is var _;
return invocation is { TargetMethod: { ReceiverType: INamedTypeSymbol receiverType, Name: MatchMethodName }, Arguments: [_, _] }
&& alternativeMonadTypes.Value.TryGetValue(receiverType.ConstructedFrom, out alternativeMonadType)
&& (matchReceiverType = receiverType) is var _;
}

private static Diagnostic? AnalyzeMatchInvocation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@ public static bool MatchAnonymousUnaryFunctionWithSingleReturn(
IAnonymousFunctionOperation anonymousFunction,
[NotNullWhen(true)] out IReturnOperation? returnOperation)
=> MatchAnonymousFunctionWithSingleReturn(anonymousFunction, out returnOperation)
&& anonymousFunction.Symbol.Parameters.Length == 1;
&& anonymousFunction.Symbol.Parameters is [_];

/// <summary>Matches an anonymous function of the shape <c>(...) => y</c>.</summary>
public static bool MatchAnonymousFunctionWithSingleReturn(
IAnonymousFunctionOperation anonymousFunction,
[NotNullWhen(true)] out IReturnOperation? functionReturnOperation)
{
functionReturnOperation = null;
return anonymousFunction.Body.Operations.Length == 1
&& anonymousFunction.Body.Operations[0] is IReturnOperation returnOperation
&& (functionReturnOperation = returnOperation) is var _;
return anonymousFunction.Body.Operations is [IReturnOperation returnOperation]
&& (functionReturnOperation = returnOperation) is var _;
}
}
3 changes: 1 addition & 2 deletions Funcky.Analyzers/Funcky.Analyzers/Funcky.Analyzers.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
<PackageReference Include="PolySharp" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
<PackageReference Include="Nullable" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
8 changes: 3 additions & 5 deletions Funcky.Analyzers/Funcky.Analyzers/MonadReturnMatching.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ private static bool IsReturn(AlternativeMonadType alternativeMonadType, IMethodS

private static bool IsReturnFunction(AlternativeMonadType alternativeMonadType, IAnonymousFunctionOperation anonymousFunction)
=> MatchAnonymousUnaryFunctionWithSingleReturn(anonymousFunction, out var returnOperation)
&& returnOperation is { ReturnedValue: IInvocationOperation returnedValue }
&& IsReturn(alternativeMonadType, returnedValue.TargetMethod)
&& returnedValue.Arguments.Length == 1
&& returnedValue.Arguments[0].Value is IParameterReferenceOperation { Parameter.ContainingSymbol: var parameterContainingSymbol }
&& SymbolEqualityComparer.Default.Equals(parameterContainingSymbol, anonymousFunction.Symbol);
&& returnOperation is { ReturnedValue: IInvocationOperation { Arguments: [{ Value: IParameterReferenceOperation { Parameter.ContainingSymbol: var parameterContainingSymbol } }] } returnedValue }
&& IsReturn(alternativeMonadType, returnedValue.TargetMethod)
&& SymbolEqualityComparer.Default.Equals(parameterContainingSymbol, anonymousFunction.Symbol);

private static bool IsImplicitReturn(AlternativeMonadType alternativeMonadType, IAnonymousFunctionOperation anonymousFunction)
=> MatchAnonymousUnaryFunctionWithSingleReturn(anonymousFunction, out var returnOperation)
Expand Down
2 changes: 1 addition & 1 deletion Funcky.Analyzers/Funcky.Analyzers/OperationMatching.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static bool MatchArguments(
{
firstArgument = null;
secondArgument = null;
return operation.Arguments.Length is 2
return operation.Arguments is [_, _]
&& (firstArgument = operation.GetArgumentForParameterAtIndex(0)) is var _
&& (secondArgument = operation.GetArgumentForParameterAtIndex(1)) is var _
&& matchFirstArgument(firstArgument)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ private static bool TakesExpressionTree(SymbolInfo info, INamedTypeSymbol expres
=> GetAllSymbols(info).Any(symbol => TakesExpressionTreeAsFirstArgument(symbol, expressionType));

private static bool TakesExpressionTreeAsFirstArgument(ISymbol symbol, INamedTypeSymbol expressionType)
=> symbol is IMethodSymbol method
&& method.Parameters.Length > 0
&& SymbolEqualityComparer.Default.Equals(expressionType, method.Parameters[0].Type?.OriginalDefinition);
=> symbol is IMethodSymbol { Parameters: [var firstParameter, ..] }
&& SymbolEqualityComparer.Default.Equals(expressionType, firstParameter.Type.OriginalDefinition);

private sealed record IsExpressionTreeContext(
SyntaxNode Syntax,
Expand Down
2 changes: 1 addition & 1 deletion Funcky.Async/Funcky.Async.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" PrivateAssets="all" Condition="'$(TargetFramework)' == 'net5.0'" />
<PackageReference Include="Nullable" PrivateAssets="all" />
<PackageReference Include="PolySharp" PrivateAssets="all" />
<PackageReference Include="System.Linq.Async" />
</ItemGroup>
<ItemGroup>
Expand Down
6 changes: 2 additions & 4 deletions Funcky.SourceGenerator/Funcky.SourceGenerator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@
<LangVersion>preview</LangVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="$(AssemblyName).Test" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
<PackageReference Include="PolySharp" PrivateAssets="all" />
</ItemGroup>
</Project>
14 changes: 4 additions & 10 deletions Funcky.SourceGenerator/OrNoneFromTryPatternGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private static IncrementalValueProvider<ImmutableArray<MethodPartial>> GetOrNone
.Collect();

private static bool IsSyntaxTargetForGeneration(SyntaxNode node, CancellationToken cancellationToken)
=> node is ClassDeclarationSyntax { AttributeLists.Count: > 0 };
=> node is ClassDeclarationSyntax { AttributeLists: [_, ..] };

private static SemanticTarget? GetSemanticTargetForGeneration(GeneratorSyntaxContext context, CancellationToken cancellationToken)
=> context.Node is ClassDeclarationSyntax classDeclarationSyntax
Expand All @@ -51,23 +51,17 @@ private static bool IsSyntaxTargetForGeneration(SyntaxNode node, CancellationTok
.Where(a => a.AttributeClass?.ToDisplayString() == AttributeFullName)
.Where(AttributeBelongsToPartialPart(classDeclarationSyntax))
.Select(ParseAttribute)
.ToImmutableArray() is { Length: >=1 } attributes
.ToImmutableArray() is [_, ..] attributes
? new SemanticTarget(classDeclarationSyntax, attributes)
: null;

private static Func<AttributeData, bool> AttributeBelongsToPartialPart(ClassDeclarationSyntax partialPart)
=> attribute => attribute.ApplicationSyntaxReference?.GetSyntax().Ancestors().OfType<ClassDeclarationSyntax>().FirstOrDefault() == partialPart;

private static ParsedAttribute ParseAttribute(AttributeData attribute)
{
const int typeNameIndex = 0;
const int methodNameIndex = 1;
return attribute.ConstructorArguments.Length >= 2
&& attribute.ConstructorArguments[typeNameIndex].Value is INamedTypeSymbol type
&& attribute.ConstructorArguments[methodNameIndex].Value is string methodName
=> attribute.ConstructorArguments is [{ Value: INamedTypeSymbol type }, { Value: string methodName }, ..]
? new ParsedAttribute(type, methodName)
: throw new InvalidOperationException("Invalid attribute: expected a named type and a method name");
}

private static MethodPartial ToMethodPartial(SemanticTarget semanticTarget, Compilation compilation)
=> new(
Expand Down Expand Up @@ -132,7 +126,7 @@ private static ParameterSyntax GenerateParameter(IParameterSymbol parameter, int
.WithAttributeLists(GenerateParameterAttributeLists(parameter));

private static SyntaxList<AttributeListSyntax> GenerateParameterAttributeLists(IParameterSymbol parameter)
=> GenerateParameterAttributes(parameter).ToImmutableArray() is { Length: >0 } attributes
=> GenerateParameterAttributes(parameter).ToImmutableArray() is [_, ..] attributes
? SingletonList(AttributeList(SeparatedList(attributes)))
: List<AttributeListSyntax>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using FsCheck.Xunit;

namespace Funcky.Test.Extensions;

public sealed class HttpHeadersNonValidatedExtensionsTest
{
[Property]
Expand Down
2 changes: 1 addition & 1 deletion Funcky.Test/Funcky.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FsCheck.Xunit" />
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
<PackageReference Include="PolySharp" PrivateAssets="all" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Numerics;

namespace Funcky.Extensions;

public static partial class ParseExtensions
{
public static Option<TNumber> ParseNumberOrNone<TNumber>(this string value, NumberStyles style, IFormatProvider? provider)
Expand Down
5 changes: 2 additions & 3 deletions Funcky/Extensions/ParseExtensions/ParseExtensions.TimeOnly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
using Funcky.Internal;

namespace Funcky.Extensions;

[OrNoneFromTryPattern(typeof(TimeOnly), nameof(TimeOnly.TryParse))]
[OrNoneFromTryPattern(typeof(TimeOnly), nameof(TimeOnly.TryParseExact))]
public static partial class ParseExtensions
{
}
public static partial class ParseExtensions;
#endif
2 changes: 1 addition & 1 deletion Funcky/Extensions/StringExtensions/Chunk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ private static IEnumerable<string> ChunkString(string source, int size)
}

// If there is anything left to emit, we will emit the last chunk.
if (source.Length > 0)
if (source is not "")
{
yield return source.Substring(index * size);
}
Expand Down
4 changes: 2 additions & 2 deletions Funcky/Extensions/StringExtensions/SplitLazy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private static FindNextIndex IndexOfCharSeparators(char[] separator)

private static FindNextIndex IndexOfStringSeparator(string separator)
=> (text, startIndex)
=> separator.Length == 0
=> separator is ""
? Option<(int Index, int SeparatorLength)>.None
: text
.IndexOfOrNone(separator, startIndex, StringComparison.Ordinal)
Expand Down Expand Up @@ -91,7 +91,7 @@ private static FindNextIndex IndexOfStringSeparators(string[] separators)

private static Func<string, Option<(int Index, int SeparatorLength)>> IndexOfAnyOrNone(string text, int startIndex)
=> separator
=> separator.Length == 0
=> separator is ""
? Option<(int Index, int SeparatorLength)>.None
: text.IndexOfOrNone(separator, startIndex, StringComparison.Ordinal).AndThen(index => (index, separator.Length));

Expand Down
3 changes: 1 addition & 2 deletions Funcky/Funcky.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" PrivateAssets="all" Condition="'$(TargetFramework)' == '$(TargetFrameworkForPublicApiAnalyzers)'" />
<PackageReference Include="Microsoft.Bcl.HashCode" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
<PackageReference Include="Nullable" PrivateAssets="all" />
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
<PackageReference Include="PolySharp" PrivateAssets="all" />
<PackageReference Include="System.Collections.Immutable" Condition="'$(TargetFramework)' == 'netstandard2.0' Or '$(TargetFramework)' == 'netstandard2.1'" />

<!-- .NET Core 3.1 ships with System.Text.Json, but we reference the NuGet version instead, so we always get System.Text.Json >= 5.0.0. It is the first version to never return null converter from CreateConverter(...). -->
Expand Down
Loading

0 comments on commit a1abd3f

Please sign in to comment.