Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

source generator #320

Closed
ufcpp opened this issue Sep 28, 2020 · 3 comments
Closed

source generator #320

ufcpp opened this issue Sep 28, 2020 · 3 comments
Labels

Comments

@ufcpp
Copy link
Owner

ufcpp commented Sep 28, 2020

C# 9.0 の partial method/module initializer 新文法の説明と合わせて source generator の話したい…

https://ufcpp.net/study/csharp/misc/analyzer-generator/ に1ページ追加。

初期案

既存の技術と比べて:

  • コンパイラー組み込み
    • 今、Razor とか gRPC.Tools とか外部ツールでやってることを直接的に組み込めて、パフォーマンス的においしい
  • ビルド時生成
    • T4 みたいに保存時生成じゃない
      • コミットしなくても別にいいし、開発者ごとの言語設定の差で差分が出て困るとかを避けれる
    • 実行時(動的)コード生成じゃない
      • リフレクションが使えない/使いにくい状況で JSON シリアライズとかができる
      • パフォーマンス的にもだいぶ改善になる
  • ソースコード(IL じゃなくて C# コードをテキストで)生成
    • エディター上で F12 (定義へ移動)もできるし
    • デバッグ実行時に F11 (ステップ イン実行)もできるし

既存技術置き換えユースケース:

https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.md

  • コンパイラー組み込みによるパフォーマンス改善の見込み
    • Razor からの C# コード生成
    • gRPC (proto からの C# コード生成)
  • 脱リフレクションによるパフォーマンス改善・動かせる環境拡大の見込み
    • ASP.NET の DI がらみとか
    • Regex の事前コンパイル
    • (JSON とかの)シリアライザー
    • System.CommandLine

その他のユースケース:

  • ガチガチの最適化
  • PropertyChanged がらみとか
  • Logging injection とか
  • ラッパー構造体
    • strong-typedef の類
      ‐ MasterId みたいな、int にエイリアスを付けて、間違った数値・違う型の Id を参照しちゃうみたいな問題を避けるやつ
  • mix-in みたいなやつ
    • インターフェイスのデフォルト実装とか拡張メソッドだとステートを持てないので
    • ステートを持った何かにインターフェイス実装を移譲
  • record 関連のカスタマイズ
    • record によるコンパイラー合成コードで満足できない場合、手書きで挙動は上掛ける
      ‐ とはいえ、手書きだと煩雑なコードが多すぎるので、それを source generator で生成したい
      ‐ Equals を shallow 比較じゃなくて deep 比較にするとか
      ‐ PrintMembers で ToString 表示するメンバーをコントロールするとか
  • 同期コードから非同期コード生成
    • IEnumerable に対する LINQ から、IAsyncEnumerable に対する Select(IAsyncEnumerable, Func)Select(IEnumerable, AsyncFunc) みたいなやつの生成
  • arity 違いコード生成
    ‐ タプルとか Action/Func みたいに ActionAction<T>Action<T1, T2>... みたいなのが大量に並んでるやつとか
  • number コード生成
    • int, short, long, ... みたいに、+ 演算子を持ってることはわかってるけどインターフェイスは実装してない・virtual call のコストが許容できないものをコード生成で対処

自作してみてるやつ:

  • https://github.com/ufcpp/MemberAccessGenerator
    • loose typing な言語ではできるような「プロパティの名前アクセス、インデックス アクセス」の類
      ‐ これも汎用シリアライズの脱リフレクション化で使えたりする
  • https://github.com/ufcpp/StringLiteralGenerator
    • UTF-8 バイト列のビルド時生成
      ‐ string リテラルは UTF-16 で記録されてしまうので、変換のコストをなくすために使う「ガチガチの最適化」系ツール
  • https://github.com/ufcpp/MixinGenerator/
    • 昔、Code Fix (クイックアクションを使ってひと手間手作業が挟まる)方式で作ったもの、source generator に置き換えれば完全自動に
      ‐ mix-in をコード生成で実現してる
@ufcpp ufcpp added the C# 9.0 label Sep 28, 2020
@ufcpp

This comment has been minimized.

@ufcpp
Copy link
Owner Author

ufcpp commented Feb 6, 2021

一応それっぽいページ1個足した。

積みタスク:

  • (gRPC とか)今後 roslyn source generator 化されそうなもののリスト書く?
    • 実際に source generator 化されたタイミングで書き足す?
  • 他のもっとニッチな利用例も挙げる?
  • NuGet パッケージ参照の話、実はまだなさそう… #332 NuGet パッケージの話自体足す
  • F12 で定義に飛んで、F9 でブレイクポイントを仕掛けて、F11 でステップイン実行できる話、動画とってリンク貼る

@ufcpp
Copy link
Owner Author

ufcpp commented Mar 21, 2021

@ufcpp ufcpp closed this as completed Mar 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant