-
Notifications
You must be signed in to change notification settings - Fork 1
Compile-time metaprogramming #327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Labels
Comments
E.g. inside the partial library, using a convenience class instead of assembling the code using AST nodes. Transformations::register('class', function($class) {
if (array_key_exists('value', $class->value->annotations)) {
$class->value->implements[]= '\lang\Value';
foreach ($class->value->body as $type => $node) {
if ('$' !== $type{0}) continue;
$fields[]= $node->value->name;
}
$args= $init= [];
foreach ($fields as $name) {
$class->value->body[$name.'()']= new Code('public function '.$name.'() {
return $this->'.$name.';
}');
$args[]= '$'.$name;
$init[]= '$this->'.$name.'= $'.$name.';';
}
$class->value->body['__construct()']= new Code('public function __construct('.
implode(', ', $args).') { '.implode('', $init).' }'
);
$class->value->body['toString()']= new Code('public function toString() {
return nameof($this)."@".\util\Objects::stringOf(get_object_vars($this));
}');
$class->value->body['hashCode()']= new Code('public function hashCode() {
return nameof($this);
}');
$class->value->body['compareTo()']= new Code('public function compareTo($value) {
return 1;
}');
}
return $class;
}); $ cat Demo.php
<?php
use util\cmd\Console;
<<value>>
class Demo {
private string $id, $name;
public static function main(array<string> $args) {
Console::writeLine(new self(...$args));
}
}
$ xp Demo 1549 Timm
Demo@[
id => "1549"
name => "Timm"
] |
6 tasks
API is now far more concise: use lang\ast\transform\Transformations;
use lang\ast\nodes\Method;
use lang\ast\nodes\Signature;
use lang\ast\Code;
Transformations::register('class', function($class) {
if ($class->value->annotation('getters')) {
foreach ($class->value->properties() as $property) {
$class->value->inject(new Method(
['public'],
$property->name,
new Signature([], $property->type),
[new Code('return $this->'.$property->name.';')]
));
}
}
yield $class;
}); See https://github.com./xp-framework/ast |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Scope of Change
The XP Compiler will be extended to support compile-time metaprogramming
Rationale
Build libraries like
xp-forge/partial
into compiler.Functionality
The compiler finds an implementation which was previously registered via
Transformations::register()
for class nodes. The function gets executed and transforms the above to the following PHP:Security considerations
Speed impact
Dependencies
xp-framework/compiler#19
Related documents
https://dzone.com/articles/compile-time-metaprogramming
http://groovy-lang.org/metaprogramming.html#_available_ast_transformations
http://groovy-lang.org/metaprogramming.html#developing-ast-xforms
http://notatube.blogspot.de/2010/12/project-lombok-creating-custom.html
xp-framework/compiler#15
https://wiki.php.net/rfc/parser-extension-api
microsoft/TypeScript#5595
The text was updated successfully, but these errors were encountered: