Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 自己紹介 - Kazuma Inagaki - 21新卒 - SWETグループ所属 - Vimmer

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 Roslynアナライザーの概要 - Roslynとは - Roslynアナライザーとは

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 コンパイラ オレオレルール - 型違反 - 未定義関数 - 未定義変数 - etc... Roslynアナライザーに やってもらおう! 一般的なルール

Slide 12

Slide 12 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 どうやってやってもらうんだ..?

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 バグの混入 ビルドする クラッシュする public class BadServiceNoInject : IBadServiceNoInject { public BadServiceNoInject () { } } ビルドが成功する 端末等で操作

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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を配置する

Slide 50

Slide 50 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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を配置する

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする 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

Slide 60

Slide 60 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする 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) にアナライザーを適用したい

Slide 61

Slide 61 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする 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#スクリ プトを配置する

Slide 62

Slide 62 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする 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#スクリプトを置く必要があります。

Slide 63

Slide 63 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーが動作する範囲の設定をする 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を押す

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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)に アナライザーが適用されます 。

Slide 67

Slide 67 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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)に アナライザーが適用されます 。

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 JetBrains Rider上でのRoslynアナライザーの振る舞い エディタ上に問題箇所がハイライトさ れ、修正ポップアップに詳細が表示さ れる Code | Inspect Code…から実行 すれば、インスペクション結果ウィンド ウに出力される NOTE: Visual Studio、 VS Codeでの動作は未検証です。

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーの診断ルールごとに診断の重要度(severity)が設定されている - error - warning - suggestion - silent - none

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 ルールセット ファイルによる重要度の設定 アナライザーのIDを指定 アナライザーの重要度を上書き

Slide 87

Slide 87 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 ルールセット ファイルによる重要度の設定 アナライザーのIDを指定 アナライザーの重要度を上書き

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 アナライザーに怒られるコードを 仕方なく書いた 自動生成されたコードに対して アナライザーが警告を出してしまう なぜ抑制するのか

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 [SuppressMessage("ApiDesign", "RS0030")] public async Task M() { await Task.Delay(100); } 警告を抑制出来る! アナライザーのID アナライザーのカテゴリー

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 public async Task M() { await Task.Delay(100); #pragma warning disable RS0030 await Task.Delay(100); #pragma warning restore RS0030 } このステートメントに限り 抑制出来る!

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

コマンドラインからバッ チモードでUnityを起動 コードをPush 注意: 一般的なlintツールとは異なり、コン パイルログに混ざってアナライザーの診断 結果も出力される Copyright: Jenkins project https://jenkins.io

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

ソリューション・プロジェクトを作成する 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

Slide 118

Slide 118 text

ソリューション・プロジェクトを作成する 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

Slide 119

Slide 119 text

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

Slide 120

Slide 120 text

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

Slide 121

Slide 121 text

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

Slide 122

Slide 122 text

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

Slide 123

Slide 123 text

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

Slide 124

Slide 124 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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 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); } } }

Slide 125

Slide 125 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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 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メソッド(必須メソッド) 実際の診断を行うメソッドの実装

Slide 126

Slide 126 text

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

Slide 127

Slide 127 text

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

Slide 128

Slide 128 text

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

Slide 129

Slide 129 text

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

Slide 130

Slide 130 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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); } } 診断に必要な情報を取得 実際の診断を行うメソッドの実装 診断結果を作成して返す シンボルの名前に小文字を含むか判定

Slide 131

Slide 131 text

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

Slide 132

Slide 132 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 呼び出しを検査する例 var hoge = new ArrayList(); System.Collections.ArrayListをインスタン ス化しています。 System.Collections.Generic.Listを代わりに 使用してください。

Slide 133

Slide 133 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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 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(); while (symbol.Name != "") { collectedNamespace.Add(symbol.Name); symbol = symbol.ContainingNamespace; } collectedNamespace.Reverse(); return string.Join(".", collectedNamespace); } } }

Slide 134

Slide 134 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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 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(); while (symbol.Name != "") { collectedNamespace.Add(symbol.Name); symbol = symbol.ContainingNamespace; } collectedNamespace.Reverse(); return string.Join(".", collectedNamespace); } } } Initializeメソッド(必須メソッド) 実際の診断を行うメソッド 完全修飾型名の取得

Slide 135

Slide 135 text

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

Slide 136

Slide 136 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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

Slide 137

Slide 137 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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); } 診断に必要な情報を取得 実際の診断を行うメソッドの実装 診断結果を作成して返す シンボルの完全修飾型名を取得(後述) シンボルの型を取得

Slide 138

Slide 138 text

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

Slide 139

Slide 139 text

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

Slide 140

Slide 140 text

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

Slide 141

Slide 141 text

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

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

ソリューション・プロジェクトを作成する 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

Slide 144

Slide 144 text

ソリューション・プロジェクトを作成する 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

Slide 145

Slide 145 text

ソリューション・プロジェクトを作成する 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

Slide 146

Slide 146 text

ソリューション・プロジェクトを作成する 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

Slide 147

Slide 147 text

ソリューション・プロジェクトを作成する 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

Slide 148

Slide 148 text

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

Slide 149

Slide 149 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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); } } }

Slide 150

Slide 150 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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); } } } テストメソッドの準備 テストデータの準備 テストの実行 期待値と実測値の比較

Slide 151

Slide 151 text

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

Slide 152

Slide 152 text

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

Slide 153

Slide 153 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 var analyzer = new RoslynToyAnalyzer(); var actual = await DiagnosticAnalyzerRunner.Run(analyzer, testData); テストの実行 テスト対象のアナライザーのインスタンスを作成 アナライザーのインスタンスとテストデータを渡し、実測値を取得 (DeNAがOSSとして公開しているパッケージです) See also: https://github.com/DeNA/Dena.CodeAnalysis.Testing

Slide 154

Slide 154 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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と期待値を比較 アナライザーが出力した警告文と期待値を比較 差分表示例

Slide 155

Slide 155 text

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

Slide 156

Slide 156 text

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

Slide 157

Slide 157 text

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

Slide 158

Slide 158 text

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

Slide 159

Slide 159 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 const string testData = @" /// public static class Foo { } "; テストデータの準備 どの部分がアナライザーに怒られることを期待するのかわからない... テストの意図が、テストデータを見ただけで分かりづらい...

Slide 160

Slide 160 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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

Slide 161

Slide 161 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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

Slide 162

Slide 162 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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

Slide 163

Slide 163 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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

Slide 164

Slide 164 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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

Slide 165

Slide 165 text

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

Slide 166

Slide 166 text

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

Slide 167

Slide 167 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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を一度にたくさんしている

Slide 168

Slide 168 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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 - レポートされた問題を人間にわかりやすく説明したメッ セージ を比較している。

Slide 169

Slide 169 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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()); これらを一度に比較したい!

Slide 170

Slide 170 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 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());

Slide 171

Slide 171 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 DiagnosticsAssert.AreEqual(IEnumerable expected, IEnumerable 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());

Slide 172

Slide 172 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 DiagnosticsAssert.AreEqual(IEnumerable expected, IEnumerable 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());

Slide 173

Slide 173 text

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

Slide 174

Slide 174 text

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

Slide 175

Slide 175 text

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

Slide 176

Slide 176 text

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

Slide 177

Slide 177 text

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

Slide 178

Slide 178 text

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

Slide 179

Slide 179 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 UPMパッケージを インストールする Asmdefの参照によるスコープ設定 NOTE: 既出のスライドを参照 NOTE: Code Editor Package for VS v1.2.4以降、Code Editor Package for VSCode v2.0.11以降でも利 用可能 利用する方法

Slide 180

Slide 180 text

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

Slide 181

Slide 181 text

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

Slide 182

Slide 182 text

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

Slide 183

Slide 183 text

こちらに登壇時の映 像をいれるので、文 字を載せないように して下さい。 参考にしたサイト - 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

Slide 184

Slide 184 text

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