Skip to content

Commit

Permalink
Blueprint::printClass() rewritten (BC break)
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Apr 17, 2024
1 parent 16de2dd commit 7646c8f
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 69 deletions.
67 changes: 42 additions & 25 deletions src/Latte/Essential/Blueprint.php
Expand Up @@ -9,8 +9,6 @@

namespace Latte\Essential;

use Latte;
use Latte\Runtime\Template;
use Nette\PhpGenerator as Php;


Expand All @@ -20,24 +18,46 @@
*/
final class Blueprint
{
public function printClass(Template $template, ?string $name = null): void
public function generateTemplateClass(
array $params,
?string $name = 'Template',
?string $extends = null,
): Php\ClassType
{
if (!class_exists(Php\ClassType::class)) {
throw new \LogicException('Nette PhpGenerator is required to print template, install package `nette/php-generator`.');
throw new \LogicException('Nette PhpGenerator is required to generate blueprint, install package `nette/php-generator`.');
}

$name = $name ?: 'Template';
$namespace = new Php\PhpNamespace(Php\Helpers::extractNamespace($name));
$class = $namespace->addClass(Php\Helpers::extractShortName($name));
if ($extends) {
if (class_exists($extends)) {
if ((new \ReflectionClass($extends))->isFinal()) {
throw new \LogicException("Blueprint error: Unable to extend final class $extends");
}
$class->setExtends($extends);
} elseif (trait_exists($extends)) {
$class->addTrait($extends);
} else {
throw new \LogicException("Blueprint error: Class '$extends' doesn't exist.");
}
$params = array_diff_key($params, get_class_vars($extends));
}
$this->addProperties($class, $params);
return $class;
}


$this->addProperties($class, $template->getParameters());
$functions = array_diff_key($template->global->fn->getAll(), (new Latte\Essential\CoreExtension)->getFunctions());
$this->addFunctions($class, $functions);
public function printClass(Php\ClassType $class): void
{
$this->printCode((string) $class->getNamespace());
}

$end = $this->printCanvas();
$this->printHeader('Native types');
$this->printCode((string) $namespace);
echo $end;

public function clickableFile(string $file, int $line = 1): string
{
$link = 'editor://open/?file=' . rawurlencode(strtr($file, '/', DIRECTORY_SEPARATOR)) . '&line=' . $line;
return '<a href="' . htmlspecialchars($link) . '">' . htmlspecialchars($file) . '</a>';
}


Expand All @@ -46,24 +66,16 @@ public function printClass(Template $template, ?string $name = null): void
*/
public function printVars(array $vars): void
{
if (!class_exists(Php\Type::class)) {
throw new \LogicException('Nette PhpGenerator is required to print template, install package `nette/php-generator`.');
}

$res = '';
foreach ($vars as $name => $value) {
if (str_starts_with($name, 'ʟ_')) {
continue;
if (!str_starts_with($name, 'ʟ_')) {
$type = $this->getType($value);
$res .= "{varType $type $$name}\n";
}

$type = $this->getType($value);
$res .= "{varType $type $$name}\n";
}

$end = $this->printCanvas();
$this->printHeader('varPrint');
$this->printCode($res ?: 'No variables', 'latte');
echo $end;
}


Expand Down Expand Up @@ -134,12 +146,17 @@ public function printParameters(
}


public function printCanvas(): string
public function printBegin(): void
{
echo '<script src="https://nette.github.io/resources/prism/prism.js"></script>';
echo '<link rel="stylesheet" href="https://nette.github.io/resources/prism/prism.css">';
echo "<div style='all:initial;position:fixed;overflow:auto;z-index:1000;left:0;right:0;top:0;bottom:0;color:black;background:white;padding:1em'>\n";
return "</div>\n";
}


public function printEnd(): void
{
echo "</div>\n";
}


Expand Down
11 changes: 8 additions & 3 deletions src/Latte/Essential/Nodes/TemplatePrintNode.php
Expand Up @@ -13,14 +13,13 @@
use Latte\Compiler\Nodes;
use Latte\Compiler\Nodes\StatementNode;
use Latte\Compiler\NodeTraverser;
use Latte\Compiler\PhpHelpers;
use Latte\Compiler\PrintContext;
use Latte\Compiler\Tag;
use Latte\Compiler\Token;


/**
* {templatePrint [ClassName]}
* {templatePrint [ParentClass]}
*/
class TemplatePrintNode extends StatementNode
{
Expand All @@ -37,7 +36,13 @@ public static function create(Tag $tag): static

public function print(PrintContext $context): string
{
return '(new Latte\Essential\Blueprint)->printClass($this, ' . PhpHelpers::dump($this->template) . '); exit;';
return $context->format(<<<'XX'
$ʟ_bp = new Latte\Essential\Blueprint;
$ʟ_bp->printBegin();
$ʟ_bp->printClass($ʟ_bp->generateTemplateClass($this->getParameters(), extends: %dump));
$ʟ_bp->printEnd();
exit;
XX, $this->template);
}


Expand Down
11 changes: 9 additions & 2 deletions src/Latte/Essential/Nodes/VarPrintNode.php
Expand Up @@ -33,9 +33,16 @@ public static function create(Tag $tag): static

public function print(PrintContext $context): string
{
$vars = $this->all ? 'get_defined_vars()'
$vars = $this->all
? 'get_defined_vars()'
: 'array_diff_key(get_defined_vars(), $this->getParameters())';
return "(new Latte\\Essential\\Blueprint)->printVars($vars); exit;";
return <<<XX
\$ʟ_bp = new Latte\\Essential\\Blueprint;
\$ʟ_bp->printBegin();
\$ʟ_bp->printVars($vars);
\$ʟ_bp->printEnd();
exit;
XX;
}


Expand Down
55 changes: 55 additions & 0 deletions tests/common/Blueprint.printClass.phpt
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

use Tester\Assert;

require __DIR__ . '/../bootstrap.php';


$latte = new Latte\Engine;
$latte->setLoader(new Latte\Loaders\StringLoader);
$latte->addFunction('Abc', function (stdClass $a, $b = 132) {});


class ParentTemplate
{
public $int;
}

$params = ['int' => 123, 'unknown' => null];

$blueprint = new Latte\Essential\Blueprint;
ob_start();
$blueprint->printClass($blueprint->generateTemplateClass($params));
$res = ob_get_clean();

Assert::match(
<<<'XX'
%A%class Template
{
public int $int;
public mixed $unknown;
}
%A%
XX,
$res,
);


ob_start();
$blueprint->printClass($blueprint->generateTemplateClass($params, name: Foo\Template::class, extends: ParentTemplate::class));
$res = ob_get_clean();

Assert::match(
<<<'XX'
%A%namespace Foo;
class Template extends \ParentTemplate
{
public mixed $unknown;
}
%A%
XX,
$res,
);
Expand Up @@ -7,9 +7,9 @@ use Tester\Assert;
require __DIR__ . '/../bootstrap.php';


$printer = new Latte\Essential\Blueprint;
$blueprint = new Latte\Essential\Blueprint;
ob_start();
$printer->printVars(['int' => 123, 'unknown' => null]);
$blueprint->printVars(['int' => 123, 'unknown' => null]);
$res = ob_get_clean();

Assert::match(
Expand Down
35 changes: 0 additions & 35 deletions tests/tags/printClass.phpt

This file was deleted.

10 changes: 8 additions & 2 deletions tests/tags/templatePrint.phpt
Expand Up @@ -22,7 +22,10 @@ Assert::match(
{
extract($this->params);
(new Latte\Essential\Blueprint)->printClass($this, null);
$ʟ_bp = new Latte\Essential\Blueprint;
$ʟ_bp->printBegin();
$ʟ_bp->printClass($ʟ_bp->generateTemplateClass($this->getParameters(), extends: null));
$ʟ_bp->printEnd();
exit;
%A%
XX,
Expand All @@ -37,7 +40,10 @@ Assert::match(
{
extract($this->params);
(new Latte\Essential\Blueprint)->printClass($this, 'Foo');
$ʟ_bp = new Latte\Essential\Blueprint;
$ʟ_bp->printBegin();
$ʟ_bp->printClass($ʟ_bp->generateTemplateClass($this->getParameters(), extends: 'Foo'));
$ʟ_bp->printEnd();
exit;
%A%
XX,
Expand Down

0 comments on commit 7646c8f

Please sign in to comment.