예제 #1
0
 /**
  * {@inheritdoc}
  */
 public function convert(TargetInterface $target)
 {
     // If the hook implementation contains logic, we cannot convert it and
     // that's that. So we'll leave a FIXME and bail out.
     /** @var \Pharborist\Functions\FunctionDeclarationNode $hook */
     $hook = $target->getIndexer('function')->get('hook_menu');
     if ($hook->is(new ContainsLogicFilter())) {
         $hook->setDocComment(DocCommentNode::create($this->pluginDefinition['fixme']));
         $target->save($hook);
         return;
     }
     $hook_menu = new HookMenu($target, $this->routeConverters);
     foreach ($hook_menu->getSourceRoutes() as $path => $route) {
         /** @var \Drupal\drupalmoduleupgrader\Routing\Drupal7\RouteWrapper $route */
         if ($route->containsKey('page callback')) {
             $plugin_id = $this->routeConverters->hasDefinition($route['page callback']) ? $route['page callback'] : 'default';
             /** @var \Drupal\drupalmoduleupgrader\Routing\RouteConverterInterface $converter */
             $this->routeConverters->createInstance($plugin_id)->buildRoute($target, $route);
         }
     }
     $routing = [];
     foreach ($hook_menu->getDestinationRoutes() as $name => $route) {
         $routing[$name] = ['path' => $route->getPath()->__toString(), 'defaults' => $route->getDefaults(), 'requirements' => $route->getRequirements()];
     }
     $this->writeInfo($target, 'routing', $routing);
 }
 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);
 }
예제 #3
0
    /**
     * {@inheritdoc}
     */
    public function convert(TargetInterface $target)
    {
        $indexer = $target->getIndexer('function');
        $hooks = array_filter($this->pluginDefinition['hook'], [$indexer, 'has']);
        foreach ($hooks as $hook) {
            /** @var \Pharborist\Functions\FunctionDeclarationNode $function */
            $function = $indexer->get($hook);
            // The $edit parameter is defunct in Drupal 8, but we'll leave it in
            // there as an empty array to prevent errors, and move it to the back
            // of the line.
            /** @var \Pharborist\Functions\ParameterNode $edit */
            $edit = $function->getParameterList()->shift()->setReference(FALSE)->setValue(NullNode::create());
            $function->appendParameter($edit);
            // Slap a FIXME on the hook implementation, informing the developer that
            // $edit and $category are dead.
            $comment = $function->getDocComment();
            $comment_text = $comment ? $comment->getCommentText() : '';
            if ($comment_text) {
                $comment_text .= "\n\n";
            }
            $comment_text .= <<<'END'
@FIXME
The $edit and $category parameters are gone in Drupal 8. They have been left
here in order to prevent 'undefined variable' errors, but they will never
actually be passed to this hook. You'll need to modify this function and
remove every reference to them.
END;
            $function->setDocComment(DocCommentNode::create($comment_text));
            $this->rewriteFunction($this->rewriter, $function->getParameterAtIndex(0), $target);
            $target->save($function);
        }
    }
    /**
     * {@inheritdoc}
     */
    public function convert(TargetInterface $target)
    {
        /** @var \Pharborist\Functions\FunctionDeclarationNode $function */
        $function = $target->getIndexer('function')->get('hook_user_login');
        // The $edit parameter is defunct in Drupal 8, but we'll leave it in
        // there as an empty array to prevent errors, and move it to the back
        // of the line.
        /** @var \Pharborist\Functions\ParameterNode $edit */
        $edit = $function->getParameterList()->shift()->setReference(FALSE)->setValue(ArrayNode::create([]));
        $function->appendParameter($edit);
        // Slap a FIXME on the hook implementation, informing the developer that
        // $edit and $category are dead.
        $comment = $function->getDocComment();
        $comment_text = $comment ? $comment->getCommentText() : '';
        if ($comment_text) {
            $comment_text .= "\n\n";
        }
        $comment_text .= <<<'END'
@FIXME
The $edit parameter is gone in Drupal 8. It has been left here in order to
prevent 'undefined variable' errors, but it will never actually be passed to
this hook. You'll need to modify this function and remove every reference to it.
END;
        $function->setDocComment(DocCommentNode::create($comment_text));
        $rewriter = $this->rewriters->createInstance('_rewriter:user');
        $this->rewriteFunction($rewriter, $function->getParameterAtIndex(0), $target);
        $target->save($function);
    }
예제 #5
0
    /**
     * {@inheritdoc}
     */
    public function convert(TargetInterface $target)
    {
        $unit_tests = [];
        $test_files = $target->getIndexer('class')->getQuery(['file'])->condition('parent', 'DrupalUnitTestCase')->execute()->fetchCol();
        foreach ($test_files as $test_file) {
            /** @var \Pharborist\Objects\Classnode[] $tests */
            $tests = $target->open($test_file)->find(Filter::isInstanceOf('\\Pharborist\\Objects\\SingleInheritanceNode'))->toArray();
            foreach ($tests as $test) {
                if ((string) $test->getExtends() === 'DrupalUnitTestCase') {
                    $unit_tests[] = $test;
                }
            }
        }
        /** @var \Pharborist\Objects\ClassNode $unit_test */
        foreach ($unit_tests as $unit_test) {
            $unit_test->setExtends('\\Drupal\\Tests\\UnitTestCase');
            $comment_text = <<<END
@FIXME
Unit tests are now written for the PHPUnit framework. You will need to refactor
this test in order for it to work properly.
END;
            $comment = DocCommentNode::create($comment_text);
            $unit_test->setDocComment($comment);
            $ns = 'Drupal\\Tests\\' . $target->id() . '\\Unit';
            $doc = RootNode::create($ns)->getNamespace($ns)->append($unit_test->remove());
            WhitespaceNode::create("\n\n")->insertBefore($unit_test);
            $this->write($target, 'tests/src/Unit/' . $unit_test->getName() . '.php', "<?php\n\n{$doc}");
        }
    }
예제 #6
0
 protected function setComment(NodeInterface $node, $comment_text)
 {
     if ($this->supportsDocComments($node)) {
         /** @var \Pharborist\DocCommentTrait $node */
         $node->setDocComment(DocCommentNode::create($comment_text));
     } else {
         LineCommentBlockNode::create($comment_text)->insertBefore($node->getStatement());
     }
 }
 /**
  * {@inheritdoc}
  */
 public function execute()
 {
     $this->moduleHandler->loadInclude($this->configuration['module'], 'php', 'api');
     $hook = $this->configuration['hook'];
     $function = FunctionDeclarationNode::create($this->target->id() . '_' . $hook);
     $function->setDocComment(DocCommentNode::create('Implements hook_' . $hook));
     $reflector = new \ReflectionFunction('hook_' . $hook);
     $function->matchReflector($reflector);
     $module = $this->target->getPath('.module');
     $doc = $this->target->open($module)->append($function);
     $this->target->save($doc);
 }
예제 #8
0
 public function execute()
 {
     /** @var \Pharborist\Objects\ClassNode $class */
     $class = $this->target->getIndexer('class')->get($this->configuration['target']);
     // Use reflection to get the method definition.
     list($interface, $method) = explode('::', $this->configuration['definition']);
     $interface = new \ReflectionClass($interface);
     $method = $interface->getMethod($method);
     $node = ClassMethodNode::create($method->getName());
     $node->setDocComment(DocCommentNode::create('@inheritdoc'));
     $class->appendMethod($node);
     $node->matchReflector($method);
     // @TODO There needs to be a way to implement the method body!
     $this->target->save($class);
 }
예제 #9
0
 /**
  * {@inheritdoc}
  */
 public function convert(TargetInterface $target)
 {
     // If the hook implementation contains logic, we cannot convert it and
     // that's that. So we'll leave a FIXME and bail out.
     /** @var \Pharborist\Functions\FunctionDeclarationNode $hook */
     $hook = $target->getIndexer('function')->get('hook_menu');
     if ($hook->is(new ContainsLogicFilter())) {
         $hook->setDocComment(DocCommentNode::create($this->pluginDefinition['fixme']));
         $target->save($hook);
         return;
     }
     // Links are split out by group because there are separate config files
     // for each link type.
     $links = ['menu' => new LinkIndex(), 'task' => new LinkIndex(), 'action' => new LinkIndex(), 'contextual' => new LinkIndex()];
     $hook_menu = new HookMenu($target, $this->routeConverters);
     foreach ($hook_menu->getSourceRoutes()->getAllLinks() as $path => $source) {
         /** @var LinkBinding $binding */
         $binding = $this->linkBinding->create($source, $hook_menu->getDestinationRoute($path));
         // Skip if the converter wasn't able to find a destination.
         $destination = $binding->getDestination();
         if (empty($destination)) {
             continue;
         }
         if ($binding instanceof MenuLinkBinding) {
             $links['menu']->addBinding($binding);
         } elseif ($binding instanceof LocalTaskLinkBinding) {
             $links['task']->addBinding($binding);
         } elseif ($binding instanceof LocalActionLinkBinding) {
             $links['action']->addBinding($binding);
         } elseif ($source->isContextualLink()) {
             $links['contextual']->addBinding($binding);
         }
     }
     $links = array_map(function (LinkIndex $index) {
         return $index->build();
     }, $links);
     foreach ($links['contextual'] as $link) {
         $link['group'] = $target->id();
     }
     foreach ($links as $group => $data) {
         if ($data) {
             $this->writeInfo($target, 'links.' . $group, $data);
         }
     }
 }
예제 #10
0
    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());
    }
 /**
  * {@inheritdoc}
  */
 public function convert(TargetInterface $target)
 {
     $hook = $target->getIndexer('function')->get($this->pluginDefinition['hook'])->before(DocCommentNode::create($this->pluginDefinition['fixme']));
     $target->save($hook);
 }
예제 #12
0
 /**
  * Converts the test's getInfo() method to an annotation.
  *
  * @param \Pharborist\Objects\ClassNode $test
  */
 private function convertInfo(ClassNode $test)
 {
     $info = $this->extractInfo($test);
     if ($info) {
         $comment = '';
         $comment .= $info['description'] . "\n\n";
         $comment .= '@group ' . $this->target->id();
         if (isset($info['dependencies'])) {
             $comment .= "\n";
             foreach ($info['dependencies'] as $module) {
                 $comment .= '@requires module . ' . $module . "\n";
             }
         }
         $test->setDocComment(DocCommentNode::create($comment));
     } else {
         $this->log->error('Could not get info for test {class}.', ['class' => $test->getName()]);
     }
 }
예제 #13
0
 /**
  * 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();
 }
 /**
  * Builds a FIXME notice using either the text in the plugin definition,
  * or passed-in text.
  *
  * @param string|NULL $text
  *  The FIXME notice's text, with variable placeholders and no translation.
  * @param array $variables
  *  Optional variables to use in translation. If empty, the FIXME will not
  *  be translated.
  * @param string|NULL $style
  *  The comment style. Returns a LineCommentBlockNode if this is set to
  *  self::LINE_COMMENT, a DocCommentNode if self::DOC_COMMENT, or the FIXME
  *  as a string if set to anything else.
  *
  * @return mixed
  */
 protected function buildFixMe($text = NULL, array $variables = [], $style = self::LINE_COMMENT)
 {
     $fixMe = "@FIXME\n" . ($text ?: $this->pluginDefinition['fixme']);
     if (isset($this->pluginDefinition['documentation'])) {
         $fixMe .= "\n";
         foreach ($this->pluginDefinition['documentation'] as $doc) {
             $fixMe .= "\n@see ";
             $fixMe .= isset($doc['url']) ? $doc['url'] : (string) $doc;
         }
     }
     if ($variables) {
         $fixMe = $this->t($fixMe, $variables);
     }
     switch ($style) {
         case self::LINE_COMMENT:
             return LineCommentBlockNode::create($fixMe);
         case self::DOC_COMMENT:
             return DocCommentNode::create($fixMe);
         default:
             return $fixMe;
     }
 }