Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Unity開発でのミスを未然に防ぐRoslynアナライザーのすゝめ【DeNA TechCon 2022】

Unity開発でのミスを未然に防ぐRoslynアナライザーのすゝめ【DeNA TechCon 2022】

コードをビルドすることなく、ミスを検知できたらゲーム開発が楽になると思いませんか?

.NETの静的解析器であるRoslynアナライザーを使うことで、ビルドをすることなく問題のあるコードを検出してくれるようになります。

また、Roslynアナライザーは各々のエンジニアがカスタムルールを実装できます。例えば弊社では、実行時にリフレクションでインスタンス化されるクラスのコンストラクタが、IL2CPPビルド時に未使用コードと判別され削除されないように、Roslynアナライザーを実装し、導入することでリリースブロッカーとなりえる問題を早期発見できるようにしています。

そんな便利なRoslynアナライザーですが、 情報が少なくハードルが高い印象を持っている人もいるのではないでしょうか。

本セッションではRoslynアナライザーの導入と、カスタムルール実装のハードルを下げるための情報を共有します。

資料内でのリンク集:
p153,154, https://github.com/DeNA/Dena.CodeAnalysis.Testing
p160,161,162,163,164, https://github.com/DeNA/Dena.CodeAnalysis.Testing
p183-1, https://swet.dena.com/entry/2021/05/25/100000
p183-2, https://www.nowsprinting.com/entry/2021/11/01/083258
p183-3, https://www.nowsprinting.com/entry/2021/04/18/200619
p183-4, https://github.com/dotnet/roslyn-analyzers/tree/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers
p183-5, https://github.com/code-cracker/code-cracker
p183-6, https://github.com/Cysharp/UniTask

◆ You Tube
https://youtu.be/g93LBwvOzxA

◆ You Tube チャンネル登録はこちら↓
https://youtube.com/c/denatech?sub_confirmation=1

◆ Twitter
https://twitter.com/DeNAxTech

◆ DeNA Engineering
https://engineering.dena.com/

◆ DeNA Engineer Blog
https://engineering.dena.com/blog/

◆ DeNA TechCon 2022 公式サイト
https://techcon2022.dena.dev/spring/

8a84268593355816432ceaf78777d585?s=128

DeNA_Tech
PRO

March 17, 2022
Tweet

More Decks by DeNA_Tech

Other Decks in Technology

Transcript

  1. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Unity開発でのミスを未然に防ぐ Roslynアナライザーのすゝめ システム本部品質統括部品質管理部SWET第二グループ Kazuma Inagaki

  2. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 自己紹介 - Kazuma Inagaki - 21新卒

    - SWETグループ所属 - Vimmer
  3. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 - Roslynアナライザーの概要 - Roslynアナライザーができること、使い方 - カスタムルールの作り方

    - カスタムアナライザーをテストする方法 - 作成したアナライザーをUPMパッケージに内包して配布、利用する NOTE: バージョンによってバグによる制約があるため、 このスライドではUnity 2021.2 + Rider Editor package v3.0.9を基準に書いています。 目次
  4. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 - Roslynアナライザーの概要 - Roslynアナライザーができること、使い方 - カスタムルールの作り方

    - カスタムアナライザーをテストする方法 - 作成したアナライザーをUPMパッケージに内包して配布、利用する NOTE: バージョンによってバグによる制約があるため、 このスライドではUnity 2021.2 + Rider Editor package v3.0.9を基準に書いています。 目次
  5. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーの概要 - Roslynとは - Roslynアナライザーとは

  6. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynとは - C#6.0から導入された.NETコンパイラプラットフォームの通称 - 公開されているもの -

    C#、VB向けコンパイラ - コード生成API - コード解析API
  7. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーとは - Roslynのコード解析APIを用いて作成された、コードの問題を検出するプログ ラムのこと

  8. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーとは - Roslynのコード解析APIを用いて作成された、コードの問題を検出するプログ ラムのこと

  9. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 コンパイラ オレオレルール - 型違反 - 未定義関数

    - 未定義変数 - etc... - コーディング規約 - 非推奨のAPIの使用 - etc... 一般的なルール
  10. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 コンパイラ オレオレルール - 型違反 - 未定義関数

    - 未定義変数 - etc... - コーディング規約 - 非推奨のAPIの使用 - etc... 一般的なルール
  11. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 コンパイラ オレオレルール - 型違反 - 未定義関数

    - 未定義変数 - etc... Roslynアナライザーに やってもらおう! 一般的なルール
  12. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 どうやってやってもらうんだ..?

  13. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 IDE上でRoslynアナライザーを使用 IDE上にレポートされる IDE上で欠陥を作り込む Unity上でRoslynアナライザーを使用 ビルド時にUnityエディタ上にレポートされる Unityを開く

  14. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 それだけではない!

  15. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 コンパイラ オレオレルール - コーディング規約 - 非推奨のAPIの使用

    - etc...
  16. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 コンパイラ オレオレルール - コーディング規約 - 非推奨のAPIの使用

    - etc...
  17. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 コンパイラ オレオレルール - コーディング規約 - 非推奨のAPIの使用

    - etc... エンジニア 誰でも診断ルールを 自作できる
  18. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 - Roslynアナライザーの概要 - Roslynアナライザーができること、使い方 - カスタムルールの作り方

    - カスタムアナライザーをテストする方法 - 作成したアナライザーをUPMパッケージに内包して配布、利用する NOTE: バージョンによってバグによる制約があるため、 このスライドではUnity 2021.2 + Rider Editor package v3.0.9を基準に書いています。 目次
  19. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーができること、使い方 - 様々な診断ルールを持つアナライザーの紹介 - Unity上でRoslynアナライザーを使う方法 -

    JetBrains Rider上でRoslynアナライザーを使う方法 - アナライザーTips
  20. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーができること、使い方 - 様々な診断ルールを持つアナライザーの紹介 - Unity上でRoslynアナライザーを使う方法 -

    JetBrains Rider上でRoslynアナライザーを使う方法 - アナライザーTips
  21. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 様々な診断ルールを持つアナライザーの紹介 - Microsoft.CodeAnalysis.BannedApiAnalyzer - 汎用的に特定のAPIを使用禁止にできるアナライザー -

    例: UniTaskでなくTaskを使用していたら怒るルール - codecracker.CSharp - dispose漏れを怒るルール(CS0022) - DeNA内で作成したアナライザー - Preserve属性のつけ忘れを怒るルール
  22. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 様々な診断ルールを持つアナライザーの紹介 - Microsoft.CodeAnalysis.BannedApiAnalyzer - 汎用的に特定のAPIを使用禁止にできるアナライザー -

    例: UniTaskでなくTaskを使用していたら怒るルール - codecracker.CSharp - dispose漏れを怒るルール(CS0022) - DeNA内で作成したアナライザー - Preserveのつけ忘れを怒るルール
  23. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); } Taskを使用した例 UniTaskを使用した例 public async UniTask M() { await UniTask.Delay(100); }
  24. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); } Taskを使用した例 UniTaskを使用した例 UniTaskでなく、Taskを使っている public async UniTask M() { await UniTask.Delay(100); }
  25. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); } Taskを使用した例 UniTaskを使用した例 Do not used banned APIs public async UniTask M() { await UniTask.Delay(100); }
  26. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 様々な診断ルールを持つアナライザーの紹介 - Microsoft.CodeAnalysis.BannedApiAnalyzer - 汎用的に特定のAPIを使用禁止にできるアナライザー -

    例: UniTaskでなくTaskを使用していたら怒るルール - codecracker.CSharp - dispose漏れを怒るルール(CS0022) - DeNA内で作成したアナライザー - Preserveのつけ忘れを怒るルール
  27. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public class MustDisposeClass : IDisposable {

    } void M() { var hoge = new MustDisposeClass(); }
  28. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public class MustDisposeClass : IDisposable {

    } void M() { var hoge = new MustDisposeClass(); } Disposeができていない!
  29. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public class MustDisposeClass : IDisposable {

    } void M() { var hoge = new MustDisposeClass(); } MustDisposeClass should be disposed.
  30. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public class MustDisposeClass : IDisposable {

    } void M() { var hoge = new MustDisposeClass(); }
  31. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public class MustDisposeClass : IDisposable {

    } void M() { var hoge = new MustDisposeClass(); } using (var hoge = new MustDisposeClass()) { } void M() { var hoge = new MustDisposeClass(); hoge.Dispose(); }
  32. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public class MustDisposeClass : IDisposable {

    } void M() { var hoge = new MustDisposeClass(); } using (var hoge = new MustDisposeClass()) { } void M() { var hoge = new MustDisposeClass(); hoge.Dispose(); }
  33. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 様々な診断ルールを持つアナライザーの紹介 - Microsoft.CodeAnalysis.BannedApiAnalyzer - 汎用的に特定のAPIを使用禁止にできるアナライザー -

    例: UniTaskでなくTaskを使用していたら怒るルール - codecracker.CSharp - dispose漏れを怒るルール(CS0022) - DeNA内で作成したアナライザー - Preserve属性のつけ忘れを怒るルール
  34. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 var services = new ServiceCollection(); services.AddSingleton<IGoodService,

    GoodService>(); services.AddSingleton<IBadServiceNoInject, BadServiceNoInject>(); DIコンテナへの登録
  35. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 var services = new ServiceCollection(); services.AddSingleton<IGoodService,

    GoodService>(); services.AddSingleton<IBadServiceNoInject, BadServiceNoInject>(); DIコンテナへの登録
  36. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public class GoodService : IGoodService {

    [Preserve] public GoodService() { } } public class BadServiceNoInject : IBadServiceNoInject { public BadServiceNoInject() { } } var services = new ServiceCollection(); services.AddSingleton<IGoodService, GoodService>(); services.AddSingleton<IBadServiceNoInject, BadServiceNoInject>(); DIコンテナへの登録
  37. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Preserve属性あり Preserve属性なし public class GoodService :

    IGoodService { [Preserve] public GoodService() { } } public class BadServiceNoInject : IBadServiceNoInject { public BadServiceNoInject() { } } var services = new ServiceCollection(); services.AddSingleton<IGoodService, GoodService>(); services.AddSingleton<IBadServiceNoInject, BadServiceNoInject>(); DIコンテナへの登録
  38. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Preserve属性あり Preserve属性なし public class GoodService :

    IGoodService { [Preserve] public GoodService() { } } public class BadServiceNoInject : IBadServiceNoInject { public BadServiceNoInject() { } } var services = new ServiceCollection(); services.AddSingleton<IGoodService, GoodService>(); services.AddSingleton<IBadServiceNoInject, BadServiceNoInject>(); DIコンテナへの登録
  39. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 var services = new ServiceCollection(); services.AddSingleton<IGoodService,

    GoodService>(); services.AddSingleton<IBadServiceNoInject, BadServiceNoInject>(); DIコンテナへの登録 Preserve属性あり Preserve属性なし public class GoodService : IGoodService { [Preserve] public GoodService() { } } public class BadServiceNoInject : IBadServiceNoInject { public BadServiceNoInject() { } } IL2CPPでビルドした時に最適化によって、直接使用されない且つ Preserve 属性の無いコンストラクタを持つクラスはストリップされる。
  40. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 バグの混入 ビルドする クラッシュする public class BadServiceNoInject

    : IBadServiceNoInject { public BadServiceNoInject () { } } ビルドが成功する 端末等で操作
  41. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザなし アナライザあり ビルドが失敗する ミスが早く見つかる public class

    BadServiceNoInject : IBadServiceNoInject { public BadServiceNoInject () { } } クラッシュする public class BadServiceNoInject : IBadServiceNoInject { public BadServiceNoInject () { } } ビルドが成功する 端末等で操作
  42. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーができること、使い方 - 様々な診断ルールを持つアナライザーの紹介 - Unity上でRoslynアナライザーを使う方法 -

    JetBrains Rider上でRoslynアナライザーを使う方法 - アナライザーTips
  43. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーができること、使い方 - 様々な診断ルールを持つアナライザーの紹介 - Unity上でRoslynアナライザーを使う方法 -

    JetBrains Rider上でRoslynアナライザーを使う方法 - アナライザーTips
  44. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Unity上でRoslynアナライザーを使う方法 - Unityへの導入の仕方 - Unityエディター上でのアナライザーの振る舞い

  45. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Unity上でRoslynアナライザーを使う方法 - Unityへの導入の仕方 - Unityエディター上でのアナライザーの振る舞い

  46. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 dllを、Unityプロジェクト下の 任意のフォルダに配置する Unity上で設定する アナライザーが動作する 範囲の設定をする Unityへの導入の仕方

  47. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 dllを、Unityプロジェクト下の 任意のフォルダに配置する Unity上で設定する アナライザーが動作する 範囲の設定をする Unityへの導入の仕方

  48. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assets/Hoge/ ├── Editor │ └── YourLibrary.Editor.asmdef

    ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef
  49. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assets/Hoge/ ├── Editor │ └── YourLibrary.Editor.asmdef

    ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef Assets/Hoge/ ├── Analyzers │ ├── your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef Assets下の任意のディレクトリに アナライザーのdllを配置する
  50. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assets/Hoge/ ├── Editor │ └── YourLibrary.Editor.asmdef

    ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef Assets/Hoge/ ├── Analyzers │ ├── your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef Assets下の任意のディレクトリに アナライザーのdllを配置する
  51. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 dllを、Unityプロジェクト下の 任意のフォルダに配置する Unity上で設定する アナライザーが動作する 範囲の設定をする Unityへの導入の仕方

  52. Unity上での設定の仕方 1. アナライザーのDLLをProjectウィンドウで選択(インス ペクタが開く) 2. Select Platforms for plugin下のチェックボックスをすべ てoff

    3. Applyボタンをクリック 4. 栞アイコンをクリック 5. ウィンドウに”RoslynAnalyzer”と入力し、Enterを押す
  53. Unity上での設定の仕方 1. アナライザーのDLLをProjectウィンドウで選択(インス ペクタが開く) 2. Select Platforms for plugin下のチェックボックスをすべ てoff

    3. Applyボタンをクリック 4. 栞アイコンをクリック 5. ウィンドウに”RoslynAnalyzer”と入力し、Enterを押す
  54. Unity上での設定の仕方 1. アナライザーのDLLをProjectウィンドウで選択(インス ペクタが開く) 2. Select Platforms for plugin下のチェックボックスをすべ てoff

    3. Applyボタンをクリック 4. 栞アイコンをクリック 5. ウィンドウに”RoslynAnalyzer”と入力し、Enterを押す
  55. Unity上での設定の仕方 1. アナライザーのDLLをProjectウィンドウで選択(インス ペクタが開く) 2. Select Platforms for plugin下のチェックボックスをすべ てoff

    3. Applyボタンをクリック 4. 栞アイコンをクリック 5. ウィンドウに”RoslynAnalyzer”と入力し、Enterを押す
  56. Unity上での設定の仕方 1. アナライザーのDLLをProjectウィンドウで選択(インス ペクタが開く) 2. Select Platforms for plugin下のチェックボックスをすべ てoff

    3. Applyボタンをクリック 4. 栞アイコンをクリック 5. ウィンドウに”RoslynAnalyzer”と入力し、Enterを押す
  57. Unity上での設定の仕方 1. アナライザーのDLLをProjectウィンドウで選択(インス ペクタが開く) 2. Select Platforms for plugin下のチェックボックスをすべ てoff

    3. Applyボタンをクリック 4. 栞アイコンをクリック 5. ウィンドウに”RoslynAnalyzer”と入力し、Enterを押す
  58. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 dllを、Unityプロジェクト下の 任意のフォルダに配置する Unity上で設定する アナライザーが動作する 範囲の設定をする Unityへの導入の仕方

  59. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする Assets/Hoge/ ├── Analyzers │ ├──

    your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef
  60. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする Assets/Hoge/ ├── Analyzers │ ├──

    your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef YourLibrary.Runtimeアセンブリに含まれる C#スクリプト(YourLibraryCode.cs) にアナライザーを適用したい
  61. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする Assets/Hoge/ ├── Analyzers │ ├──

    your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef Assets/Hoge/ ├── Analyzers │ ├── Analyzers.asmdef │ ├── dummyFile.cs │ ├── your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef Assets下のアナライザーDLLが含まれる ディレクトリにasmdefとダミーのC#スクリ プトを配置する
  62. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする Assets/Hoge/ ├── Analyzers │ ├──

    your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef Assets/Hoge/ ├── Analyzers │ ├── Analyzers.asmdef │ ├── dummyFile.cs │ ├── your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef Analyzersを別アセンブリから参照する際にはア センブリの生成が必要です。そのため、何かしら のC#スクリプトを置く必要があります。
  63. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする Assets/Hoge/ ├── Analyzers │ ├──

    Analyzers.asmdef │ ├── dummyFile.cs │ ├── your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef 1. アナライザーを適用したい asmdefをinspecterで開く (無い場合はasmdef作成する) 2. Assembly Defintion Reference に アナライザーを含む アセンブリ(Analyzers)を追加 3. applyを押す
  64. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする 1. アナライザーを適用したい asmdefをinspecterで開く (無い場合はasmdef作成する) 2.

    Assembly Defintion Reference に アナライザーを含む アセンブリ(Analyzers)を追加 3. applyを押す
  65. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする 1. アナライザーを適用したい asmdefをinspecterで開く (無い場合はasmdef作成する) 2.

    Assembly Defintion Reference に アナライザーを含む アセンブリ(Analyzers)を追加 3. applyを押す
  66. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assets/Hoge/ ├── Analyzers │ ├── Analyzers.asmdef

    │ ├── dummyFile.cs │ ├── your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef アナライザーが動作する範囲の設定をする Assets/your.library/ ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef YourLibrary.Runtimeアセンブリに含まれる C#コード(YourLibraryCode.cs)に アナライザーが適用されます 。
  67. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assets/Hoge/ ├── Analyzers │ ├── your.library.analyzers.asmdef

    │ ├── your.library.analyzers.dll │ └── your.library.analyzers.dll.meta ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef アナライザーが動作する範囲の設定をする Assets/your.library/ ├── Editor │ └── YourLibrary.Editor.asmdef ├── Runtime │ ├── YourLibrary.Runtime.asmdef │ └── YourLibraryCode.cs └── Tests └── YourLibrary.Tests.asmdef YourLibrary.Runtimeアセンブリに含まれる C#コード(YourLibraryCode.cs)に アナライザーが適用されます 。
  68. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Unity上でRoslynアナライザーを使う方法 - Unityへの導入の仕方 - Unityエディター上でのアナライザーの振る舞い

  69. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Unityエディター上でのRoslynアナライザーの振る舞い ↑のように、重要度に応じた結果が出力される 重要度がエラーなら、コンパイルエ ラーと同等の扱いになる

  70. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーができること、使い方 - 様々な診断ルールを持つアナライザーの紹介 - Unity上でRoslynアナライザーを使う方法 -

    JetBrains Rider上でRoslynアナライザーを使う方法 - アナライザーTips
  71. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 JetBrains Rider上でRoslynアナライザーを使う方法 Unity上にRoslynアナライザーを導 入する Unityから、Assets |

    Open C# Projectなどの操作をするだけ NOTE: Visual Studio、 VS Codeでの動作は未検証です。
  72. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 JetBrains Rider上でRoslynアナライザーを使う方法 Unity上にRoslynアナライザーを導 入する Unityから、Assets |

    Open C# Projectなどの操作をするだけ NOTE: Visual Studio、 VS Codeでの動作は未検証です。
  73. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 JetBrains Rider上でのRoslynアナライザーの振る舞い エディタ上に問題箇所がハイライトさ れ、修正ポップアップに詳細が表示さ れる Code

    | Inspect Code…から実行 すれば、インスペクション結果ウィンド ウに出力される NOTE: Visual Studio、 VS Codeでの動作は未検証です。
  74. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーができること、使い方 - 様々な診断ルールを持つアナライザーの紹介 - Unity上でRoslynアナライザーを使う方法 -

    JetBrains Rider上でRoslynアナライザーを使う方法 - アナライザーTips
  75. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 RoslynアナライザーTips - 重要度の設定 - Roslynアナライザーの診断を抑制する方法 -

    RoslynアナライザーをCI上で動かす NOTE: Visual Studio、VS Codeでの動作は未検証です。
  76. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 RoslynアナライザーTips - 重要度の設定 - Roslynアナライザーの診断を抑制する方法 -

    RoslynアナライザーをCI上で動かす NOTE: Visual Studio、VS Codeでの動作は未検証です。
  77. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーの診断ルールごとに診断の重要度(severity)が設定されている - error - warning -

    suggestion - silent - none
  78. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 - CS1002: エラー - CS0219: 警告

    各アナライザにはデフォルトの重 要度が設定されている
  79. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 - CS1002: エラー - CS0219: 警告

    各アナライザにはデフォルトの重 要度が設定されている
  80. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 - CS1002: エラー - CS0219: 警告

    CS0219をエラーにした いなぁ... 各アナライザにはデフォルトの重 要度が設定されている
  81. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 - ルールセット ファイル - ルールセット ファイル

    - EditorConfig ファイル - DotSetting ファイル 重要度設定の方法 Unity JetBrains Rider
  82. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 - ルールセット ファイル - ルールセット ファイル

    - EditorConfig ファイル - DotSetting ファイル 重要度設定の方法 Unity JetBrains Rider
  83. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 ルールセット ファイルによる重要度の設定 Assets/ ├── your.library.analyzers.dll ├──

    your.library.analyzers.dll.meta ├── RethrowError.cs ├── Default.ruleset └── Subfolder ├── Subfoloder.asmdef └── RethrowError.cs Assets直下に Default.rulesetを配置する
  84. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 ルールセット ファイルによる重要度の設定 Assets/ ├── your.library.analyzers.dll ├──

    your.library.analyzers.dll.meta ├── RethrowError.cs ├── Default.ruleset └── Subfolder ├── Subfoloder.asmdef └── RethrowError.cs Assets直下に ”Default.ruleset” という名前で ファイルを配置する <?xml version="1.0" encoding="utf-8"?> <RuleSet Name="New Rule Set" Description=" " ToolsVersion="10.0"> <Rules AnalyzerId="your.library.analyzers" RuleNamespace="your.library.analyzers"> <Rule Id="YourAnalyzersID" Action="Error" /> </Rules> </RuleSet>
  85. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 ルールセット ファイルによる重要度の設定 <?xml version="1.0" encoding="utf-8"?> <RuleSet

    Name="New Rule Set" Description=" " ToolsVersion="10.0"> <Rules AnalyzerId="your.library.analyzers" RuleNamespace="your.library.analyzers"> <Rule Id="YourAnalyzersID" Action="Error" /> </Rules> </RuleSet>
  86. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 ルールセット ファイルによる重要度の設定 <?xml version="1.0" encoding="utf-8"?> <RuleSet

    Name="New Rule Set" Description=" " ToolsVersion="10.0"> <Rules AnalyzerId="your.library.analyzers" RuleNamespace="your.library.analyzers"> <Rule Id="YourAnalyzersID" Action="Error" /> </Rules> </RuleSet> アナライザーのIDを指定 アナライザーの重要度を上書き
  87. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 ルールセット ファイルによる重要度の設定 <?xml version="1.0" encoding="utf-8"?> <RuleSet

    Name="New Rule Set" Description=" " ToolsVersion="10.0"> <Rules AnalyzerId="your.library.analyzers" RuleNamespace="your.library.analyzers"> <Rule Id="YourAnalyzersID" Action="Error" /> </Rules> </RuleSet> アナライザーのIDを指定 アナライザーの重要度を上書き
  88. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 RoslynアナライザーTips - 重要度の設定 - Roslynアナライザーの診断を抑制する方法 -

    RoslynアナライザーをCI上で動かす NOTE: Visual Studio、VS Codeでの動作は未検証です。
  89. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーに怒られるコードを 仕方なく書いた 自動生成されたコードに対して アナライザーが警告を出してしまう なぜ抑制するのか

  90. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーの診断を抑制する方法 - ファイルパス、拡張子単位での抑制(Unityでは不可能) - クラス、メソッド単位での抑制 -

    ステートメント単位での抑制
  91. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーの診断を抑制する方法 - ファイルパス、拡張子単位での抑制(Unityでは不可能) - クラス、メソッド単位での抑制 -

    ステートメント単位での抑制
  92. ファイルパス、拡張子単位の抑制 1. Preferences… | Editor | Inspection Settings を開く 2.

    Elements to Skip で除外するフォルダや拡張子のパターン を追加する 3. Saveボタン右のプルダウンで、 Solution YOUR_PROJECT_NAME team-shared を選択して保存
  93. ファイルパス、拡張子単位の抑制 1. Preferences… | Editor | Inspection Settings を開く 2.

    Elements to Skip で除外するフォルダや拡張子のパターン を追加する 3. Saveボタン右のプルダウンで、 Solution YOUR_PROJECT_NAME team-shared を選択して保存
  94. ファイルパス、拡張子単位の抑制 1. Preferences… | Editor | Inspection Settings を開く 2.

    Elements to Skip で除外するフォルダや拡張子のパターン を追加する 3. Saveボタン右のプルダウンで、 Solution YOUR_PROJECT_NAME team-shared を選択して保存
  95. ファイルパス、拡張子単位の抑制 1. Preferences… | Editor | Inspection Settings を開く 2.

    Elements to Skip で除外するフォルダや拡張子のパターン を追加する 3. Saveボタン右のプルダウンで、 Solution YOUR_PROJECT_NAME team-shared を選択して保存
  96. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーの診断を抑制する方法 - ファイルパス、拡張子単位での抑制(Unityでは不可能) - クラス、メソッド単位での抑制 -

    ステートメント単位での抑制
  97. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); } Do not use Task. Use the UniTask
  98. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); } このメソッド内だけに限り 使うことを許可したいなぁ ...
  99. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 [SuppressMessage("ApiDesign", "RS0030")] public async Task M()

    { await Task.Delay(100); } このメソッド内だけに限り 使うことを許可したいなぁ ...
  100. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 [SuppressMessage("ApiDesign", "RS0030")] public async Task M()

    { await Task.Delay(100); } このメソッド内だけに限り 使うことを許可したいなぁ ... アナライザーのID アナライザーのカテゴリー
  101. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 [SuppressMessage("ApiDesign", "RS0030")] public async Task M()

    { await Task.Delay(100); } 警告を抑制出来る! アナライザーのID アナライザーのカテゴリー
  102. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーの診断を抑制する方法 - ファイルパス、拡張子単位での抑制(Unityでは不可能) - クラス、メソッド単位での抑制 -

    ステートメント単位での抑制
  103. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); await Task.Delay(100); } Do not use Task. Use the UniTask.
  104. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); await Task.Delay(100); } Do not use Task. Use the UniTask. このステートメントに限り 警告を抑制したい
  105. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); #pragma warning disable RS0030 await Task.Delay(100); #pragma warning restore RS0030 }
  106. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); #pragma warning disable RS0030 await Task.Delay(100); #pragma warning restore RS0030 }
  107. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); #pragma warning disable RS0030 await Task.Delay(100); #pragma warning restore RS0030 }
  108. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await

    Task.Delay(100); #pragma warning disable RS0030 await Task.Delay(100); #pragma warning restore RS0030 } このステートメントに限り 抑制出来る!
  109. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 RoslynアナライザーTips - 重要度の設定 - Roslynアナライザーの診断を抑制する方法 -

    RoslynアナライザーをCI上で動かす NOTE: Visual Studio、VS Codeでの動作は未検証です。
  110. コマンドラインからバッ チモードでUnityを起動 コードをPush 注意: 一般的なlintツールとは異なり、コン パイルログに混ざってアナライザーの診断 結果も出力される Copyright: Jenkins project

    https://jenkins.io
  111. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 目次 - Roslynアナライザーの概要 - Roslynアナライザーができること、使い方 -

    カスタムルールの作り方 - カスタムアナライザをテストする方法 - 作成したアナライザーをUPMパッケージに内包して配布、利用する NOTE: バージョンによってバグによる制約があるため、 このスライドではUnity 2021.2 + Rider Editor package v3.0.9を基準に書いています。
  112. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 カスタムルールの作り方 - ソリューションプロジェクトの作成 - 定義を検査する例 -

    呼び出しを検査する例
  113. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 カスタムルールの作り方 - ソリューションプロジェクトの作成 - 定義を検査する例 -

    呼び出しを検査する例
  114. ソリューション・プロジェクトを作成する 1. ソリューションを作成する 2. Analyzerのプロジェクトを作成する 3. プロジェクトをソリューションに追加する 4. 必要なパッケージをインストールする RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.csproj │ └── RoslynToyAnalyzer.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet new sln -o RoslynToyAnalyzer
  115. ソリューション・プロジェクトを作成する 1. ソリューションを作成する 2. Analyzerのプロジェクトを作成する 3. プロジェクトをソリューションに追加する 4. 必要なパッケージをインストールする RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.csproj │ └── RoslynToyAnalyzer.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet new classlib -o RoslynToyAnalyzer
  116. ソリューション・プロジェクトを作成する 1. ソリューションを作成する 2. Analyzerのプロジェクトを作成する 3. プロジェクトをソリューションに追加する 4. 必要なパッケージをインストールする RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.csproj │ └── RoslynToyAnalyzer.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet sln add RoslynToyAnalyzer/RoslynToyAnalyzer.csproj
  117. ソリューション・プロジェクトを作成する 1. ソリューションを作成する 2. Analyzerのプロジェクトを作成する 3. プロジェクトをソリューションに追加する 4. 必要なパッケージをインストールする RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.csproj │ └── RoslynToyAnalyzer.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet add RoslynToyAnalyzer package Microsoft.CodeAnalysis.Analyzers --version 3.3.2 dotnet add RoslynToyAnalyzer package Microsoft.CodeAnalysis.CSharp --version 3.5.0
  118. ソリューション・プロジェクトを作成する 1. ソリューションを作成する 2. Analyzerのプロジェクトを作成する 3. プロジェクトをソリューションに追加する 4. 必要なパッケージをインストールする RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.csproj │ └── RoslynToyAnalyzer.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet add RoslynToyAnalyzer package Microsoft.CodeAnalysis.Analyzers --version 3.3.2 dotnet add RoslynToyAnalyzer package Microsoft.CodeAnalysis.CSharp --version 3.5.0
  119. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 カスタムルールの作り方 - ソリューションプロジェクトの作成 - 定義を検査する例 -

    呼び出しを検査する例
  120. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 定義を検査する例 public class Foo { }

    NamedTypeのシンボル名に小文字を含む命 名に対して警告を出す
  121. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 定義を検査する例 public class Foo { }

    NamedTypeのシンボル名に小文字を含んだ 名前 Foo が使用されています。
  122. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 定義を検査する例 public class Foo { }

    NamedTypeって何?
  123. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 定義を検査する例 public class Foo { }

    NamedTypeはclass、Enum、struct、 Interfaceを含んだシンボルの名前を意味し ます。
  124. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax;

    using Microsoft.CodeAnalysis.Diagnostics; using System.Collections.Immutable; using System.Linq; namespace RoslynToyAnalyzer { [DiagnosticAnalyzer(LanguageNames.CSharp)] public class RoslynToyAnalyzer : DiagnosticAnalyzer { private static readonly DiagnosticDescriptor _toyRule = new DiagnosticDescriptor( id: "TOY001", title: "NamedTypeのシンボルに小文字を含む命名を禁止するアナライザー", messageFormat: "NamedTypeのシンボルに小文字を含んだ命名 {0} が使用されています", category: "RoslynToyAnalyzer", defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(_toyRule); } } public override void Initialize(AnalysisContext context) { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType); } private static void AnalyzeSymbol(SymbolAnalysisContext context) { var namedTypeSymbol = (INamedTypeSymbol)context.Symbol; if (namedTypeSymbol.Name.ToCharArray().Any(char.IsLower)) { var diagnostic = Diagnostic.Create( _toyRule, namedTypeSymbol.Locations[0], namedTypeSymbol.Name); context.ReportDiagnostic(diagnostic); } } }
  125. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax;

    using Microsoft.CodeAnalysis.Diagnostics; using System.Collections.Immutable; using System.Linq; namespace RoslynToyAnalyzer { [DiagnosticAnalyzer(LanguageNames.CSharp)] public class RoslynToyAnalyzer : DiagnosticAnalyzer { private static readonly DiagnosticDescriptor _toyRule = new DiagnosticDescriptor( id: "TOY001", title: "NamedTypeのシンボルに小文字を含む命名を禁止するアナライザー", messageFormat: "NamedTypeのシンボルに小文字を含んだ命名 {0} が使用されています", category: "RoslynToyAnalyzer", defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(_toyRule); } } public override void Initialize(AnalysisContext context) { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType); } private static void AnalyzeSymbol(SymbolAnalysisContext context) { var namedTypeSymbol = (INamedTypeSymbol)context.Symbol; if (namedTypeSymbol.Name.ToCharArray().Any(char.IsLower)) { var diagnostic = Diagnostic.Create( _toyRule, namedTypeSymbol.Locations[0], namedTypeSymbol.Name); context.ReportDiagnostic(diagnostic); } } } アナライザークラス アナライザーの診断ルールの宣言 SupportedDiagnosticsプロパティ(必須プロパティ) Initializeメソッド(必須メソッド) 実際の診断を行うメソッドの実装
  126. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 [DiagnosticAnalyzer(LanguageNames.CSharp)] public class RoslynToyAnalyzer : DiagnosticAnalyzer

    { public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { } public override void Initialize(AnalysisContext context) { } } アナライザーのベースとなるクラスを継承 DiagnosticAnalyzer属性をつける SupportedDiagnosticsメソッドの実装が必要(後述) Initializeメソッドの実装が必要(後述) アナライザークラスの作成
  127. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 private static readonly DiagnosticDescriptor _toyRule =

    new DiagnosticDescriptor( id: "TOY001", title: "NamedTypeのシンボルに小文字を含む命名を禁止するアナライザー ", messageFormat: "NamedTypeのシンボルに小文字を含んだ命名 {0} が使用されています ", category: "RoslynToyAnalyzer", defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); アナライザーのカテゴリを指定 診断時に出力する警告文のテンプレートを定義 デフォルトの重要度を設定 デフォルトで診断が有効な場合はtrueを返す アナライザーの診断ルールの宣言 アナライザーのIDを指定 診断内容を説明するタイトル
  128. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get

    { return ImmutableArray.Create(_toyRule); } } 作成したアナライザが提供するアナライザーの一覧を配列で返す SupportedDiagnosticsプロパティの実装(必須) DiagnosticAnalyzerを継承したので、SupportedDiagnosticsプロパティの実装が必要
  129. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public override void Initialize(AnalysisContext context) {

    context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType); } コールバックを受け取りたい契機をAnalysisContextに登録する Initializeメソッドの実装(必須) Roslynコンパイラによってアナライザーがロードされると呼ばれるメソッド DiagnosticAnalyzerを継承したので、Initializeメソッドの実装が必要 シンボルの意味解析ごとに動作させたいメソッド ”AnalyzeSymbol”を、”RegisterSymbolAction”で登録
  130. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 private static void AnalyzeSymbol(SymbolAnalysisContext context) {

    var namedTypeSymbol = (INamedTypeSymbol)context.Symbol; if (namedTypeSymbol.Name.ToCharArray().Any(char.IsLower)) { var diagnostic = Diagnostic.Create( _toyRule, namedTypeSymbol.Locations[0], namedTypeSymbol.Name); context.ReportDiagnostic(diagnostic); } } 診断に必要な情報を取得 実際の診断を行うメソッドの実装 診断結果を作成して返す シンボルの名前に小文字を含むか判定
  131. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 カスタムルールの作り方 - ソリューションプロジェクトの作成 - 定義を検査する例 -

    呼び出しを検査する例
  132. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 呼び出しを検査する例 var hoge = new ArrayList();

    System.Collections.ArrayListをインスタン ス化しています。 System.Collections.Generic.Listを代わりに 使用してください。
  133. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 using System.Collections.Generic; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics;

    using System.Collections.Immutable; using Microsoft.CodeAnalysis.Operations; namespace RoslynToyAnalyzer { [DiagnosticAnalyzer(LanguageNames.CSharp)] public class RoslynToyAnalyzer : DiagnosticAnalyzer { private static readonly DiagnosticDescriptor _toyRule2 = new DiagnosticDescriptor( id: "TOY002", title: "System.Collections.ArrayListのインスタンス作成を禁止するアナライザー ", messageFormat: "System.Collections.ArrayListをインスタンス化しています。 System.Collections.Generic.Listを代わりに使用してくださ い。", category: "RoslynToyAnalyzer", defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(_toyRule2); } } public override void Initialize(AnalysisContext context) { context.RegisterOperationAction(AnalyzeCreationObject, OperationKind.ObjectCreation); } private static void AnalyzeCreationObject(OperationAnalysisContext context) { var operation = (IObjectCreationOperation)context.Operation; var symbol = operation.Type; var symbolFullName = GetSymbolFullName(symbol); if (symbolFullName != "System.Collections.ArrayList") return; var diagnostic = Diagnostic.Create( _toyRule2, operation.Syntax.GetLocation(), symbol.Name); context.ReportDiagnostic(diagnostic); } private static string GetSymbolFullName(INamespaceOrTypeSymbol symbol) { var collectedNamespace = new List<string>(); while (symbol.Name != "") { collectedNamespace.Add(symbol.Name); symbol = symbol.ContainingNamespace; } collectedNamespace.Reverse(); return string.Join(".", collectedNamespace); } } }
  134. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 using System.Collections.Generic; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics;

    using System.Collections.Immutable; using Microsoft.CodeAnalysis.Operations; namespace RoslynToyAnalyzer { [DiagnosticAnalyzer(LanguageNames.CSharp)] public class RoslynToyAnalyzer : DiagnosticAnalyzer { private static readonly DiagnosticDescriptor _toyRule2 = new DiagnosticDescriptor( id: "TOY002", title: "System.Collections.ArrayListのインスタンス作成を禁止するアナライザー ", messageFormat: "System.Collections.ArrayListをインスタンス化しています。 System.Collections.Generic.Listを代わりに使用してくださ い。", category: "RoslynToyAnalyzer", defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(_toyRule2); } } public override void Initialize(AnalysisContext context) { context.RegisterOperationAction(AnalyzeCreationObject, OperationKind.ObjectCreation); } private static void AnalyzeCreationObject(OperationAnalysisContext context) { var operation = (IObjectCreationOperation)context.Operation; var symbol = operation.Type; var symbolFullName = GetSymbolFullName(symbol); if (symbolFullName != "System.Collections.ArrayList") return; var diagnostic = Diagnostic.Create( _toyRule2, operation.Syntax.GetLocation(), symbol.Name); context.ReportDiagnostic(diagnostic); } private static string GetSymbolFullName(INamespaceOrTypeSymbol symbol) { var collectedNamespace = new List<string>(); while (symbol.Name != "") { collectedNamespace.Add(symbol.Name); symbol = symbol.ContainingNamespace; } collectedNamespace.Reverse(); return string.Join(".", collectedNamespace); } } } Initializeメソッド(必須メソッド) 実際の診断を行うメソッド 完全修飾型名の取得
  135. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public override void Initialize(AnalysisContext context) {

    context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); context.RegisterOperationAction(AnalyzeCreationObject, OperationKind.ObjectCreation); } コールバックを受け取りたい契機をAnalysisContextに登録する Initializeメソッドの実装(必須) Roslynコンパイラによってアナライザーがロードされると呼ばれるメソッド DiagnosticAnalyzerを継承したので、Initializeメソッドの実装が必要 オブジェクトのインスタンスが作成されるごとに動作させたいメソッド ”AnalyzeCreationObject”を、”RegisterOperationAction”で登録
  136. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public override void Initialize(AnalysisContext context) {

    context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); context.RegisterOperationAction(AnalyzeCreationObject, OperationKind.ObjectCreation); } Initializeメソッドの実装(必須) - メソッド呼び出し(Invocation) - 変数初期化(VariableInitializer) - 配列の作成(ArrayCreation) - Etc… See also: https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.codeanalysis.operationkind
  137. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 private static void AnalyzeCreationObject(OperationAnalysisContext context) {

    var operation = (IObjectCreationOperation)context.Operation; var symbol = operation.Type; var symbolFullName = GetSymbolFullName(symbol); if (symbolFullName != "System.Collections.ArrayList") return; var diagnostic = Diagnostic.Create( _toyRule2, operation.Syntax.GetLocation(), symbol.Name); context.ReportDiagnostic(diagnostic); } 診断に必要な情報を取得 実際の診断を行うメソッドの実装 診断結果を作成して返す シンボルの完全修飾型名を取得(後述) シンボルの型を取得
  138. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 private static string GetSymbolFullName(INamespaceOrTypeSymbol symbol) {

    var collectedNamespace = new List<string>(); while (symbol.Name != "") { collectedNamespace.Add(symbol.Name); symbol = symbol.ContainingNamespace; } collectedNamespace.Reverse(); return string.Join(".", collectedNamespace); } シンボルの完全修飾型名を取得するメソッドの実装 .を連結して文字列として返す シンボルの型を再帰的にたどる NOTE: .NETでは完全修飾型名には”.”以外の 文字列が含まれますが、Roslynの既存実装で は”+”を使っていないため、それに合わせて います。
  139. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 目次 - Roslynアナライザーの概要 - Roslynアナライザーができること、使い方 -

    カスタムルールの作り方 - カスタムアナライザをテストする方法 - 作成したアナライザーをUPMパッケージに内包して配布、利用する NOTE: バージョンによってバグによる制約があるため、 このスライドではUnity 2021.2 + Rider Editor package v3.0.9を基準に書いています。
  140. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 カスタムアナライザーをテストする - ソリューションプロジェクトの作成 - テストコードの解説 -

    テストを簡単に書くTips
  141. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 カスタムアナライザーをテストする - ソリューションプロジェクトの作成 - テストコードの解説 -

    テストを簡単に書くTips
  142. ソリューション・プロジェクトを作成する 1. テストのプロジェクトを作成 2. テストプロジェクトをソリューションに追加 3. テストコードプロジェクトからの参照を追加 4. テストに必要なパッケージをインストール RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.cs │ └── RoslynToyAnalyzer.csproj ├── RoslynToyAnalyzer.Test │ ├── RoslynToyAnalyzer.Test.csproj │ └── RoslynToyAnalyzerTest.cs └── RoslynToyAnalyzers.sln 実行コマンド
  143. ソリューション・プロジェクトを作成する 1. テストのプロジェクトを作成 2. テストプロジェクトをソリューションに追加 3. テストコードプロジェクトからの参照を追加 4. テストに必要なパッケージをインストール RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.cs │ └── RoslynToyAnalyzer.csproj ├── RoslynToyAnalyzer.Test │ ├── RoslynToyAnalyzer.Test.csproj │ └── RoslynToyAnalyzerTest.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet new nunit -o RoslynToyAnalyzer.Test
  144. ソリューション・プロジェクトを作成する 1. テストのプロジェクトを作成 2. テストプロジェクトをソリューションへ追加 3. テストコードプロジェクトからの参照を追加 4. テストに必要なパッケージをインストール RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.cs │ └── RoslynToyAnalyzer.csproj ├── RoslynToyAnalyzer.Test │ ├── RoslynToyAnalyzer.Test.csproj │ └── RoslynToyAnalyzerTest.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet sln RoslynToyAnalyzers.sln add RoslynToyAnalyzer.Test/RoslynToyAnalyzer.Test.csproj
  145. ソリューション・プロジェクトを作成する 1. テストのプロジェクトを作成 2. テストプロジェクトをソリューションへ追加 3. テストコードプロジェクトからの参照を追加 4. テストに必要なパッケージをインストール RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.cs │ └── RoslynToyAnalyzer.csproj ├── RoslynToyAnalyzer.Test │ ├── RoslynToyAnalyzer.Test.csproj │ └── RoslynToyAnalyzerTest.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet add RoslynToyAnalyzer.Test/RoslynToyAnalyzer.Test.csproj reference RoslynToyAnalyzer/RoslynToyAnalyzer.csproj
  146. ソリューション・プロジェクトを作成する 1. テストのプロジェクトを作成 2. テストプロジェクトをソリューションへ追加 3. テストコードプロジェクトからの参照を追加 4. テストに必要なパッケージをインストール RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.cs │ └── RoslynToyAnalyzer.csproj ├── RoslynToyAnalyzer.Test │ ├── RoslynToyAnalyzer.Test.csproj │ └── RoslynToyAnalyzerTest.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.Analyzers --version 3.3.2 dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.CSharp --version 3.5.0 dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.CSharp.Workspaces --version 3.5.0 dotnet add RoslynToyAnalyzer.Test package Dena.CodeAnalysis.Testing --version 2.0.0
  147. ソリューション・プロジェクトを作成する 1. テストのプロジェクトを作成 2. テストプロジェクトをソリューションへ追加 3. テストコードプロジェクトからの参照を追加 4. テストに必要なパッケージをインストール RoslynToyAnalyzer

    ├── RoslynToyAnalyzer │ ├── RoslynToyAnalyzer.cs │ └── RoslynToyAnalyzer.csproj ├── RoslynToyAnalyzer.Test │ ├── RoslynToyAnalyzer.Test.csproj │ └── RoslynToyAnalyzerTest.cs └── RoslynToyAnalyzers.sln 実行コマンド dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.Analyzers --version 3.3.2 dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.CSharp --version 3.5.0 dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.CSharp.Workspaces --version 3.5.0 dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.MSTest --version 1.1.0 dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.MSTest --version 1.1.0 dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.CSharp.CodeRefactoring.Testing.MSTest --version 1.1.0 dotnet add RoslynToyAnalyzer.Test package Dena.CodeAnalysis.Testing --version 2.0.0 実行コマンド dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.Analyzers --version 3.3.2 dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.CSharp --version 3.5.0 dotnet add RoslynToyAnalyzer.Test package Microsoft.CodeAnalysis.CSharp.Workspaces --version 3.5.0 dotnet add RoslynToyAnalyzer.Test package Dena.CodeAnalysis.Testing --version 2.0.0
  148. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 カスタムアナライザーをテストする - ソリューションプロジェクトの作成 - テストコードの解説 -

    テストを簡単に書くTips 今回はNUnitを用いて説明します
  149. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 using System.Linq; using System.Threading.Tasks; using Dena.CodeAnalysis.CSharp.Testing;

    using Microsoft.CodeAnalysis.Text; using NUnit.Framework; namespace RoslynToyAnalyzer.Test { public class RoslynToyAnalyzerTest {     [Test] public async Task RoslynToyAnalyzer_クラスのシンボル名に小文字を含む_Toy001がレポートされる() { const string testData = @" /// public static class Foo { } "; var analyzer = new RoslynToyAnalyzer(); var actual = await DiagnosticAnalyzerRunner.Run(analyzer, testData); Assert.AreEqual(1, actual.Length); Assert.AreEqual("TOY001", actual.First().Id); Assert.AreEqual("NamedTypeのシンボルに小文字を含んだ命名 Foo が使用されています", actual.First().GetMessage()); LocationAssert.HaveTheSpan( new LinePosition(2, 20), new LinePosition(2, 23), actual.First().Location); } } }
  150. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 using System.Linq; using System.Threading.Tasks; using Dena.CodeAnalysis.CSharp.Testing;

    using Microsoft.CodeAnalysis.Text; using NUnit.Framework; namespace RoslynToyAnalyzer.Test { public class RoslynToyAnalyzerTest {     [Test] public async Task RoslynToyAnalyzer_クラスのシンボル名に小文字を含む_Toy001がレポートされる() { const string testData = @" /// public static class Foo { } "; var analyzer = new RoslynToyAnalyzer(); var actual = await DiagnosticAnalyzerRunner.Run(analyzer, testData); Assert.AreEqual(1, actual.Length); Assert.AreEqual("TOY001", actual.First().Id); Assert.AreEqual("NamedTypeのシンボルに小文字を含んだ命名 Foo が使用されています", actual.First().GetMessage()); LocationAssert.HaveTheSpan( new LinePosition(2, 20), new LinePosition(2, 23), actual.First().Location); } } } テストメソッドの準備 テストデータの準備 テストの実行 期待値と実測値の比較
  151. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public class RoslynToyAnalyzerTest {     [Test] public

    async Task RoslynToyAnalyzer_クラスのシンボル名に小文字を含む _Toy001がレポートされる() { // ここにテストを書いていく } } テストメソッドの準備 テストメソッドに[Test]属性をつける
  152. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 const string testData = @" ///

    public static class Foo { } "; テストデータの準備 アナライザーの診断対象として渡すC#のコードを記述
  153. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 var analyzer = new RoslynToyAnalyzer(); var

    actual = await DiagnosticAnalyzerRunner.Run(analyzer, testData); テストの実行 テスト対象のアナライザーのインスタンスを作成 アナライザーのインスタンスとテストデータを渡し、実測値を取得 (DeNAがOSSとして公開しているパッケージです) See also: https://github.com/DeNA/Dena.CodeAnalysis.Testing
  154. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assert.AreEqual(1, actual.Length); Assert.AreEqual("TOY001", actual.First().Id); Assert.AreEqual("NamedTypeのシンボルに小文字を含んだ命名 Foo

    が使用されています ", actual.First().GetMessage()); LocationAssert.HaveTheSpan( new LinePosition(2, 20), // 期待する始点 new LinePosition(2, 23), // 期待する終点 actual.First().Location); 実測値と期待値の比較 アナライザーが出力した警告の数と期待値を比較 診断結果に含まれる解析対象の位置と期待値(始点と終点)を比較 (DeNAがOSSとして公開しているパッケージです) See also: https://github.com/DeNA/Dena.CodeAnalysis.Testing アナライザーのIDと期待値を比較 アナライザーが出力した警告文と期待値を比較 差分表示例
  155. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 カスタムアナライザーをテストする - ソリューションプロジェクトの作成 - テストコードの解説 -

    テストを簡単に書くTips
  156. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 これまでに紹介したテストの問題点 - 警告される位置がわかりにくい - 一度にAssertをたくさんしている

  157. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 これまでに紹介したテストの問題点 - 警告される位置がわかりにくい - 一度にAssertをたくさんしている

  158. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 const string testData = @" ///

    public static class Foo { } "; テストデータの準備 アナライザーの診断対象として渡すC#のコードを記述
  159. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 const string testData = @" ///

    public static class Foo { } "; テストデータの準備 どの部分がアナライザーに怒られることを期待するのかわからない... テストの意図が、テストデータを見ただけで分かりづらい...
  160. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public static class {|Foo|TOY001|クラス名のシンボルに小文字を含んだ命名 Foo が使用されています

    |} { } public static class Foo { } 参考 https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/UnitTests/SymbolIsBannedAnalyzerTests.cs
  161. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public static class {|Foo|TOY001|クラス名のシンボルに小文字を含んだ命名 Foo が使用されています

    |} { } public static class Foo { } 警告が出る箇所の期待値 警告が出る位置 期待するアナライザー のID 期待する警告文 参考 https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/UnitTests/SymbolIsBannedAnalyzerTests.cs
  162. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public static class {|Foo|TOY001|クラス名のシンボルに小文字を含んだ命名 Foo が使用されています

    |} { } public static class Foo { } 警告が出る箇所の期待値 警告が出る位置 期待するアナライザー のID 期待する警告文 マーカーを抽出する 参考 https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/UnitTests/SymbolIsBannedAnalyzerTests.cs
  163. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public static class {|Foo|TOY001|クラス名のシンボルに小文字を含んだ命名 Foo が使用されています

    |} { } public static class Foo { } 警告が出る箇所の期待値 警告が出る位置 期待するアナライザー のID 期待する警告文 マーカーを抽出する マーカーを除外し、ソースコードを 作成 マーカーから期待値(DiagnosticのList) を作成 参考 https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/UnitTests/SymbolIsBannedAnalyzerTests.cs
  164. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public static class {|Foo|TOY001|クラス名のシンボルに小文字を含んだ命名 Foo が使用されています

    |} { } public static class Foo { } 警告が出る箇所の期待値 警告が出る位置 期待するアナライザー のID 期待する警告文 マーカーを除外し、ソースコードを 作成 マーカーから期待値(DiagnosticのList) を作成 アサーションで実測値と比較する アナライザーに渡し、実測値を作成する 参考 https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/UnitTests/SymbolIsBannedAnalyzerTests.cs
  165. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。     var analyzer = new RoslynToyAnalyzer();     var

    (source, expectedDiagnostics) =     ReadAndParseTestData.CreateSourceAndExpectedDiagnosticFromFile(@" /// public static class {|Foo|TOY001|NamedTypeのシンボルに小文字を含んだ命名 Foo が使用されています |} { } ");     var actualDiagnostics = await DiagnosticAnalyzerRunner.Run( analyzer, source     ); テストの意図が、テストデータを見ただけでわかる! テストの期待値をマーカーから自動で生成できる!
  166. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 これまでに紹介したテストの問題点 - 警告される位置がわかりにくい - 一度にAssertをたくさんしている

  167. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assert.AreEqual(expectedDiagnostics.Count, actualDiagnostics.Length); Assert.AreEqual(expectedDiagnostics.First().Id, actualDiagnostics.First().Id); Assert.AreEqual(expectedDiagnostics.First().GetMessage(), actualDiagnostics.First().GetMessage());

    Assert.AreEqual(expectedDiagnostics.First().Location.GetLineSpan(), actualDiagnostics.First().Location.GetLineSpan()); Assertを一度にたくさんしている
  168. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assert.AreEqual(expectedDiagnostics.Count, actualDiagnostics.Length); Assert.AreEqual(expectedDiagnostics.First().Id, actualDiagnostics.First().Id); Assert.AreEqual(expectedDiagnostics.First().GetMessage(), actualDiagnostics.First().GetMessage());

    Assert.AreEqual(expectedDiagnostics.First().Location.GetLineSpan(), actualDiagnostics.First().Location.GetLineSpan()); - レポートされた問題の数 - レポートされた問題のファイル内の位置 - アナライザーの ID - レポートされた問題を人間にわかりやすく説明したメッ セージ を比較している。
  169. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assert.AreEqual(expectedDiagnostics.Count, actualDiagnostics.Length); Assert.AreEqual(expectedDiagnostics.First().Id, actualDiagnostics.First().Id); Assert.AreEqual(expectedDiagnostics.First().GetMessage(), actualDiagnostics.First().GetMessage());

    Assert.AreEqual(expectedDiagnostics.First().Location.GetLineSpan(), actualDiagnostics.First().Location.GetLineSpan()); これらを一度に比較したい!
  170. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Assert.AreEqual(expectedDiagnostics.Count, actualDiagnostics.Length); Assert.AreEqual(expectedDiagnostics.First().Id, actualDiagnostics.First().Id); Assert.AreEqual(expectedDiagnostics.First().GetMessage(), actualDiagnostics.First().GetMessage());

    Assert.AreEqual(expectedDiagnostics.First().Location.GetLineSpan(), actualDiagnostics.First().Location.GetLineSpan());
  171. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 DiagnosticsAssert.AreEqual(IEnumerable<Diagnostic> expected, IEnumerable<Diagnostic> actual); レポートされた問題の数( DiagnosticのIEnumerableの個数)

    レポートされた問題のファイル内の位置(ファイルパス含む) アナライザーの ID メッセージ の4つの観点を比較している Assert.AreEqual(expectedDiagnostics.Count, actualDiagnostics.Length); Assert.AreEqual(expectedDiagnostics.First().Id, actualDiagnostics.First().Id); Assert.AreEqual(expectedDiagnostics.First().GetMessage(), actualDiagnostics.First().GetMessage()); Assert.AreEqual(expectedDiagnostics.First().Location.GetLineSpan(), actualDiagnostics.First().Location.GetLineSpan());
  172. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 DiagnosticsAssert.AreEqual(IEnumerable<Diagnostic> expected, IEnumerable<Diagnostic> actual); レポートされた問題の数( DiagnosticのIEnumerableの個数)

    レポートされた問題のファイル内の位置(ファイルパス含む) アナライザーの ID メッセージ の4つの観点を比較している Assert.Fail failed. Missing 1 diagnostics, extra 1 diagnostics of all 1 diagnostics: missing path/to/file1.cs: (1,2)-(3,4), CS1001, Identifier expected extra path/to/file2.cs: (5,6)-(7,8), CS1002, ; expected 出力例 Assert.AreEqual(expectedDiagnostics.Count, actualDiagnostics.Length); Assert.AreEqual(expectedDiagnostics.First().Id, actualDiagnostics.First().Id); Assert.AreEqual(expectedDiagnostics.First().GetMessage(), actualDiagnostics.First().GetMessage()); Assert.AreEqual(expectedDiagnostics.First().Location.GetLineSpan(), actualDiagnostics.First().Location.GetLineSpan());
  173. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 - Roslynアナライザーの概要 - Roslynアナライザーができること、使い方 - カスタムルールの作り方

    - カスタムアナライザーをテストする方法 - 作成したアナライザーをUPMパッケージに内包して配布、利用する NOTE: バージョンによってバグによる制約があるため、 このスライドではUnity 2021.2 + Rider Editor package v3.0.9を基準に書いています。 目次
  174. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーをUPMパッケージとして配布、利用する - 配布する方法 - 利用する方法

  175. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーをUPMパッケージとして配布、利用する - 配布する方法 - 利用する方法

  176. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザを作成 楽に配布したい 気軽に使ってほしい

  177. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 配布する方法 UPMパッケージを配布用に作成する Roslynアナライザーのdllを内包する OpenUPM、gitリポジトリ等で配布する 自作UPMパッケージ Roslynアナライザーのdllを同梱する

  178. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーをUPMパッケージとして配布、利用する - 配布する方法 - 利用する方法

  179. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 UPMパッケージを インストールする Asmdefの参照によるスコープ設定 NOTE: 既出のスライドを参照 NOTE:

    Code Editor Package for VS v1.2.4以降、Code Editor Package for VSCode v2.0.11以降でも利 用可能 利用する方法
  180. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。

  181. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーは... コンパイラが検知できない 欠陥を検知できる 自作、配布が 簡単にできる ニーズに合った

    利用ができる
  182. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーは... コンパイラが検知できない 欠陥を検知できる 自作、配布が 簡単にできる ニーズに合った

    利用ができる
  183. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 参考にしたサイト - Unityプロジェクト向けRoslynアナライザの作り方 - https://swet.dena.com/entry/2021/05/25/100000 -

    カスタムRoslyn AnalyzerをUPMパッケージとして配布する - https://www.nowsprinting.com/entry/2021/11/01/083258 - Unity 2020.時点のRoslyn Analyzerサポート状況まとめ - https://www.nowsprinting.com/entry/2021/04/18/200619 - Microsoft.CodeAnalysis.BannedApiAnalyzer - https://github.com/dotnet/roslyn-analyzers/tree/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers - codecracker.CSharp - https://github.com/code-cracker/code-cracker - UniTask - https://github.com/Cysharp/UniTask
  184. こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。