NameResolverTest.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. class PHPParser_Tests_NodeVisitor_NameResolverTest extends PHPUnit_Framework_TestCase
  3. {
  4. /**
  5. * @covers PHPParser_NodeVisitor_NameResolver
  6. */
  7. public function testResolveNames() {
  8. $code = <<<EOC
  9. <?php
  10. namespace Foo {
  11. use Hallo as Hi;
  12. new Bar();
  13. new Hi();
  14. new Hi\\Bar();
  15. new \\Bar();
  16. new namespace\\Bar();
  17. bar();
  18. hi();
  19. Hi\\bar();
  20. foo\\bar();
  21. \\bar();
  22. namespace\\bar();
  23. }
  24. namespace {
  25. use Hallo as Hi;
  26. new Bar();
  27. new Hi();
  28. new Hi\\Bar();
  29. new \\Bar();
  30. new namespace\\Bar();
  31. bar();
  32. hi();
  33. Hi\\bar();
  34. foo\\bar();
  35. \\bar();
  36. namespace\\bar();
  37. }
  38. EOC;
  39. $expectedCode = <<<EOC
  40. namespace Foo {
  41. use Hallo as Hi;
  42. new \\Foo\\Bar();
  43. new \\Hallo();
  44. new \\Hallo\\Bar();
  45. new \\Bar();
  46. new \\Foo\\Bar();
  47. bar();
  48. hi();
  49. \\Hallo\\bar();
  50. \\Foo\\foo\\bar();
  51. \\bar();
  52. \\Foo\\bar();
  53. }
  54. namespace {
  55. use Hallo as Hi;
  56. new \\Bar();
  57. new \\Hallo();
  58. new \\Hallo\\Bar();
  59. new \\Bar();
  60. new \\Bar();
  61. bar();
  62. hi();
  63. \\Hallo\\bar();
  64. \\foo\\bar();
  65. \\bar();
  66. \\bar();
  67. }
  68. EOC;
  69. $parser = new PHPParser_Parser(new PHPParser_Lexer_Emulative);
  70. $prettyPrinter = new PHPParser_PrettyPrinter_Default;
  71. $traverser = new PHPParser_NodeTraverser;
  72. $traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver);
  73. $stmts = $parser->parse($code);
  74. $stmts = $traverser->traverse($stmts);
  75. $this->assertEquals($expectedCode, $prettyPrinter->prettyPrint($stmts));
  76. }
  77. /**
  78. * @covers PHPParser_NodeVisitor_NameResolver
  79. */
  80. public function testResolveLocations() {
  81. $code = <<<EOC
  82. <?php
  83. namespace NS;
  84. class A extends B implements C {
  85. use A;
  86. }
  87. interface A extends C {
  88. public function a(A \$a);
  89. }
  90. A::b();
  91. A::\$b;
  92. A::B;
  93. new A;
  94. \$a instanceof A;
  95. namespace\a();
  96. namespace\A;
  97. try {
  98. \$someThing;
  99. } catch (A \$a) {
  100. \$someThingElse;
  101. }
  102. EOC;
  103. $expectedCode = <<<EOC
  104. namespace NS;
  105. class A extends \\NS\\B implements \\NS\\C
  106. {
  107. use \\NS\\A;
  108. }
  109. interface A extends \\NS\\C
  110. {
  111. public function a(\\NS\\A \$a);
  112. }
  113. \\NS\\A::b();
  114. \\NS\\A::\$b;
  115. \\NS\\A::B;
  116. new \\NS\\A();
  117. \$a instanceof \\NS\\A;
  118. \\NS\\a();
  119. \\NS\\A;
  120. try {
  121. \$someThing;
  122. } catch (\\NS\\A \$a) {
  123. \$someThingElse;
  124. }
  125. EOC;
  126. $parser = new PHPParser_Parser(new PHPParser_Lexer_Emulative);
  127. $prettyPrinter = new PHPParser_PrettyPrinter_Default;
  128. $traverser = new PHPParser_NodeTraverser;
  129. $traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver);
  130. $stmts = $parser->parse($code);
  131. $stmts = $traverser->traverse($stmts);
  132. $this->assertEquals($expectedCode, $prettyPrinter->prettyPrint($stmts));
  133. }
  134. public function testNoResolveSpecialName() {
  135. $stmts = array(new PHPParser_Node_Expr_New(new PHPParser_Node_Name('self')));
  136. $traverser = new PHPParser_NodeTraverser;
  137. $traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver);
  138. $this->assertEquals($stmts, $traverser->traverse($stmts));
  139. }
  140. protected function createNamespacedAndNonNamespaced(array $stmts) {
  141. return array(
  142. new PHPParser_Node_Stmt_Namespace(new PHPParser_Node_Name('NS'), $stmts),
  143. new PHPParser_Node_Stmt_Namespace(null, $stmts),
  144. );
  145. }
  146. public function testAddNamespacedName() {
  147. $stmts = $this->createNamespacedAndNonNamespaced(array(
  148. new PHPParser_Node_Stmt_Class('A'),
  149. new PHPParser_Node_Stmt_Interface('B'),
  150. new PHPParser_Node_Stmt_Function('C'),
  151. new PHPParser_Node_Stmt_Const(array(
  152. new PHPParser_Node_Const('D', new PHPParser_Node_Scalar_String('E'))
  153. )),
  154. ));
  155. $traverser = new PHPParser_NodeTraverser;
  156. $traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver);
  157. $stmts = $traverser->traverse($stmts);
  158. $this->assertEquals('NS\\A', (string) $stmts[0]->stmts[0]->namespacedName);
  159. $this->assertEquals('NS\\B', (string) $stmts[0]->stmts[1]->namespacedName);
  160. $this->assertEquals('NS\\C', (string) $stmts[0]->stmts[2]->namespacedName);
  161. $this->assertEquals('NS\\D', (string) $stmts[0]->stmts[3]->consts[0]->namespacedName);
  162. $this->assertEquals('A', (string) $stmts[1]->stmts[0]->namespacedName);
  163. $this->assertEquals('B', (string) $stmts[1]->stmts[1]->namespacedName);
  164. $this->assertEquals('C', (string) $stmts[1]->stmts[2]->namespacedName);
  165. $this->assertEquals('D', (string) $stmts[1]->stmts[3]->consts[0]->namespacedName);
  166. }
  167. public function testAddTraitNamespacedName() {
  168. $stmts = $this->createNamespacedAndNonNamespaced(array(
  169. new PHPParser_Node_Stmt_Trait('A')
  170. ));
  171. $traverser = new PHPParser_NodeTraverser;
  172. $traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver);
  173. $stmts = $traverser->traverse($stmts);
  174. $this->assertEquals('NS\\A', (string) $stmts[0]->stmts[0]->namespacedName);
  175. $this->assertEquals('A', (string) $stmts[1]->stmts[0]->namespacedName);
  176. }
  177. /**
  178. * @expectedException PHPParser_Error
  179. * @expectedExceptionMessage Cannot use "C" as "B" because the name is already in use on line 2
  180. */
  181. public function testAlreadyInUseError() {
  182. $stmts = array(
  183. new PHPParser_Node_Stmt_Use(array(
  184. new PHPParser_Node_Stmt_UseUse(new PHPParser_Node_Name('A\B'), 'B', array('startLine' => 1)),
  185. new PHPParser_Node_Stmt_UseUse(new PHPParser_Node_Name('C'), 'B', array('startLine' => 2)),
  186. ))
  187. );
  188. $traverser = new PHPParser_NodeTraverser;
  189. $traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver);
  190. $traverser->traverse($stmts);
  191. }
  192. }