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 {
}
}