public function execute()
 {
     $ns = $this->extractNS($this->configuration['class']);
     $class = $this->extractLocal($this->configuration['class']);
     $doc = RootNode::create($ns);
     $ns = $doc->getNamespace($ns);
     Token::newline()->insertBefore($ns);
     Token::newline()->appendTo($ns);
     $class = ClassNode::create($class);
     if ($parent = $this->configuration['parent']) {
         Parser::parseSnippet('use ' . ltrim($parent, '\\') . ';')->appendTo($ns)->after(Token::newline());
         $class->setExtends($this->extractLocal($parent));
     }
     $interfaces = (array) $this->configuration['interfaces'];
     foreach ($interfaces as $interface) {
         Parser::parseSnippet('use ' . ltrim($interface, '\\') . ';')->appendTo($ns)->after(Token::newline());
     }
     $class->setImplements(array_map([$this, 'extractLocal'], $interfaces));
     if (isset($this->configuration['doc'])) {
         $class->setDocComment(DocCommentNode::create($this->configuration['doc']));
     }
     $class->appendTo($ns)->before(Token::newline());
     $destination = $this->getUnaliasedPath($this->configuration['destination']);
     $dir = subStr($destination, 0, strrPos($destination, '/'));
     $this->fs->mkdir($dir);
     file_put_contents($destination, $doc->getText());
     // Need to store the class' local name as its index identifier because
     // \Pharborist\Filter::isClass() doesn't support lookup by qualified path.
     $this->target->getIndexer('class')->addFile($destination);
 }
    public function testUseDeclarations()
    {
        $snippet = <<<'EOF'
namespace Test {
  use const Other\MY_CONST;
  use function Other\my_func;
  use Other\MyClass;
  use Other\OtherClass as Bind;
  class TestClass {}
}
EOF;
        /** @var NamespaceNode $namespace */
        $namespace = Parser::parseSnippet($snippet);
        $declarations = $namespace->getUseDeclarations();
        $this->assertCount(4, $declarations);
        $aliases = $namespace->getClassAliases();
        $this->assertCount(2, $aliases);
        $this->assertArrayHasKey('MyClass', $aliases);
        $this->assertEquals('\\Other\\MyClass', $aliases['MyClass']);
        $this->assertArrayHasKey('Bind', $aliases);
        $this->assertEquals('\\Other\\OtherClass', $aliases['Bind']);
        $class_node = $namespace->find(Filter::isClass('TestClass'))[0];
        $this->assertTrue($namespace->owns($class_node));
        $class_node = ClassNode::create('Dummy');
        $this->assertFalse($namespace->owns($class_node));
    }
 public function test()
 {
     $class = ClassNode::create('Foobaz');
     $indexer = $this->getMock('\\Drupal\\drupalmoduleupgrader\\IndexerInterface');
     $indexer->method('get')->with('Foobaz')->willReturn(new NodeCollection([$class]));
     $this->container->get('plugin.manager.drupalmoduleupgrader.indexer')->method('createInstance')->with('class')->willReturn($indexer);
     $config = ['definition' => '\\Drupal\\Core\\Block\\BlockPluginInterface::blockForm', 'target' => 'Foobaz'];
     $plugin = new Implement($config, uniqID(), []);
     $plugin->setTarget($this->target);
     try {
         // We expect a CodeManagerIOException because we're implementing the
         // method on a class that is not officially part of the target's code.
         // That's OK, though.
         $plugin->execute();
     } catch (IOException $e) {
     }
     $this->assertTrue($class->hasMethod('blockForm'));
     $method = $class->getMethod('blockForm');
     $this->assertInstanceOf('\\Pharborist\\Objects\\ClassMethodNode', $method);
     $parameters = $method->getParameters();
     $this->assertCount(2, $parameters);
     $this->assertEquals($parameters[0]->getName(), 'form');
     $this->assertNull($parameters[0]->getTypeHint());
     $this->assertEquals($parameters[1]->getName(), 'form_state');
     $type = $parameters[1]->getTypeHint();
     $this->assertInstanceOf('\\Pharborist\\Namespaces\\NameNode', $type);
     $this->assertEquals('Drupal\\Core\\Form\\FormStateInterface', $type->getText());
 }
    public function testBuildClass()
    {
        $classNode = ClassNode::create('MyClass');
        $this->assertEquals('class MyClass {}', $classNode->getText());
        $classNode->setFinal(TRUE);
        $this->assertEquals('final class MyClass {}', $classNode->getText());
        $classNode->setFinal(FALSE);
        $this->assertEquals('class MyClass {}', $classNode->getText());
        $classNode->setName('MyTest');
        $this->assertEquals('class MyTest {}', $classNode->getText());
        $classNode->setExtends('MyClass');
        $this->assertEquals('class MyTest extends MyClass {}', $classNode->getText());
        $classNode->setExtends('BaseClass');
        $this->assertEquals('class MyTest extends BaseClass {}', $classNode->getText());
        $classNode->setExtends(NULL);
        $this->assertNull($classNode->getExtends());
        $this->assertEquals('class MyTest {}', $classNode->getText());
        $classNode->setImplements('MyInterface');
        $this->assertEquals('class MyTest implements MyInterface {}', $classNode->getText());
        $classNode->setImplements('Yai');
        $this->assertEquals('class MyTest implements Yai {}', $classNode->getText());
        $classNode->setImplements(NULL);
        $this->assertNull($classNode->getImplementList());
        $this->assertEquals('class MyTest {}', $classNode->getText());
        $classNode->appendProperty('someProperty');
        $classNode->appendMethod('someMethod');
        $expected = <<<'EOF'
class MyTest {

  private $someProperty;

  public function someMethod() {
  }

}
EOF;
        $this->assertEquals($expected, $classNode->getText());
        $property = $classNode->getProperty('someProperty');
        $property->getClassMemberListNode()->setDocComment(DocCommentNode::create('Some property.'));
        $method = $classNode->getMethod('someMethod');
        $method->setDocComment(DocCommentNode::create('Some method.'));
        $expected = <<<'EOF'
class MyTest {

  /**
   * Some property.
   */
  private $someProperty;

  /**
   * Some method.
   */
  public function someMethod() {
  }

}
EOF;
        $this->assertEquals($expected, $classNode->getText());
    }
 public function testChangeDocComment()
 {
     $node = ClassNode::create('Foo');
     $node->setDocComment(DocCommentNode::create('Ni!'));
     $node->setDocComment(DocCommentNode::create('Noo!'));
     $comment = $node->getDocComment();
     $this->assertInstanceOf('\\Pharborist\\DocCommentNode', $comment);
     $this->assertEquals('Noo!', $comment->getCommentText());
 }
 public function test()
 {
     $class = ClassNode::create('Wambooli');
     $indexer = $this->getMock('\\Drupal\\drupalmoduleupgrader\\IndexerInterface');
     $indexer->method('get')->with('Wambooli')->willReturn(new NodeCollection([$class]));
     $this->container->get('plugin.manager.drupalmoduleupgrader.indexer')->method('createInstance')->with('class')->willReturn($indexer);
     $config = ['source' => 'Wambooli', 'destination' => 'Drupal\\foo\\Wambooli'];
     $plugin = new PSR4($config, uniqID(), []);
     $plugin->setTarget($this->target);
     $plugin->execute();
     $url = $this->target->getPath('src/Wambooli.php');
     $this->assertFileExists($url);
 }
    public function testDocComment()
    {
        $class = ClassNode::create('Wambooli');
        $class->setDocComment(DocCommentNode::create('Double wambooli!'));
        $this->assertInstanceOf('\\Pharborist\\DocCommentNode', $class->getDocComment());
        $indexer = $this->getMock('\\Drupal\\drupalmoduleupgrader\\IndexerInterface');
        $indexer->method('get')->with('Wambooli')->willReturn(new NodeCollection([$class]));
        $this->container->get('plugin.manager.drupalmoduleupgrader.indexer')->method('createInstance')->with('class')->willReturn($indexer);
        $config = ['type' => 'class', 'id' => 'Wambooli', 'note' => 'You need to rewrite this thing because I said so!'];
        $plugin = new Notify($config, uniqID(), []);
        $plugin->setTarget($this->target);
        $plugin->execute();
        $comment = $class->getDocComment();
        $this->assertInstanceOf('\\Pharborist\\DocCommentNode', $comment);
        $expected = <<<END
Double wambooli!

You need to rewrite this thing because I said so!
END;
        $this->assertEquals($expected, $comment->getCommentText());
    }
 public function test()
 {
     $callback = Parser::parseSnippet('function foo_submit(&$form, &$form_state) {}');
     $function_indexer = $this->getMock('\\Drupal\\drupalmoduleupgrader\\IndexerInterface');
     $function_indexer->method('get')->with('foo_submit')->willReturn(new NodeCollection([$callback]));
     $class = ClassNode::create('FooForm');
     $class_indexer = $this->getMock('\\Drupal\\drupalmoduleupgrader\\IndexerInterface');
     $class_indexer->method('get')->with('FooForm')->willReturn(new NodeCollection([$class]));
     $this->container->get('plugin.manager.drupalmoduleupgrader.indexer')->method('createInstance')->willReturnCallback(function ($which) use($class_indexer, $function_indexer) {
         switch ($which) {
             case 'class':
                 return $class_indexer;
             case 'function':
                 return $function_indexer;
             default:
                 break;
         }
     });
     $config = ['callback' => 'foo_submit', 'destination' => 'FooForm::submitForm'];
     $plugin = new FormCallbackToMethod($config, uniqID(), []);
     $plugin->setTarget($this->target);
     try {
         // We expect a CodeManagerIOException because we're implementing the
         // method on a class that is not officially part of the target's code.
         // That's OK, though.
         $plugin->execute();
     } catch (IOException $e) {
     }
     $this->assertTrue($class->hasMethod('submitForm'));
     $parameters = $class->getMethod('submitForm')->getParameters();
     $this->assertCount(2, $parameters);
     $this->assertEquals('form', $parameters[0]->getName());
     $this->assertInstanceOf('\\Pharborist\\TokenNode', $parameters[0]->getTypeHint());
     $this->assertSame(T_ARRAY, $parameters[0]->getTypeHint()->getType());
     $this->assertInstanceOf('\\Pharborist\\TokenNode', $parameters[0]->getReference());
     $this->assertEquals('form_state', $parameters[1]->getName());
     $this->assertInstanceOf('\\Pharborist\\Namespaces\\NameNode', $parameters[1]->getTypeHint());
     $this->assertEquals('Drupal\\Core\\Form\\FormStateInterface', $parameters[1]->getTypeHint()->getText());
     $this->assertNull($parameters[1]->getReference());
 }
 /**
  * A helper function to ease exception catching in the __toString() method.
  *
  * @return string
  */
 protected function toString()
 {
     $doc = RootNode::create($this->getNamespace());
     $class = ClassNode::create($this->getName());
     $constructor = ClassMethodNode::create('__construct');
     $class->appendMethod($constructor);
     $constructorDocString = '';
     foreach ($this->getProperties() as $name => $info) {
         $class->createProperty($name, isset($info['default']) ? $info['default'] : NULL, 'protected');
         if (isset($info['description'])) {
             $propertyDocString = "@var {$info['type']} {$name}\n  {$info['description']}";
             $constructorDocString .= "@param {$info['type']} {$name}\n  {$info['description']}\n\n";
         } else {
             $propertyDocString = "@var {$info['type']} {$name}";
             $constructorDocString .= "@param {$info['type']} {$name}\n\n";
         }
         $class->getProperty($name)->closest(Filter::isInstanceOf('\\Pharborist\\Objects\\ClassMemberListNode'))->setDocComment(DocCommentNode::create($propertyDocString));
         $constructor->appendParameter(ParameterNode::create($name));
         $expression = Parser::parseSnippet("\$this->{$name} = \${$name};");
         $constructor->getBody()->lastChild()->before($expression);
         $getter = ClassMethodNode::create('get' . ucfirst($name));
         $class->appendMethod($getter);
         $class->getMethod('get' . ucfirst($name))->setDocComment(DocCommentNode::create("Gets the {$name} value."));
         $getter_expression = Parser::parseSnippet("return \$this->{$name};");
         $getter->getBody()->lastChild()->before($getter_expression);
     }
     $class->getMethod('__construct')->setDocComment(DocCommentNode::create($constructorDocString));
     $doc->getNamespace($this->getNamespace())->getBody()->append($class);
     /* @todo dispatch an event to allow subscribers to alter $doc */
     $formatter = FormatterFactory::getPsr2Formatter();
     $formatter->format($doc->getNamespace($this->getNamespace()));
     return $doc->getText();
 }