はじめに
今回はUnityでIncremental Source Generator
のAdditionalTextsProvider
を利用する方法を紹介したいと思います。
その前に
どこかのバージョンから?かSource Generator
でSystem.IOを利用できなくなったみたいです。
context.RegisterSourceOutput(sampleProvider, (context, syntax) => { // 「アナライザーに対して禁止された API を使用しない」というエラーが出る var txt = System.IO.File.ReadAllText("path-to-txt"); });
RS1035: シンボル 'File' はアナライザーによって使用禁止です: Do not do file IO in analyzers
おそらく入力に対して一意に出力が決まるべきという思想があるのだと思います(多分)。特にIncremental
を実現するためには、それが重要なのかと。
AdditionalFilesを利用してファイルを読み込む
そこでAdditionalFiles
を利用することで、指定したパスにあるファイルを読み取ることができます。やり方としては.csproj
に以下を追加してあげます。
<ItemGroup> <AdditionalFiles Include="読み取りたいファイルへのパス" /> </ItemGroup>
これを受け取るにはAdditionalTextsProvider
を利用してあげます。
[Generator(LanguageNames.CSharp)] public class SampleSourceGenerator : IIncrementalGenerator { public void Initialize(IncrementalGeneratorInitializationContext context) { var provider = context.AdditionalTextsProvider; context.RegisterSourceOutput(provider, static (context, additionalText) => { var source = $$$""" // FilePath : {{{additionalText.Path}}} """; context.AddSource("Sample.Generated.cs", source); }); } }
Unityでの場合
Unityでは.csproj
は自動生成されるため、基本的にユーザーは追記することができません。そこでcsc.rsp
を利用することで実現できます。ファイルを置く場所はAdditionalFiles
の定義を加えたい.asmdef
と同階層です。(.asmdef
を利用していない場合はAssets/csc.rps
)
↓ csc.rsp
/additionalfile:Assets/Scripts/Definition/Sample.cs
ちょっとした裏技(?)
AdditionalFiles
として.cs
を読み取り、SourceGenerator
上で構文解析するという裏技もあったりします。これを利用すれば、アセンブリを超えて色々できちゃいます。
var provider = context.AdditionalTextsProvider .Where(x => x.Path.EndsWith("Hoge.cs")); context.RegisterSourceOutput(provider, static (context, additionalText) => { // additionalTextから構文解析 SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(additionalText.GetText()); // 色々中身を解析していく... // やろうと思えばコンパイルもできるはず });