Unity 6 のマニュアルを見ていたら、Roslyn Analyzer についての機能追加があったので紹介します。
Microsoft.CodeAnalysis.Csharp 4.3
アナライザおよびコードジェネレーターをビルドするときに使用する Microsoft.CodeAnalysis.Csharp のバージョンが4.3になったことが明記されました。
なお、実際は Unity 2022.3.12f1 から 4.3 に上がっていたことが知られています。
参考:neue cc - 2022年(2024年)のC# Incremental Source Generator開発手法
Report analyzer diagnostics
アナライザおよびコードジェネレーターの実行時間を Editor.log に出力する機能です。
Windows では Edit > Preferences、macOS では Unity > Settings で Preferencesウィンドウを開き、Diagnostics タブを選択します。

最初は警告が表示されますが、I understand, show me the settings ボタンを押すと設定項目が表示されます。

Code を展開して EnableDomainReloadTimings をonにすると有効化できます。 この機能が有効な間、Consoleウィンドウに次の警告が出ます。
Diagnostic switches are active and may impact performance or degrade your user experience. Switches can be configured through the Diagnostics section in the Preferences window. EnableDomainReloadTimings: True
この状態でコンパイルが走ると、Editor.log に次のようにアナライザごとに使用した時間と割合が出力されます。 これが対象のアセンブリ(DLL)ごとに出ます。
[1134/1140 0s] Csc Library/Bee/artifacts/200b0aEDbg.dag/TestHelper.UI.Tests.dll (+2 others) Total analyzer execution time: 1.084 seconds. NOTE: Elapsed time may be less than analyzer execution time because analyzers can run concurrently. Time (s) % Analyzer 0.754 69 IDisposableAnalyzers, Version=4.0.4.0, Culture=neutral, PublicKeyToken=3feb74da3c492280 0.258 23 IDisposableAnalyzers.FieldAndPropertyDeclarationAnalyzer (IDISP002, IDISP006, IDISP008) 0.252 23 IDisposableAnalyzers.CreationAnalyzer (IDISP004, IDISP014) 0.181 16 IDisposableAnalyzers.AssignmentAnalyzer (IDISP001, IDISP003, IDISP008) 0.036 3 IDisposableAnalyzers.LocalDeclarationAnalyzer (IDISP001, IDISP007) 0.009 <1 IDisposableAnalyzers.DisposeCallAnalyzer (IDISP007, IDISP016, IDISP017) 0.008 <1 IDisposableAnalyzers.ReturnValueAnalyzer (IDISP005, IDISP011, IDISP012, IDISP013) 0.006 <1 IDisposableAnalyzers.ArgumentAnalyzer (IDISP001, IDISP003) 0.001 <1 IDisposableAnalyzers.MethodReturnValuesAnalyzer (IDISP015) 0.001 <1 IDisposableAnalyzers.SuppressFinalizeAnalyzer (IDISP024) 0.001 <1 IDisposableAnalyzers.ClassDeclarationAnalyzer (IDISP025, IDISP026) <0.001 <1 IDisposableAnalyzers.DisposeMethodAnalyzer (IDISP009, IDISP010, IDISP018, IDISP019, IDISP020, IDISP021, IDISP023) <0.001 <1 IDisposableAnalyzers.UsingStatementAnalyzer (IDISP007) <0.001 <1 IDisposableAnalyzers.FinalizerAnalyzer (IDISP022, IDISP023) <0.001 <1 IDisposableAnalyzers.SemanticModelCacheAnalyzer (SyntaxTreeCacheAnalyzer) 0.330 30 nunit.analyzers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 0.102 9 NUnit.Analyzers.TestCaseSourceUsage.TestCaseSourceUsesStringAnalyzer (NUnit1002, NUnit1011, NUnit1015, NUnit1016, NUnit1017, NUnit1018, NUnit1019, NUnit1020, NUnit1029, NUnit1030) 0.051 4 NUnit.Analyzers.DisposeFieldsInTearDown.DisposeFieldsAndPropertiesInTearDownAnalyzer (NUnit1032) 0.046 4 NUnit.Analyzers.TestMethodAccessibilityLevel.TestMethodAccessibilityLevelAnalyzer (NUnit1026) 0.031 2 NUnit.Analyzers.ValueSourceUsage.ValueSourceUsageAnalyzer (NUnit1021, NUnit1022, NUnit1023, NUnit1024, NUnit1025) 0.016 1 NUnit.Analyzers.TestMethodUsage.TestMethodUsageAnalyzer (NUnit1005, NUnit1006, NUnit1007, NUnit1012, NUnit1013, NUnit1014, NUnit1027) 0.012 1 NUnit.Analyzers.StringConstraintWrongActualType.StringConstraintWrongActualTypeAnalyzer (NUnit2024) 0.009 <1 NUnit.Analyzers.SameAsOnValueTypes.SameAsOnValueTypesAnalyzer (NUnit2040) 0.008 <1 NUnit.Analyzers.ComparableTypes.ComparableTypesAnalyzer (NUnit2041, NUnit2042) 0.007 <1 NUnit.Analyzers.SameAsIncompatibleTypes.SameAsIncompatibleTypesAnalyzer (NUnit2020) 0.006 <1 NUnit.Analyzers.EqualToIncompatibleTypes.EqualToIncompatibleTypesAnalyzer (NUnit2021) 0.004 <1 NUnit.Analyzers.WithinUsage.WithinUsageAnalyzer (NUnit2047) 0.004 <1 NUnit.Analyzers.ParallelizableUsage.ParallelizableUsageAnalyzer (NUnit1008, NUnit1009, NUnit1010) 0.004 <1 NUnit.Analyzers.NullConstraintUsage.NullConstraintUsageAnalyzer (NUnit2023) 0.004 <1 NUnit.Analyzers.DelegateRequired.DelegateRequiredAnalyzer (NUnit2044) 0.004 <1 NUnit.Analyzers.SameActualExpectedValue.SameActualExpectedValueAnalyzer (NUnit2009) 0.003 <1 NUnit.Analyzers.MissingProperty.MissingPropertyAnalyzer (NUnit2022) 0.003 <1 NUnit.Analyzers.IgnoreCaseUsage.IgnoreCaseUsageAnalyzer (NUnit2008) 0.003 <1 NUnit.Analyzers.SomeItemsIncompatibleTypes.SomeItemsIncompatibleTypesAnalyzer (NUnit2026) 0.003 <1 NUnit.Analyzers.ClassicModelAssertUsage.ClassicModelAssertUsageAnalyzer (NUnit2001, NUnit2002, NUnit2003, NUnit2004, NUnit2005, NUnit2006, NUnit2015, NUnit2016, NUnit2017, NUnit2018, NUnit2019, NUnit2027, NUnit2028, NUnit2029, NUnit2030, NUnit2031, NUnit2032, NUnit2033, NUnit2034, NUnit2035, NUnit2036, NUnit2037, NUnit2038, NUnit2039) 0.002 <1 NUnit.Analyzers.ConstActualValueUsage.ConstActualValueUsageAnalyzer (NUnit2007) 0.002 <1 NUnit.Analyzers.TestCaseUsage.TestCaseUsageAnalyzer (NUnit1001, NUnit1003, NUnit1004) 0.002 <1 NUnit.Analyzers.UpdateStringFormatToInterpolatableString.UpdateStringFormatToInterpolatableStringAnalyzer (NUnit2050) 0.001 <1 NUnit.Analyzers.ValuesUsage.ValuesUsageAnalyzer (NUnit1031) 0.001 <1 NUnit.Analyzers.CollectionAssertUsage.CollectionAssertUsageAnalyzer (NUnit2049) 0.001 <1 NUnit.Analyzers.StringAssertUsage.StringAssertUsageAnalyzer (NUnit2048) <0.001 <1 NUnit.Analyzers.DiagnosticSuppressors.NonNullableFieldOrPropertyIsUninitializedSuppressor () <0.001 <1 NUnit.Analyzers.DiagnosticSuppressors.AvoidUninstantiatedInternalClassSuppressor () <0.001 <1 NUnit.Analyzers.DiagnosticSuppressors.DereferencePossiblyNullReferenceSuppressor () <0.001 <1 NUnit.Analyzers.UseAssertMultiple.UseAssertMultipleAnalyzer (NUnit2045) <0.001 <1 NUnit.Analyzers.ConstraintUsage.SomeItemsConstraintUsageAnalyzer (NUnit2014) <0.001 <1 NUnit.Analyzers.DiagnosticSuppressors.TypesThatOwnDisposableFieldsShouldBeDisposableSuppressor () <0.001 <1 NUnit.Analyzers.NonTestMethodAccessibilityLevel.NonTestMethodAccessibilityLevelAnalyzer (NUnit1028) <0.001 <1 NUnit.Analyzers.ConstraintUsage.ComparisonConstraintUsageAnalyzer (NUnit2043) <0.001 <1 NUnit.Analyzers.ConstraintUsage.StringConstraintUsageAnalyzer (NUnit2011, NUnit2012, NUnit2013) <0.001 <1 NUnit.Analyzers.ConstraintUsage.EqualConstraintUsageAnalyzer (NUnit2010) <0.001 <1 NUnit.Analyzers.ContainsConstraintWrongActualType.ContainsConstraintWrongActualTypeAnalyzer (NUnit2025) <0.001 <1 NUnit.Analyzers.UseCollectionConstraint.UseCollectionConstraintAnalyzer (NUnit2046) [ 0s] Csc Library/Bee/artifacts/200b0aEDbg.dag/TestHelper.UI.Tests.dll (+2 others) [CacheWrite 00000000000000000000000000000004]
Tips:
Editor.log は、Consoleウィンドウ右上の ︙ > Open Editor Log で開けます(macOSの場合コンソールappで開きます)。
Additional files
Assets フォルダ下に拡張子 .additionalfile のファイルを置くと、ファイルパスを Additional files としてアナライザに渡すことができます。 たとえば Foo.DemoAnalyzers.additionalfile というファイルを置くと、csproj ファイルに次のように追加されます。
<ItemGroup> <AdditionalFiles Include="Assets/Foo.DemoAnalyzers.additionalfile" /> </ItemGroup>
ただし、ファイル名は Filename.[Analyzer Name].additionalfile と決まっているため、たとえば BannedApiAnalyzers のように規定のファイル名しか受け付けないアナライザには使用できません。
参考:How to use Microsoft.CodeAnalysis.BannedApiAnalyzers
これについては BannedApiAnalyzers に Issue #78124 が立っていますが、Unity側でなんとかしてほしいというのはそれはそう*1。
なおこの機能、マニュアルに記載されたのは Unity 6.0 ですが、APIリファレンスを見ると Unity 2021.3 からあったようです。
Roslyn global config file
記事タイトルから逸脱しますが、この機能は Unity 6.2 時点でもマニュアルには未記載、APIリファレンスには Unity 2021.3 から記載されていたものです。
拡張子 .globalconfig のファイルを置くと、アナライザの重大度(severity)を設定できます。つまり ruleset ファイル を置き換えるものです。
ファイルフォーマットは、先頭に is_global = true を書く以外は EditorConfig の重大度設定と同じ*2で、たとえば次のように書きます。
is_global = true dotnet_diagnostic.IDISP001.severity = error
なお、置き場所やファイル名にはルールがあります。 Default.globalconfig(全アセンブリに効く)や Assembly-CSharp.globalconfig(Assembly-CSharpに効く)は Assets 直下に、 アセンブリ個々にはアセンブリ定義ファイル(.asmdef)と同じディレクトリに任意の名前で置きます。
また、csproj ファイルに GlobalAnalyzerConfigFiles として追加されるため、IDE でもUnityエディタと同じ設定を共有できます。 しかし、JetBrains Rider には本稿執筆時点で次のバグがあり、対応が待たれます。[10/7 追記]
参考: