/**
  * {@inheritdoc}
  */
 public function get($id)
 {
     $all = new NodeCollection([]);
     $files = $this->getQuery(['file'])->distinct(TRUE)->condition('id', $id)->execute()->fetchCol();
     array_walk($files, function ($file) use($all, $id) {
         $all->add($this->target->open($file)->find(Filter::isFunctionCall($id)));
     });
     return $all;
 }
 /**
  * {@inheritdoc}
  */
 public function rewrite(ParameterNode $parameter)
 {
     // Don't even try to rewrite the function if the parameter is reassigned.
     if ($this->isReassigned($parameter)) {
         $error = $this->t('@function() cannot be parametrically rewritten because @parameter is reassigned.', ['@parameter' => $parameter->getName(), '@function' => $parameter->getFunction()->getName()->getText()]);
         throw new \LogicException($error);
     }
     foreach ($this->getExpressions($parameter)->not($this->isAssigned) as $expr) {
         $property = $this->getProperty($expr);
         if (empty($property)) {
             continue;
         }
         $getter = $this->rewriteAsGetter($expr, $property);
         if ($getter) {
             $empty = $expr->closest(Filter::isFunctionCall('empty', 'isset'));
             // If the original expression was wrapped by a call to isset() or
             // empty(), we need to replace it entirely.
             if ($getter instanceof CallNode && $empty instanceof CallNode) {
                 // If the isset() or empty() call was negated, reverse that logic.
                 $parent = $empty->parent();
                 if ($parent instanceof BooleanNotNode) {
                     $parent->replaceWith($getter);
                 } else {
                     $empty->replaceWith(BooleanNotNode::fromExpression($getter));
                 }
             } else {
                 $expr->replaceWith($getter);
             }
         }
     }
     foreach ($this->getExpressions($parameter)->filter($this->isAssigned) as $expr) {
         // If the property cannot be determined, don't even try to rewrite the
         // expression.
         $property = $this->getProperty($expr);
         if (empty($property)) {
             continue;
         }
         $assignment = $expr->closest(Filter::isInstanceOf('\\Pharborist\\Operators\\AssignNode'));
         $setter = $this->rewriteAsSetter($expr, $property, $assignment);
         if ($setter) {
             $assignment->replaceWith($setter);
         }
     }
     // Set the type hint, if one is defined.
     if (isset($this->pluginDefinition['type_hint'])) {
         $parameter->setTypeHint($this->pluginDefinition['type_hint']);
         // If the type hint extends FieldableEntityInterface, rewrite any field
         // lookups (e.g. $node->body[LANGUAGE_NONE][0]['value']).
         if (in_array('Drupal\\Core\\Entity\\FieldableEntityInterface', class_implements($this->pluginDefinition['type_hint']))) {
             $filter = new FieldValueFilter($parameter->getName());
             foreach ($parameter->getFunction()->find($filter) as $lookup) {
                 $lookup->replaceWith(self::rewriteFieldLookup($lookup));
             }
         }
     }
 }
    public function testRewriteWithCacheReset()
    {
        $original = <<<'END'
user_load(30, TRUE);
END;
        $expected = <<<'END'
// @FIXME
// To reset the user cache, use EntityStorageInterface::resetCache().
\Drupal::entityManager()->getStorage('user')->load(30);
END;
        $snippet = Parser::parseSnippet($original);
        $function_call = $snippet->children(Filter::isFunctionCall('user_load'))->get(0);
        $rewritten = $this->plugin->rewrite($function_call, $this->target);
        $function_call->replaceWith($rewritten);
        $this->assertEquals($expected, $snippet->getText());
    }
 /**
  * {@inheritdoc}
  */
 public function analyze(TargetInterface $target)
 {
     $indexer = $target->getIndexer('function');
     $issues = [];
     if ($indexer->has('hook_uninstall')) {
         /** @var \Pharborist\NodeCollection $variable_del */
         $variable_del = $indexer->get('hook_uninstall')->find(Filter::isFunctionCall('variable_del'));
         if (sizeof($variable_del) > 0) {
             $issue = $this->buildIssue($target);
             $variable_del->each(function (FunctionCallNode $function_call) use($issue) {
                 $issue->addViolation($function_call, $this);
             });
             $issues[] = $issue;
         }
     }
     return $issues;
 }
    public function testForeignStringKey()
    {
        $original = <<<'END'
<?php
variable_set('bar_wambooli', TRUE);
END;
        $expected = <<<'END'
<?php
// @FIXME
// This looks like another module's variable. You'll need to rewrite this call
// to ensure that it uses the correct configuration object.
variable_set('bar_wambooli', TRUE);
END;
        $snippet = Parser::parseSource($original);
        $function_call = $snippet->find(Filter::isFunctionCall('variable_set'))->get(0);
        $rewritten = $this->plugin->rewrite($function_call, $this->target);
        $this->assertNull($rewritten);
        $this->assertSame($expected, $snippet->getText());
    }
    public function testStringKeyAndUnextractableDefaultValue()
    {
        $original = <<<'END'
<?php
variable_get('foo_wambooli', array());
END;
        $expected = <<<'END'
<?php
// @FIXME
// Could not extract the default value because it is either indeterminate, or
// not scalar. You'll need to provide a default value in
// config/install/@module.settings.yml and config/schema/@module.schema.yml.
variable_get('foo_wambooli', array());
END;
        $snippet = Parser::parseSource($original);
        $function_call = $snippet->find(Filter::isFunctionCall('variable_get'))->get(0);
        $rewritten = $this->plugin->rewrite($function_call, $this->target);
        $this->assertInstanceOf('\\Pharborist\\Objects\\ObjectMethodCallNode', $rewritten);
        $this->assertEquals('\\Drupal::config(\'foo.settings\')->get(\'foo_wambooli\')', $rewritten->getText());
        $this->assertSame($expected, $snippet->getText());
    }
    /**
     * This test is failing at the moment because for whatever reason,
     * $snippet->children() is only fetching the first call to node_load().
     */
    public function _testRewriteWithCacheReset()
    {
        $original = <<<'END'
node_load(30);
node_load(30, TRUE);
node_load(30, 32);
node_load(30, 32, TRUE);
END;
        $expected = <<<'END'
\Drupal::entityManager()->getStorage('user')->load(30);
// FIXME: To reset the node cache, use EntityStorageInterface::resetCache().
\Drupal::entityManager()->getStorage('user')->load(30);
\Drupal::entityManager()->getStorage('user')->loadRevision(32);
// FIXME: To reset the node cache, use EntityStorageInterface::resetCache().
\Drupal::entityManager()->getStorage('user')->loadRevision(32);
END;
        $snippet = Parser::parseSnippet($original);
        $function_calls = $snippet->children(Filter::isFunctionCall('node_load'));
        foreach ($function_calls as $function_call) {
            $rewritten = $this->plugin->rewrite($function_call, $this->target);
            $function_call->replaceWith($rewritten);
        }
        $this->assertEquals($expected, $snippet->getText());
    }
 /**
  * {@inheritdoc}
  */
 public function rewrite(ParameterNode $parameter)
 {
     parent::rewrite($parameter);
     $function = $parameter->getFunction();
     $form_state = Token::variable('$' . $parameter->getName());
     $set_errors = $function->find(Filter::isFunctionCall('form_set_error', 'form_error'));
     /** @var \Pharborist\Functions\FunctionCallNode $set_error */
     foreach ($set_errors as $set_error) {
         $arguments = $set_error->getArguments();
         $method = $set_error->getName()->getText() == 'form_set_error' ? 'setErrorByName' : 'setError';
         $rewrite = ObjectMethodCallNode::create(clone $form_state, $method)->appendArgument(clone $arguments[0])->appendArgument(clone $arguments[1]);
         $set_error->replaceWith($rewrite);
     }
     // form_clear_error() --> $form_state->clearErrors().
     $clear_errors = $function->find(Filter::isFunctionCall('form_clear_error'));
     foreach ($clear_errors as $clear_error) {
         $clear_error->replaceWith(ObjectMethodCallNode::create(clone $form_state, 'clearErrors'));
     }
     // form_get_errors() --> $form_state->getErrors()
     $get_errors = $function->find(Filter::isFunctionCall('form_get_errors'));
     foreach ($get_errors as $get_error) {
         $get_error->replaceWith(ObjectMethodCallNode::create(clone $form_state, 'getErrors'));
     }
     // form_get_error() --> $form_state->getError()
     $get_errors = $function->find(Filter::isFunctionCall('form_get_error'));
     /** @var \Pharborist\Functions\FunctionCallNode $get_error */
     foreach ($get_errors as $get_error) {
         $rewrite = ObjectMethodCallNode::create(clone $form_state, 'getError')->appendArgument($get_error->getArguments()->get(0));
         $get_error->replaceWith($rewrite);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function getUsages($identifier)
 {
     $function = $this->prepareID($identifier);
     $files = $this->getQuery(['file'])->distinct()->condition('id', $function)->condition('type', 'Pharborist\\Functions\\FunctionCallNode')->execute()->fetchCol();
     $usages = new NodeCollection();
     foreach ($files as $file) {
         $this->target->open($file)->find(Filter::isFunctionCall($function))->addTo($usages);
     }
     return $usages;
 }
 /**
  * @return \Pharborist\Objects\ClassNode
  */
 public function build()
 {
     $controller = $this->render();
     $builder = $this->addMethod($this->builder, $controller, 'buildForm');
     if ($this->isConfig) {
         $builder->find(Filter::isFunctionCall('system_settings_form'))->each(function (FunctionCallNode $call) {
             $call->setName('parent::buildForm')->appendArgument(Token::variable('$form_state'));
         });
     }
     if ($this->validator) {
         $this->addMethod($this->validator, $controller, 'validateForm')->getParameterAtIndex(0)->setReference(TRUE)->setTypeHint('array');
     }
     if ($this->submitHandler) {
         $this->addMethod($this->submitHandler, $controller, $this->isConfig ? '_submitForm' : 'submitForm')->getParameterAtIndex(0)->setReference(TRUE)->setTypeHint('array');
     }
     return $controller;
 }
    public function testGetStatement()
    {
        $function = <<<END
function foobaz() {
  return foo();
}
END;
        $function = Parser::parseSnippet($function);
        $foo = $function->find(Filter::isFunctionCall('foo'))->get(0)->getStatement();
        $this->assertInstanceOf('\\Pharborist\\StatementNode', $foo);
        $this->assertEquals('return foo();', $foo->getText());
        $this->assertSame($function, $function->getStatement());
    }