问题标签 [sourcegenerators]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
572 浏览

c# - 如何发布这个依赖 Nuget 的 C# 源代码生成器?

我创建了一个 C# 源代码生成器,并希望将其发布到 Nuget。

但是我遇到了警告/错误,例如:

  • Some target frameworks declared in the dependencies group of the nuspec and the lib/ref folder do not have exact matches in the other location. Consult the list of actions below: - Add lib or ref assemblies for the netstandard2.0 target framework
  • An instance of analyzer Cosmogenesis.Generator.CosmosGenerator cannot be created from [..]\Cosmogenesis.Generator.dll : Could not load file or assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified..(或 Version=2.0.0.0 取决于我正在尝试的内容)

有一些资源解释了如何,但似乎没有一个在我的确切场景中起作用,即:

  • Cosmogenesis.Core
    • .NET 标准 2.1
    • 不依赖于生成器,但生成的源代码依赖于它
  • Cosmogenesis.Generator(刚刚发布在 Nuget 上Cosmogenesis
    • .NET 标准 2.0
    • 这是源生成器

理想情况下,我希望能够Cosmogenesis从 Nuget 安装,它会自动Cosmogenesis.Core与生成器一起引入。

使用 NuGet 包中的功能<--解释了我的方案(不同的 .net 标准要求除外)。....作为一个附带问题:如果它解释如何使其被自动引用,为什么它有代码来检查是否引用了一个程序集?

反正...

这是Github 上的 Cosmogenesis

Cosmogenesis.Core出版没有任何麻烦。

Cosmogenesis.Generator也使用此.csproj发布

有用。但是,消费者需要参考这两个包。我希望他们只需要参考一个包。

当我添加<IncludeBuildOutput>false</IncludeBuildOutput>(按照上面的教程)时,在构建时我收到这个警告:Some target frameworks declared...[见上文]。如果我忽略它并无论如何发布它,当我在项目中使用包并构建它时,生成器不会运行并且我收到以下警告:An instance of analyzer...[见上文]。

当我添加<PackageReference Include="Cosmogenesis.Core" Version="0.0.1" />(按照上面的教程)时,我得到一个错误。生成器是 .NET Standard 2.0,而 .Core 包是 2.1。错误是:error NU1202: Package Cosmogenesis.Core 0.0.1 is not compatible with netstandard2.0 (.NETStandard,Version=v2.0). Package Cosmogenesis.Core 0.0.1 supports: netstandard2.1 (.NETStandard,Version=v2.1)。可以理解。

当我将生成器项目设置为 2.1 以修复不匹配时,构建时没有出现警告,但是消费者再次收到An instance of analyzer...错误。 C# Source Generators - 编写代码来编写代码 - David Wengier说它们必须是 .net 标准 2.0。

这是我的第一个 nuget 包。还有我的第一个源生成器。任何人都可以建议吗?

编辑:我 75% 确定这个 roslyn github 问题的解决方案可以解决我的问题。

0 投票
2 回答
867 浏览

c# - 将 Unity 与 Source Generator 结合在一起 - Unity 在编译期间不会拾取生成的代码

当我尝试将 Unity 与 Source Generator 结合时遇到问题。

我能够构建一个源生成器并将生成的分析器放在 Unity 中,我的 IDE 能够获取生成的代码(语法突出显示正在工作),但是当 unity 编译它时它无法找到相关的代码,因此给出编译错误。 屏幕截图,IDE 已正确突出显示,但 Unity 控制台中出现错误

似乎人们遇到了类似的问题,但无法找到解决方案。我试图通过第三方库强制 Unity 使用更新版本的 Compiler(3.10),但这似乎也不能解决问题。

据我所知,问题似乎是 Unity 使用的编译器已经过时,但我认为如果是这种情况,我强迫它使用更新版本的编译器的技巧应该可以解决问题。

源生成器无法正常工作的原因是什么,我该如何解决?我不介意使用黑客,因为该项目不是商业的。


更新:

我试图通过在源生成器运行时写入文件来确认我的分析器在某个时间点正在运行。我可以看到我的文件被写入配置的目录,我假设我的生成器在某个时候被使用。

obj但是我在Unity的文件夹中看不到任何生成的源代码。这与我在 Unity 之外运行 Source Generator 时的行为不同。

这背后的可能原因是什么?


更新 2:

为了更清楚(感谢@david-ao 的建议),我认为包含修剪生成的 csproj 可能会有所帮助(在 Unity 中 csproj 是自动生成的,因此我覆盖了项目生成过程并添加了一些必要的设置):

我试图通过上述设置实现以下结果:

  1. 编译时引用分析器
  2. 将生成的文件输出到适当的目录(我故意希望它不在obj文件夹中)
  3. 使用3.10.0-1.final编译器。

如果有帮助,这里是完整生成的 csproj 文件。

0 投票
1 回答
456 浏览

c# - VS Code 不知道 c#9 源代码生成器生成的代码

我有一个控制台应用程序,它引用了一个包含源生成器的项目。

一切正常,代码运行并执行预期的操作,但 VS Code 不知道生成的代码。

我在我的项目中有一个类

在引用的项目中,我生成了这个部分方法的实现:

代码构建并运行良好,但 VS Code 并不满意: 在此处输入图像描述

如何告诉 VS Code 考虑生成代码?

0 投票
1 回答
524 浏览

c# - 用源生成器替换反射

我有一个使用反射的工厂,我想用源生成器生成的反射来替换它。

生成的代码应如下所示:

使用反射,我发现我的类型是这样的:

如何通过 GeneratorExecutionContext.Compilation 对象进行与通过反射代码相同的搜索?

0 投票
1 回答
220 浏览

c# - 每个类获得一个 Roslyn 语法接收器

我有一个简单的源生成器定义为

我在一个包含几个部分类的文件上运行这个生成器。但是,它似乎Execute()只被调用一次,并且Class包含的​​是具有该Main()方法的类,即使我在文件中有其他类。

所以,我的问题是:如何让Execute()每个受影响的语法节点运行一次,即,让它在每个部分类中运行一次?

0 投票
0 回答
347 浏览

c# - C# 源代码生成器在 Razor 视图中表现不佳

所以我在我的 ASP.NET Core MVC 项目中有这个源生成器,它可以生成如下视图模型:

源生成器工作出色。但是,当我尝试加载使用生成模型的视图时,我收到此错误:

InvalidOperationException:传递到 ViewDataDictionary 的模型项的类型为“Boilerplate.Areas.AdminPortal.Models.PersonListModel”,但此 ViewDataDictionary 实例需要“Boilerplate.Areas.AdminPortal.Models.PersonListModel”类型的模型项。

换句话说,它是在说“我想要一个 PersonListModel,但你给了我一个 PersonListModel”(LOL)。如果我在应用程序在调试模式下运行时更改Boilerplate.Areas.AdminPortal.Models.PersonListModel为简单PersonListModel,这会暂时修复它。但在某些时候,它会再次显示此错误。然后,如果我将代码从PersonListModel回更改为Boilerplate.Areas.AdminPortal.Models.PersonListModel(原始代码),它会再次工作一段时间。

显然,在 Razor 视图引擎难以识别传递给 ViewDataDictionary 的模型项是正确的位置时存在某种脱节。这是一个已知的错误?有解决方法还是我只是运气不好?谢谢!

0 投票
1 回答
172 浏览

c# - 源代码生成:如何从 InvocationExpressionSyntax 获取涉及的类型

我正在尝试编写一个源生成器,并且需要扩展方法调用中涉及的类型。

问题是,这个扩展方法是由源生成器自己生成的。所以如果我尝试 get ISymbol,我会在我的 Generator 类中得到 null 。

是否有可能获得我需要的信息?

这是示例

ConvertTo<T>()扩展方法是从源生成器生成的。我可以找到正确的InvocationExpressionSyntax,但我怎样才能获得完全限定的someObjectand类型OtherType

这是生成器

更新:另外我认为我需要的不仅仅是类型。我需要ISymbol获取类型的所有属性

更新 2:我做了一小步,将ConvertTo<T>方法设为局部并使用此方法引用分离项目。我得到了IMethodSymbolnow 并拥有ITypeSymbolfor OtherType,但ITypeSymbolforsomeObjectobject类型,因为扩展方法签名。但我需要具体的类型符号someObject

0 投票
1 回答
143 浏览

c# - 如何对 SourceGenerator 进行单元测试?

我写了一个 SourceGenerator,但我该如何测试呢?

主要问题是如何模仿GeneratorExecutionContext(或只是Compilation在其中)哪个生成器进入Execute方法。我认为有一种正确的方法可以为单元测试制作假的 SyntaxTrees,但我找不到它。有很多关于源生成器本身的文章,但没有一篇解释如何测试生成器。

0 投票
3 回答
1016 浏览

c# - Visual Studio 中未加载源生成器依赖项

我正在研究源代码生成器,但我遇到了依赖问题:

有很多关于如何将依赖项打包到nuget中的信息,但我直接引用分析器项目是这样的:

在我添加的分析器项目<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>中,所有依赖项都在输出目录中可用,但 VS 没有使用该目录 - 它使用AppData\Local\Temp\VBCSCompiler\AnalyzerAssemblyLoader\[...]它并且只复制一个 DLL。

可以做些什么来完成这项工作?

0 投票
0 回答
68 浏览

c# - Generate boilerplate code based on classes in another project

I have a visual studio solution with a couple of C# projects. One of them contains my domain classes and has no infrastructure dependencies and another contains classes that depend on various 3rd party libraries, it's what you'd call an infrastructure project.

For each class in my domain project I have to write a corresponding class in my infrastructure project which contains just some boilerplate code required for using a feature of one of the 3rd party dependencies so I'd like to generate that automatically whenever my domain class is changed.

I was able to generate the classes containing this boilerplate code by creating a source generator with a ISyntaxReceiver that adds the abstract syntax tree of my domain classes for which I need to generate the boilerplate code to a list which is then used by my source generator to create the required classes. I then added this source generator as a project reference to my domain project but I have a problem: the infrastructure classes I need to generate inherit from a class of a 3rd party dependency so I have to add that 3rd party dependency to my domain project.

What I tried to do was to add my source generator as a project reference to my infrastructure project (which already references the 3rd party dependency, and also my domain project) but the source generator does not run because the ISyntaxReceiver's OnVisitSyntaxNode method does not get called for any of the classes in the referenced domain project.

Does anyone know if it's possible to create a source generator that generates code based on classes in projects referenced by the project that references that source generator?

I am aware of the AnalyzerAdditionalFiles, but seems like that should be used for making generation decisions based on more than just C# code