Код: Выделить всё
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using System.Text;
namespace TestGenerator;
[Generator]
public class TestGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
// Register a syntax receiver to collect information during the initial parsing phase
var classDeclarations = context.SyntaxProvider.ForAttributeWithMetadataName(
"TestGenerator.TestSourceGeneratorAttribute",
predicate: static (s, _) => (s is ClassDeclarationSyntax || s is StructDeclarationSyntax) && s is TypeDeclarationSyntax type && type.Modifiers.Any(SyntaxKind.PartialKeyword),
transform: static (ctx, _) =>
{
if (ctx.TargetNode is TypeDeclarationSyntax typeDeclarationSyntax)
{
return typeDeclarationSyntax.Identifier.ToString();
}
return null;
})
.Where(static m => m is not null);
var compilationAndClasses = classDeclarations.Collect();
// Set up the generation phase
context.RegisterSourceOutput(compilationAndClasses, static (spc, classes) =>
{
foreach (var typeDefinition in classes)
{
// Add the generated source to the output
spc.AddSource($"{typeDefinition}.g.cs",
SourceText.From(GetSource(typeDefinition), Encoding.UTF8));
}
});
}
private static string GetSource(string source)
{
return $"""
//
#nullable enable
using System;
/// {source}
""";
}
}
Код: Выделить всё
namespace TestGenerator.Test
{
[TestSourceGenerator]
public partial class TestClassGenerated
{
}
}
Код: Выделить всё
//
#nullable enable
using System;
/// TestClassGenerated
Код: Выделить всё
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading.Tasks;
namespace TestGenerator.Test;
[TestClass]
public class TestGeneratorUnitTest
{
[TestMethod]
public async Task Test123()
{
// Arrange
var source = """
using System;
namespace TestGenerator.Test
{
[TestSourceGenerator]
public partial class MyClass
{
}
}
""";
var expectedGeneratedCode = @"
//
#nullable enable
using System;
/// MyClass
";
var test = new CSharpSourceGeneratorTest
{
TestState =
{
Sources = { source },
GeneratedSources =
{
(typeof(TestGenerator), "MyClass.g.cs", expectedGeneratedCode)
}
}
};
// Act & Assert
await test.RunAsync();
}
}
Я создал репродукция, которую нужно добавить сюда
https://github.com/luizfbicalho/TestSourceGenerator
Я ожидаю, что тест сгенерирует файл MyClass
Подробнее здесь: https://stackoverflow.com/questions/787 ... -works-but