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(); }