108 lines
2.5 KiB
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";
|
|
}
|
|
}
|