-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
Related to #48
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
using System.Collections.Immutable; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
using Microsoft.CodeAnalysis.Text; | ||
|
||
namespace WeihanLi.EntityFramework.SourceGenerator; | ||
|
||
[Generator] | ||
public class EFRepositorySourceGenerator : IIncrementalGenerator | ||
{ | ||
public void Initialize(IncrementalGeneratorInitializationContext context) | ||
{ | ||
var additionalFiles = context.AdditionalTextsProvider | ||
.Where(file => file.Path.EndsWith(".template")) | ||
.Select((file, cancellationToken) => file.GetText(cancellationToken)?.ToString()) | ||
.Where(content => !string.IsNullOrEmpty(content)); | ||
|
||
var dbContextDeclarations = context.SyntaxProvider | ||
.CreateSyntaxProvider( | ||
predicate: static (s, _) => IsDbContextDeclaration(s), | ||
transform: static (ctx, _) => GetDbContextDeclaration(ctx)) | ||
.Where(static m => m is not null); | ||
|
||
var combined = dbContextDeclarations.Combine(additionalFiles.Collect()); | ||
|
||
context.RegisterSourceOutput(combined, (spc, source) => | ||
{ | ||
var (dbContextDeclaration, templates) = source; | ||
var dbContextName = dbContextDeclaration!.Identifier.Text; | ||
var repositoryNamespace = dbContextDeclaration!.Parent!.GetNamespace(); | ||
var generatedCode = GenerateRepositoryCode(dbContextName, repositoryNamespace, templates); | ||
spc.AddSource($"{dbContextName}Repository.g.cs", SourceText.From(generatedCode, Encoding.UTF8)); | ||
Check failure on line 33 in src/WeihanLi.EntityFramework.SourceGenerator/EFRepositorySourceGenerator.cs GitHub Actions / build
Check failure on line 33 in src/WeihanLi.EntityFramework.SourceGenerator/EFRepositorySourceGenerator.cs GitHub Actions / build
Check failure on line 33 in src/WeihanLi.EntityFramework.SourceGenerator/EFRepositorySourceGenerator.cs GitHub Actions / build
|
||
}); | ||
} | ||
|
||
private static bool IsDbContextDeclaration(SyntaxNode node) | ||
{ | ||
return node is ClassDeclarationSyntax classDeclaration && | ||
classDeclaration.BaseList?.Types.Any(t => t.ToString().Contains("DbContext")) == true; | ||
} | ||
|
||
private static ClassDeclarationSyntax? GetDbContextDeclaration(GeneratorSyntaxContext context) | ||
{ | ||
var classDeclaration = (ClassDeclarationSyntax)context.Node; | ||
return classDeclaration; | ||
} | ||
|
||
private static string GenerateRepositoryCode(string dbContextName, string repositoryNamespace, ImmutableArray<string> templates) | ||
{ | ||
var builder = new StringBuilder(); | ||
Check failure on line 51 in src/WeihanLi.EntityFramework.SourceGenerator/EFRepositorySourceGenerator.cs GitHub Actions / build
Check failure on line 51 in src/WeihanLi.EntityFramework.SourceGenerator/EFRepositorySourceGenerator.cs GitHub Actions / build
Check failure on line 51 in src/WeihanLi.EntityFramework.SourceGenerator/EFRepositorySourceGenerator.cs GitHub Actions / build
|
||
builder.AppendLine("using WeihanLi.EntityFramework;"); | ||
builder.AppendLine($"namespace {repositoryNamespace}"); | ||
builder.AppendLine("{"); | ||
|
||
foreach (var template in templates) | ||
{ | ||
var code = template.Replace("{{DbContextName}}", dbContextName); | ||
builder.AppendLine(code); | ||
} | ||
|
||
builder.AppendLine("}"); | ||
return builder.ToString(); | ||
} | ||
} | ||
|
||
internal static class SyntaxNodeExtensions | ||
{ | ||
public static string GetNamespace(this SyntaxNode node) | ||
{ | ||
while (node != null) | ||
{ | ||
if (node is NamespaceDeclarationSyntax namespaceDeclaration) | ||
{ | ||
return namespaceDeclaration.Name.ToString(); | ||
} | ||
|
||
node = node.Parent; | ||
Check warning on line 78 in src/WeihanLi.EntityFramework.SourceGenerator/EFRepositorySourceGenerator.cs GitHub Actions / build
Check warning on line 78 in src/WeihanLi.EntityFramework.SourceGenerator/EFRepositorySourceGenerator.cs GitHub Actions / build
Check warning on line 78 in src/WeihanLi.EntityFramework.SourceGenerator/EFRepositorySourceGenerator.cs GitHub Actions / build
|
||
} | ||
|
||
return string.Empty; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<LangVersion>latest</LangVersion> | ||
<OutputPath>bin\$(Configuration)\</OutputPath> | ||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> | ||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> | ||
<IsPackable>true</IsPackable> | ||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
<PackageId>WeihanLi.EntityFramework.SourceGenerator</PackageId> | ||
<Title>WeihanLi.EntityFramework.SourceGenerator</Title> | ||
<Description>Source generator for WeihanLi.EntityFramework</Description> | ||
<Authors>WeihanLi</Authors> | ||
<Company>WeihanLi</Company> | ||
<Product>WeihanLi.EntityFramework</Product> | ||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression> | ||
<RepositoryUrl>https://github.com/WeihanLi/WeihanLi.EntityFramework</RepositoryUrl> | ||
<RepositoryType>git</RepositoryType> | ||
<Copyright>Copyright 2019-2024 (c) WeihanLi</Copyright> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" PrivateAssets="all" /> | ||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" PrivateAssets="all" /> | ||
</ItemGroup> | ||
|
||
</Project> |