Skip to content

Commit

Permalink
Merge pull request #694 from polyadic/dotnet-7
Browse files Browse the repository at this point in the history
  • Loading branch information
bash authored Nov 2, 2022
2 parents 672e9f1 + e9ec7a5 commit 2b2508e
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 3 deletions.
1 change: 1 addition & 0 deletions Funcky.Async/Funcky.Async.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<PropertyGroup>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisModeReliability>All</AnalysisModeReliability>
<EnablePackageValidation>true</EnablePackageValidation>
<NoWarn>$(NoWarn);RS0026</NoWarn><!-- RS0026: Do not add multiple overloads with optional parameters -->
</PropertyGroup>
<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//HintName: .g.cs
// <auto-generated/>
#nullable enable

namespace Funcky.Extensions
{
public static partial class ParseExtensions
{
[global::System.Diagnostics.Contracts.Pure]
public static Funcky.Monads.Option<global::Funcky.Extensions.Target> ParseTargetOrNone(this string candidate, [global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("foo")] string format) => global::Funcky.Extensions.Target.TryParse(candidate, format, out var result) ? result : default(Funcky.Monads.Option<global::Funcky.Extensions.Target>);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//HintName: OrNoneFromTryPatternAttribute.g.cs
namespace Funcky.Internal
{
[global::System.Diagnostics.Conditional("COMPILE_TIME_ONLY")]
[global::System.AttributeUsage(global::System.AttributeTargets.Class, AllowMultiple = true)]
internal class OrNoneFromTryPatternAttribute : global::System.Attribute
{
public OrNoneFromTryPatternAttribute(global::System.Type type, string method)
=> (Type, Method) = (type, method);

public global::System.Type Type { get; }

public string Method { get; }
}
}
31 changes: 31 additions & 0 deletions Funcky.SourceGenerator.Test/OrNoneGeneratorSnapshotTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,35 @@ public static bool TryParseExact(string candidate, out Target result)

return TestHelper.Verify(source + Environment.NewLine + OptionSource);
}

[Fact]
public Task CopiesStringSyntaxAttributeFromOriginalDefinition()
{
const string source = """
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using Funcky.Internal;
namespace Funcky.Extensions
{
[OrNoneFromTryPattern(typeof(Target), nameof(Target.TryParse))]
public static partial class ParseExtensions
{
}
public sealed class Target
{
public static bool TryParse(string candidate, [StringSyntaxAttribute("foo")] string format, out Target result)
{
result = default!;
return false;
}
}
}
""";

return TestHelper.Verify(source + Environment.NewLine + OptionSource);
}
}
23 changes: 22 additions & 1 deletion Funcky.SourceGenerator/OrNoneFromTryPatternGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Funcky.SourceGenerator;
public sealed class OrNoneFromTryPatternGenerator : IIncrementalGenerator
{
private const string AttributeFullName = "Funcky.Internal.OrNoneFromTryPatternAttribute";
private const string StringSyntaxAttributeFullName = "System.Diagnostics.CodeAnalysis.StringSyntaxAttribute";
private static readonly IEnumerable<string> GeneratedFileHeadersSource = ImmutableList.Create("// <auto-generated/>", "#nullable enable", string.Empty);

public void Initialize(IncrementalGeneratorInitializationContext context)
Expand Down Expand Up @@ -127,7 +128,27 @@ private static ParameterSyntax GenerateParameter(IParameterSymbol parameter, int
=> Parameter(Identifier(GetParameterName(parameter, index)))
.WithModifiers(index == 0 ? TokenList(Token(SyntaxKind.ThisKeyword)) : TokenList())
.WithType(GenerateTypeSyntax(parameter.Type))
.WithDefault(GetParameterDefaultValue(parameter));
.WithDefault(GetParameterDefaultValue(parameter))
.WithAttributeLists(GenerateParameterAttributeLists(parameter));

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

private static IEnumerable<AttributeSyntax> GenerateParameterAttributes(IParameterSymbol parameter)
=> parameter.GetAttributes().Where(ShouldCopyParameterAttribute).Select(GenerateParameterAttribute);

private static AttributeSyntax GenerateParameterAttribute(AttributeData originalAttribute)
=> Attribute(
ParseName(GenerateTypeSyntax(originalAttribute.AttributeClass!).ToString()),
AttributeArgumentList(SeparatedList(originalAttribute.ConstructorArguments.Select(GenerateAttributeArgument))));

private static AttributeArgumentSyntax GenerateAttributeArgument(TypedConstant argumentValue)
=> AttributeArgument(ParseExpression(argumentValue.ToCSharpString()));

private static bool ShouldCopyParameterAttribute(AttributeData originalAttribute)
=> originalAttribute.AttributeClass?.ToDisplayString() == StringSyntaxAttributeFullName;

private static TypeSyntax GenerateTypeSyntax(ITypeSymbol type)
{
Expand Down
1 change: 1 addition & 0 deletions Funcky.Xunit/Funcky.Xunit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<RootNamespace>Funcky</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<EnablePackageValidation>true</EnablePackageValidation>
<NoWarn>$(NoWarn);NU5104</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
Expand Down
5 changes: 3 additions & 2 deletions Funcky/Funcky.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk; Microsoft.Build.CentralPackageVersions">
<PropertyGroup>
<TargetFrameworks>net6.0;net5.0;netcoreapp3.1;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>net7.0;net6.0;net5.0;netcoreapp3.1;netstandard2.0;netstandard2.1</TargetFrameworks>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<Product>Funcky</Product>
Expand All @@ -14,12 +14,13 @@
<PropertyGroup>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisModeReliability>All</AnalysisModeReliability>
<EnablePackageValidation>true</EnablePackageValidation>
</PropertyGroup>
<PropertyGroup>
<DefineConstants>$(DefineConstants);CONTRACTS_FULL</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" PrivateAssets="all" Condition="'$(TargetFramework)' == 'net6.0'" />
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" PrivateAssets="all" Condition="'$(TargetFramework)' == 'net7.0'" />
<PackageReference Include="Microsoft.Bcl.HashCode" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
<PackageReference Include="Nullable" PrivateAssets="all" />
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
Expand Down
34 changes: 34 additions & 0 deletions Funcky/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,40 @@ Funcky.RequireClass<T>.RequireClass() -> void
Funcky.RequireStruct<T>
Funcky.RequireStruct<T>.RequireStruct() -> void
static Funcky.Extensions.EnumerableExtensions.ElementAtOrNone<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Index index) -> Funcky.Monads.Option<TSource>
static Funcky.Extensions.ParseExtensions.ParseBigIntegerOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.Numerics.BigInteger>
static Funcky.Extensions.ParseExtensions.ParseBigIntegerOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.Numerics.BigInteger>
static Funcky.Extensions.ParseExtensions.ParseByteOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<byte>
static Funcky.Extensions.ParseExtensions.ParseByteOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<byte>
static Funcky.Extensions.ParseExtensions.ParseDateOnlyOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.DateOnly>
static Funcky.Extensions.ParseExtensions.ParseDateOnlyOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.DateOnly>
static Funcky.Extensions.ParseExtensions.ParseDateTimeOffsetOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.DateTimeOffset>
static Funcky.Extensions.ParseExtensions.ParseDateTimeOffsetOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.DateTimeOffset>
static Funcky.Extensions.ParseExtensions.ParseDateTimeOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.DateTime>
static Funcky.Extensions.ParseExtensions.ParseDateTimeOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.DateTime>
static Funcky.Extensions.ParseExtensions.ParseDecimalOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<decimal>
static Funcky.Extensions.ParseExtensions.ParseDecimalOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<decimal>
static Funcky.Extensions.ParseExtensions.ParseDoubleOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<double>
static Funcky.Extensions.ParseExtensions.ParseDoubleOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<double>
static Funcky.Extensions.ParseExtensions.ParseGuidOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.Guid>
static Funcky.Extensions.ParseExtensions.ParseGuidOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.Guid>
static Funcky.Extensions.ParseExtensions.ParseInt16OrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<short>
static Funcky.Extensions.ParseExtensions.ParseInt16OrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<short>
static Funcky.Extensions.ParseExtensions.ParseInt32OrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<int>
static Funcky.Extensions.ParseExtensions.ParseInt32OrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<int>
static Funcky.Extensions.ParseExtensions.ParseInt64OrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<long>
static Funcky.Extensions.ParseExtensions.ParseInt64OrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<long>
static Funcky.Extensions.ParseExtensions.ParseSByteOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<sbyte>
static Funcky.Extensions.ParseExtensions.ParseSByteOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<sbyte>
static Funcky.Extensions.ParseExtensions.ParseSingleOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<float>
static Funcky.Extensions.ParseExtensions.ParseSingleOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<float>
static Funcky.Extensions.ParseExtensions.ParseTimeOnlyOrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.TimeOnly>
static Funcky.Extensions.ParseExtensions.ParseTimeOnlyOrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<System.TimeOnly>
static Funcky.Extensions.ParseExtensions.ParseUInt16OrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<ushort>
static Funcky.Extensions.ParseExtensions.ParseUInt16OrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<ushort>
static Funcky.Extensions.ParseExtensions.ParseUInt32OrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<uint>
static Funcky.Extensions.ParseExtensions.ParseUInt32OrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<uint>
static Funcky.Extensions.ParseExtensions.ParseUInt64OrNone(this string? candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<ulong>
static Funcky.Extensions.ParseExtensions.ParseUInt64OrNone(this System.ReadOnlySpan<char> candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option<ulong>
static Funcky.Extensions.QueryableExtensions.ElementAtOrNone<TSource>(this System.Linq.IQueryable<TSource>! source, int index) -> Funcky.Monads.Option<TSource>
static Funcky.Extensions.QueryableExtensions.ElementAtOrNone<TSource>(this System.Linq.IQueryable<TSource>! source, System.Index index) -> Funcky.Monads.Option<TSource>
static Funcky.Extensions.StreamExtensions.ReadByteOrNone(this System.IO.Stream! stream) -> Funcky.Monads.Option<byte>
Expand Down

0 comments on commit 2b2508e

Please sign in to comment.