Skip to content

Releases: hhvm/hack-codegen

Cleanup of release tarballs

21 Feb 01:49
45de685
Compare
Choose a tag to compare

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

20 Feb 22:37
58be8fb
Compare
Choose a tag to compare

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

19 Feb 01:56
4525842
Compare
Choose a tag to compare

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() or HackBuilderKeys::literal()
  • add a new class implements IHackBuilderValueRenderer<T> or IHackBuilderKeyRenderer<T>
  • use HackBuilderKeys::lambda(($config, $value) ==> 'code') or HackBuilderValues::lambda(($config, $value) ==> $code)

The lambda approach is especially useful for containers.

v2.0: safer, simpler, and more powerful

16 Feb 01:27
0baa1ec
Compare
Choose a tag to compare

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

15 Feb 02:34
9cbaa57
Compare
Choose a tag to compare

No significant changes.

Better default root directory, remove .hhconfig from export

10 Feb 04:01
Compare
Choose a tag to compare
  • 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

25 Jan 21:07
Compare
Choose a tag to compare
Merge pull request #10 from facebook/filetypes

Add support for php and decl file types

Set and use namespaces

14 Jan 01:55
Compare
Choose a tag to compare

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

12 Oct 23:45
Compare
Choose a tag to compare
v1.1.1

Fix test warning, improve naming in tests

With namespaces

25 Aug 05:43
Compare
Choose a tag to compare

Everything was moved to namespace Facebook\HackCodegen