2008年11月18日

System.CodeDom

今回はSystem.CodeDom名前空間 のクラスたちで遊ぶ。CodeDomのクラスを用いるとソースコードの構成をクラスで表現することが出来る。例のごとくHelloWorldを作成してみる。

CodeCompileUnit compileiUnit = new CodeCompileUnit();

//名前空間追加
CodeNamespace sampleNamespace = new CodeNamespace("CodeDomSample");
compileiUnit.Namespaces.Add(sampleNamespace);

//System名前空間をインポート
CodeNamespaceImport systemImport = new CodeNamespaceImport("System");
sampleNamespace.Imports.Add(systemImport);

//クラス追加
CodeTypeDeclaration programType = new CodeTypeDeclaration("Program");
programType.IsClass = true;
sampleNamespace.Types.Add(programType);

//メソッド追加
CodeEntryPointMethod mainMethod = new CodeEntryPointMethod();
programType.Members.Add(mainMethod);

//メソッド内処理の設定
CodeMethodInvokeExpression hello = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("Console"),
                                                                  "WriteLine",
                                                                  new CodePrimitiveExpression("Hello World"));

CodeExpressionStatement consoleWriteStatement = new CodeExpressionStatement(hello);
mainMethod.Statements.Add(consoleWriteStatement);

大きな流れは

  1. CodeCompileUnitクラスのオブジェクトを生成
  2. CodeCompileUnitオブジェクトに名前空間を追加
  3. 名前空間オブジェクトにタイプ(クラス)を追加
  4. タイプオブジェクトにメンバ(メソッド)追加
  5. メソッドにステートメント(処理)を追加
となる。
これをCodeDomProviderクラスを継承したクラスに渡せばソースコードファイルを生成することができる。

private void GenerateCodeFile(CodeCompileUnit unit)
{
    Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
    string fileName = "HelloWorld." + provider.FileExtension;
    using (System.IO.StreamWriter writer = new System.IO.StreamWriter(fileName))
    {
        System.CodeDom.Compiler.CodeGeneratorOptions options = new System.CodeDom.Compiler.CodeGeneratorOptions();
        options.IndentString = "    ";
        provider.GenerateCodeFromCompileUnit(unit, writer, new System.CodeDom.Compiler.CodeGeneratorOptions());
        writer.Close();
    }
}

生成されたHelloWorldソースは以下

//------------------------------------------------------------------------------
// 
//     このコードはツールによって生成されました。
//     ランタイム バージョン:2.0.50727.1433
//
//     このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
//     コードが再生成されるときに損失したりします。
// 
//------------------------------------------------------------------------------

namespace CodeDomSample {
    using System;

    public class Program {
        
        public static void Main() {
            Console.WriteLine("Hello World");
        }
    }
}

auto-generatedのコメントは消せないのかな。

0 件のコメント:

コメントを投稿