Hack Builder
BaseCodeBuilder
provides basic features useful for generating code in most C-style programming langauges, such as
indentation, if blocks, and so on.
HackBuilder
extends
BaseCodeBuilder
with features of the Hack language.
When using Hack Codegen, BaseCodeBuilder
is not usually used directly: HackBuilder
is used to
generate function/method bodies and pseudo-main code, and higher-level APIs are used to create
classes, functions, etc.
The recommended way to get an instance of a HackBuilder
is to first get an instance of a
HackCodegenFactory
, then call ->codegenHackBuilder()
on it.
Fundamentals
$builder->add('some code');
is the lowest-level function: it appends the string you provide to
the generated code. On top of this, there is:
->addLine('some code')
: also adds a newline->addLines($vector_of_lines)
: adds multiple lines
Many methods have a sprintf
-style shortcut - eg:
->addf('foo %s bar', $var)
->addLinef('foo %s bar', $var)
As readable code is a goal of Hack Codegen, several whitespace helpers are provided:
->ensureNewLine()
: add a newline if we’re not currently at the start of a line->ensureEmptyLine()
: adds newlines as needed to have an empty line before any more code->indent()
: increase the number of spaces added to the start of any new non-empty lines (by default, this increases by 2 spaces - seeIHackCodegenConfig
to change this)->unindent()
: do the opposite->addLineWithSuggestedLineBreaks()
: any\0
in the input string is replaced with a space if it will still fit in the desired maximum line length, otherwise a newline is added (and indented if needed)->addMultilineCall($call, $args)
: either renders the call all on one line, or with one argument on one line, depending on if it can fit within the maximum line length
Finally, you can get the generated code as a string by calling ->getCode()
.
Values
While the fundamentals can be combined with var_export()
directly to generate code
for values, Hack Codegen provides an extensible system to simplify this; the simplest
interface to this is
HackBuilder::addValue<T>(T $value, IHackBuilderValueRenderer<T> $formatter)
.
The two simplest renderers are:
HackBuilderValues::export()
implementsIHackBuilderValueRenderer<mixed>
, so is able to render any value; it usesvar_export()
, but fixes up builtins to be instantiable, eg replacingHH\Vector { }
withVector { }
HackBuilderValues::literal()
implementsIHackBuilderValueRenderer<string>
, and takes the value as literal code
More complicated renderers are available, including nested definitions for collections. Additionally, shortcuts are provided for common uses:
->addAssigment('$someVar', $value, $renderer)
: assigns$value
to$somevar
->addReturn('$somevar', $value, $renderer)
: return $value from the current function
->addReturnf()
is also available, however it always treats the final string as literal code.
Blocks
Helpers are provided for common block constructs - eg:
1
2
3
4
5
<?hh
$builder
->startIf('$condition')
->addLine('doStuff();')
->endIf()
See the reference documentation for details.