Merge branch '3.4' into 4.3
* 3.4: [Config][ReflectionClassResource] Handle parameters with undefined constant as their default values fix dumping number-like string parameters [Console] Fix autocomplete multibyte input support [Config] don't break on virtual stack frames in ClassExistenceResource
This commit is contained in:
commit
73ea89b4c2
@ -183,15 +183,17 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$props = [
|
$props = [
|
||||||
'file' => $trace[$i]['file'],
|
'file' => isset($trace[$i]['file']) ? $trace[$i]['file'] : null,
|
||||||
'line' => $trace[$i]['line'],
|
'line' => isset($trace[$i]['line']) ? $trace[$i]['line'] : null,
|
||||||
'trace' => \array_slice($trace, 1 + $i),
|
'trace' => \array_slice($trace, 1 + $i),
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($props as $p => $v) {
|
foreach ($props as $p => $v) {
|
||||||
$r = new \ReflectionProperty('Exception', $p);
|
if (null !== $v) {
|
||||||
$r->setAccessible(true);
|
$r = new \ReflectionProperty('Exception', $p);
|
||||||
$r->setValue($e, $v);
|
$r->setAccessible(true);
|
||||||
|
$r->setValue($e, $v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,12 +141,56 @@ class ReflectionClassResource implements SelfCheckingResourceInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) {
|
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) {
|
||||||
yield preg_replace('/^ @@.*/m', '', $m);
|
|
||||||
|
|
||||||
$defaults = [];
|
$defaults = [];
|
||||||
|
$parametersWithUndefinedConstants = [];
|
||||||
foreach ($m->getParameters() as $p) {
|
foreach ($m->getParameters() as $p) {
|
||||||
$defaults[$p->name] = $p->isDefaultValueAvailable() ? $p->getDefaultValue() : null;
|
if (!$p->isDefaultValueAvailable()) {
|
||||||
|
$defaults[$p->name] = null;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$p->isDefaultValueConstant() || \defined($p->getDefaultValueConstantName())) {
|
||||||
|
$defaults[$p->name] = $p->getDefaultValue();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$defaults[$p->name] = $p->getDefaultValueConstantName();
|
||||||
|
$parametersWithUndefinedConstants[$p->name] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$parametersWithUndefinedConstants) {
|
||||||
|
yield preg_replace('/^ @@.*/m', '', $m);
|
||||||
|
} else {
|
||||||
|
$stack = [
|
||||||
|
$m->getDocComment(),
|
||||||
|
$m->getName(),
|
||||||
|
$m->isAbstract(),
|
||||||
|
$m->isFinal(),
|
||||||
|
$m->isStatic(),
|
||||||
|
$m->isPublic(),
|
||||||
|
$m->isPrivate(),
|
||||||
|
$m->isProtected(),
|
||||||
|
$m->returnsReference(),
|
||||||
|
$m->hasReturnType() ? $m->getReturnType()->getName() : '',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($m->getParameters() as $p) {
|
||||||
|
if (!isset($parametersWithUndefinedConstants[$p->name])) {
|
||||||
|
$stack[] = (string) $p;
|
||||||
|
} else {
|
||||||
|
$stack[] = $p->isOptional();
|
||||||
|
$stack[] = $p->hasType() ? $p->getType()->getName() : '';
|
||||||
|
$stack[] = $p->isPassedByReference();
|
||||||
|
$stack[] = $p->isVariadic();
|
||||||
|
$stack[] = $p->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield implode(',', $stack);
|
||||||
|
}
|
||||||
|
|
||||||
yield print_r($defaults, true);
|
yield print_r($defaults, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,8 +64,12 @@ class ReflectionClassResourceTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideHashedSignature
|
* @dataProvider provideHashedSignature
|
||||||
*/
|
*/
|
||||||
public function testHashedSignature($changeExpected, $changedLine, $changedCode)
|
public function testHashedSignature($changeExpected, $changedLine, $changedCode, $setContext = null)
|
||||||
{
|
{
|
||||||
|
if ($setContext) {
|
||||||
|
$setContext();
|
||||||
|
}
|
||||||
|
|
||||||
$code = <<<'EOPHP'
|
$code = <<<'EOPHP'
|
||||||
/* 0*/
|
/* 0*/
|
||||||
/* 1*/ class %s extends ErrorException
|
/* 1*/ class %s extends ErrorException
|
||||||
@ -83,7 +87,9 @@ class ReflectionClassResourceTest extends TestCase
|
|||||||
/*13*/ protected function prot($a = []) {}
|
/*13*/ protected function prot($a = []) {}
|
||||||
/*14*/
|
/*14*/
|
||||||
/*15*/ private function priv() {}
|
/*15*/ private function priv() {}
|
||||||
/*16*/ }
|
/*16*/
|
||||||
|
/*17*/ public function ccc($bar = A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC) {}
|
||||||
|
/*18*/ }
|
||||||
EOPHP;
|
EOPHP;
|
||||||
|
|
||||||
static $expectedSignature, $generateSignature;
|
static $expectedSignature, $generateSignature;
|
||||||
@ -98,7 +104,9 @@ EOPHP;
|
|||||||
}
|
}
|
||||||
|
|
||||||
$code = explode("\n", $code);
|
$code = explode("\n", $code);
|
||||||
$code[$changedLine] = $changedCode;
|
if (null !== $changedCode) {
|
||||||
|
$code[$changedLine] = $changedCode;
|
||||||
|
}
|
||||||
eval(sprintf(implode("\n", $code), $class = 'Foo'.str_replace('.', '_', uniqid('', true))));
|
eval(sprintf(implode("\n", $code), $class = 'Foo'.str_replace('.', '_', uniqid('', true))));
|
||||||
$signature = implode("\n", iterator_to_array($generateSignature(new \ReflectionClass($class))));
|
$signature = implode("\n", iterator_to_array($generateSignature(new \ReflectionClass($class))));
|
||||||
|
|
||||||
@ -142,6 +150,10 @@ EOPHP;
|
|||||||
yield [0, 7, 'protected int $prot;'];
|
yield [0, 7, 'protected int $prot;'];
|
||||||
yield [0, 9, 'private string $priv;'];
|
yield [0, 9, 'private string $priv;'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
yield [1, 17, 'public function ccc($bar = 187) {}'];
|
||||||
|
yield [1, 17, 'public function ccc($bar = ANOTHER_ONE_THAT_WILL_NEVER_BE_DEFINED_CCCCCCCCC) {}'];
|
||||||
|
yield [1, 17, null, static function () { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEventSubscriber()
|
public function testEventSubscriber()
|
||||||
|
@ -226,7 +226,7 @@ class QuestionHelper extends Helper
|
|||||||
} elseif ("\177" === $c) { // Backspace Character
|
} elseif ("\177" === $c) { // Backspace Character
|
||||||
if (0 === $numMatches && 0 !== $i) {
|
if (0 === $numMatches && 0 !== $i) {
|
||||||
--$i;
|
--$i;
|
||||||
$fullChoice = substr($fullChoice, 0, -1);
|
$fullChoice = self::substr($fullChoice, 0, -1);
|
||||||
// Move cursor backwards
|
// Move cursor backwards
|
||||||
$output->write("\033[1D");
|
$output->write("\033[1D");
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ class QuestionHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pop the last character off the end of our string
|
// Pop the last character off the end of our string
|
||||||
$ret = substr($ret, 0, $i);
|
$ret = self::substr($ret, 0, $i);
|
||||||
} elseif ("\033" === $c) {
|
} elseif ("\033" === $c) {
|
||||||
// Did we read an escape sequence?
|
// Did we read an escape sequence?
|
||||||
$c .= fread($inputStream, 2);
|
$c .= fread($inputStream, 2);
|
||||||
@ -266,7 +266,7 @@ class QuestionHelper extends Helper
|
|||||||
$remainingCharacters = substr($ret, \strlen(trim($this->mostRecentlyEnteredValue($fullChoice))));
|
$remainingCharacters = substr($ret, \strlen(trim($this->mostRecentlyEnteredValue($fullChoice))));
|
||||||
$output->write($remainingCharacters);
|
$output->write($remainingCharacters);
|
||||||
$fullChoice .= $remainingCharacters;
|
$fullChoice .= $remainingCharacters;
|
||||||
$i = \strlen($fullChoice);
|
$i = self::strlen($fullChoice);
|
||||||
|
|
||||||
$matches = array_filter(
|
$matches = array_filter(
|
||||||
$autocomplete($ret),
|
$autocomplete($ret),
|
||||||
|
@ -175,19 +175,20 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
|||||||
// Acm<NEWLINE>
|
// Acm<NEWLINE>
|
||||||
// Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
|
// Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
|
||||||
// <NEWLINE>
|
// <NEWLINE>
|
||||||
// <UP ARROW><UP ARROW><NEWLINE>
|
// <UP ARROW><UP ARROW><UP ARROW><NEWLINE>
|
||||||
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
|
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
|
||||||
// <DOWN ARROW><NEWLINE>
|
// <DOWN ARROW><NEWLINE>
|
||||||
// S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
|
// S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
|
||||||
// F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
|
// F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
|
||||||
$inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
|
// F⭐<TAB><BACKSPACE><BACKSPACE>⭐<TAB><NEWLINE>
|
||||||
|
$inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\nF⭐\t\177\177⭐\t\n");
|
||||||
|
|
||||||
$dialog = new QuestionHelper();
|
$dialog = new QuestionHelper();
|
||||||
$helperSet = new HelperSet([new FormatterHelper()]);
|
$helperSet = new HelperSet([new FormatterHelper()]);
|
||||||
$dialog->setHelperSet($helperSet);
|
$dialog->setHelperSet($helperSet);
|
||||||
|
|
||||||
$question = new Question('Please select a bundle', 'FrameworkBundle');
|
$question = new Question('Please select a bundle', 'FrameworkBundle');
|
||||||
$question->setAutocompleterValues(['AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle']);
|
$question->setAutocompleterValues(['AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle', 'F⭐Y']);
|
||||||
|
|
||||||
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||||
$this->assertEquals('AsseticBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
$this->assertEquals('AsseticBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||||
@ -197,6 +198,7 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
|||||||
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||||
$this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
$this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||||
$this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
$this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||||
|
$this->assertEquals('F⭐Y', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAskWithAutocompleteCallback()
|
public function testAskWithAutocompleteCallback()
|
||||||
|
@ -324,6 +324,11 @@ class XmlDumper extends Dumper
|
|||||||
if (\in_array($value, ['null', 'true', 'false'], true)) {
|
if (\in_array($value, ['null', 'true', 'false'], true)) {
|
||||||
$element->setAttribute('type', 'string');
|
$element->setAttribute('type', 'string');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (\is_string($value) && (is_numeric($value) || preg_match('/^0b[01]*$/', $value) || preg_match('/^0x[0-9a-f]++$/i', $value))) {
|
||||||
|
$element->setAttribute('type', 'string');
|
||||||
|
}
|
||||||
|
|
||||||
$text = $this->document->createTextNode(self::phpToXml($value));
|
$text = $this->document->createTextNode(self::phpToXml($value));
|
||||||
$element->appendChild($text);
|
$element->appendChild($text);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,17 @@ $container = new ContainerBuilder(new ParameterBag([
|
|||||||
'values' => [true, false, null, 0, 1000.3, 'true', 'false', 'null'],
|
'values' => [true, false, null, 0, 1000.3, 'true', 'false', 'null'],
|
||||||
'binary' => "\xf0\xf0\xf0\xf0",
|
'binary' => "\xf0\xf0\xf0\xf0",
|
||||||
'binary-control-char' => "This is a Bell char \x07",
|
'binary-control-char' => "This is a Bell char \x07",
|
||||||
|
'null string' => 'null',
|
||||||
|
'string of digits' => '123',
|
||||||
|
'string of digits prefixed with minus character' => '-123',
|
||||||
|
'true string' => 'true',
|
||||||
|
'false string' => 'false',
|
||||||
|
'binary number string' => '0b0110',
|
||||||
|
'numeric string' => '-1.2E2',
|
||||||
|
'hexadecimal number string' => '0xFF',
|
||||||
|
'float string' => '10100.1',
|
||||||
|
'positive float string' => '+10100.1',
|
||||||
|
'negative float string' => '-10100.1',
|
||||||
]));
|
]));
|
||||||
|
|
||||||
return $container;
|
return $container;
|
||||||
|
@ -126,6 +126,17 @@ class ProjectServiceContainer extends Container
|
|||||||
],
|
],
|
||||||
'binary' => 'ðððð',
|
'binary' => 'ðððð',
|
||||||
'binary-control-char' => 'This is a Bell char ',
|
'binary-control-char' => 'This is a Bell char ',
|
||||||
|
'null string' => 'null',
|
||||||
|
'string of digits' => '123',
|
||||||
|
'string of digits prefixed with minus character' => '-123',
|
||||||
|
'true string' => 'true',
|
||||||
|
'false string' => 'false',
|
||||||
|
'binary number string' => '0b0110',
|
||||||
|
'numeric string' => '-1.2E2',
|
||||||
|
'hexadecimal number string' => '0xFF',
|
||||||
|
'float string' => '10100.1',
|
||||||
|
'positive float string' => '+10100.1',
|
||||||
|
'negative float string' => '-10100.1',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,17 @@
|
|||||||
</parameter>
|
</parameter>
|
||||||
<parameter key="binary" type="binary">8PDw8A==</parameter>
|
<parameter key="binary" type="binary">8PDw8A==</parameter>
|
||||||
<parameter key="binary-control-char" type="binary">VGhpcyBpcyBhIEJlbGwgY2hhciAH</parameter>
|
<parameter key="binary-control-char" type="binary">VGhpcyBpcyBhIEJlbGwgY2hhciAH</parameter>
|
||||||
|
<parameter key="null string" type="string">null</parameter>
|
||||||
|
<parameter key="string of digits" type="string">123</parameter>
|
||||||
|
<parameter key="string of digits prefixed with minus character" type="string">-123</parameter>
|
||||||
|
<parameter key="true string" type="string">true</parameter>
|
||||||
|
<parameter key="false string" type="string">false</parameter>
|
||||||
|
<parameter key="binary number string" type="string">0b0110</parameter>
|
||||||
|
<parameter key="numeric string" type="string">-1.2E2</parameter>
|
||||||
|
<parameter key="hexadecimal number string" type="string">0xFF</parameter>
|
||||||
|
<parameter key="float string" type="string">10100.1</parameter>
|
||||||
|
<parameter key="positive float string" type="string">+10100.1</parameter>
|
||||||
|
<parameter key="negative float string" type="string">-10100.1</parameter>
|
||||||
</parameters>
|
</parameters>
|
||||||
<services>
|
<services>
|
||||||
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true"/>
|
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true"/>
|
||||||
|
@ -6,6 +6,17 @@ parameters:
|
|||||||
values: [true, false, null, 0, 1000.3, 'true', 'false', 'null']
|
values: [true, false, null, 0, 1000.3, 'true', 'false', 'null']
|
||||||
binary: !!binary 8PDw8A==
|
binary: !!binary 8PDw8A==
|
||||||
binary-control-char: !!binary VGhpcyBpcyBhIEJlbGwgY2hhciAH
|
binary-control-char: !!binary VGhpcyBpcyBhIEJlbGwgY2hhciAH
|
||||||
|
null string: 'null'
|
||||||
|
string of digits: '123'
|
||||||
|
string of digits prefixed with minus character: '-123'
|
||||||
|
true string: 'true'
|
||||||
|
false string: 'false'
|
||||||
|
binary number string: '0b0110'
|
||||||
|
numeric string: '-1.2E2'
|
||||||
|
hexadecimal number string: '0xFF'
|
||||||
|
float string: '10100.1'
|
||||||
|
positive float string: '+10100.1'
|
||||||
|
negative float string: '-10100.1'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
service_container:
|
service_container:
|
||||||
|
Reference in New Issue
Block a user