Skip to content

Commit 94583a9

Browse files
committed
[Validator] Changed NodeTraverser to traverse nodes iteratively, not recursively
In this way, the deep method call chains are avoided. Also, it is possible to avoid the many calls to leaveNode(), which are currently not really needed.
1 parent cf1281f commit 94583a9

File tree

13 files changed

+107
-202
lines changed

13 files changed

+107
-202
lines changed

src/Symfony/Component/Validator/Context/ExecutionContext.php

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
use Symfony\Component\Validator\Group\GroupManagerInterface;
2121
use Symfony\Component\Validator\Mapping\PropertyMetadataInterface;
2222
use Symfony\Component\Validator\Node\Node;
23-
use Symfony\Component\Validator\Util\NodeStackInterface;
23+
use Symfony\Component\Validator\NodeVisitor\NodeObserverInterface;
2424
use Symfony\Component\Validator\Util\PropertyPath;
2525
use Symfony\Component\Validator\Validator\ValidatorInterface;
2626
use Symfony\Component\Validator\Violation\ConstraintViolationBuilder;
@@ -33,7 +33,7 @@
3333
*
3434
* @see ExecutionContextInterface
3535
*/
36-
class ExecutionContext implements ExecutionContextInterface, LegacyExecutionContextInterface, NodeStackInterface
36+
class ExecutionContext implements ExecutionContextInterface, LegacyExecutionContextInterface, NodeObserverInterface
3737
{
3838
/**
3939
* @var ValidatorInterface
@@ -76,13 +76,6 @@ class ExecutionContext implements ExecutionContextInterface, LegacyExecutionCont
7676
*/
7777
private $node;
7878

79-
/**
80-
* The trace of nodes from the root node to the current node.
81-
*
82-
* @var \SplStack
83-
*/
84-
private $nodeStack;
85-
8679
/**
8780
* Creates a new execution context.
8881
*
@@ -108,49 +101,18 @@ public function __construct(ValidatorInterface $validator, $root, GroupManagerIn
108101
$this->translator = $translator;
109102
$this->translationDomain = $translationDomain;
110103
$this->violations = new ConstraintViolationList();
111-
$this->nodeStack = new \SplStack();
112104
}
113105

114106
/**
115107
* Sets the values of the context to match the given node.
116108
*
117-
* Internally, all nodes are stored on a stack and can be removed from that
118-
* stack using {@link popNode()}.
119-
*
120109
* @param Node $node The currently validated node
121110
*/
122-
public function pushNode(Node $node)
111+
public function setCurrentNode(Node $node)
123112
{
124-
$this->nodeStack->push($node);
125113
$this->node = $node;
126114
}
127115

128-
/**
129-
* Sets the values of the context to match the previous node.
130-
*
131-
* The current node is removed from the internal stack and returned.
132-
*
133-
* @return Node|null The currently validated node or null, if no node was
134-
* on the stack
135-
*/
136-
public function popNode()
137-
{
138-
// Nothing to do if the stack is empty
139-
if (0 === count($this->nodeStack)) {
140-
return null;
141-
}
142-
143-
// Remove the current node from the stack
144-
$poppedNode = $this->nodeStack->pop();
145-
146-
// Adjust the current node to the previous node
147-
$this->node = count($this->nodeStack) > 0
148-
? $this->nodeStack->top()
149-
: null;
150-
151-
return $poppedNode;
152-
}
153-
154116
/**
155117
* {@inheritdoc}
156118
*/

src/Symfony/Component/Validator/Node/PropertyNode.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Validator\Node;
1313

14+
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
1415
use Symfony\Component\Validator\Mapping\PropertyMetadataInterface;
1516

1617
/**
@@ -32,6 +33,11 @@
3233
*/
3334
class PropertyNode extends Node
3435
{
36+
/**
37+
* @var object
38+
*/
39+
public $object;
40+
3541
/**
3642
* @var PropertyMetadataInterface
3743
*/
@@ -40,6 +46,8 @@ class PropertyNode extends Node
4046
/**
4147
* Creates a new property node.
4248
*
49+
* @param object $object The object the property
50+
* belongs to
4351
* @param mixed $value The property value
4452
* @param PropertyMetadataInterface $metadata The property's metadata
4553
* @param string $propertyPath The property path leading
@@ -49,16 +57,24 @@ class PropertyNode extends Node
4957
* @param string[]|null $cascadedGroups The groups in which
5058
* cascaded objects should
5159
* be validated
60+
*
61+
* @throws UnexpectedTypeException If $object is not an object
5262
*/
53-
public function __construct($value, PropertyMetadataInterface $metadata, $propertyPath, array $groups, $cascadedGroups = null)
63+
public function __construct($object, $value, PropertyMetadataInterface $metadata, $propertyPath, array $groups, $cascadedGroups = null)
5464
{
65+
if (!is_object($object)) {
66+
throw new UnexpectedTypeException($object, 'object');
67+
}
68+
5569
parent::__construct(
5670
$value,
5771
$metadata,
5872
$propertyPath,
5973
$groups,
6074
$cascadedGroups
6175
);
76+
77+
$this->object = $object;
6278
}
6379

6480
}

0 commit comments

Comments
 (0)