Merge branch '4.4' into 5.2

* 4.4:
  install compatible versions of mongodb/mongodb only
  fix resolving parent/self/static type annotations
  [Console] fix QuestionHelper::getHiddenResponse() not working with space in project directory name
  [WebLink] Escape double quotes in attributes values
This commit is contained in:
Christian Flothmann 2021-02-17 16:24:54 +01:00
commit e3b0c8868c
12 changed files with 126 additions and 14 deletions

View File

@ -255,7 +255,7 @@ install:
fi
phpenv global $PHP
rm vendor/composer/package-versions-deprecated -Rf
([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb ^1.9.0)
([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb)
tfold 'composer update' $COMPOSER_UP
tfold 'phpunit install' ./phpunit install
if [[ $deps = high ]]; then

View File

@ -411,7 +411,7 @@ class QuestionHelper extends Helper
$exe = $tmpExe;
}
$sExec = shell_exec($exe);
$sExec = shell_exec('"'.$exe.'"');
$value = $trimmable ? rtrim($sExec) : $sExec;
$output->writeln('');

View File

@ -142,11 +142,31 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
break;
}
$parentClass = null;
$types = [];
/** @var DocBlock\Tags\Var_|DocBlock\Tags\Return_|DocBlock\Tags\Param $tag */
foreach ($docBlock->getTagsByName($tag) as $tag) {
if ($tag && !$tag instanceof InvalidTag && null !== $tag->getType()) {
$types = array_merge($types, $this->phpDocTypeHelper->getTypes($tag->getType()));
foreach ($this->phpDocTypeHelper->getTypes($tag->getType()) as $type) {
switch ($type->getClassName()) {
case 'self':
case 'static':
$resolvedClass = $class;
break;
case 'parent':
if (false !== $resolvedClass = $parentClass ?? $parentClass = get_parent_class($class)) {
break;
}
// no break
default:
$types[] = $type;
continue 2;
}
$types[] = new Type(Type::BUILTIN_TYPE_OBJECT, $type->isNullable(), $resolvedClass, $type->isCollection(), $type->getCollectionKeyType(), $type->getCollectionValueType());
}
}
}

View File

@ -17,6 +17,7 @@ use phpDocumentor\Reflection\Types\Collection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\TraitUsage\DummyUsedInTrait;
use Symfony\Component\PropertyInfo\Tests\Fixtures\TraitUsage\DummyUsingTrait;
use Symfony\Component\PropertyInfo\Type;
@ -136,6 +137,7 @@ class PhpDocExtractorTest extends TestCase
null,
null,
],
['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], null, null],
];
}
@ -342,6 +344,38 @@ class PhpDocExtractorTest extends TestCase
];
}
/**
* @dataProvider propertiesStaticTypeProvider
*/
public function testPropertiesStaticType(string $class, string $property, Type $type)
{
$this->assertEquals([$type], $this->extractor->getTypes($class, $property));
}
public function propertiesStaticTypeProvider(): array
{
return [
[ParentDummy::class, 'propertyTypeStatic', new Type(Type::BUILTIN_TYPE_OBJECT, false, ParentDummy::class)],
[Dummy::class, 'propertyTypeStatic', new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)],
];
}
/**
* @dataProvider propertiesParentTypeProvider
*/
public function testPropertiesParentType(string $class, string $property, ?array $types)
{
$this->assertEquals($types, $this->extractor->getTypes($class, $property));
}
public function propertiesParentTypeProvider(): array
{
return [
[ParentDummy::class, 'parentAnnotationNoParent', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'parent')]],
[Dummy::class, 'parentAnnotation', [new Type(Type::BUILTIN_TYPE_OBJECT, false, ParentDummy::class)]],
];
}
protected function isPhpDocumentorV5()
{
if (class_exists(InvalidTag::class)) {

View File

@ -24,6 +24,8 @@ use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended2;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php74Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php7ParentDummy;
use Symfony\Component\PropertyInfo\Type;
/**
@ -66,12 +68,15 @@ class ReflectionExtractorTest extends TestCase
'arrayWithKeys',
'arrayWithKeysAndComplexValue',
'arrayOfMixed',
'parentAnnotation',
'foo',
'foo2',
'foo3',
'foo4',
'foo5',
'files',
'propertyTypeStatic',
'parentAnnotationNoParent',
'a',
'DOB',
'Id',
@ -118,12 +123,15 @@ class ReflectionExtractorTest extends TestCase
'arrayWithKeys',
'arrayWithKeysAndComplexValue',
'arrayOfMixed',
'parentAnnotation',
'foo',
'foo2',
'foo3',
'foo4',
'foo5',
'files',
'propertyTypeStatic',
'parentAnnotationNoParent',
'date',
'c',
'd',
@ -159,12 +167,15 @@ class ReflectionExtractorTest extends TestCase
'arrayWithKeys',
'arrayWithKeysAndComplexValue',
'arrayOfMixed',
'parentAnnotation',
'foo',
'foo2',
'foo3',
'foo4',
'foo5',
'files',
'propertyTypeStatic',
'parentAnnotationNoParent',
],
$noPrefixExtractor->getProperties('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy')
);
@ -200,20 +211,21 @@ class ReflectionExtractorTest extends TestCase
/**
* @dataProvider php7TypesProvider
*/
public function testExtractPhp7Type($property, array $type = null)
public function testExtractPhp7Type(string $class, string $property, array $type = null)
{
$this->assertEquals($type, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy', $property, []));
$this->assertEquals($type, $this->extractor->getTypes($class, $property, []));
}
public function php7TypesProvider()
{
return [
['foo', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]],
['bar', [new Type(Type::BUILTIN_TYPE_INT)]],
['baz', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]],
['buz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy')]],
['biz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'stdClass')]],
['donotexist', null],
[Php7Dummy::class, 'foo', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]],
[Php7Dummy::class, 'bar', [new Type(Type::BUILTIN_TYPE_INT)]],
[Php7Dummy::class, 'baz', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]],
[Php7Dummy::class, 'buz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy')]],
[Php7Dummy::class, 'biz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Php7ParentDummy::class)]],
[Php7Dummy::class, 'donotexist', null],
[Php7ParentDummy::class, 'parent', [new Type(Type::BUILTIN_TYPE_OBJECT, false, \stdClass::class)]],
];
}

View File

@ -145,6 +145,11 @@ class Dummy extends ParentDummy
*/
public $arrayOfMixed;
/**
* @var parent
*/
public $parentAnnotation;
public static function getStatic()
{
}

View File

@ -48,6 +48,16 @@ class ParentDummy
*/
public $files;
/**
* @var static
*/
public $propertyTypeStatic;
/**
* @var parent
*/
public $parentAnnotationNoParent;
/**
* @return bool|null
*/

View File

@ -14,7 +14,7 @@ namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class Php7Dummy extends \stdClass
class Php7Dummy extends Php7ParentDummy
{
public function getFoo(): array
{

View File

@ -0,0 +1,19 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
class Php7ParentDummy extends \stdClass
{
public function getParent(): parent
{
}
}

View File

@ -172,6 +172,10 @@ final class PhpDocTypeHelper
return [$docType, null];
}
if (\in_array($docType, ['parent', 'self', 'static'], true)) {
return ['object', $docType];
}
return ['object', substr($docType, 1)]; // substr to strip the namespace's `\`-prefix
}
}

View File

@ -39,14 +39,14 @@ final class HttpHeaderSerializer
foreach ($link->getAttributes() as $key => $value) {
if (\is_array($value)) {
foreach ($value as $v) {
$attributesParts[] = sprintf('%s="%s"', $key, $v);
$attributesParts[] = sprintf('%s="%s"', $key, preg_replace('/(?<!\\\\)"/', '\"', $v));
}
continue;
}
if (!\is_bool($value)) {
$attributesParts[] = sprintf('%s="%s"', $key, $value);
$attributesParts[] = sprintf('%s="%s"', $key, preg_replace('/(?<!\\\\)"/', '\"', $value));
continue;
}

View File

@ -44,4 +44,12 @@ class HttpHeaderSerializerTest extends TestCase
{
$this->assertNull($this->serializer->serialize([]));
}
public function testSerializeDoubleQuotesInAttributeValue()
{
$this->assertSame('</foo>; rel="alternate"; title="\"escape me\" \"already escaped\" \"\"\""', $this->serializer->serialize([
(new Link('alternate', '/foo'))
->withAttribute('title', '"escape me" \"already escaped\" ""\"'),
]));
}
}