Skip to content

Commit c021934

Browse files
Merge pull request #51 from matthiasnoback/issue_49
Fix reported issue
2 parents 163d732 + c080da7 commit c021934

File tree

8 files changed

+77
-23
lines changed

8 files changed

+77
-23
lines changed

ArgumentValidator.php

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,33 @@ public function __construct(
3030

3131
public function validate(\ReflectionParameter $parameter, $argument)
3232
{
33-
if ($parameter->isArray()) {
34-
if ($parameter->allowsNull() && is_null($argument)) {
35-
return;
36-
}
37-
$this->validateArrayArgument($argument);
38-
} elseif ($parameter->getClass()) {
39-
$this->validateObjectArgument($parameter->getClass()->getName(), $argument, $parameter->allowsNull());
33+
$parameterType = $parameter->getType();
34+
if ($parameterType === null) {
35+
return;
36+
}
37+
38+
if ($parameterType->getName() === 'array') {
39+
$this->validateArrayArgument($parameter, $argument);
40+
} elseif (class_exists($parameterType->getName())) {
41+
$this->validateObjectArgument($parameterType->getName(), $argument, $parameter->allowsNull());
4042
}
4143

4244
// other arguments don't need to be or can't be validated
4345
}
4446

45-
private function validateArrayArgument($argument)
47+
private function validateArrayArgument(\ReflectionParameter $parameter, $argument)
4648
{
47-
if (!is_array($argument)) {
49+
if ($parameter->allowsNull() && is_null($argument)) {
50+
return;
51+
}
52+
53+
if (class_exists('Symfony\Component\ExpressionLanguage\Expression') && $argument instanceof Expression) {
54+
$this->validateExpressionArgument('array', $argument, $parameter->allowsNull());
55+
} else {
56+
if (is_array($argument)) {
57+
return;
58+
}
59+
4860
throw new TypeHintMismatchException(sprintf(
4961
'Argument of type "%s" should have been an array',
5062
gettype($argument)
@@ -95,14 +107,14 @@ private function validateDefinitionArgument($className, Definition $definition)
95107
$this->validateClass($className, $resultingClass);
96108
}
97109

98-
private function validateExpressionArgument($className, Expression $expression, $allowsNull)
110+
private function validateExpressionArgument($type, Expression $expression, $allowsNull)
99111
{
100112
$expressionLanguage = new ExpressionLanguage();
101113

102114
$this->validateExpressionSyntax($expression, $expressionLanguage);
103115

104116
if ($this->evaluateExpressions) {
105-
$this->validateExpressionResult($className, $expression, $allowsNull, $expressionLanguage);
117+
$this->validateExpressionResult($type, $expression, $allowsNull, $expressionLanguage);
106118
}
107119
}
108120

@@ -115,7 +127,7 @@ private function validateExpressionSyntax(Expression $expression, ExpressionLang
115127
}
116128
}
117129

118-
private function validateExpressionResult($className, Expression $expression, $allowsNull, ExpressionLanguage $expressionLanguage)
130+
private function validateExpressionResult($expectedType, Expression $expression, $allowsNull, ExpressionLanguage $expressionLanguage)
119131
{
120132
try {
121133
$result = $expressionLanguage->evaluate($expression, array('container' => $this->containerBuilder));
@@ -130,20 +142,29 @@ private function validateExpressionResult($className, Expression $expression, $a
130142

131143
throw new TypeHintMismatchException(sprintf(
132144
'Argument for type-hint "%s" is an expression that evaluates to null, which is not allowed',
133-
$className
145+
$expectedType
134146
));
135147
}
136148

137-
if (!is_object($result)) {
149+
if ($expectedType === 'array' && !is_array($result)) {
138150
throw new TypeHintMismatchException(sprintf(
139-
'Argument for type-hint "%s" is an expression that evaluates to a non-object',
140-
$className
151+
'Argument for type-hint "%s" is an expression that evaluates to a non-array',
152+
$expectedType
141153
));
142154
}
143155

144-
$resultingClass = get_class($result);
156+
if (class_exists($expectedType)) {
157+
if (!is_object($result)) {
158+
throw new TypeHintMismatchException(sprintf(
159+
'Argument for type-hint "%s" is an expression that evaluates to a non-object',
160+
$expectedType
161+
));
162+
}
145163

146-
$this->validateClass($className, $resultingClass);
164+
$resultingClass = get_class($result);
165+
166+
$this->validateClass($expectedType, $resultingClass);
167+
}
147168
}
148169

149170
private function validateClass($expectedClassName, $actualClassName)

ArgumentsValidator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private function shouldParameterHaveAnArgument(\ReflectionParameter $parameter)
4141
return false;
4242
}
4343

44-
if ($parameter->getClass() && $parameter->allowsNull()) {
44+
if ($parameter->getType() instanceof \ReflectionType && $parameter->getType()->allowsNull()) {
4545
// e.g. LoggerInterface $logger = null
4646
return false;
4747
}

Error/ValidationErrorList.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ public function add(ValidationErrorInterface $error)
1111
$this->errors[] = $error;
1212
}
1313

14-
public function count()
14+
public function count(): int
1515
{
1616
return count($this->errors);
1717
}
1818

19-
public function getIterator()
19+
public function getIterator(): \ArrayIterator
2020
{
2121
return new \ArrayIterator($this->errors);
2222
}

Exception/InvalidExpressionException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function __construct($expression, \Exception $exception)
1212
$expression,
1313
$exception->getMessage()
1414
),
15-
null,
15+
0,
1616
$exception
1717
);
1818
}

Exception/InvalidExpressionSyntaxException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public function __construct($expression, SyntaxError $exception)
1414
$expression,
1515
$exception->getMessage()
1616
),
17-
null,
17+
0,
1818
$exception
1919
);
2020
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Matthias\SymfonyServiceDefinitionValidator\Tests\Functional\Fixtures;
5+
6+
final class Issue49
7+
{
8+
public function __construct(array $values)
9+
{
10+
}
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
parameters:
2+
app_config:
3+
abc:
4+
- a
5+
- b
6+
- c
7+
8+
services:
9+
app.services.service_id:
10+
class: Matthias\SymfonyServiceDefinitionValidator\Tests\Functional\Fixtures\Issue49
11+
arguments:
12+
- "@=parameter('app_config')['abc']"

Tests/Functional/FunctionalTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ public function testIfTheServiceDefinitionsAreCorrectTheContainerWillBeCompiled(
5252
$this->addToAssertionCount(1);
5353
}
5454

55+
public function testIssue49(): void
56+
{
57+
$loader = new YamlFileLoader($this->container, new FileLocator(__DIR__ . '/Fixtures'));
58+
$loader->load('issue_49.yml');
59+
60+
$this->container->compile();
61+
62+
$this->addToAssertionCount(1);
63+
}
64+
5565
public function testIfAServiceDefinitionWithAnExpressionArgumentIsCorrectTheContainerWillBeCompiled()
5666
{
5767
if (!class_exists('Symfony\Component\DependencyInjection\ExpressionLanguage')) {

0 commit comments

Comments
 (0)