| Server IP : 139.59.63.204 / Your IP : 216.73.217.62 Web Server : Apache/2.4.58 (Ubuntu) System : Linux ubuntu-s-1vcpu-1gb-blr1-01 6.8.0-110-generic #110-Ubuntu SMP PREEMPT_DYNAMIC Thu Mar 19 15:09:20 UTC 2026 x86_64 User : root ( 0) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/abyogasms.com/vendor/nette/php-generator/src/PhpGenerator/ |
Upload File : |
<?php declare(strict_types=1);
/**
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*/
namespace Nette\PhpGenerator;
use Nette;
use Nette\Utils\Strings;
use function array_filter, array_map, count, end, get_debug_type, implode, is_scalar, ltrim, preg_replace, rtrim, str_contains, str_repeat, str_replace, strlen, substr;
/**
* Generates PHP code.
*/
class Printer
{
public int $wrapLength = 120;
public string $indentation = "\t";
public int $linesBetweenProperties = 0;
public int $linesBetweenMethods = 2;
public int $linesBetweenUseTypes = 0;
public string $returnTypeColon = ': ';
public bool $bracesOnNextLine = true;
public bool $singleParameterOnOneLine = false;
public bool $omitEmptyNamespaces = true;
public bool $declareOnOpenTag = false;
protected ?PhpNamespace $namespace = null;
protected Dumper $dumper;
private bool $resolveTypes = true;
public function __construct()
{
$this->dumper = new Dumper;
}
public function printFunction(GlobalFunction $function, ?PhpNamespace $namespace = null): string
{
$this->namespace = $this->resolveTypes ? $namespace : null;
$line = 'function '
. ($function->getReturnReference() ? '&' : '')
. $function->getName();
$returnType = $this->printReturnType($function);
$params = $this->printParameters($function, strlen($line) + strlen($returnType) + 2); // 2 = parentheses
$body = $this->printFunctionBody($function);
$braceOnNextLine = $this->isBraceOnNextLine(str_contains($params, "\n"), (bool) $returnType);
return $this->printDocComment($function)
. $this->printAttributes($function->getAttributes())
. $line
. $params
. $returnType
. ($braceOnNextLine ? "\n" : ' ')
. "{\n" . $this->indent($body) . "}\n";
}
public function printClosure(Closure $closure, ?PhpNamespace $namespace = null): string
{
$this->namespace = $this->resolveTypes ? $namespace : null;
$uses = [];
foreach ($closure->getUses() as $param) {
$uses[] = ($param->isReference() ? '&' : '') . '$' . $param->getName();
}
$useStr = strlen($tmp = implode(', ', $uses)) > $this->wrapLength && count($uses) > 1
? "\n" . $this->indentation . implode(",\n" . $this->indentation, $uses) . ",\n"
: $tmp;
$body = $this->printFunctionBody($closure);
return $this->printAttributes($closure->getAttributes(), inline: true)
. 'function '
. ($closure->getReturnReference() ? '&' : '')
. $this->printParameters($closure)
. ($uses ? " use ($useStr)" : '')
. $this->printReturnType($closure)
. " {\n" . $this->indent($body) . '}';
}
public function printArrowFunction(Closure $closure, ?PhpNamespace $namespace = null): string
{
$this->namespace = $this->resolveTypes ? $namespace : null;
foreach ($closure->getUses() as $use) {
if ($use->isReference()) {
throw new Nette\InvalidArgumentException('Arrow function cannot bind variables by-reference.');
}
}
$body = $this->printFunctionBody($closure);
return $this->printAttributes($closure->getAttributes())
. 'fn'
. ($closure->getReturnReference() ? '&' : '')
. $this->printParameters($closure)
. $this->printReturnType($closure)
. ' => ' . rtrim($body, "\n") . ';';
}
public function printMethod(Method $method, ?PhpNamespace $namespace = null, bool $isInterface = false): string
{
$this->namespace = $this->resolveTypes ? $namespace : null;
$method->validate();
$line = ($method->isAbstract() && !$isInterface ? 'abstract ' : '')
. ($method->isFinal() ? 'final ' : '')
. ($method->getVisibility() ? $method->getVisibility() . ' ' : '')
. ($method->isStatic() ? 'static ' : '')
. 'function '
. ($method->getReturnReference() ? '&' : '')
. $method->getName();
$returnType = $this->printReturnType($method);
$params = $this->printParameters($method, strlen($line) + strlen($returnType) + strlen($this->indentation) + 2);
$body = $this->printFunctionBody($method);
$braceOnNextLine = $this->isBraceOnNextLine(str_contains($params, "\n"), (bool) $returnType);
return $this->printDocComment($method)
. $this->printAttributes($method->getAttributes())
. $line
. $params
. $returnType
. ($method->isAbstract() || $isInterface
? ";\n"
: ($braceOnNextLine ? "\n" : ' ') . "{\n" . $this->indent($body) . "}\n");
}
private function printFunctionBody(Closure|GlobalFunction|Method|PropertyHook $function): string
{
$code = Helpers::simplifyTaggedNames($function->getBody(), $this->namespace);
$code = Strings::normalize($code);
return ltrim(rtrim($code) . "\n");
}
public function printClass(
ClassType|InterfaceType|TraitType|EnumType $class,
?PhpNamespace $namespace = null,
): string
{
$this->namespace = $this->resolveTypes ? $namespace : null;
$class->validate();
$resolver = $this->namespace
? $this->namespace->simplifyType(...)
: fn($s) => $s;
$traits = [];
if ($class instanceof ClassType || $class instanceof TraitType || $class instanceof EnumType) {
foreach ($class->getTraits() as $trait) {
$resolutions = implode(";\n", $trait->getResolutions());
$resolutions = Helpers::simplifyTaggedNames($resolutions, $this->namespace);
$traits[] = $this->printDocComment($trait)
. 'use ' . $resolver($trait->getName())
. ($resolutions
? " {\n" . $this->indent($resolutions) . ";\n}\n"
: ";\n");
}
}
$cases = [];
$enumType = null;
if ($class instanceof EnumType) {
$enumType = $class->getType();
foreach ($class->getCases() as $case) {
$enumType ??= is_scalar($case->getValue()) ? get_debug_type($case->getValue()) : null;
$cases[] = $this->printDocComment($case)
. $this->printAttributes($case->getAttributes())
. 'case ' . $case->getName()
. ($case->getValue() === null ? '' : ' = ' . $this->dump($case->getValue()))
. ";\n";
}
}
$readOnlyClass = $class instanceof ClassType && $class->isReadOnly();
$consts = [];
$methods = [];
foreach ($class->getConstants() as $const) {
$consts[] = $this->printConstant($const);
}
foreach ($class->getMethods() as $method) {
if ($readOnlyClass && $method->getName() === Method::Constructor) {
$method = clone $method;
array_map(fn($param) => $param instanceof PromotedParameter ? $param->setReadOnly(false) : null, $method->getParameters());
}
$methods[] = $this->printMethod($method, $namespace, $class->isInterface());
}
$properties = [];
if ($class instanceof ClassType || $class instanceof TraitType || $class instanceof InterfaceType) {
foreach ($class->getProperties() as $property) {
$properties[] = $this->printProperty($property, $readOnlyClass, $class instanceof InterfaceType);
}
}
$members = array_filter([
implode('', $traits),
$this->joinProperties($consts),
$this->joinProperties($cases),
$this->joinProperties($properties),
($methods && $properties ? str_repeat("\n", $this->linesBetweenMethods - 1) : '')
. implode(str_repeat("\n", $this->linesBetweenMethods), $methods),
]);
if ($class instanceof ClassType) {
$line[] = $class->isAbstract() ? 'abstract' : null;
$line[] = $class->isFinal() ? 'final' : null;
$line[] = $class->isReadOnly() ? 'readonly' : null;
}
$line[] = match (true) {
$class instanceof ClassType => $class->getName() ? 'class ' . $class->getName() : null,
$class instanceof InterfaceType => 'interface ' . $class->getName(),
$class instanceof TraitType => 'trait ' . $class->getName(),
$class instanceof EnumType => 'enum ' . $class->getName() . ($enumType ? $this->returnTypeColon . $enumType : ''),
};
$line[] = ($class instanceof ClassType || $class instanceof InterfaceType) && $class->getExtends()
? 'extends ' . implode(', ', array_map($resolver, (array) $class->getExtends()))
: null;
$line[] = ($class instanceof ClassType || $class instanceof EnumType) && $class->getImplements()
? 'implements ' . implode(', ', array_map($resolver, $class->getImplements()))
: null;
$line[] = $class->getName() ? null : '{';
return $this->printDocComment($class)
. $this->printAttributes($class->getAttributes())
. implode(' ', array_filter($line))
. ($class->getName() ? "\n{\n" : "\n")
. ($members ? $this->indent(implode("\n", $members)) : '')
. '}'
. ($class->getName() ? "\n" : '');
}
public function printNamespace(PhpNamespace $namespace): string
{
$this->namespace = $this->resolveTypes ? $namespace : null;
$name = $namespace->getName();
$uses = [
$this->printUses($namespace),
$this->printUses($namespace, PhpNamespace::NameFunction),
$this->printUses($namespace, PhpNamespace::NameConstant),
];
$uses = implode(str_repeat("\n", $this->linesBetweenUseTypes), array_filter($uses));
$items = [];
foreach ($namespace->getClasses() as $class) {
$items[] = $this->printClass($class, $namespace);
}
foreach ($namespace->getFunctions() as $function) {
$items[] = $this->printFunction($function, $namespace);
}
$body = ($uses ? $uses . "\n" : '')
. implode("\n", $items);
if ($namespace->hasBracketedSyntax()) {
return 'namespace' . ($name ? " $name" : '') . "\n{\n"
. $this->indent($body)
. "}\n";
} else {
return ($name ? "namespace $name;\n\n" : '')
. $body;
}
}
public function printFile(PhpFile $file): string
{
$namespaces = [];
foreach ($file->getNamespaces() as $namespace) {
if (!$this->omitEmptyNamespaces || $namespace->getClasses() || $namespace->getFunctions()) {
$namespaces[] = $this->printNamespace($namespace);
}
}
$strictTypes = $file->hasStrictTypes();
return '<?php' . ($strictTypes && $this->declareOnOpenTag ? ' declare(strict_types=1);' : '')
. "\n"
. ($file->getComment() ? "\n" . $this->printDocComment($file) : '')
. "\n"
. ($strictTypes && !$this->declareOnOpenTag ? "declare(strict_types=1);\n\n" : '')
. implode("\n\n", $namespaces);
}
/** @param PhpNamespace::Name* $of */
protected function printUses(PhpNamespace $namespace, string $of = PhpNamespace::NameNormal): string
{
$prefix = [
PhpNamespace::NameNormal => '',
PhpNamespace::NameFunction => 'function ',
PhpNamespace::NameConstant => 'const ',
][$of];
$uses = [];
foreach ($namespace->getUses($of) as $alias => $original) {
$uses[] = Helpers::extractShortName($original) === $alias
? "use $prefix$original;\n"
: "use $prefix$original as $alias;\n";
}
return implode('', $uses);
}
protected function printParameters(Closure|GlobalFunction|Method|PropertyHook $function, int $column = 0): string
{
$special = false;
foreach ($function->getParameters() as $param) {
$param->validate();
$special = $special || $param instanceof PromotedParameter || $param->getAttributes() || $param->getComment();
}
if (!$special || ($this->singleParameterOnOneLine && count($function->getParameters()) === 1)) {
$line = $this->formatParameters($function, multiline: false);
if (!str_contains($line, "\n") && strlen($line) + $column <= $this->wrapLength) {
return $line;
}
}
return $this->formatParameters($function, multiline: true);
}
private function formatParameters(Closure|GlobalFunction|Method|PropertyHook $function, bool $multiline): string
{
$params = $function->getParameters();
$res = '';
foreach ($params as $param) {
$variadic = !$function instanceof PropertyHook && $function->isVariadic() && $param === end($params);
$attrs = $this->printAttributes($param->getAttributes(), inline: true);
$res .=
$this->printDocComment($param)
. ($attrs ? ($multiline ? substr($attrs, 0, -1) . "\n" : $attrs) : '')
. ($param instanceof PromotedParameter
? ($param->isFinal() ? 'final ' : '')
. $this->printPropertyVisibility($param)
. ($param->isReadOnly() && $param->getType() ? ' readonly' : '')
. ' '
: '')
. ltrim($this->printType($param->getType(), $param->isNullable()) . ' ')
. ($param->isReference() ? '&' : '')
. ($variadic ? '...' : '')
. '$' . $param->getName()
. ($param->hasDefaultValue() && !$variadic ? ' = ' . $this->dump($param->getDefaultValue()) : '')
. ($param instanceof PromotedParameter ? $this->printHooks($param) : '')
. ($multiline ? ",\n" : ', ');
}
return $multiline
? "(\n" . $this->indent($res) . ')'
: '(' . substr($res, 0, -2) . ')';
}
private function printConstant(Constant $const): string
{
$def = ($const->isFinal() ? 'final ' : '')
. ($const->getVisibility() ? $const->getVisibility() . ' ' : '')
. 'const '
. ltrim($this->printType($const->getType(), nullable: false) . ' ')
. $const->getName() . ' = ';
return $this->printDocComment($const)
. $this->printAttributes($const->getAttributes())
. $def
. $this->dump($const->getValue(), strlen($def)) . ";\n";
}
private function printProperty(Property $property, bool $readOnlyClass = false, bool $isInterface = false): string
{
$property->validate();
$type = $property->getType();
$def = ($property->isAbstract() && !$isInterface ? 'abstract ' : '')
. ($property->isFinal() ? 'final ' : '')
. $this->printPropertyVisibility($property)
. ($property->isStatic() ? ' static' : '')
. (!$readOnlyClass && $property->isReadOnly() && $type ? ' readonly' : '')
. ' '
. ltrim($this->printType($type, $property->isNullable()) . ' ')
. '$' . $property->getName();
$defaultValue = $property->getValue() === null && !$property->isInitialized()
? ''
: ' = ' . $this->dump($property->getValue(), strlen($def) + 3); // 3 = ' = '
return $this->printDocComment($property)
. $this->printAttributes($property->getAttributes())
. $def
. $defaultValue
. ($this->printHooks($property, $isInterface) ?: ';')
. "\n";
}
private function printPropertyVisibility(Property|PromotedParameter $param): string
{
$get = $param->getVisibility(PropertyAccessMode::Get);
$set = $param->getVisibility(PropertyAccessMode::Set);
return $set
? ($get ? "$get $set(set)" : "$set(set)")
: $get ?? 'public';
}
protected function printType(?string $type, bool $nullable): string
{
if ($type === null) {
return '';
}
if ($this->namespace) {
$type = $this->namespace->simplifyType($type);
}
return $nullable
? Type::nullable($type)
: $type;
}
/** @param PhpFile|ClassLike|GlobalFunction|Method|Property|Constant|Parameter|EnumCase|TraitUse|PropertyHook $commentable */
protected function printDocComment(/*Traits\CommentAware*/ $commentable): string
{
$multiLine = $commentable instanceof GlobalFunction
|| $commentable instanceof Method
|| $commentable instanceof ClassLike
|| $commentable instanceof PhpFile;
return Helpers::formatDocComment((string) $commentable->getComment(), $multiLine);
}
protected function printReturnType(Closure|GlobalFunction|Method $function): string
{
return ($tmp = $this->printType($function->getReturnType(), $function->isReturnNullable()))
? $this->returnTypeColon . $tmp
: '';
}
/** @param list<Attribute> $attrs */
protected function printAttributes(array $attrs, bool $inline = false): string
{
if (!$attrs) {
return '';
}
$this->dumper->indentation = $this->indentation;
$items = [];
foreach ($attrs as $attr) {
$args = $this->dumper->format('...?:', $attr->getArguments());
$args = Helpers::simplifyTaggedNames($args, $this->namespace);
$items[] = $this->printType($attr->getName(), nullable: false) . ($args === '' ? '' : "($args)");
$inline = $inline && !str_contains($args, "\n");
}
return $inline
? '#[' . implode(', ', $items) . '] '
: '#[' . implode("]\n#[", $items) . "]\n";
}
private function printHooks(Property|PromotedParameter $property, bool $isInterface = false): string
{
$hooks = $property->getHooks();
if (!$hooks) {
return '';
}
$simple = true;
foreach ($hooks as $type => $hook) {
$simple = $simple && ($hook->isAbstract() || $isInterface);
$hooks[$type] = $this->printDocComment($hook)
. $this->printAttributes($hook->getAttributes())
. ($hook->isAbstract() || $isInterface
? ($hook->getReturnReference() ? '&' : '')
. $type . ';'
: ($hook->isFinal() ? 'final ' : '')
. ($hook->getReturnReference() ? '&' : '')
. $type
. ($hook->getParameters() ? $this->printParameters($hook) : '')
. ' '
. ($hook->isShort()
? '=> ' . $hook->getBody() . ';'
: "{\n" . $this->indent($this->printFunctionBody($hook)) . '}'));
}
return $simple
? ' { ' . implode(' ', $hooks) . ' }'
: " {\n" . $this->indent(implode("\n", $hooks)) . "\n}";
}
public function setTypeResolving(bool $state = true): static
{
$this->resolveTypes = $state;
return $this;
}
protected function indent(string $s): string
{
$s = str_replace("\t", $this->indentation, $s);
return Strings::indent($s, 1, $this->indentation);
}
protected function dump(mixed $var, int $column = 0): string
{
$this->dumper->indentation = $this->indentation;
$this->dumper->wrapLength = $this->wrapLength;
$s = $this->dumper->dump($var, $column);
$s = Helpers::simplifyTaggedNames($s, $this->namespace);
return $s;
}
/** @param string[] $props */
private function joinProperties(array $props): string
{
return $this->linesBetweenProperties
? implode(str_repeat("\n", $this->linesBetweenProperties), $props)
: preg_replace('#^(\w.*\n)\n(?=\w.*;)#m', '$1', implode("\n", $props));
}
protected function isBraceOnNextLine(bool $multiLine, bool $hasReturnType): bool
{
return $this->bracesOnNextLine && (!$multiLine || $hasReturnType);
}
}