Skip to content

Commit

Permalink
Support new in initializers
Browse files Browse the repository at this point in the history
  • Loading branch information
malarzm committed Aug 7, 2022
1 parent 94bc351 commit 8f43d78
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 4 deletions.
32 changes: 28 additions & 4 deletions lib/Doctrine/Common/Proxy/ProxyGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
use function mkdir;
use function preg_match;
use function preg_match_all;
use function preg_replace;
use function preg_split;
use function random_bytes;
use function rename;
use function rtrim;
Expand All @@ -58,6 +60,7 @@

use const DIRECTORY_SEPARATOR;
use const PHP_VERSION_ID;
use const PREG_SPLIT_DELIM_CAPTURE;

/**
* This factory is used to generate proxy classes.
Expand Down Expand Up @@ -1089,10 +1092,7 @@ private function buildParametersString(array $parameters, array $renameParameter
}

$parameterDefinition .= '$' . ($renameParameters ? $renameParameters[$i] : $param->getName());

if ($param->isDefaultValueAvailable()) {
$parameterDefinition .= ' = ' . var_export($param->getDefaultValue(), true);
}
$parameterDefinition .= $this->getParameterDefaultValue($param);

$parameterDefinitions[] = $parameterDefinition;
}
Expand All @@ -1116,6 +1116,30 @@ private function getParameterType(ReflectionParameter $parameter)
return $this->formatType($parameter->getType(), $declaringFunction, $parameter);
}

private function getParameterDefaultValue(ReflectionParameter $parameter)
{
if (! $parameter->isDefaultValueAvailable()) {
return '';
}

if (PHP_VERSION_ID < 80100) {
return ' = ' . var_export($parameter->getDefaultValue(), true);
}

$value = rtrim(substr(explode('$' . $parameter->getName() . ' = ', (string) $parameter, 2)[1], 0, -2));
$parts = preg_split('{(\'(?:[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')}', $value, -1, PREG_SPLIT_DELIM_CAPTURE);

foreach ($parts as $i => &$part) {
if ($part === '' || $i % 2 !== 0) {
continue;
}

$part = preg_replace('/(?(DEFINE)(?<V>[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+))(?<!\\\\)(?&V)(?:\\\\(?&V))*+::/', '\\\\$0', $part);
}

return ' = ' . implode('', $parts);
}

/**
* @param ReflectionParameter[] $parameters
*
Expand Down
18 changes: 18 additions & 0 deletions tests/Doctrine/Tests/Common/Proxy/PHP81NewInInitializers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\Common\Proxy;

class PHP81NewInInitializers
{
public function onlyInitializer($foo = new \stdClass()): void
{

}

public function typed(\DateTimeInterface $foo = new \DateTimeImmutable('now')): void
{

}
}
25 changes: 25 additions & 0 deletions tests/Doctrine/Tests/Common/Proxy/ProxyGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,31 @@ public function testEnumDefaultInPublicProperty() : void
$this->assertSame($object->isEnum, \Doctrine\Tests\Common\Proxy\YesOrNo::YES);
}

/**
* @requires PHP >= 8.1.0
*/
public function testPhp81NewInInitializers()
{
$className = PHP81NewInInitializers::class;

if (!class_exists('Doctrine\Tests\Common\ProxyProxy\__CG__\PHP81NewInInitializers', false)) {
$metadata = $this->createClassMetadata($className, ['id']);

$proxyGenerator = new ProxyGenerator(__DIR__ . '/generated', __NAMESPACE__ . 'Proxy');
$this->generateAndRequire($proxyGenerator, $metadata);
}

self::assertStringContainsString(
'onlyInitializer($foo = new \stdClass()): void',
file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyPHP81NewInInitializers.php')
);

self::assertStringContainsString(
'typed(\DateTimeInterface $foo = new \DateTimeImmutable(\'now\')): void',
file_get_contents(__DIR__ . '/generated/__CG__DoctrineTestsCommonProxyPHP81NewInInitializers.php')
);
}

/**
* @param string $className
* @param mixed[] $ids
Expand Down

0 comments on commit 8f43d78

Please sign in to comment.