public function testSetVisibilityTokenText() { /** @var ClassNode $class_node */ $class_node = Parser::parseSnippet('class Foo { public function wrassle() {} }'); /** @var ClassMethodNode $method */ $method = $class_node->getStatements()[0]; $method->setVisibility('private'); $this->assertSame('private', $method->getVisibility()->getText()); $method->setVisibility('protected'); $this->assertSame('protected', $method->getVisibility()->getText()); $method->setVisibility('public'); $this->assertSame('public', $method->getVisibility()->getText()); $method->setVisibility(T_PRIVATE); $this->assertSame('private', $method->getVisibility()->getText()); $method->setVisibility(T_PROTECTED); $this->assertSame('protected', $method->getVisibility()->getText()); $method->setVisibility(T_PUBLIC); $this->assertSame('public', $method->getVisibility()->getText()); $method->setVisibility(Token::_private()); $this->assertSame('private', $method->getVisibility()->getText()); $method->setVisibility(Token::_protected()); $this->assertSame('protected', $method->getVisibility()->getText()); $method->setVisibility(Token::_public()); $this->assertSame('public', $method->getVisibility()->getText()); }
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); }
/** * Creates a negated version of any expression. For instance, passing a * VariableNode will result in !$var. * * @param \Pharborist\ExpressionNode $expr * The expression to negate. * * @return static */ public static function fromExpression(ExpressionNode $expr) { $not = new static(); $not->addChild(Token::not(), 'operator'); /** @var \Pharborist\Node $expr */ $not->addChild($expr->remove(), 'operand'); return $not; }
/** * Creates a new, blank PHP source file. * * @param string|NULL $ns * If provided, the new document will have this namespace added to it. * * @return static */ public static function create($ns = NULL) { $node = new RootNode(); $node->addChild(Token::openTag()); if (is_string($ns) && $ns) { NamespaceNode::create($ns)->appendTo($node)->after(Token::newline()); } return $node; }
/** * @param Node $key * Array element's key. * @param Node $value * Array element's value. * * @return ArrayPairNode */ public static function create($key, $value) { $node = new ArrayPairNode(); $node->addChild($key, 'key'); $node->addChild(Token::space()); $node->addChild(Token::doubleArrow()); $node->addChild(Token::space()); $node->addChild($value, 'value'); return $node; }
/** * Creates a new array lookup. * * @param \Pharborist\ExpressionNode $array * The expression representing the array (usually a VariableNode). * @param \Pharborist\ExpressionNode $key * The expression representing the key (usually a string). * * @return static */ public static function create(ExpressionNode $array, ExpressionNode $key) { $node = new static(); /** @var Node $array */ $node->addChild($array, 'array'); $node->addChild(Token::openBracket()); /** @var Node $key */ $node->addChild($key, 'key'); $node->addChild(Token::closeBracket()); return $node; }
/** * Creates a method call on an object with an empty argument list. * * @param Node $object * The expression that is an object. * @param string $method_name * The name of the called method. * * @return static */ public static function create(Node $object, $method_name) { /** @var ObjectMethodCallNode $node */ $node = new static(); $node->addChild($object, 'object'); $node->addChild(Token::objectOperator(), 'operator'); $node->addChild(Token::identifier($method_name), 'methodName'); $node->addChild(Token::openParen(), 'openParen'); $node->addChild(new CommaListNode(), 'arguments'); $node->addChild(Token::closeParen(), 'closeParen'); return $node; }
/** * Creates a method call on a class with an empty argument list. * * @param Node|string $class_name * The class node which is typically NameNode of class. * @param string $method_name * The name of the called method. * * @return static */ public static function create($class_name, $method_name) { if (is_string($class_name)) { $class_name = NameNode::create($class_name); } /** @var ClassMethodCallNode $node */ $node = new static(); $node->addChild($class_name, 'className'); $node->addChild(Token::doubleColon()); $node->addChild(Token::identifier($method_name), 'methodName'); $node->addChild(Token::openParen(), 'openParen'); $node->addChild(new CommaListNode(), 'arguments'); $node->addChild(Token::closeParen(), 'closeParen'); return $node; }
/** * @param boolean $is_reference * @return $this */ public function setReference($is_reference) { if ($is_reference) { if (!isset($this->reference)) { /** @var \Pharborist\Functions\FunctionDeclarationNode|\Pharborist\Objects\ClassMethodNode|\Pharborist\Objects\InterfaceMethodNode $this */ $this->reference = Token::reference(); $this->name->before($this->reference); } } else { if (isset($this->reference)) { $this->reference->remove(); } } return $this; }
/** * Create namespace path. * * @param string $name * @return NameNode */ public static function create($name) { $parts = explode('\\', $name); $name_node = new NameNode(); foreach ($parts as $i => $part) { $part = trim($part); if ($i > 0) { $name_node->append(Token::namespaceSeparator()); } if ($part !== '') { $name_node->append(Token::identifier($part)); } } return $name_node; }
/** * @param boolean $is_static * * @return $this */ public function setStatic($is_static) { if ($is_static) { if (!isset($this->static)) { $this->static = Token::_static(); $this->visibility->after([Token::space(), $this->static]); } } else { if (isset($this->static)) { // Remove whitespace after static keyword. $this->static->next()->remove(); // Remove static keyword. $this->static->remove(); } } return $this; }
/** * @param boolean $is_static * @return $this */ public function setStatic($is_static) { if ($is_static) { if (!isset($this->static)) { // Insert before T_FUNCTION. $function_token = $this->name->previous()->previous(); $this->static = Token::_static(); $function_token->before([$this->static, Token::space()]); } } else { if (isset($this->static)) { // Remove whitespace after static keyword. $this->static->next()->remove(); // Remove static keyword. $this->static->remove(); } } return $this; }
public function testSetAlias() { /** @var \Pharborist\Namespaces\UseDeclarationBlockNode $declaration_block */ $declaration_block = Parser::parseSnippet('use Foobar;'); $declaration = $declaration_block->getDeclarationStatements()[0]->getDeclarations()[0]; $this->assertFalse($declaration->hasAlias()); $alias = Token::identifier('TestAlias'); $declaration->setAlias($alias); $this->assertTrue($declaration->hasAlias()); $this->assertEquals('TestAlias', $declaration->getAlias()->getText()); $this->assertEquals('Foobar as TestAlias', $declaration->getText()); $declaration->setAlias('Overridden'); $this->assertTrue($declaration->hasAlias()); $this->assertEquals('Overridden', $declaration->getAlias()->getText()); $this->assertEquals('Foobar as Overridden', $declaration->getText()); $declaration->setAlias(NULL); $this->assertFalse($declaration->hasAlias()); $this->assertEquals('Foobar', $declaration->getText()); }
public function testHasKey() { /** @var ArrayNode $array */ $array = Parser::parseExpression('array("a", "b", "c")'); $this->assertTrue($array->hasKey(0)); $array = Parser::parseExpression('array("a" => "apple", "b" => "bear", "c" => "cauldron")'); $this->assertTrue($array->hasKey('a')); $this->assertFalse($array->hasKey('d')); $array = Parser::parseExpression('array(0 => "foo", 1 => "baz", 2 => array(0 => "a", 1 => "b", 2 => "c"))'); $this->assertTrue($array->hasKey(1)); $this->assertFalse($array->hasKey('2')); $array = Parser::parseExpression('array(0 => "foo", 1 => array(0 => "a", 1 => "b", 2 => "c"))'); $this->assertTrue($array->hasKey(1)); $this->assertTrue($array->hasKey(2)); $this->assertFalse($array->hasKey(2, FALSE)); $array = Parser::parseExpression('array($key => "hurrr")'); $this->assertFalse($array->hasKey('$key')); $var = Token::variable('$key'); $this->assertTrue($array->hasKey($var)); }
/** * @param string|integer|TokenNode|NULL $visibility * @return $this */ public function setVisibility($visibility) { if ($visibility === NULL) { $this->removeVisibility(); } else { if ($visibility === 'private' || $visibility === T_PRIVATE) { $visibility = Token::_private(); } elseif ($visibility === 'protected' || $visibility === T_PROTECTED) { $visibility = Token::_protected(); } elseif ($visibility === 'public' || $visibility === T_PUBLIC) { $visibility = Token::_public(); } if (isset($this->visibility)) { $this->visibility->replaceWith($visibility); } else { /** @var \Pharborist\ParentNode $this */ $this->prepend([$visibility, Token::space()]); $this->visibility = $visibility; } } return $this; }
/** * 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; }
/** * @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 static function space() { return Token::whitespace(' '); }
public function visitNamespaceNode(NamespaceNode $node) { $first = $node->getBody()->firstToken(); $has_braces = $first->getType() === '{'; $this->indentLevel = $has_braces ? 1 : 0; if (!$has_braces) { foreach ($node->children(Filter::isTokenType(';')) as $semicolon) { $next = $semicolon->next(); $newlines = str_repeat($this->config['nl'], 2); if ($next instanceof WhitespaceNode) { $next->setText($newlines); } else { $semicolon->after(Token::whitespace($newlines)); } } } }
public function testChainMethodCall() { $object = Token::variable('$object'); $method_call = ObjectMethodCallNode::create($object, 'someMethod'); $chained_call = $method_call->appendMethodCall('chained'); $this->assertEquals('$object->someMethod()', $chained_call->getObject()->getText()); $this->assertEquals('chained', $chained_call->getMethodName()->getText()); $source = <<<'EOF' <?php $object->someMethod(); EOF; $tree = Parser::parseSource($source); /** @var ExpressionStatementNode $expr_statement */ $expr_statement = $tree->firstChild()->next(); /** @var ObjectMethodCallNode $method_call */ $method_call = $expr_statement->getExpression(); $method_call->appendMethodCall('chained'); $expected = <<<'EOF' <?php $object->someMethod()->chained(); EOF; $this->assertEquals($expected, $tree->getText()); }
/** * @param string|NameNode|CommaListNode|array|NULL $implements * @throws \InvalidArgumentException * @return $this */ public function setImplements($implements) { if ($implements === NULL) { if (isset($this->implements)) { // Remove whitespace after implements keyword. $this->implements->previous()->remove(); // Remove implements keyword $this->implements->previous()->remove(); // Remove whitespace before implements keyword. $this->implements->previous()->remove(); // Remove implements list. $this->implements->remove(); $this->implements = NULL; } } else { // Type conversions. if (is_string($implements)) { $implements = NameNode::create($implements); } if ($implements instanceof NameNode) { $implementList = new CommaListNode(); $implementList->append($implements); $implements = $implementList; } if (is_array($implements)) { $implementList = new CommaListNode(); foreach ($implements as $implement) { if (is_string($implement)) { $implementList->appendItem(NameNode::create($implement)); } elseif ($implement instanceof NameNode) { $implementList->appendItem($implement); } else { throw new \InvalidArgumentException('Invalid $implements argument'); } } $implements = $implementList; } // Set implements. if (isset($this->implements)) { $this->implements->replaceWith($implements); } else { $after = isset($this->extends) ? $this->extends : $this->name; $after->after([Token::space(), Token::_implements(), Token::space(), $implements]); } $this->implements = $implements; } return $this; }
/** * Get the keys of the array. * * @param boolean $recursive * (optional) TRUE to get keys of array elements that are also arrays. * * @return NodeCollection */ public function getKeys($recursive = TRUE) { $keys = new NodeCollection(); $index = 0; foreach ($this->elements->getItems() as $element) { if ($element instanceof ArrayPairNode) { $keys->add($element->getKey()); $value = $element->getValue(); } else { $keys->add(Token::integer($index++)); $value = $element; } if ($recursive && $value instanceof ArrayNode) { $keys->add($value->getKeys($recursive)); } } return $keys; }
/** * Creates an empty lexical variables list if it does not already exist. */ protected function createLexicalVariables() { if (!$this->hasLexicalVariables()) { $this->lexicalUse = Token::_use(); $this->lexicalOpenParen = Token::openParen(); $this->lexicalVariables = new CommaListNode(); $this->lexicalCloseParen = Token::closeParen(); $this->closeParen->after([Token::space(), $this->lexicalUse, Token::space(), $this->lexicalOpenParen, $this->lexicalVariables, $this->lexicalCloseParen]); } }
/** * Insert item before index. * * @param Node $item * @param int $index * @throws \OutOfBoundsException * Index out of bounds. * @return $this */ public function insertItem(Node $item, $index) { $items = $this->getItems(); if ($items->isEmpty()) { if ($index !== 0) { throw new \OutOfBoundsException('index out of bounds'); } $this->append($item); } else { $max_index = count($items) - 1; if ($index < 0 || $index > $max_index) { throw new \OutOfBoundsException('index out of bounds'); } $items[$index]->before([$item, Token::comma(), Token::space()]); } return $this; }
public function testIndex() { $first = Token::identifier('hello'); $second = Token::identifier('world'); $not_found = Token::identifier('notfound'); $collection = new NodeCollection([$first, $second], FALSE); $this->assertEquals(0, $collection->indexOf(Filter::is($first))); $this->assertEquals(1, $collection->indexOf(Filter::is($second))); $this->assertEquals(-1, $collection->indexOf(Filter::is($not_found))); }
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); } }
/** * @param ExpressionNode|NULL $node * @return $this */ public function setValue($node) { if ($node === NULL) { if (isset($this->value)) { $this->value->previousUntil(Filter::isInstanceOf('\\Pharborist\\Variables\\VariableNode'))->remove(); $this->value->remove(); } } else { if (isset($this->value)) { /** @var Node $node */ $this->value->replaceWith($node); } else { $this->append([Token::space(), Token::assign(), Token::space(), $node]); } } return $this; }
/** * {@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); } }
public function testCreate() { $lookup = ArrayLookupNode::create(Token::variable('$form_state'), new StringNode(T_CONSTANT_ENCAPSED_STRING, "'storage'")); $this->assertEquals('$form_state[\'storage\']', $lookup->getText()); }
/** * @param boolean $is_final * @return $this */ public function setFinal($is_final) { if ($is_final) { if (!isset($this->final)) { $this->final = Token::_final(); $this->prepend([$this->final, Token::space()]); $this->setAbstract(FALSE); } } else { if (isset($this->final)) { // Remove whitespace. $this->final->next()->remove(); // Remove final. $this->final->remove(); } } return $this; }