Skip to content

Commit

Permalink
Add filter parameter types to code to allow statical analysis [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Jun 15, 2022
1 parent 379921e commit 46fb48e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
45 changes: 43 additions & 2 deletions src/Latte/Compiler/TemplateGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

use Latte;
use Latte\ContentType;
use Latte\Essential\Blueprint;
use Nette\PhpGenerator as Php;


/**
Expand Down Expand Up @@ -38,6 +40,7 @@ public function generate(
string $className,
?string $comment = null,
bool $strictMode = false,
array $filters = [],
): string {
$context = new PrintContext($node->contentType);
$scope = $context->getVariableScope();
Expand Down Expand Up @@ -78,13 +81,18 @@ public function generate(
. ($method['body'] ? "\t\t$method[body]\n" : '') . "\t}";
}

$comment .= "\n@property Filters$className \$filters";
$comment = str_replace('*/', '* /', $comment);
$comment = str_replace("\n", "\n * ", "/**\n" . trim($comment)) . "\n */\n";

$code = "<?php\n\n"
. ($strictMode ? "declare(strict_types=1);\n\n" : '')
. "use Latte\\Runtime as LR;\n\n"
. ($comment === null ? '' : '/** ' . str_replace('*/', '* /', $comment) . " */\n")
. $comment
. "final class $className extends Latte\\Runtime\\Template\n{\n"
. implode("\n\n", $members)
. "\n}\n";
. "\n}\n\n\n"
. $this->generateStub($node, 'Filters' . $className, $filters);

$code = PhpHelpers::optimizeEcho($code);
$code = PhpHelpers::reformatCode($code);
Expand Down Expand Up @@ -124,6 +132,39 @@ private function generateBlocks(array $blocks, PrintContext $context): void
}


private function generateStub(Node $node, string $className, $filters): string
{
if (!class_exists(Php\ClassType::class)) {
return '';
}

$used = [];
(new NodeTraverser)->traverse($node, function (Node $node) use (&$used) {
if ($node instanceof Nodes\Php\FilterNode) {
$used[$node->name->name] = true;
}
});

$class = new Php\ClassType($className);
$filters = array_intersect_key($filters, $used);
foreach ($filters as $name => $callback) {
$func = (new Php\Factory)->fromCallable($callback);
$type = Blueprint::printType($func->getReturnType(), $func->isReturnNullable(), null) ?: 'mixed';
$params = [];
$list = $func->getParameters();
foreach ($list as $param) {
$variadic = $func->isVariadic() && $param === end($list);
$params[] = (Blueprint::printType($param->getType(), $param->isNullable(), null) ?: 'mixed')
. ($variadic ? '...' : '');
}

$class->addComment('@property callable(' . implode(', ', $params) . "): $type \$$name");
}

return (string) $class;
}


/**
* @param Nodes\Php\ParameterNode[] $params
*/
Expand Down
1 change: 1 addition & 0 deletions src/Latte/Engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ public function generate(TemplateNode $node, string $name): string
$this->getTemplateClass($name),
$comment,
$this->strictTypes,
$this->getFilters(),
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Latte/Essential/Blueprint.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function addFunctions(Php\ClassType $class, array $funcs): void
}


private function printType(?string $type, bool $nullable, ?Php\PhpNamespace $namespace): string
public static function printType(?string $type, bool $nullable, ?Php\PhpNamespace $namespace): string
{
if ($type === null) {
return '';
Expand Down Expand Up @@ -123,7 +123,7 @@ public function printParameters(
$list = $function->getParameters();
foreach ($list as $param) {
$variadic = $function->isVariadic() && $param === end($list);
$params[] = ltrim($this->printType($param->getType(), $param->isNullable(), $namespace) . ' ')
$params[] = ltrim(self::printType($param->getType(), $param->isNullable(), $namespace) . ' ')
. ($param->isReference() ? '&' : '')
. ($variadic ? '...' : '')
. '$' . $param->getName()
Expand Down

0 comments on commit 46fb48e

Please sign in to comment.