1: <?php
2: namespace Pharborist\Namespaces;
3:
4: use Pharborist\ParentNode;
5: use Pharborist\TokenNode;
6: use Pharborist\Filter;
7: use Pharborist\WhitespaceNode;
8: use Pharborist\Token;
9: use Pharborist\Node;
10: use Pharborist\Parser;
11:
12: /**
13: * A use declaration importing a class, function, or constant into a namespace.
14: *
15: * Example:
16: * ```
17: * use Cleese;
18: * use Chapman as Palin;
19: * ```
20: */
21: class UseDeclarationNode extends ParentNode {
22: /**
23: * @var NameNode
24: */
25: protected $name;
26:
27: /**
28: * @var TokenNode
29: */
30: protected $alias;
31:
32: /**
33: * @param string $import
34: * Fully qualified class name; can also include optional alias.
35: *
36: * @return UseDeclarationNode
37: */
38: public static function create($import) {
39: /** @var UseDeclarationBlockNode $use_declaration_block_node */
40: $use_declaration_block_node = Parser::parseSnippet('use ' . $import . ';');
41: return $use_declaration_block_node->getDeclarationStatements()[0]->getDeclarations()[0];
42: }
43:
44: /**
45: * @return NameNode
46: */
47: public function getName() {
48: return $this->name;
49: }
50:
51: /**
52: * @return boolean
53: */
54: public function hasAlias() {
55: return isset($this->alias);
56: }
57:
58: /**
59: * @return Node
60: */
61: public function getAlias() {
62: return $this->alias;
63: }
64:
65: /**
66: * Sets the imported item's alias. If NULL is passed, the alias is removed.
67: *
68: * @param \Pharborist\TokenNode|string|NULL $alias
69: *
70: * @return $this
71: */
72: public function setAlias($alias) {
73: if (is_string($alias)) {
74: $alias = new TokenNode(T_STRING, $alias);
75: }
76:
77: if ($alias instanceof TokenNode) {
78: if ($this->hasAlias()) {
79: $this->alias->replaceWith($alias);
80: }
81: else {
82: $this->alias = $alias;
83: $this->addChild(WhitespaceNode::create(' '));
84: $this->addChild(Token::_as());
85: $this->addChild(WhitespaceNode::create(' '));
86: $this->addChild($alias, 'alias');
87: }
88: }
89: elseif ($alias === NULL && $this->hasAlias()) {
90: $this->alias->previousUntil(Filter::isInstanceOf('\Pharborist\Namespaces\NameNode'))->remove();
91: $this->alias->remove();
92: $this->alias = NULL;
93: }
94: else {
95: throw new \InvalidArgumentException();
96: }
97:
98: return $this;
99: }
100:
101: /**
102: * Test if use declaration is for class.
103: *
104: * @return bool
105: * TRUE if use declaration of class.
106: */
107: public function isClass() {
108: /** @var UseDeclarationStatementNode $parent */
109: $parent = $this->parent->parent;
110: return $parent->importsClass();
111: }
112:
113: /**
114: * Test if use declaration is for function.
115: *
116: * @return bool
117: * TRUE if use declaration of function.
118: */
119: public function isFunction() {
120: /** @var UseDeclarationStatementNode $parent */
121: $parent = $this->parent->parent;
122: return $parent->importsFunction();
123: }
124:
125: /**
126: * Test if use declaration is for const.
127: *
128: * @return bool
129: * TRUE if use declaration of const.
130: */
131: public function isConst() {
132: /** @var UseDeclarationStatementNode $parent */
133: $parent = $this->parent->parent;
134: return $parent->importsConst();
135: }
136:
137: /**
138: * Name bounded inside namespace.
139: *
140: * @return string
141: */
142: public function getBoundedName() {
143: if ($this->alias) {
144: return $this->alias->getText();
145: }
146: else {
147: return $this->name->lastChild()->getText();
148: }
149: }
150: }
151: