Hack用のコードジェネレータの新しいバージョンをリリースしました。
前のバージョンでは、デフォルトのジェネレータしか使用できなかったのを独自のジェネレータを使用できるようにしました。
サンプルのプロジェクト下記に用意してあります。
https://github.com/holyshared/hhpack-codegen-example
利用する為の設定
composer.json
hhpack/codegenを開発用のパッケージに追加します。
"require-dev": { "hhpack/codegen": "^0.2.0" },
hh_autoload.json
ジェネレータの設定が読み込めるように、devRootsにパスを追加します。
パスが間違っていると、設定が読み込めないので注意してください。
{ "roots": "src", "devRoots": "/path/to/" // 設定ファイルがあるパス }
ジェネレータの設定ファイルを追加する
名前空間に対して、対応するジェネレータをマッピングするのは変わっていないです。
今回のバージョンではジェネレータに対して、名前と説明をメタ情報と持たせることができます。
このメタ情報は、コマンドラインからジェネレータを指定するのに使用します。
下記の例ではジェネレータにそれぞれ、package:class、package:testclassという名前をつけています。
<?hh //strict namespace HHPack\Example\Generators; use HHPack\Codegen\Cli\{ DefinedGenerator }; use HHPack\Codegen\Contract\{ GeneratorProvider }; use HHPack\Codegen\HackUnit\{ TestClassGenerator }; use HHPack\Codegen\Project\{ PackageClassGenerator }; use function HHPack\Codegen\Cli\{ namespace_of, define_generator }; final class Generators implements GeneratorProvider { public function generators(): Iterator<DefinedGenerator> { // Link package namespace to generator yield define_generator('package:class', 'generate class file for package') ->mapTo( namespace_of('HHPack\Example', 'src')-> map(PackageClassGenerator::class) ); // Link package test namespace to generator yield define_generator('package:testclass', 'generate test class file for package') ->mapTo( namespace_of'HHPack\Example\Test' 'test')-> map(TestClassGenerator::class) ); } }
コードの生成
コードを生成するにはコマンドラインからジェネレーターを指定します。
利用できるジェネレータは、ヘルプで確認できます。
vendor/bin/codegen -h Usage: codegen [OPTIONS] [GEN] [NAME] Arguments: GEN: generator name (ex. lib, test) package:class generate class file for package package:testclass generate test class file for package NAME: generate class name (ex. Foo\Bar) Options: -h, --help Display help message -v, --version Display version
今回の例だと、package:class、package:testclassを利用できます。
vendor/bin/codegen package:class [CLASS_NAME] vendor/bin/codegen package:testclass [CLASS_NAME]
例えば下記の例だと、src/FooにBarのクラスファイルを生成します。
vendor/bin/codegen package:class Foo\\Bar
独自ジェネレータ
独自のジェネレータを使用したい場合は、インタフェースのHHPack\Codegen\Contract\ClassFileGeneratableを実装すればいいです。
詳しくはデフォルトで組み込まれているソースを参考にしてください。
use HHPack\Codegen\{GenerateClassFile}; use HHPack\Codegen\Contract\{ClassFileGeneratable}; use Facebook\HackCodegen\{ICodegenFactory, CodegenFile, CodegenClass}; final class MyGenerator implements ClassFileGeneratable { public static function from(ICodegenFactory $factory): this { return new self($factory); } public function generate(GenerateClassFile $target): CodegenFile { } }