public function testMerge() { $left = new TextNode('foo', new Context('bar')); $right = new TextNode('baz', new Context('qux')); $merged = TextNode::merge($left, $right); $this->assertEquals(new TextNode('foobaz'), $merged); }
private function visitText(Element $element) { $nodes = array(); // Walk childs and merge adjacent text nodes if needed $last = null; $last_index = -1; foreach ($element->getChildren() as $child) { $node = $child->accept($this); // Merge text nodes together if ($last instanceof AST\TextNode && $node instanceof AST\TextNode) { // Prevent merge once a context is set if ($last->hasContext()) { throw new Exception('Unexpected text node after context'); } $nodes[$last_index] = $last = AST\TextNode::merge($last, $node); } else { $nodes[] = $node; $last = $node; $last_index++; } } // Once nodes are merged, we just "AND" them all together. $root = null; foreach ($nodes as $index => $node) { if (!$root) { $root = $node; continue; } if ($node instanceof AST\Context) { if ($root instanceof AST\ContextAbleInterface) { $root = $root->withContext($node); } else { throw new Exception('Unexpected context after non-contextualizable node'); } } elseif ($node instanceof AST\Node) { $root = new AST\Boolean\AndExpression($root, $node); } else { throw new Exception('Unexpected node type inside text node.'); } } return $root; }