126 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			2.9 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 $sectionAction = null;
 | |
| 
 | |
|     public string $viewPath = "";
 | |
|     
 | |
|     public string $filePath = "";
 | |
| 
 | |
|     public string $classPath = "";
 | |
| 
 | |
|     public array $switchStack = [];
 | |
| 
 | |
|     public array $iterationStack = [];
 | |
| 
 | |
|     public array $useStack = [];
 | |
| 
 | |
|     public array $sections = [];
 | |
| 
 | |
|     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 tokenName(string $token) : string
 | |
|     {
 | |
|         return explode('.', $token)[0];
 | |
|     }
 | |
| 
 | |
|     public function tokenOptions(string $token, bool $export = false) : array|string
 | |
|     {
 | |
|         $options = array_slice(explode('.', strtolower($token)), 1);
 | |
| 
 | |
|         return $export ? var_export($options, true) : $options;
 | |
|     }
 | |
| 
 | |
|     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";
 | |
|     }
 | |
| }
 |