picea/src/Compiler/Context.php

108 lines
2.5 KiB
PHP

<?php declare(strict_types=1);
namespace Picea\Compiler;
use Picea\Compiler;
abstract class Context {
public string $namespace = "";
public string $extendFrom = "";
public string $className = "";
public string $compiledSource = "";
public string $viewPath = "";
public string $filePath = "";
public array $switchStack = [];
public array $iterateStack = [];
public array $useStack = [];
public int $functions = 0;
public array $functionStack = [];
public array $hooks = [];
public Compiler $compiler;
public function hook(string $path, Callable $callback) : self
{
$this->hooks[$path] ??= [];
$this->hooks[$path][] = $callback;
return $this;
}
public function run(string $path, ...$arguments) : self
{
if ( $this->hooks[$path] ?? false ) {
while ( $callback = array_pop($this->hooks[$path]) ) {
$callback(...$arguments);
}
}
}
public function renderUses() : string
{
return implode(",", $this->useStack ?? []);
}
public function renderFunctions() : string
{
if ($this->extendFrom) {
return "parent::exportFunctions();";
}
else {
$cls = $this->compiledClassPath();
$ns = $this->namespace ? "\\{$this->namespace}\\" : "";
$list = ['static $caching = [];'];
foreach ($this->functionStack as $name => $function) {
$list[] = <<<FUNC
if ( false === ( ( \$caching['$ns$name'] ?? false) || function_exists( '$ns$name' ) ) ) {
\$caching['$ns$name'] = true;
function $name(...\$arguments) {
return $cls::\$context->functionStack['$name'](...\$arguments);
}
}
FUNC;
}
return implode(PHP_EOL, $list);
}
}
public function exportFunctions() : void
{
}
public function pushFunction($name, Callable $callable) : void
{
$this->functionStack[$name] = $callable;
}
public function compiledClassPath() : string
{
if ($this->namespace) {
return "\\{$this->namespace}\\{$this->className}";
}
return $this->className;
}
public function cacheFilename() : string
{
return strtolower(str_replace("\\", DIRECTORY_SEPARATOR, $this->namespace)) . ".context";
}
}