/**
  * Rewrites an assignment expression as a property setter. Returns NULL if
  * the expression cannot be rewritten.
  *
  * @param \Pharborist\ExpressionNode $expr
  *  The expression to rewrite.
  * @param string $property
  *  The property being used in the expression.
  * @param \Pharborist\Operators\AssignNode $assignment
  *  The entire assignment expression being rewritten.
  *
  * @return \Pharborist\ExpressionNode|NULL
  */
 public function rewriteAsSetter(ExpressionNode $expr, $property, AssignNode $assignment)
 {
     if ($expr instanceof ObjectPropertyNode) {
         // Should be getRootObject() or getLookupRoot().
         // @see Pharborist issue #191
         $object = clone $expr->getObject();
     } elseif ($expr instanceof ArrayLookupNode) {
         $object = clone $expr->getRootArray();
     }
     if (isset($object) && isset($this->pluginDefinition['properties'][$property]['set'])) {
         return ObjectMethodCallNode::create($object, $this->pluginDefinition['properties'][$property]['set'])->appendArgument(clone $assignment->getRightOperand());
     }
 }
 /**
  * {@inheritdoc}
  */
 public function rewriteAsSetter(ExpressionNode $expr, $property, AssignNode $assignment)
 {
     /** @var \Pharborist\ArrayLookupNode $expr */
     $object = clone $expr->getRootArray();
     $keys = $expr->getKeys();
     $value = clone $assignment->getRightOperand();
     // $form_state['values']['baz'] = 'foo' --> $form_state->setValue(['baz'], 'foo')
     if ($property == 'values') {
         array_shift($keys);
         return ObjectMethodCallNode::create($object, 'setValue')->appendArgument(ArrayNode::create($keys))->appendArgument($value);
     } elseif (isset($this->pluginDefinition['properties'][$property]['set'])) {
         return parent::rewriteAsSetter($expr, $property, $assignment);
     } else {
         return ObjectMethodCallNode::create($object, 'set')->appendArgument(ArrayNode::create($keys))->appendArgument($value);
     }
 }