/** * Utility method to PSR4-ify a class. It'll move the class into its own file * in the given module's namespace. The class is modified in-place, so you * should clone it before calling this function if you want to make a PSR-4 * *copy* of it. * * @param \Drupal\drupalmoduleupgrader\TargetInterface $target * The module which will own the class. * @param \Pharborist\ClassNode $class * The class to modify. * * @return \Pharborist\ClassNode * The modified class, returned for convenience. */ public static function toPSR4(TargetInterface $target, ClassNode $class) { $ns = 'Drupal\\' . $target->id(); RootNode::create($ns)->getNamespace($ns)->append($class->remove()); WhitespaceNode::create("\n\n")->insertBefore($class); return $class; }
/** * {@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}"); } }
/** * {@inheritdoc} */ public function execute() { /** @var \Pharborist\Objects\ClassNode $class */ $class = $this->target->getIndexer('class')->get($this->configuration['source']); $ns = substr($this->configuration['destination'], 0, strrpos($this->configuration['destination'], '\\')); $doc = RootNode::create($ns); $ns = $doc->getNamespace($ns); WhitespaceNode::create("\n")->appendTo($ns); $import = []; if ($parent = $class->getExtends()) { $import[] = $parent->getAbsolutePath(); } $interfaces = $class->getImplementList(); if ($interfaces) { foreach ($interfaces->getItems() as $interface) { $import[] = $interface->getAbsolutePath(); } } foreach ($class->getMethods() as $method) { foreach ($method->getParameters() as $parameter) { $type_hint = $parameter->getTypeHint(); if ($type_hint instanceof NameNode) { $import[] = $type_hint->getAbsolutePath(); } } } foreach (array_unique($import) as $i) { Parser::parseSnippet('use ' . ltrim($i, '\\') . ';')->appendTo($ns); WhitespaceNode::create("\n")->appendTo($ns); } WhitespaceNode::create("\n")->appendTo($ns); $class->remove()->appendTo($ns); $search_for = ['Drupal\\' . $this->target->id(), '\\']; $replace_with = ['src', '/']; $path = str_replace($search_for, $replace_with, $this->configuration['destination']) . '.php'; file_put_contents($this->target->getPath($path), $doc->getText()); }
/** * Sets the imported item's alias. If NULL is passed, the alias is removed. * * @param \Pharborist\TokenNode|string|NULL $alias * * @return $this */ public function setAlias($alias) { if (is_string($alias)) { $alias = new TokenNode(T_STRING, $alias); } if ($alias instanceof TokenNode) { if ($this->hasAlias()) { $this->alias->replaceWith($alias); } else { $this->alias = $alias; $this->addChild(WhitespaceNode::create(' ')); $this->addChild(Token::_as()); $this->addChild(WhitespaceNode::create(' ')); $this->addChild($alias, 'alias'); } } elseif ($alias === NULL && $this->hasAlias()) { $this->alias->previousUntil(Filter::isInstanceOf('\\Pharborist\\Namespaces\\NameNode'))->remove(); $this->alias->remove(); $this->alias = NULL; } else { throw new \InvalidArgumentException(); } return $this; }
private function updateArray(ArrayNode $node, $data) { $i = 0; foreach ($node->getElements() as $el) { if ($el instanceof ArrayPairNode) { $k = (string) $el->getKey(); $k = trim($k, '"\''); $v = $el->getValue(); if (!isset($data[$k])) { $this->cleanAround($el); } else { if ($v instanceof ArrayNode && is_array($data[$k])) { $v = $this->updateArray($v, $data[$k]); unset($data[$k]); } else { $v->replaceWith(Parser::parseExpression($data[$k])); unset($data[$k]); } } } elseif ($el instanceof ArrayNode && (!isset($data[$i]) || is_array($data[$i]))) { if (!isset($data[$i])) { $this->cleanAround($el); } else { $this->updateArray($el, $data[$i]); unset($data[$i]); $i++; } } else { if (!isset($data[$i])) { $this->cleanAround($el); } else { $el->replaceWith(Parser::parseExpression($data[$i])); unset($data[$i]); $i++; } } } foreach ($data as $key => $val) { $v = Parser::parseExpression(self::var_codify($val)); if (!is_integer($key)) { $v = ArrayPairNode::create(Node::fromValue($key), $v); } $comma = false; $list = $node->getElementList(); $children = []; foreach ($list->children() as $child) { $children[] = $child; } $prev = end($children); if ($prev) { do { if ((string) $prev === ',') { $comma = true; break; } } while (is_object($prev) && ($prev = $prev->previous()) instanceof WhitespaceNode); } else { $comma = true; } $indent = 0; $prev = end($children); while ($prev && strpos($prev, "\n") === false) { $prev = $prev->previous(); } $indent = ''; if ($prev) { $prev = explode("\n", (string) $prev); $prev = array_pop($prev); for ($i = 0; $i < strlen($prev); $i++) { if (in_array($prev[$i], ["\t", ' '])) { $indent .= $prev[$i]; } else { break; } } } if (!$comma) { $list->append(Token::comma()); } $list->append(Token::newline()); if ($indent) { $list->append(WhitespaceNode::create($indent)); } $list->append($v); } }
public function visitWhitespaceNode(WhitespaceNode $node) { if ($node->previousToken()->getType() === T_DOC_COMMENT) { return; } // Normalise whitespace. $nl_count = $node->getNewlineCount(); if ($nl_count > 0) { $node->setText($this->getNewlineIndent($node)); } else { $prev = $node->previousToken(); if ($prev instanceof CommentNode && $prev->isLineComment()) { // Whitespace has already been processed. } else { $node->setText(' '); } } }
public function move(ClassNode $test) { $ns = 'Drupal\\' . $this->target->id() . '\\Tests'; RootNode::create($ns)->getNamespace($ns)->append($test->remove()); WhitespaceNode::create("\n\n")->insertBefore($test); $this->writeClass($this->target, $test); }
public static function whitespace($ws) { return WhitespaceNode::create($ws); }
/** * Creates an empty implementation of a hook. * * @param TargetInterface $target * The target module. * @param string $hook * The hook to implement, without the hook_ prefix. * * @return \Pharborist\Functions\FunctionDeclarationNode * The hook implementation, appended to the main module file. */ protected function implement(TargetInterface $target, $hook) { $function = FunctionDeclarationNode::create($target->id() . '_' . $hook); $function->setDocComment(DocCommentNode::create('Implements hook_' . $hook . '().')); $module_file = $target->getPath('.module'); $target->open($module_file)->append($function); WhitespaceNode::create("\n")->insertBefore($function); WhitespaceNode::create("\n")->insertAfter($function); return $function; }