TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.7 KiB
88 lines
2.7 KiB
<?php
|
|
/**
|
|
* This file is part of TypePHP.
|
|
*
|
|
* @link https://www.swoole.com/
|
|
* @contact service@swoole.com
|
|
*/
|
|
|
|
namespace TypePhp\Transform;
|
|
|
|
use PhpParser\Modifiers;
|
|
use PhpParser\Node;
|
|
use PhpParser\Node\Expr;
|
|
use PhpParser\Node\Param;
|
|
use PhpParser\Node\Stmt;
|
|
use TypePhp\Exception\SyntaxError;
|
|
use TypePhp\Diagnostics\CompileTimeAttributeDiagnostic;
|
|
|
|
final class GetterLowering
|
|
{
|
|
public static function validateTarget(Node $node): void
|
|
{
|
|
if (!CompileTimeAttribute::has($node, 'Getter')) {
|
|
return;
|
|
}
|
|
|
|
if ($node instanceof Stmt\Property) {
|
|
if ($node->isStatic()) {
|
|
throw new SyntaxError('Getter can only be applied to instance properties');
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ($node instanceof Param && $node->isPromoted()) {
|
|
return;
|
|
}
|
|
|
|
throw new SyntaxError('Getter can only be applied to instance properties');
|
|
}
|
|
|
|
/** @return list<Stmt\ClassMethod> */
|
|
public static function lowerProperty(Stmt\Property $property): array
|
|
{
|
|
if (CompileTimeAttribute::has($property, 'Getter') && $property->hooks !== []) {
|
|
throw new SyntaxError('Getter cannot be applied to properties with hooks');
|
|
}
|
|
if (!CompileTimeAttribute::consume($property, 'Getter')) {
|
|
return [];
|
|
}
|
|
|
|
$methods = [];
|
|
foreach ($property->props as $prop) {
|
|
$methods[] = self::createGetter(
|
|
$prop->name->toString(),
|
|
$property->type,
|
|
$property,
|
|
);
|
|
}
|
|
return $methods;
|
|
}
|
|
|
|
public static function lowerPromotedProperty(Param $param): ?Stmt\ClassMethod
|
|
{
|
|
if (CompileTimeAttribute::has($param, 'Getter') && $param->hooks !== []) {
|
|
throw new SyntaxError('Getter cannot be applied to properties with hooks');
|
|
}
|
|
if (!$param->isPromoted() || !is_string($param->var->name) || !CompileTimeAttribute::consume($param, 'Getter')) {
|
|
return null;
|
|
}
|
|
|
|
return self::createGetter($param->var->name, $param->type, $param);
|
|
}
|
|
|
|
private static function createGetter(string $property, ?Node $type, Node $target): Stmt\ClassMethod
|
|
{
|
|
$method = new Stmt\ClassMethod('get' . ucfirst($property), [
|
|
'flags' => Modifiers::PUBLIC,
|
|
'returnType' => $type === null ? null : clone $type,
|
|
'stmts' => [new Stmt\Return_(new Expr\PropertyFetch(
|
|
new Expr\Variable('this'),
|
|
$property,
|
|
))],
|
|
], $target->getAttributes());
|
|
CompileTimeAttributeDiagnostic::markGenerated($method, 'Getter', $target);
|
|
return $method;
|
|
}
|
|
|
|
}
|
|
|