我尝试使用以下代码片段在内存中运行 C# 源生成器:
var syntaxTree = await SyntaxTreeFromRelativeFile("testdata/IMyInterface.cs");
var compilation = CSharpCompilation.Create("compilation", ImmutableArray.Create(syntaxTree), References);
var generator = new ProxyGenerator();
GeneratorDriver driver = CSharpGeneratorDriver.Create(generator);
driver = driver.RunGenerators(compilation);
Run Code Online (Sandbox Code Playgroud)
References设置为编译代码所需的源:
public static readonly ImmutableArray<MetadataReference> References = ImmutableArray.Create<MetadataReference>(
// System
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(GCSettings).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Attribute).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
// JetBrains
MetadataReference.CreateFromFile(typeof(UsedImplicitlyAttribute).Assembly.Location),
// some custom ones
);
Run Code Online (Sandbox Code Playgroud)
虽然生成器以这种方式运行得很好,但遗憾的是它没有达到预期的效果,因为源生成器依赖于一个属性来知道是否为指定类型生成源。确切的来源如下:
[MyAttribute]
public interface IMyInterface { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
源生成器正确拾取属性,但它被解析为ExtendedErrorTypeSymbol结果类型为NotAnAttributeType。但是,扩展错误类型符号还有一个候选符号,这正是我期望它匹配的符号。
这让我感到惊讶,因为显然类型是一个属性,并且作为正常编译的一部分运行源生成器实际上确实生成了所有正确的类型。这似乎意味着由于这次运行的内存性质,发生了一些奇怪的事情。
据我所知,我的列表References涵盖了正确认识到某物是属性(mscorlib、System.Runtime、netstandard和System.Core)所需的所有内容,尽管也许还MetadataReference缺少另一个?
我确实发现了这个 …
是否有任何标准方法/选项,如何安排通过生成Source Generators并添加到构建过程中的文件在项目结构中也物理可见(以便开发人员可以通过 VS 解决方案资源管理器窗口查看结果代码)?
我的意思是,除了将代码直接保存到生成器中的文件中之外Execute(),我预计这可能会带来其他复杂性(尚未尝试)。
编辑:
C:\Users\user\AppData\Local\Temp\.vsdbgsrc\some-guid\FileNameHint.cs. 不幸的是,标准 VS 导航 (F12) 不起作用(无论调试会话活动如何)。Edit3:在某个时候,这才开始起作用。不知道为什么。也许是 VS 的一个 bug 被修复了?
Edit2:查看解决方案资源管理器中的分析器节点,我发现当我第一次打开程序时,源生成器成功运行,然后它停止,并且在对代码进行一些更改后,它生成的所有内容都会消失。
immediately after opening solution:
> Analyzers
>> MySourceGenerators
>>> MySourceGenerators.NotifyPropertyChangesGenerator
>>>> _NotifyChangedClass_Notify.cs
after making any edits
> Analyzers
>> MySourceGenerators
>>> MySourceGenerators.NotifyPropertyChangesGenerator
>>>> This generator is not generating files.
Run Code Online (Sandbox Code Playgroud)
编辑:按照注释的建议进行调用后Debugger.Launch(),我可以确认生成器代码正在运行,并且源文本看起来与预期的完全一样。但 IDE 和编译器仍然会给出错误,就好像未包含结果一样。
我正在尝试设置一个源生成器以从本地项目引用运行,但无法让它实际运行。我的 NUnit 测试正在通过,所以我知道实际的生成逻辑很好,但是准系统测试项目既无法编译,又会在 Visual Studio 中报告错误。我正在使用 Visual Studio 2022 Preview 5.0,以防万一。
immediately after opening solution:
> Analyzers
>> MySourceGenerators
>>> MySourceGenerators.NotifyPropertyChangesGenerator
>>>> _NotifyChangedClass_Notify.cs
after making any edits
> Analyzers
>> MySourceGenerators
>>> MySourceGenerators.NotifyPropertyChangesGenerator
>>>> This generator is …Run Code Online (Sandbox Code Playgroud) c# roslyn roslyn-code-analysis sourcegenerators csharp-source-generator
我想生成一个静态类,它应该有一个方法,具体取决于特定参考程序集中的其他类。
一个简化的例子:
// Generator.csproj
[Generator]
public class MyGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
// Register a factory that can create our custom syntax receiver
context.RegisterForSyntaxNotifications(() => new MySyntaxReceiver());
}
public void Execute(GeneratorExecutionContext context)
{
// var syntaxReceiver = (MySyntaxReceiver)context.SyntaxReceiver;
}
}
private class MySyntaxReceiver : ISyntaxReceiver
{
....
}
Run Code Online (Sandbox Code Playgroud)
// Core.csproj
// namespace Core.Entities
class Entity1 : IAccessControl {}
class Entity2 {}
class Entity3 : IAccessControl {}
Run Code Online (Sandbox Code Playgroud)
// Persistence.csproj => has a reference to Core …Run Code Online (Sandbox Code Playgroud) 我不知道如何发送还包含 Roslyn 源生成器的 .Net 库,并让源生成器访问主项目的源代码,而不添加从主项目到生成器的显式引用。
目前,我的源代码生成器只能看到我的库的源代码,而看不到主调用项目的源代码。
这是我设置项目的方式:
User "console" test project -> project dependency on -> My lib -> project dependency on -> My source generator
我的库和源生成器一起分发,我希望用户引用该库,但不必担心设置源生成器。
有没有办法找出类是否partial在 Roslyn 分析器内?有一个PartialImplementationPartin IMethodSymbol,但没有类似的 for INamedTypeSymbol。
我正在编写一个源生成器,并且仅在可能的情况下才生成该类的第二部分(如果第一部分是部分的)。
c# partial-classes roslyn-code-analysis csharp-source-generator
我有一个像这样的通用类:
public class Property<TObjectType>
{
}
Run Code Online (Sandbox Code Playgroud)
我想使用新的System.Text.Json 源生成器,但它似乎不适用于通用类。JsonSerializerContext这是该类的派生:
[JsonSerializable(typeof(Property<>))]
public partial class PropertyJsonContext<TObjectType> : JsonSerializerContext
{
}
Run Code Online (Sandbox Code Playgroud)
该错误有点奇怪,因为它使所有其他非通用JsonSerializerContext实现因这两个错误而失败:
Error CS0534: 'XXXJsonContext' does not implement inherited abstract member 'JsonSerializerContext.GeneratedSerializerOptions.get'
Error CS0534: 'XXXJsonContext' does not implement inherited abstract member 'JsonSerializerContext.GetTypeInfo(Type)'
Run Code Online (Sandbox Code Playgroud)
我认为还有一个与我的问题有关的警告:
CSC : warning CS8785: Generator 'JsonSourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'ArgumentException' with message 'The hintName 'PropertyJsonContext`1.NSPropertyTObjectType.g.cs' …Run Code Online (Sandbox Code Playgroud) 我正在开发一个使用 C# 9 的源生成器的项目,但是当生成代码时,我希望将生成的代码的不同文件发送到生成代码的现有项目中的特定文件路径/位置。
这可能吗?我知道我可以指定它们全部放入的文件夹:
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
并将“生成”更改为我希望生成的文件位于其中的文件夹。就像我已经有一个名为“模型”的文件夹一样,我知道我会将“生成”更改为“模型”,然后将其放在那里。
但是,一旦它位于该文件路径内,它就会被放入一个名称为源生成器的项目名称的文件夹中,然后放入另一个名为 namespace.generatorclassname 的文件夹中。
所以在这种情况下,我所发生的事情是:
这是我当前发生的上述场景的屏幕截图: 生成的文件夹结构的屏幕截图
但是,如果我希望将每个文件生成到目标项目预先存在的文件夹结构中的不同位置,该怎么办?那可能吗?有任何想法吗?
我开始使用 .NET 5 中的源生成器来生成一些自定义序列化代码。这对于我的用例来说非常有效。不过,我还想以 JSON 文件的形式为所述序列化器创建自定义架构。不幸的是,我无法找到使用源生成器输出所述生成文件的方法。这有可能吗?或者也许我应该使用其他生成方法?
如何将源生成器作为 nuget 包添加到 C# net5 项目?
要将项目添加为源生成器,请使用以下代码完成此工作:
<ItemGroup>
<ProjectReference Include="..\xyz.SourceGenerators\xyz.SourceGenerators.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false"
SetTargetFramework="TargetFramework=netstandard2.0" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
不过,我正在寻找 XMLPackageReference以添加 nuget 包作为源生成器。
我无法理解 Roslyn 文档并将其与我在增量源生成器上工作时看到的内容相匹配。
https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/compiler-api-model
它有一张信息非常丰富的图片。
据我了解,语法树是解析器工作的结果(这是正确的吗?)。我可以通过 IncrementalGeneratorInitializationContext.SyntaxProvider 访问语法树。让我困惑的是 GeneratorSyntaxContext 有一个名为 SemanticModel 的属性,它似乎允许访问符号。我认为符号是编译的产物,在处理语法时不应该可用。
这引出了另一个问题。编译器管道的哪一部分对应于编译?是活页夹吗?