Skip to content

Commit 6128ddb

Browse files
authored
Fix rewriter when the sync method is in the same extensions class (#110)
Pull request #108 fixed EF Core async to sync generation. EF Core async methods are found in the `EntityFrameworkQueryableExtensions` class, so a mapping from EntityFrameworkQueryableExtensions to System.Linq.Queryable was added. Unfortunately, this was not enough. The `EntityFrameworkQueryableExtensions` class also contains extension methods that have both an async and a sync method. For example: `ExecuteDeleteAsync` and `ExecuteDelete`. This commit fixes the translation for those methods where both the async and sync methods are in the same extension class.
1 parent 3fe6513 commit 6128ddb

4 files changed

Lines changed: 38 additions & 11 deletions

‎src/Zomp.SyncMethodGenerator/AsyncToSyncRewriter.cs‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1844,7 +1844,18 @@ private InvocationExpressionSyntax UnwrapExtension(InvocationExpressionSyntax ie
18441844
var newName = reducedFrom.Name;
18451845
newName = changeMemoryToSpan ? GetNewName(reducedFrom) : RemoveAsync(newName);
18461846

1847-
var fullyQualifiedName = $"{MakeType(reducedFrom.ContainingType)}.{newName}";
1847+
var newNameExistsInContainingType = semanticModel.Compilation.References
1848+
.Select(semanticModel.Compilation.GetAssemblyOrModuleSymbol)
1849+
.Append(semanticModel.Compilation.Assembly)
1850+
.OfType<IAssemblySymbol>()
1851+
.Select(assemblySymbol => assemblySymbol.GetTypeByMetadataName(reducedFrom.ContainingType.ToString()))
1852+
.OfType<INamedTypeSymbol>()
1853+
.SelectMany(symbol => symbol.GetMembers(newName))
1854+
.Any();
1855+
1856+
var fullyQualifiedName = newNameExistsInContainingType
1857+
? $"{reducedFrom.ContainingType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}.{newName}"
1858+
: $"{MakeType(reducedFrom.ContainingType)}.{newName}";
18481859

18491860
var es = (ies.Expression switch
18501861
{
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
using System.Linq;
21
using System.Threading;
32
using System.Threading.Tasks;
43

5-
namespace Zomp.SyncMethodGenerator.IntegrationTests;
4+
namespace GenerationSandbox.Tests;
65

76
using Microsoft.EntityFrameworkCore;
87

@@ -14,12 +13,18 @@ public partial class EntityFrameworkQueryableExtensions
1413
/// <summary>
1514
/// Test method.
1615
/// </summary>
17-
/// <param name="source">The source.</param>
16+
/// <param name="dbContext">The db context.</param>
1817
/// <param name="cancellationToken">The cancellation token.</param>
1918
/// <returns>The result.</returns>
2019
[Zomp.SyncMethodGenerator.CreateSyncVersion]
21-
public async Task<bool> QueryableExtensionAsync(IQueryable<object> source, CancellationToken cancellationToken)
20+
public async Task<int> QueryableExtensionAsync(DbContext dbContext, CancellationToken cancellationToken)
2221
{
23-
return await source.AnyAsync(cancellationToken);
22+
var dbSet = dbContext.Set<object>();
23+
if (await dbSet.AnyAsync(cancellationToken))
24+
{
25+
return await dbSet.ExecuteDeleteAsync(cancellationToken);
26+
}
27+
28+
return 0;
2429
}
2530
}

‎tests/Generator.Tests/ExtensionMethodTests.cs‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ public async IAsyncEnumerable<T> WhereLessThan(T threshold)
122122

123123
[Fact]
124124
public Task EntityFrameworkQueryableExtensions() => """
125-
using System.Linq;
126125
using System.Threading;
127126
using System.Threading.Tasks;
128127
@@ -133,9 +132,15 @@ namespace Zomp.SyncMethodGenerator.IntegrationTests
133132
public partial class EntityFrameworkQueryableExtensions
134133
{
135134
[Zomp.SyncMethodGenerator.CreateSyncVersion]
136-
public async Task<bool> QueryableExtensionAsync(IQueryable<object> source, CancellationToken cancellationToken)
135+
public async Task<int> QueryableExtensionAsync(DbContext dbContext, CancellationToken cancellationToken)
137136
{
138-
return await source.AnyAsync(cancellationToken);
137+
var dbSet = dbContext.Set<object>();
138+
if (await dbSet.AnyAsync(cancellationToken))
139+
{
140+
return await dbSet.ExecuteDeleteAsync(cancellationToken);
141+
}
142+
143+
return 0;
139144
}
140145
}
141146
}

‎tests/Generator.Tests/Snapshots/ExtensionMethodTests.EntityFrameworkQueryableExtensions#Zomp.SyncMethodGenerator.IntegrationTests.EntityFrameworkQueryableExtensions.QueryableExtensionAsync.g.verified.cs‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ namespace Zomp.SyncMethodGenerator.IntegrationTests
55
{
66
public partial class EntityFrameworkQueryableExtensions
77
{
8-
public bool QueryableExtension(global::System.Linq.IQueryable<object> source)
8+
public int QueryableExtension(global::Microsoft.EntityFrameworkCore.DbContext dbContext)
99
{
10-
return global::System.Linq.Queryable.Any(source);
10+
var dbSet = dbContext.Set<object>();
11+
if (global::System.Linq.Queryable.Any(dbSet))
12+
{
13+
return global::Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteDelete(dbSet);
14+
}
15+
16+
return 0;
1117
}
1218
}
1319
}

0 commit comments

Comments
 (0)