hhpack / codegen
Hack 的库代码生成器
0.4.0
2019-04-30 06:43 UTC
Requires
- hhvm: >=3.21.0
- facebook/definition-finder: ^2.4
- facebook/hack-codegen: ^4.2
- hhpack/getopt: ^1.7
- hhvm/hhvm-autoload: ^2.0
- hhvm/hsl: ^4.1
- hhvm/type-assert: ^3.3
Requires (Dev)
- facebook/fbexpect: ^2.5
- hhvm/hacktest: ^1.5
README
此包提供用于生成源代码的命令行程序。
您可以在配置文件中将生成器映射到 命名空间。
基本用法
创建生成器配置文件
创建一个指定生成器类的配置文件。
在配置文件中,您定义命名空间和生成器链接。
namespace MyPackage\Generators; use HHPack\Codegen\Contract\{NamedGenerator, GeneratorProvider}; use HHPack\Codegen\HackTest\{TestClassGenerator}; use HHPack\Codegen\Project\{PackageClassGenerator}; use function HHPack\Codegen\Cli\{define_generator, namespace_of}; final class Generators implements GeneratorProvider { const LIB = 'HHPack\\Codegen\\Example'; const LIB_TEST = 'HHPack\\Codegen\\Example\\Test'; public function generators(): Iterator<NamedGenerator> { /** * vendor/bin/codegen lib:class LibClass */ yield define_generator("lib:class", "generate library class file.") ->mapTo( namespace_of(static::LIB, 'example/src') ->map(PackageClassGenerator::class), ); /** * vendor/bin/codegen lib:testclass LibClassTest */ yield define_generator("lib:testclass", "generate test class file.") ->mapTo( namespace_of(static::LIB_TEST, 'example/test') ->map(TestClassGenerator::class), ); } }
将自动加载设置追加到 hh_autoload.json
在 devRoots 中设置读取生成器的路径。
有关 hh_autoload.json 的详细信息,请参阅 hhvm-autoload。
{ "roots": "src", "devRoots": "/path/to/" }
为包生成类文件
将生成器的名称指定为第一个参数,类名指定为第二个参数。
vendor/bin/codegen [GEN_NANE] LibClass
自定义生成器
如果您想使用自己的生成器,实现 ClassFileGeneratable。
use HHPack\Codegen\{GenerateClassFile}; use HHPack\Codegen\Contract\{ClassFileGeneratable}; use Facebook\HackCodegen\{ICodegenFactory, CodegenFile, CodegenClass}; final class CustomClassGenerator implements ClassFileGeneratable { public function __construct(private ICodegenFactory $cg) {} public static function from(ICodegenFactory $factory): this { return new self($factory); } public function generate(GenerateClassFile $target): CodegenFile { return $this->cg ->codegenFile($target->fileName()) ->setNamespace($target->belongsNamespace()) ->addClass($this->classOf($target->name())); } private function classOf(string $className): CodegenClass { return $this->cg->codegenClass($className)->setIsFinal(true); } }
您只需在生成器定义中指定它。
在下面的示例中,您可以使用命令 vendor/bin/codegen myproject:loader MyLoader 生成代码。
yield define_generator("myproject:loader", "generate loader class file.")
->mapTo(
namespace_of('MyProject\Loader', 'MyProject/Loader')
->map(CustomClassGenerator::class) // Map generator to namespace
);
运行测试
可以使用以下命令执行测试。
composer update
composer test