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 = [
|
||||
'file' => $trace[$i]['file'],
|
||||
'line' => $trace[$i]['line'],
|
||||
'file' => isset($trace[$i]['file']) ? $trace[$i]['file'] : null,
|
||||
'line' => isset($trace[$i]['line']) ? $trace[$i]['line'] : null,
|
||||
'trace' => \array_slice($trace, 1 + $i),
|
||||
];
|
||||
|
||||
foreach ($props as $p => $v) {
|
||||
$r = new \ReflectionProperty('Exception', $p);
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($e, $v);
|
||||
if (null !== $v) {
|
||||
$r = new \ReflectionProperty('Exception', $p);
|
||||
$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) {
|
||||
yield preg_replace('/^ @@.*/m', '', $m);
|
||||
|
||||
$defaults = [];
|
||||
$parametersWithUndefinedConstants = [];
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,12 @@ class ReflectionClassResourceTest extends TestCase
|
||||
/**
|
||||
* @dataProvider provideHashedSignature
|
||||
*/
|
||||
public function testHashedSignature($changeExpected, $changedLine, $changedCode)
|
||||
public function testHashedSignature($changeExpected, $changedLine, $changedCode, $setContext = null)
|
||||
{
|
||||
if ($setContext) {
|
||||
$setContext();
|
||||
}
|
||||
|
||||
$code = <<<'EOPHP'
|
||||
/* 0*/
|
||||
/* 1*/ class %s extends ErrorException
|
||||
@ -83,7 +87,9 @@ class ReflectionClassResourceTest extends TestCase
|
||||
/*13*/ protected function prot($a = []) {}
|
||||
/*14*/
|
||||
/*15*/ private function priv() {}
|
||||
/*16*/ }
|
||||
/*16*/
|
||||
/*17*/ public function ccc($bar = A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC) {}
|
||||
/*18*/ }
|
||||
EOPHP;
|
||||
|
||||
static $expectedSignature, $generateSignature;
|
||||
@ -98,7 +104,9 @@ EOPHP;
|
||||
}
|
||||
|
||||
$code = explode("\n", $code);
|
||||
$code[$changedLine] = $changedCode;
|
||||
if (null !== $changedCode) {
|
||||
$code[$changedLine] = $changedCode;
|
||||
}
|
||||
eval(sprintf(implode("\n", $code), $class = 'Foo'.str_replace('.', '_', uniqid('', true))));
|
||||
$signature = implode("\n", iterator_to_array($generateSignature(new \ReflectionClass($class))));
|
||||
|
||||
@ -142,6 +150,10 @@ EOPHP;
|
||||
yield [0, 7, 'protected int $prot;'];
|
||||
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()
|
||||
|
@ -226,7 +226,7 @@ class QuestionHelper extends Helper
|
||||
} elseif ("\177" === $c) { // Backspace Character
|
||||
if (0 === $numMatches && 0 !== $i) {
|
||||
--$i;
|
||||
$fullChoice = substr($fullChoice, 0, -1);
|
||||
$fullChoice = self::substr($fullChoice, 0, -1);
|
||||
// Move cursor backwards
|
||||
$output->write("\033[1D");
|
||||
}
|
||||
@ -240,7 +240,7 @@ class QuestionHelper extends Helper
|
||||
}
|
||||
|
||||
// Pop the last character off the end of our string
|
||||
$ret = substr($ret, 0, $i);
|
||||
$ret = self::substr($ret, 0, $i);
|
||||
} elseif ("\033" === $c) {
|
||||
// Did we read an escape sequence?
|
||||
$c .= fread($inputStream, 2);
|
||||
@ -266,7 +266,7 @@ class QuestionHelper extends Helper
|
||||
$remainingCharacters = substr($ret, \strlen(trim($this->mostRecentlyEnteredValue($fullChoice))));
|
||||
$output->write($remainingCharacters);
|
||||
$fullChoice .= $remainingCharacters;
|
||||
$i = \strlen($fullChoice);
|
||||
$i = self::strlen($fullChoice);
|
||||
|
||||
$matches = array_filter(
|
||||
$autocomplete($ret),
|
||||
|
@ -175,19 +175,20 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
||||
// Acm<NEWLINE>
|
||||
// Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
|
||||
// <NEWLINE>
|
||||
// <UP ARROW><UP ARROW><NEWLINE>
|
||||
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
|
||||
// <UP ARROW><UP ARROW><UP ARROW><NEWLINE>
|
||||
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
|
||||
// <DOWN ARROW><NEWLINE>
|
||||
// S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><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();
|
||||
$helperSet = new HelperSet([new FormatterHelper()]);
|
||||
$dialog->setHelperSet($helperSet);
|
||||
|
||||
$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('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('AsseticBundle', $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()
|
||||
|
@ -324,6 +324,11 @@ class XmlDumper extends Dumper
|
||||
if (\in_array($value, ['null', 'true', 'false'], true)) {
|
||||
$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));
|
||||
$element->appendChild($text);
|
||||
}
|
||||
|
@ -11,6 +11,17 @@ $container = new ContainerBuilder(new ParameterBag([
|
||||
'values' => [true, false, null, 0, 1000.3, 'true', 'false', 'null'],
|
||||
'binary' => "\xf0\xf0\xf0\xf0",
|
||||
'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;
|
||||
|
@ -126,6 +126,17 @@ class ProjectServiceContainer extends Container
|
||||
],
|
||||
'binary' => 'ðððð',
|
||||
'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 key="binary" type="binary">8PDw8A==</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>
|
||||
<services>
|
||||
<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']
|
||||
binary: !!binary 8PDw8A==
|
||||
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:
|
||||
service_container:
|
||||
|
Reference in New Issue
Block a user