Skip to content

Commit

Permalink
Some more list patterns and improved patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
FreeApophis committed Dec 4, 2023
1 parent c907848 commit 3106ede
Show file tree
Hide file tree
Showing 9 changed files with 20 additions and 34 deletions.
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 @@ -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,7 +10,7 @@ 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(
Expand Down
3 changes: 1 addition & 2 deletions Funcky.Analyzers/Funcky.Analyzers/MonadReturnMatching.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ 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 }
&& returnOperation is { ReturnedValue: IInvocationOperation { Arguments: [{ Value: IParameterReferenceOperation { Parameter.ContainingSymbol: var parameterContainingSymbol } }] } returnedValue }
&& IsReturn(alternativeMonadType, returnedValue.TargetMethod)
&& returnedValue.Arguments is [{ Value: IParameterReferenceOperation { Parameter.ContainingSymbol: var parameterContainingSymbol } }]
&& SymbolEqualityComparer.Default.Equals(parameterContainingSymbol, anonymousFunction.Symbol);

private static bool IsImplicitReturn(AlternativeMonadType alternativeMonadType, IAnonymousFunctionOperation anonymousFunction)
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
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
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
6 changes: 3 additions & 3 deletions Funcky/Monads/Option/OptionJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ namespace Funcky.Monads;
public sealed class OptionJsonConverter : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
=> typeToConvert.IsGenericType &&
typeToConvert.GetGenericTypeDefinition() == typeof(Option<>);
=> typeToConvert.IsGenericType
&& typeToConvert.GetGenericTypeDefinition() == typeof(Option<>);

[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
[UnconditionalSuppressMessage("Trimming", "IL2046:\'RequiresUnreferencedCodeAttribute\' annotations must match across all interface implementations or overrides.")]
Expand All @@ -26,7 +26,7 @@ internal sealed class OptionJsonConverter<TItem>(JsonConverter<TItem> itemConver
where TItem : notnull
{
public override Option<TItem> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> reader.TokenType == JsonTokenType.Null
=> reader.TokenType is JsonTokenType.Null
? Option<TItem>.None
: itemConverter.Read(ref reader, typeof(TItem), options)!;

Expand Down

0 comments on commit 3106ede

Please sign in to comment.