Skip to content

Commit

Permalink
Add .NET 9 preview 1 methods
Browse files Browse the repository at this point in the history
  • Loading branch information
meziantou committed Feb 21, 2024
1 parent 23043ac commit 8a1ea2b
Show file tree
Hide file tree
Showing 15 changed files with 340 additions and 22 deletions.
28 changes: 14 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ jobs:
env:
RepositoryBranch: ${{github.ref}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
- run: dotnet run --project Meziantou.Polyfill.Generator/Meziantou.Polyfill.Generator.csproj
- run: dotnet pack Meziantou.Polyfill --configuration Release

- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: nuget
if-no-files-found: error
retention-days: 3
path: '**/*.nupkg'

- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: generated-code
if-no-files-found: error
Expand All @@ -46,10 +46,10 @@ jobs:
runs-on: ubuntu-latest
needs: [ create_nuget ]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup .NET Core (global.json)
uses: actions/setup-dotnet@v3
- uses: actions/download-artifact@v3
uses: actions/setup-dotnet@v4
- uses: actions/download-artifact@v4
with:
name: nuget
path: ${{ env.NuGetDirectory }}
Expand All @@ -69,11 +69,11 @@ jobs:
}
tests:
runs-on: windows-latest
runs-on: 'ubuntu-latest'
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
- run: dotnet run --project Meziantou.Polyfill.Generator/Meziantou.Polyfill.Generator.csproj
- run: dotnet test Meziantou.Polyfill.SourceGenerator.Tests
- run: dotnet test Meziantou.Polyfill.Tests
Expand All @@ -82,17 +82,17 @@ jobs:
runs-on: 'ubuntu-latest'
needs: [ validate_nuget, tests ]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
- uses: actions/download-artifact@v3
uses: actions/setup-dotnet@v4
- uses: actions/download-artifact@v4
with:
name: nuget
path: ${{ env.NuGetDirectory }}
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
- run: |
Write-Host "Current ref: $env:GITHUB_REF"
Write-Host "Searching nupkg in folder: ${{ env.NuGetDirectory }}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;

static partial class PolyfillExtensions
{
public static IEnumerable<KeyValuePair<TKey, TAccumulate>> AggregateBy<TSource, TKey, TAccumulate>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TKey, TAccumulate> seedSelector,
Func<TAccumulate, TSource, TAccumulate> func,
IEqualityComparer<TKey>? keyComparer = null) where TKey : notnull
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
if (keySelector is null)
{
throw new ArgumentNullException(nameof(keySelector));
}
if (seedSelector is null)
{
throw new ArgumentNullException(nameof(keySelector));
}
if (func is null)
{
throw new ArgumentNullException(nameof(func));
}

return Helpers.AggregateByIterator(source, keySelector, seedSelector, func, keyComparer);
}
}

file class Helpers
{
public static IEnumerable<KeyValuePair<TKey, TAccumulate>> AggregateByIterator<TSource, TKey, TAccumulate>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, TAccumulate> seedSelector, Func<TAccumulate, TSource, TAccumulate> func, IEqualityComparer<TKey>? keyComparer) where TKey : notnull
{
using IEnumerator<TSource> enumerator = source.GetEnumerator();

if (!enumerator.MoveNext())
{
yield break;
}

foreach (KeyValuePair<TKey, TAccumulate> countBy in PopulateDictionary(enumerator, keySelector, seedSelector, func, keyComparer))
{
yield return countBy;
}

static Dictionary<TKey, TAccumulate> PopulateDictionary(IEnumerator<TSource> enumerator, Func<TSource, TKey> keySelector, Func<TKey, TAccumulate> seedSelector, Func<TAccumulate, TSource, TAccumulate> func, IEqualityComparer<TKey>? keyComparer)
{
Dictionary<TKey, TAccumulate> dict = new(keyComparer);

do
{
TSource value = enumerator.Current;
TKey key = keySelector(value);

#if NET
ref TAccumulate? acc = ref System.Runtime.InteropServices.CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out bool exists);
acc = func(exists ? acc! : seedSelector(key), value);
#else
var exists = dict.TryGetValue(key, out var acc);
dict[key] = func(exists ? acc! : seedSelector(key), value);
#endif
}
while (enumerator.MoveNext());

return dict;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;

static partial class PolyfillExtensions
{
public static IEnumerable<KeyValuePair<TKey, TAccumulate>> AggregateBy<TSource, TKey, TAccumulate>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
TAccumulate seed,
Func<TAccumulate, TSource, TAccumulate> func,
IEqualityComparer<TKey>? keyComparer = null) where TKey : notnull
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
if (keySelector is null)
{
throw new ArgumentNullException(nameof(keySelector));
}
if (func is null)
{
throw new ArgumentNullException(nameof(func));
}

return Helpers.AggregateByIterator(source, keySelector, seed, func, keyComparer);
}
}

file class Helpers
{
public static IEnumerable<KeyValuePair<TKey, TAccumulate>> AggregateByIterator<TSource, TKey, TAccumulate>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, IEqualityComparer<TKey>? keyComparer) where TKey : notnull
{
using IEnumerator<TSource> enumerator = source.GetEnumerator();

if (!enumerator.MoveNext())
{
yield break;
}

foreach (KeyValuePair<TKey, TAccumulate> countBy in PopulateDictionary(enumerator, keySelector, seed, func, keyComparer))
{
yield return countBy;
}

static Dictionary<TKey, TAccumulate> PopulateDictionary(IEnumerator<TSource> enumerator, Func<TSource, TKey> keySelector, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, IEqualityComparer<TKey>? keyComparer)
{
Dictionary<TKey, TAccumulate> dict = new(keyComparer);

do
{
TSource value = enumerator.Current;
TKey key = keySelector(value);

#if NET
ref TAccumulate? acc = ref System.Runtime.InteropServices.CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out bool exists);
acc = func(exists ? acc! : seed, value);
#else
var exists = dict.TryGetValue(key, out var acc);
dict[key] = func(exists ? acc! : seed, value);
#endif
}
while (enumerator.MoveNext());

return dict;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;

static partial class PolyfillExtensions
{
public static IEnumerable<KeyValuePair<TKey, int>> CountBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? keyComparer = null) where TKey : notnull
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}

if (keySelector is null)
{
throw new ArgumentNullException(nameof(keySelector));
}

return Helpers.CountByIterator(source, keySelector, keyComparer);
}
}

file class Helpers
{
public static IEnumerable<KeyValuePair<TKey, int>> CountByIterator<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? keyComparer) where TKey : notnull
{
using IEnumerator<TSource> enumerator = source.GetEnumerator();

if (!enumerator.MoveNext())
{
yield break;
}

foreach (KeyValuePair<TKey, int> countBy in BuildCountDictionary(enumerator, keySelector, keyComparer))
{
yield return countBy;
}
}

public static Dictionary<TKey, int> BuildCountDictionary<TSource, TKey>(IEnumerator<TSource> enumerator, Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? keyComparer) where TKey : notnull
{
Dictionary<TKey, int> countsBy = new(keyComparer);

do
{
TSource value = enumerator.Current;
TKey key = keySelector(value);

#if NET
ref int currentCount = ref System.Runtime.InteropServices.CollectionsMarshal.GetValueRefOrAddDefault(countsBy, key, out _);
checked
{
currentCount++;
}
#else
if (countsBy.TryGetValue(key, out var currentCount))
{
checked
{
countsBy[key] = currentCount + 1;
}
}
else
{
countsBy[key] = 1;
}
#endif
}
while (enumerator.MoveNext());

return countsBy;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Collections.Generic;

static partial class PolyfillExtensions
{
public static IEnumerable<(int Index, TSource Item)> Index<TSource>(this IEnumerable<TSource> source)
{
int index = -1;
foreach (TSource element in source)
{
checked
{
index++;
}

yield return (index, element);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Text;

static partial class PolyfillExtensions
{
public static StringBuilder Replace(this StringBuilder target, ReadOnlySpan<char> oldValue, ReadOnlySpan<char> newValue)
{
return target.Replace(oldValue.ToString(), newValue.ToString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Text;

static partial class PolyfillExtensions
{
public static StringBuilder Replace(this StringBuilder target, ReadOnlySpan<char> oldValue, ReadOnlySpan<char> newValue, int startIndex, int count)
{
return target.Replace(oldValue.ToString(), newValue.ToString(), startIndex, count);
}
}
2 changes: 1 addition & 1 deletion Meziantou.Polyfill.Editor/Meziantou.Polyfill.Editor.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
7 changes: 5 additions & 2 deletions Meziantou.Polyfill.SourceGenerator.Tests/UnitTest1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace Meziantou.Polyfill.SourceGenerator.Tests;

public class UnitTest1
{
private const string LatestDotnetPackageVersion = "9.0.0-preview.1.24080.9";

[Fact]
public void PolyfillOptions_Included()
{
Expand All @@ -36,10 +38,10 @@ public void PolyfillOptions_Excluded()
[Fact]
public async Task NoCodeGeneratedForLatestFramework()
{
var assemblies = await NuGetHelpers.GetNuGetReferences("Microsoft.NETCore.App.Ref", "8.0.0", "ref/net8.0/");
var assemblies = await NuGetHelpers.GetNuGetReferences("Microsoft.NETCore.App.Ref", LatestDotnetPackageVersion, "ref/net9.0/");
var result = GenerateFiles("", assemblyLocations: assemblies);
var tree = Assert.Single(result.GeneratorResult.GeneratedTrees);
Assert.Equal("Meziantou.Polyfill\\Meziantou.Polyfill.PolyfillGenerator\\Debug.g.cs", tree.FilePath);
Assert.Equal("Meziantou.Polyfill/Meziantou.Polyfill.PolyfillGenerator/Debug.g.cs", tree.FilePath.Replace(Path.DirectorySeparatorChar, '/'));
}

[Fact]
Expand Down Expand Up @@ -142,6 +144,7 @@ public static TheoryData<PackageReference[]> GetConfigurations()
{
return new TheoryData<PackageReference[]>
{
{ new[] { new PackageReference("Microsoft.NETCore.App.Ref", LatestDotnetPackageVersion, "ref/net9.0/") } },
{ new[] { new PackageReference("Microsoft.NETCore.App.Ref", "8.0.0", "ref/net8.0/") } },
{ new[] { new PackageReference("Microsoft.NETCore.App.Ref", "7.0.5", "ref/net7.0/") } },
{ new[] { new PackageReference("Microsoft.NETCore.App.Ref", "6.0.16", "ref/net6.0/") } },
Expand Down
Loading

0 comments on commit 8a1ea2b

Please sign in to comment.