Unity3D :Roslyn analyzers and source generators
推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生
Roslyn analyzers and source generators
在 Unity 项目中使用 Roslyn 分析器、源生成器和规则集文件来检查代码的样式、质量和其他问题。
可以使用现有的分析器库来检查代码,并编写自己的分析器,以便在组织内推广最佳做法或约定。本页介绍如何在空的 Unity 项目中使用 Roslyn 分析器和源生成器。
注意:Roslyn 分析器仅与 Unity 公开支持的 IDE 兼容,即 Visual Studio 和 JetBrains Rider。
有关如何编写和使用 Roslyn 分析器的详细信息,请参阅 Microsoft 的分析器配置和 Roslyn 分析器入门文档。
源生成器
可以使用源生成器作为脚本编译过程中的附加步骤。编译现有代码时,可以使用源生成器添加新代码。与分析器一样,您可以使用现有的源生成器或创建自己的源生成器。
注意:Unity 仅支持“System.Text.Json”命名空间的 6.0.0 预览版。如果要在应用程序中使用此命名空间,请确保使用版本 6.0.0-preview。有关 的详细信息,请参阅 Microsoft 的 System.Text.Json 命名空间文档。System.Text.Json
若要使用 Visual Studio 设置源生成器,请执行以下操作:
- 在 Visual Studio 中,创建一个面向 .NET Standard 2.0 的 .NET 标准库项目。
- 安装 Microsoft.CodeAnalysis NuGet 包。源生成器必须使用 Microsoft.CodeAnalysis 3.8 才能与 Unity 配合使用。
- 在 Visual Studio 项目中,创建一个新的 C# 文件并添加以下代码:
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System.Text;
namespace ExampleSourceGenerator
{
[Generator]
public class ExampleSourceGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
System.Console.WriteLine(System.DateTime.Now.ToString());
var sourceBuilder = new StringBuilder(
@"
using System;
namespace ExampleSourceGenerated
{
public static class ExampleSourceGenerated
{
public static string GetTestText()
{
return ""This is from source generator ");
sourceBuilder.Append(System.DateTime.Now.ToString());
sourceBuilder.Append(
@""";
}
}
}
");
context.AddSource("exampleSourceGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
public void Initialize(GeneratorInitializationContext context) { }
}
}
- 构建要发布的源生成器。为此,请转到“生成”并选择“批量生成”选项。
- 在源生成器的项目文件夹中,找到 bin/Release/netstandard2.0/ExampleSourceGenerator.dll 文件。
- 将此文件复制到 Unity 项目中的“资源”文件夹中。
- 在资产浏览器中,单击.dll文件以打开插件检查器窗口。
- 转到为插件选择平台并禁用任何平台。
- 转到包含平台并禁用编辑器和独立。
- 转到资产标签,然后打开资产标签子菜单。
- 创建并分配一个名为 RoslynAnalyzer 的新标签。为此,请在“资产标签”子菜单的文本输入窗口中输入“RoslynAnalyzer”。此标签必须完全匹配且区分大小写。为第一个分析器创建标签后,标签将显示在“资产标签”子菜单中。您可以单击菜单中的标签名称以将其分配给其他分析器。
- 若要测试源生成器是否正常工作,请使用以下代码在编辑器中创建新的 C# 脚本:
using UnityEngine;
public class HelloFromSourceGenerator : MonoBehaviour
{
static string GetStringFromSourceGenerator()
{
return ExampleSourceGenerated.ExampleSourceGenerated.GetTestText();
}
// Start is called before the first frame update
void Start()
{
var output = "Test";
output = GetStringFromSourceGenerator();
Debug.Log(output);
}
}
- 将此脚本添加到场景中的游戏对象并进入运行模式。您应该会在控制台窗口中看到来自源生成器的消息,包括时间戳。
有关源生成器的详细信息,请参阅 Microsoft 的源生成器文档。
分析器范围
可以使用程序集定义来限制项目中分析器的范围,以便它们仅分析代码的某些部分。
Unity 将分析器应用于项目的“资源”文件夹中的所有程序集,或者父文件夹不包含程序集定义文件的任何子文件夹中的程序集。如果分析器位于包含程序集定义的文件夹或此类文件夹的子文件夹中,则分析器仅适用于从该程序集定义生成的程序集以及引用它的任何其他程序集。
例如,这意味着包可以提供仅分析与包相关的代码的分析器,这可以帮助包用户正确使用包 API。
报表分析器诊断
要查看分析器和源生成器的总执行时间或每个分析器或源生成器的相对执行时间等信息,请转到首选项>诊断开关并启用 EnableDomainReloadTiming 。启用后,信息将显示在控制台窗口中。
安装现有的 Roslyn 分析仪或源生成器
Unity 不支持直接通过 NuGet 安装 Roslyn 分析器或源生成器。下面的示例使用 ErrorProne.NET.CoreAnalyzers 库来演示如何从 NuGet 安装 Roslyn 分析器和源生成器:
- 使用“下载包”按钮将库下载为.zip文件。
- 提取.zip文件的内容。
- 在提取的文件夹中,找到包含分析器的.dll文件。在此示例中,导航到
errorprone.net.coreanalyzers<version-number>\analyzers\dotnet\cd
。所需的文件应位于此文件夹中,名为 、 和 。ErrorProne.NET.Core.dllErrorProne.Net.CoreAnalyzers.dllRuntimeContracts.dll
- 将这些文件移动到 Unity 项目中的“资源”文件夹或嵌套在“资源”文件夹中的任何文件夹中。为此,请转到“资源”>“导入新资源”,然后为每个文件选择.dll,或通过设备的文件浏览器将它们复制到项目的“资产”文件夹中。
- 单击 Unity 中资源浏览器中的.dll文件以打开插件检查器窗口。
- 在插件检查器窗口中:
- 在“为插件选择平台”标题下,禁用“任何平台”。
- 在“包括平台”标题下,禁用“编辑器”和“独立”。
- 在插件检查器窗口中的“资源标签”标题下,单击蓝色标签图标以打开“资源标签”子菜单。
- 创建并分配一个名为 RoslynAnalyzer 的新标签。为此,请在“资产标签”子菜单的文本输入窗口中键入“RoslynAnalyzer”,然后按 Return 键。此标签必须与示例完全匹配,并且区分大小写。为第一个分析器创建标签后,它将显示在“资产标签”子菜单中的可用标签列表中。您可以单击菜单中的标签名称以将其分配给其他分析器。
Unity 可识别 RoslynAnalyzer 标签,并将具有此标签的资源视为 Roslyn Analyzer 或源生成器。将标签分配给分析器时,Unity 会在分析器范围内重新编译脚本,并根据分析器中的规则分析这些脚本中的代码。与分析器位于同一程序集定义中的任何脚本都在该分析器的范围内。对于“资源”文件夹根级别的分析器,Unity 会将项目中的所有文件视为在范围内。有关作用域的详细信息,请参阅上面的分析器作用域。
若要测试分析器是否正常工作,请按照以下示例操作。如果已正确安装分析器,则 ErrorProne.NET 分析器在分析示例中的代码时会引发警告。
创建一个名为 的新脚本文件 。将以下代码复制到此脚本中并保存文件:RethrowError.cs
using System;
using UnityEngine;
public class RethrowError : MonoBehaviour
{
void Update()
{
try
{
DoSomethingInteresting();
}
catch (Exception e)
{
Debug.Log(e.Message);
throw e;
}
}
private void DoSomethingInteresting()
{
throw new System.NotImplementedException();
}
}
保存文件时,Unity 会重新编译脚本,并对脚本代码运行任何适用的分析器。正确安装 ErrorProne.NET 分析器后,它会在控制台窗口中引发有关上述代码的以下警告:
Assets\RethrowError.cs(14,23): warning EPC12: Suspicious exception handling: only e.Message is observed in exception block.
Assets\RethrowError.cs(15,19): warning ERP021: Incorrect exception propagation. Use throw; instead.
规则集文件
若要定义自己的规则来处理项目中的分析器引发的各种警告和错误,可以创建规则集文件。有关如何创建自定义规则集的详细信息,请参阅 Microsoft 的 Visual Studio 文档,了解如何创建自定义规则集。
在“资产”根文件夹中,放置一个名为“默认.规则集”的规则集文件。在 Default.ruleset 中定义的规则适用于所有预定义程序集(例如),以及使用 .asmdef 文件生成的所有程序集。Assembly-CSharp.dll
若要覆盖预定义程序集的 Default.ruleset 中的规则,请在根文件夹中创建名称为 的 .ruleset 文件。例如,中的规则适用于 中的代码。根文件夹中只允许以下 .ruleset 文件:[PredefinedAssemblyName].rulesetAssembly-CSharp.rulesetAssembly-CSharp.dll
Default.ruleset
Assembly-CSharp.ruleset
Assembly-CSharp-firstpass.ruleset
Assembly-CSharp-Editor.ruleset
Assembly-CSharp-Editor-firstpass.ruleset
工作流程:在 Unity 中测试规则集文件
要在 Unity 中测试规则集文件,请执行以下步骤:
步骤 1:设置规则集文件
- 在项目的“资产”文件夹中创建一个名为“子文件夹”的子文件夹。
- 子文件夹内:
- 创建一个新的 .asmdef 文件。
- 保存 的重复副本。
RethrowError.cs
- 使用以下代码在资产中创建 Default.ruleset 文件:
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="New Rule Set" Description=" " ToolsVersion="10.0">
<Rules AnalyzerId="ErrorProne.NET.CodeAnalyzers" RuleNamespace="ErrorProne.NET.CodeAnalyzers">
<Rule Id="ERP021" Action="Error" />
<Rule Id="EPC12" Action="None" />
</Rules>
</RuleSet>
Default.ruleset
文件定义了以下规则:
- 禁止显示 EPC12,即有关可疑异常处理的警告。
- 将 ERP021(有关异常传播不正确的警告)提升为错误。
第 2 步:重新加载项目
将规则集文件添加到项目后,重新导入应应用规则的程序集中的任何脚本。这将强制 Unity 使用新的规则集文件重新编译程序集。重新编译后,您应该在控制台窗口中看到两条消息:
Assets\Subfolder\RethrowError.cs(15,19): error ERP021: Incorrect exception propagation. Use throw; instead.
Assets\RethrowError.cs(15,19): error ERP021: Incorrect exception propagation. Use throw; instead.
请注意,Unity 将 Default.ruleset 中定义的规则应用于 和 。Assets/RethrowError.csAssets/Subfolder/RethrowError.cs
第 3 步:添加自定义规则集
在资产/子文件夹中,创建一个 .ruleset 文件,并为其指定您喜欢的任何名称(在此):exampleHello.ruleset
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="New Rule Set" Description=" " ToolsVersion="10.0">
<Rules AnalyzerId="ErrorProne.NET.CodeAnalyzers" RuleNamespace="ErrorProne.NET.CodeAnalyzers">
<Rule Id="ERP021" Action="Info" />
<Rule Id="EPC12" Action="Info" />
</Rules>
</RuleSet>
此新文件指示 Unity 将 EPC12 和 ERP021 同时打印到控制台,而不会将它们视为警告或错误。Hello.ruleset
Unity 再次编译项目后,您会在 Console 窗口中看到以下消息:
Assets\Subfolder\RethrowError.cs(14,23): info EPC12: Suspicious exception handling: only e.Message is observed in exception block.
Assets\Subfolder\RethrowError.cs(15,19): info ERP021: Incorrect exception propagation. Use throw; instead.
Assets\RethrowError.cs(15,19): error ERP021: Incorrect exception propagation. Use throw; instead.
Default.ruleset
中的规则仍然应用于 ,但它们不再应用于 ,因为 中的规则将其覆盖。Assets\RethrowError.csAssets\Subfolder\RethrowError.csHello.ruleset
有关所有允许的规则集操作文件的更多信息,请参阅 Visual Studio 文档使用代码分析规则集编辑器。
更多分析器
以下是指向其他流行 Roslyn 分析器库的 Github 存储库的链接:
- awesome-analyzers
- dotnet/roslyn-analyzers
由3D建模学习工作室整理翻译,转载请注明出处!