思い通りのソースコードができた。
成果物
前回まで
IndentedTextWriter
dotnet new console -o IndentWrite cd IndentWrite dotnet add package System.CodeDom
Program.cs
namespace IndentWrite { class Program { static void Main(string[] args) { new Generator().Run(); } } }
Generator.cs
using System; using System.IO; using Microsoft.CSharp; using System.CodeDom.Compiler; namespace IndentWrite { class Generator { // in/out/ref付きのものはFunc,Actionにないためdelegate定義必須 // https://teratail.com/questions/66340 private delegate void CreateCodeDelegate(in IndentedTextWriter tw); public void Run() { Generate(CreateCode); } // ファイル出力 private void Generate(CreateCodeDelegate createCode) { CSharpCodeProvider provider = new CSharpCodeProvider(); string sourceFile = @"Hello.cs"; using (StreamWriter sw = new StreamWriter(sourceFile, false)) { IndentedTextWriter tw = new IndentedTextWriter(sw, " "); createCode(tw); tw.Close(); } } // コード生成 public void CreateCode(in IndentedTextWriter tw) { tw.WriteLine("using System;"); tw.WriteLine(); tw.WriteLine("namespace MyNamespace"); tw.WriteLine("{"); tw.Indent++; tw.WriteLine("public sealed class MyClass"); tw.WriteLine("{"); tw.Indent++; tw.WriteLine("static void Main(string[] args)"); tw.WriteLine("{"); tw.Indent++; tw.WriteLine(@"Console.WriteLine(""Hello world"");"); tw.Indent--; tw.WriteLine("}"); tw.Indent--; tw.WriteLine("}"); tw.Indent--; tw.WriteLine("}"); } } }
出力結果
dotnet run
Hello.cs
using System; namespace MyNamespace { public sealed class MyClass { static void Main(string[] args) { Console.WriteLine("Hello world"); } } }
そう、これが欲しかった。
所感
コード生成が頭悪そう。ポイントはtw.Indent
。インデントを適時適切に指定せねばならない。なので文字列を一気に結合するわけにはいかないのが辛い。
IndentedTextWriterのためにdotnet add package System.CodeDom
せねばならないのは嫌だ。類似コードを自作したい。
ツリー構造はNode.Add(Node);
のようにすれば良さそう。ブロック文字{
の前後にある改行も指定できるようにしたい。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- SQLite 3.29.0 ※
- C# dotnet 3.0.100 ※
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux