Releases: hhvm/hack-codegen
Cleanup of release tarballs
test/ and examples/ have been marked export-ignore
in .gitattributes; this means that composer won't install them when installing a tagged release.
This means that the typechecker will not complain about missing development dependencies.
Support for generating executables
This release adds the following to the CodegenFile
class:
setShebangLine(string s);
setShebangLinef(format, ...);
setPseudoMainHeader(string);
setPseudoMainHeaderf(format, ...);
setPseudoMainFooter(string);
setPseudoMainFooterf(format, ...);
For example:
$factory->codegenFile($path)
->setShebangLine('#!/usr/bin/env hhvm')
->setPseudoMainHeader('require_once("vendor/autoload.php");')
->addFunction($factory->codegenFunction('main')/*... */ )
->setPseudoMainFooter('main();')
->save();
These new methods can not be used with <?hh // strict
files - as <?hh // strict
bans pseudomain code, it's not currently possible to have strict scripts in Hack.
addReturn/returnCase consistency, support for lambda value renderers
addReturn()
and returnCase()
consistency
These methods now take an IHackBuilderValueRenderer
instance to be consistent with other methods such as addAssignment
and addValue
.
This means that addReturn('literal')
is no longer valid - you can replace it with any of:
addReturn($any_literal, HackBuilderValues::literal())
addReturnf('some literal with no placeholders')
addReturnf('%s', $any_literal)
A similar change is needed for returnCase()
-returnCasef()
has also been added to this release
Lambda key/value renderers
If you need to generate code for a value in a way that hack-codegen
doesn't have built-in support, you now have 3 options:
- pre-process the data and use
HackBuilderValues::literal()
orHackBuilderKeys::literal()
- add a new class implements
IHackBuilderValueRenderer<T>
orIHackBuilderKeyRenderer<T>
- use
HackBuilderKeys::lambda(($config, $value) ==> 'code')
orHackBuilderValues::lambda(($config, $value) ==> $code)
The lambda approach is especially useful for containers.
v2.0: safer, simpler, and more powerful
This release breaks compatibility to:
- take advantage of modern features of Hack to detect common mistakes
- replace special-cases with more generalized and powerful systems
- better support per-site configuration, including base directory for 'generated by'
Global functions and configuration
In prior releases, the default HackCodegenConfig
implementation would be used, and could not
be consistently overridden. Now, HackCodegenConfig
takes root directory as a parameter, and the configuration can be completely be replaced by implementing IHackCodegenConfig
, which is completely threaded through the stack. This required removing the global functions which implicitly used the global configuration object.
With v1.x
$x = codegen_class('MyClass');
With v2.x:
$config = new HackCodegenConfig(MyApp::getRootDir());
$cgf = new HackCodegenFactory($config);
$x = $cgf->codegenClass('MyClass');
Format Strings
In 1.x, some function would take a format string, however, if no extra arguments were passed, it would be treated as a plain string by some functions, but not all. This has been made consistent by adding f
to the end of all functions that take a format string, and adding a version without the f that always takes a literal. Additionally, this allows the typechecker to check that format strings and parameters are valid.
With v1.x
$builder->add('foo bar'); // good
$builder->add('foo %s baz', 'bar'); // good
$builder->add('foo %s bar'); // inconsistent
$builder->add('%d', 'Not an int'); // accepted but bad
With v2.x
$builder->add('foo bar'); // good
$builder->add('foo %s baz', 'bar'); // typechecker error, too many arguments
$builder->addf('foo %s baz', 'bar'); // good
$builder->add('foo %s bar'); // good - always literally adds 'foo %s bar';
$builder->addf('%d', 'not an int'); // typechecker error, expected an int
This also applies to other methods, e.g. addReturn()
vs addReturnf()
.
Generating code for values
addVarExport()
, addVector
, addShape()
, addArray()
, and similar methods have been replaced with addValue()
. Additionally, nested containers are now fully supported.
With v1.x
$builder->add($some_literal_value);
$builder->addVarExport($some_value_to_export);
$builder->addVector(
Vector { 1, 2, 3 },
HackBuilderValues::EXPORT,
);
$builder->addMap(
Map { 'foo' => '$foo', 'bar' => '$bar' },
HackBuilderKeys::EXPORT,
HackBuilderValues::LITERAL,
);
With v2.x
$builder->addValue($some_literal_value, HackBuilderValues::literal());
$builder->addValue($some_value_to_export, HackBuilderValues::export());
$builder->addValue(
Vector { 1, 2, 3 },
HackBuilderValues::export(),
);
// ... alternatively (with line-wrapping support)...
$builder->addValue(
Vector { 1, 2, 3 },
HackBuilderValues::vector(
HackBuilderValues::export()
),
);
$builder->addValue(
Map { 'foo' => '$foo', 'bar' => '$bar' },
HackBuilderValues::map(
HackBuilderKeys::export(),
HackBuilderValues::literal(),
),
);
// Not supported on v1.x:
$builder->addValue(
Vector { Vector { '$foo', '$bar' } , Vector { '$bar', '$baz' } },
HackBuilderValues::vector(
HackBuilderValues::vector(
HackBuilderValues::literal(),
),
),
);
Additionally, addAssignment()
now supports all of the above:
$builder->addAssignment(
'$somevar',
123,
HackBuilderValues::literal(),
);
$builder->addAssignment(
'$somevar',
Vector { 1, 2, 3 },
HackBuilderValues::vector(HackBuilderValues::export()),
);
Shapes
There are now two ways to generate code for shapes, depending on if all members should be
rendered the same way:
$builder->addValue(
shape('foo' => 'bar', 'herp' => 'derp'),
HackBuilderValues::shapeWithUniformRendering(HackBuilderValues::export()),
);
$builder->addValue(
shape(
'foo' => $foo,
'bar' => Vector { 'herp', 'derp' },
),
HackBuilderValues::shapeWithPerKeyRendering(
shape(
'foo' => HackBuilderValues::literal(),
'bar' => HackBuilderValues::vector(HackBuilderValues::export()),
),
),
);
Misc
- container order is now preserved
- PHPUnit is now used instead of a custom system
Support for HHVM 3.18
No significant changes.
Better default root directory, remove .hhconfig from export
- if installed via composer in the usual way,
codegen_script()
will generate paths relative to the project root. A more flexible approach is coming in 2.x - add .hhconfig to export-ignore; this means that when tagged releases are installed via composer, the .hhconfig will be omitted - an hhconfig in subdirectories confuses some developer tools.
Add support for php and hack decl file types
Merge pull request #10 from facebook/filetypes Add support for php and decl file types
Set and use namespaces
Allows to set a namespace at the file level, as well as use namespaces, classes, functions or consts
Fix warning and improve naming in tests
v1.1.1 Fix test warning, improve naming in tests
With namespaces
Everything was moved to namespace Facebook\HackCodegen