> */ private static $handlers = []; /** @var array */ private static $dynamic_storages = []; /** * @param class-string $class */ public function registerClass(string $class): void { $callable = Closure::fromCallable([$class, 'getFunctionStorage']); foreach ($class::getFunctionIds() as $function_id) { $this->registerClosure($function_id, $callable); } } /** * @param Closure(FunctionDynamicStorageProviderEvent): ?FunctionStorage $c */ public function registerClosure(string $fq_function_name, Closure $c): void { self::$handlers[strtolower($fq_function_name)][] = $c; } public function has(string $fq_function_name): bool { return isset(self::$handlers[strtolower($fq_function_name)]); } public function getFunctionSignature( PhpParser\Node\Expr\FuncCall $stmt, StatementsAnalyzer $statements_analyzer, string $function_id, Context $context, CodeLocation $code_location ): ?FunctionStorage { $dynamic_storage_id = strtolower($statements_analyzer->getFilePath()) . ':' . $stmt->getLine() . ':' . (int)$stmt->getAttribute('startFilePos') . ':dynamic-storage' . ':-:' . strtolower($function_id); if (isset(self::$dynamic_storages[$dynamic_storage_id])) { return self::$dynamic_storages[$dynamic_storage_id]; } foreach (self::$handlers[strtolower($function_id)] ?? [] as $class_handler) { $event = new FunctionDynamicStorageProviderEvent( $statements_analyzer, $function_id, $stmt, $context, $code_location ); $result = $class_handler($event); self::$dynamic_storages[$dynamic_storage_id] = $result; if ($result) { return $result; } } return null; } }