NoUnusedImportsFixerTest.php 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * This file is part of PHP CS Fixer.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  8. *
  9. * This source file is subject to the MIT license that is bundled
  10. * with this source code in the file LICENSE.
  11. */
  12. namespace PhpCsFixer\Tests\Fixer\Import;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @internal
  16. *
  17. * @covers \PhpCsFixer\Fixer\Import\NoUnusedImportsFixer
  18. */
  19. final class NoUnusedImportsFixerTest extends AbstractFixerTestCase
  20. {
  21. /**
  22. * @dataProvider provideFixCases
  23. */
  24. public function testFix(string $expected, ?string $input = null): void
  25. {
  26. $this->doTest($expected, $input);
  27. }
  28. public static function provideFixCases(): array
  29. {
  30. return [
  31. 'simple' => [
  32. <<<'EOF'
  33. <?php
  34. use Foo\Bar;
  35. use Foo\Bar\FooBar as FooBaz;
  36. use SomeClass;
  37. $a = new Bar();
  38. $a = new FooBaz();
  39. $a = new SomeClass();
  40. use Symfony\Annotation\Template;
  41. use Symfony\Doctrine\Entities\Entity;
  42. use Symfony\Array123\ArrayInterface;
  43. class AnnotatedClass
  44. {
  45. /**
  46. * @Template(foobar=21)
  47. * @param Entity $foo
  48. */
  49. public function doSomething($foo)
  50. {
  51. $bar = $foo->toArray();
  52. /** @var ArrayInterface $bar */
  53. }
  54. }
  55. EOF
  56. ,
  57. <<<'EOF'
  58. <?php
  59. use Foo\Bar;
  60. use Foo\Bar\Baz;
  61. use Foo\Bar\FooBar as FooBaz;
  62. use Foo\Bar\Foo as Fooo;
  63. use Foo\Bar\Baar\Baar;
  64. use SomeClass;
  65. $a = new Bar();
  66. $a = new FooBaz();
  67. $a = new SomeClass();
  68. use Symfony\Annotation\Template;
  69. use Symfony\Doctrine\Entities\Entity;
  70. use Symfony\Array123\ArrayInterface;
  71. class AnnotatedClass
  72. {
  73. /**
  74. * @Template(foobar=21)
  75. * @param Entity $foo
  76. */
  77. public function doSomething($foo)
  78. {
  79. $bar = $foo->toArray();
  80. /** @var ArrayInterface $bar */
  81. }
  82. }
  83. EOF
  84. ,
  85. ],
  86. 'with_indents' => [
  87. <<<'EOF'
  88. <?php
  89. use Foo\Bar;
  90. $foo = 1;
  91. use Foo\Bar\FooBar as FooBaz;
  92. use SomeClassIndented;
  93. $a = new Bar();
  94. $a = new FooBaz();
  95. $a = new SomeClassIndented();
  96. EOF
  97. ,
  98. <<<'EOF'
  99. <?php
  100. use Foo\Bar;
  101. use Foo\Bar\Baz;
  102. $foo = 1;
  103. use Foo\Bar\FooBar as FooBaz;
  104. use Foo\Bar\Foo as Fooo;
  105. use Foo\Bar\Baar\Baar;
  106. use SomeClassIndented;
  107. $a = new Bar();
  108. $a = new FooBaz();
  109. $a = new SomeClassIndented();
  110. EOF
  111. ,
  112. ],
  113. 'in_same_namespace_1' => [
  114. <<<'EOF'
  115. <?php
  116. namespace Foo\Bar\FooBar;
  117. use Foo\Bar\FooBar\Foo as Fooz;
  118. use Foo\Bar\FooBar\Aaa\Bbb;
  119. use XYZ\FQCN_XYZ;
  120. $a = new Baz();
  121. $b = new Fooz();
  122. $c = new Bar\Fooz();
  123. $d = new Bbb();
  124. $e = new FQCN_Babo();
  125. $f = new FQCN_XYZ();
  126. EOF
  127. ,
  128. <<<'EOF'
  129. <?php
  130. namespace Foo\Bar\FooBar;
  131. use Foo\Bar\FooBar\Baz;
  132. use Foo\Bar\FooBar\Foo as Fooz;
  133. use Foo\Bar\FooBar\Bar;
  134. use Foo\Bar\FooBar\Aaa\Bbb;
  135. use \Foo\Bar\FooBar\FQCN_Babo;
  136. use XYZ\FQCN_XYZ;
  137. $a = new Baz();
  138. $b = new Fooz();
  139. $c = new Bar\Fooz();
  140. $d = new Bbb();
  141. $e = new FQCN_Babo();
  142. $f = new FQCN_XYZ();
  143. EOF
  144. ,
  145. ],
  146. 'in_same_namespace_2' => [
  147. <<<'EOF'
  148. <?php namespace App\Http\Controllers;
  149. EOF
  150. ,
  151. <<<'EOF'
  152. <?php namespace App\Http\Controllers;
  153. use Illuminate\Http\Request;
  154. use App\Http\Controllers\Controller;
  155. EOF
  156. ,
  157. ],
  158. 'in_same_namespace_multiple_1' => [
  159. <<<'EOF'
  160. <?php
  161. namespace Foooooooo;
  162. namespace Foo;
  163. use Foooooooo\Baaaaz;
  164. $a = new Bar();
  165. $b = new Baz();
  166. $c = new Baaaaz();
  167. EOF
  168. ,
  169. <<<'EOF'
  170. <?php
  171. namespace Foooooooo;
  172. namespace Foo;
  173. use Foo\Bar;
  174. use Foo\Baz;
  175. use Foooooooo\Baaaar;
  176. use Foooooooo\Baaaaz;
  177. $a = new Bar();
  178. $b = new Baz();
  179. $c = new Baaaaz();
  180. EOF
  181. ,
  182. ],
  183. 'in_same_namespace_multiple_2' => [
  184. <<<'EOF'
  185. <?php
  186. namespace Foooooooo;
  187. use Foo\Bar;
  188. $a = new Baaaar();
  189. $b = new Baaaaz();
  190. $c = new Bar();
  191. namespace Foo;
  192. use Foooooooo\Baaaaz;
  193. $a = new Bar();
  194. $b = new Baz();
  195. $c = new Baaaaz();
  196. EOF
  197. ,
  198. <<<'EOF'
  199. <?php
  200. namespace Foooooooo;
  201. use Foo\Bar;
  202. use Foo\Baz;
  203. use Foooooooo\Baaaar;
  204. use Foooooooo\Baaaaz;
  205. $a = new Baaaar();
  206. $b = new Baaaaz();
  207. $c = new Bar();
  208. namespace Foo;
  209. use Foo\Bar;
  210. use Foo\Baz;
  211. use Foooooooo\Baaaar;
  212. use Foooooooo\Baaaaz;
  213. $a = new Bar();
  214. $b = new Baz();
  215. $c = new Baaaaz();
  216. EOF
  217. ,
  218. ],
  219. 'in_same_namespace_multiple_braces' => [
  220. <<<'EOF'
  221. <?php
  222. namespace Foooooooo
  223. {
  224. use Foo\Bar;
  225. $a = new Baaaar();
  226. $b = new Baaaaz();
  227. $c = new Bar();
  228. }
  229. namespace Foo
  230. {
  231. use Foooooooo\Baaaaz;
  232. $a = new Bar();
  233. $b = new Baz();
  234. $c = new Baaaaz();
  235. }
  236. EOF
  237. ,
  238. <<<'EOF'
  239. <?php
  240. namespace Foooooooo
  241. {
  242. use Foo\Bar;
  243. use Foo\Baz;
  244. use Foooooooo\Baaaar;
  245. use Foooooooo\Baaaaz;
  246. $a = new Baaaar();
  247. $b = new Baaaaz();
  248. $c = new Bar();
  249. }
  250. namespace Foo
  251. {
  252. use Foo\Bar;
  253. use Foo\Baz;
  254. use Foooooooo\Baaaar;
  255. use Foooooooo\Baaaaz;
  256. $a = new Bar();
  257. $b = new Baz();
  258. $c = new Baaaaz();
  259. }
  260. EOF
  261. ,
  262. ],
  263. 'multiple_use' => [
  264. <<<'EOF'
  265. <?php
  266. namespace Foo;
  267. use BarB, BarC as C, BarD;
  268. use BarE;
  269. $c = new D();
  270. $e = new BarE();
  271. EOF
  272. ,
  273. <<<'EOF'
  274. <?php
  275. namespace Foo;
  276. use Bar;
  277. use BarA;
  278. use BarB, BarC as C, BarD;
  279. use BarB2;
  280. use BarB\B2;
  281. use BarE;
  282. $c = new D();
  283. $e = new BarE();
  284. EOF
  285. ,
  286. ],
  287. 'with_braces' => [
  288. <<<'EOF'
  289. <?php
  290. namespace Foo\Bar\FooBar {
  291. use Foo\Bar\FooBar\Foo as Fooz;
  292. use Foo\Bar\FooBar\Aaa\Bbb;
  293. $a = new Baz();
  294. $b = new Fooz();
  295. $c = new Bar\Fooz();
  296. $d = new Bbb();
  297. }
  298. EOF
  299. ,
  300. <<<'EOF'
  301. <?php
  302. namespace Foo\Bar\FooBar {
  303. use Foo\Bar\FooBar\Baz;
  304. use Foo\Bar\FooBar\Foo as Fooz;
  305. use Foo\Bar\FooBar\Bar;
  306. use Foo\Bar\FooBar\Aaa\Bbb;
  307. $a = new Baz();
  308. $b = new Fooz();
  309. $c = new Bar\Fooz();
  310. $d = new Bbb();
  311. }
  312. EOF
  313. ,
  314. ],
  315. 'trailing_spaces' => [
  316. <<<'EOF'
  317. <?php
  318. use Foo\Bar ;
  319. use Foo\Bar\FooBar as FooBaz ;
  320. $a = new Bar();
  321. $a = new FooBaz();
  322. EOF
  323. ,
  324. <<<'EOF'
  325. <?php
  326. use Foo\Bar ;
  327. use Foo\Bar\FooBar as FooBaz ;
  328. use Foo\Bar\Foo as Fooo ;
  329. use SomeClass ;
  330. $a = new Bar();
  331. $a = new FooBaz();
  332. EOF
  333. ,
  334. ],
  335. 'traits' => [
  336. <<<'EOF'
  337. <?php
  338. use Foo as Bar;
  339. use A\MyTrait1;
  340. class MyParent
  341. {
  342. use MyTrait1;
  343. use MyTrait2;
  344. use Bar;
  345. }
  346. EOF
  347. ,
  348. <<<'EOF'
  349. <?php
  350. use Foo;
  351. use Foo as Bar;
  352. use A\MyTrait1;
  353. class MyParent
  354. {
  355. use MyTrait1;
  356. use MyTrait2;
  357. use Bar;
  358. }
  359. EOF
  360. ,
  361. ],
  362. 'function_use' => [
  363. <<<'EOF'
  364. <?php
  365. use Foo;
  366. $f = new Foo();
  367. $a = function ($item) use ($f) {
  368. return !in_array($item, $f);
  369. };
  370. EOF
  371. ,
  372. <<<'EOF'
  373. <?php
  374. use Foo;
  375. use Bar;
  376. $f = new Foo();
  377. $a = function ($item) use ($f) {
  378. return !in_array($item, $f);
  379. };
  380. EOF
  381. ,
  382. ],
  383. 'similar_names' => [
  384. <<<'EOF'
  385. <?php
  386. use SomeEntityRepository;
  387. class SomeService
  388. {
  389. public function __construct(SomeEntityRepository $repo)
  390. {
  391. $this->repo = $repo;
  392. }
  393. }
  394. EOF
  395. ,
  396. <<<'EOF'
  397. <?php
  398. use SomeEntityRepository;
  399. use SomeEntity;
  400. class SomeService
  401. {
  402. public function __construct(SomeEntityRepository $repo)
  403. {
  404. $this->repo = $repo;
  405. }
  406. }
  407. EOF
  408. ,
  409. ],
  410. 'variable_name' => [
  411. <<<'EOF'
  412. <?php
  413. $bar = null;
  414. EOF
  415. ,
  416. <<<'EOF'
  417. <?php
  418. use Foo\Bar;
  419. $bar = null;
  420. EOF
  421. ,
  422. ],
  423. 'property name, method name, static method call, static property' => [
  424. <<<'EOF'
  425. <?php
  426. $foo->bar = null;
  427. $foo->bar();
  428. $foo::bar();
  429. $foo::bar;
  430. EOF
  431. ,
  432. <<<'EOF'
  433. <?php
  434. use Foo\Bar;
  435. $foo->bar = null;
  436. $foo->bar();
  437. $foo::bar();
  438. $foo::bar;
  439. EOF
  440. ,
  441. ],
  442. 'constant_name' => [
  443. <<<'EOF'
  444. <?php
  445. class Baz
  446. {
  447. const BAR = 0;
  448. }
  449. EOF
  450. ,
  451. <<<'EOF'
  452. <?php
  453. use Foo\Bar;
  454. class Baz
  455. {
  456. const BAR = 0;
  457. }
  458. EOF
  459. ,
  460. ],
  461. 'namespace_part' => [
  462. <<<'EOF'
  463. <?php
  464. new \Baz\Bar();
  465. EOF
  466. ,
  467. <<<'EOF'
  468. <?php
  469. use Foo\Bar;
  470. new \Baz\Bar();
  471. EOF
  472. ,
  473. ],
  474. 'use_in_string_1' => [
  475. <<<'EOF'
  476. <?php
  477. $x=<<<'EOA'
  478. use a;
  479. use b;
  480. EOA;
  481. EOF
  482. ,
  483. ],
  484. 'use_in_string_2' => [
  485. <<<'EOF'
  486. <?php
  487. $x='
  488. use a;
  489. use b;
  490. ';
  491. EOF
  492. ,
  493. ],
  494. 'use_in_string_3' => [
  495. <<<'EOF'
  496. <?php
  497. $x="
  498. use a;
  499. use b;
  500. ";
  501. EOF
  502. ,
  503. ],
  504. 'import_in_global_namespace' => [
  505. <<<'EOF'
  506. <?php
  507. namespace A;
  508. use \SplFileInfo;
  509. new SplFileInfo(__FILE__);
  510. EOF
  511. ,
  512. ],
  513. 'use_as_last_statement' => [
  514. <<<'EOF'
  515. <?php
  516. EOF
  517. ,
  518. <<<'EOF'
  519. <?php
  520. use Bar\Finder;
  521. EOF
  522. ,
  523. ],
  524. 'use_with_same_last_part_that_is_in_namespace' => [
  525. <<<'EOF'
  526. <?php
  527. namespace Foo\Finder;
  528. EOF
  529. ,
  530. <<<'EOF'
  531. <?php
  532. namespace Foo\Finder;
  533. use Bar\Finder;
  534. EOF
  535. ,
  536. ],
  537. 'used_use_with_same_last_part_that_is_in_namespace' => [
  538. <<<'EOF'
  539. <?php
  540. namespace Foo\Finder;
  541. use Bar\Finder;
  542. class Baz extends Finder
  543. {
  544. }
  545. EOF
  546. ,
  547. ],
  548. 'foo' => [
  549. <<<'EOF'
  550. <?php
  551. namespace Aaa;
  552. class Ddd
  553. {
  554. }
  555. EOF
  556. ,
  557. <<<'EOF'
  558. <?php
  559. namespace Aaa;
  560. use Aaa\Bbb;
  561. use Ccc;
  562. class Ddd
  563. {
  564. }
  565. EOF
  566. ,
  567. ],
  568. 'close_tag_1' => [
  569. '<?php
  570. ?>inline content<?php ?>',
  571. '<?php
  572. use A\AA;
  573. use B\C?>inline content<?php use A\D; use E\F ?>',
  574. ],
  575. 'close_tag_2' => [
  576. '<?php ?>',
  577. '<?php use A\B;?>',
  578. ],
  579. 'close_tag_3' => [
  580. '<?php ?>',
  581. '<?php use A\B?>',
  582. ],
  583. 'with_matches_in_comments' => [
  584. '<?php
  585. use Foo;
  586. use Bar;
  587. use Baz;
  588. //Foo
  589. #Bar
  590. /*Baz*/',
  591. ],
  592. 'with_case_insensitive_matches_in_comments' => [
  593. '<?php
  594. use Foo;
  595. use Bar;
  596. use Baz;
  597. //foo
  598. #bar
  599. /*baz*/',
  600. ],
  601. 'with_same_namespace_import_and_unused_import' => [
  602. <<<'EOF'
  603. <?php
  604. namespace Foo;
  605. use Bar\C;
  606. /* test */
  607. abstract class D extends A implements C
  608. {
  609. }
  610. EOF
  611. ,
  612. <<<'EOF'
  613. <?php
  614. namespace Foo;
  615. use Bar\C;
  616. use Foo\A;
  617. use Foo\Bar\B /* test */ ;
  618. abstract class D extends A implements C
  619. {
  620. }
  621. EOF
  622. ,
  623. ],
  624. 'with_same_namespace_import_and_unused_import_after_namespace_statement' => [
  625. <<<'EOF'
  626. <?php
  627. namespace Foo;
  628. use Foo\Bar\C;
  629. abstract class D extends A implements C
  630. {
  631. }
  632. EOF
  633. ,
  634. <<<'EOF'
  635. <?php
  636. namespace Foo;
  637. use Foo\A;
  638. use Foo\Bar\B;
  639. use Foo\Bar\C;
  640. abstract class D extends A implements C
  641. {
  642. }
  643. EOF
  644. ,
  645. ],
  646. 'wrong_casing' => [
  647. <<<'EOF'
  648. <?php
  649. use Foo\Foo;
  650. use Bar\Bar;
  651. $a = new FOO();
  652. $b = new bar();
  653. EOF
  654. ,
  655. ],
  656. 'phpdoc_unused' => [
  657. <<<'EOF'
  658. <?php
  659. class Foo extends \PHPUnit_Framework_TestCase
  660. {
  661. /**
  662. * @expectedException \Exception
  663. */
  664. public function testBar()
  665. { }
  666. }
  667. EOF
  668. ,
  669. <<<'EOF'
  670. <?php
  671. use Some\Exception;
  672. class Foo extends \PHPUnit_Framework_TestCase
  673. {
  674. /**
  675. * @expectedException \Exception
  676. */
  677. public function testBar()
  678. { }
  679. }
  680. EOF
  681. ,
  682. ],
  683. 'imported_class_is_used_for_constants_1' => [
  684. '<?php
  685. use A\ABC;
  686. $a = 5-ABC::Test;
  687. $a = 5-ABC::Test-5;
  688. $a = ABC::Test-5;
  689. ',
  690. ],
  691. 'imported_class_is_used_for_constants_2' => [
  692. '<?php
  693. use A\ABC;
  694. $a = 5-ABC::Test;
  695. $a = 5-ABC::Test-5;
  696. ',
  697. ],
  698. 'imported_class_is_used_for_constants_3' => [
  699. '<?php
  700. use A\ABC;
  701. $a = 5-ABC::Test;
  702. ',
  703. ],
  704. 'imported_class_is_used_for_constants_4' => ['<?php
  705. use A\ABC;
  706. $a = ABC::Test-5;
  707. ',
  708. ],
  709. 'imported_class_is_used_for_constants_5' => ['<?php
  710. use A\ABC;
  711. $a = 5-ABC::Test-5;
  712. ',
  713. ],
  714. 'imported_class_is_used_for_constants_6' => ['<?php
  715. use A\ABC;
  716. $b = $a-->ABC::Test;
  717. ',
  718. ],
  719. 'imported_class_name_is_prefix_with_dash_of_constant' => [
  720. <<<'EOF'
  721. <?php
  722. class Dummy
  723. {
  724. const C = 'bar-bados';
  725. }
  726. EOF
  727. ,
  728. <<<'EOF'
  729. <?php
  730. use Foo\Bar;
  731. class Dummy
  732. {
  733. const C = 'bar-bados';
  734. }
  735. EOF
  736. ,
  737. ],
  738. 'imported_class_name_is_suffix_with_dash_of_constant' => [
  739. <<<'EOF'
  740. <?php
  741. class Dummy
  742. {
  743. const C = 'tool-bar';
  744. }
  745. EOF
  746. ,
  747. <<<'EOF'
  748. <?php
  749. use Foo\Bar;
  750. class Dummy
  751. {
  752. const C = 'tool-bar';
  753. }
  754. EOF
  755. ,
  756. ],
  757. 'imported_class_name_is_inside_with_dash_of_constant' => [
  758. <<<'EOF'
  759. <?php
  760. class Dummy
  761. {
  762. const C = 'tool-bar-bados';
  763. }
  764. EOF
  765. ,
  766. <<<'EOF'
  767. <?php
  768. use Foo\Bar;
  769. class Dummy
  770. {
  771. const C = 'tool-bar-bados';
  772. }
  773. EOF
  774. ,
  775. ],
  776. 'functions_in_the_global_namespace_should_not_be_removed_even_when_declaration_has_new_lines_and_is_uppercase' => [
  777. <<<'EOF'
  778. <?php
  779. namespace Foo;
  780. use function is_int;
  781. is_int(1);
  782. EOF
  783. ,
  784. <<<'EOF'
  785. <?php
  786. namespace Foo;
  787. use function is_int;
  788. use function is_float;
  789. is_int(1);
  790. EOF
  791. ,
  792. ],
  793. 'constants_in_the_global_namespace_should_not_be_removed' => [
  794. $expected = <<<'EOF'
  795. <?php
  796. namespace Foo;
  797. use const PHP_INT_MAX;
  798. echo PHP_INT_MAX;
  799. EOF
  800. ,
  801. <<<'EOF'
  802. <?php
  803. namespace Foo;
  804. use const PHP_INT_MAX;
  805. use const PHP_INT_MIN;
  806. echo PHP_INT_MAX;
  807. EOF
  808. ,
  809. ],
  810. 'functions_in_the_global_namespace_should_not_be_removed_even_when_declaration_has_ne_lines_and_is_uppercase' => [
  811. <<<'EOF'
  812. <?php
  813. namespace Foo;use/**/FUNCTION#1
  814. is_int;#2
  815. is_int(1);
  816. EOF
  817. ,
  818. <<<'EOF'
  819. <?php
  820. namespace Foo;use/**/FUNCTION#1
  821. is_int;#2
  822. use function
  823. is_float;
  824. use
  825. const
  826. PHP_INT_MIN;
  827. is_int(1);
  828. EOF
  829. ,
  830. ],
  831. 'use_trait should never be removed' => [
  832. <<<'EOF'
  833. <?php
  834. class UsesTraits
  835. {
  836. /**
  837. * @see #4086
  838. */
  839. private function withComplexStringVariable()
  840. {
  841. $name = 'World';
  842. return "Hello, {$name}!";
  843. }
  844. use MyTrait;
  845. }
  846. EOF
  847. ],
  848. 'imported_name_is_part_of_namespace' => [
  849. <<<'EOF'
  850. <?php
  851. namespace App\Foo;
  852. class Baz
  853. {
  854. }
  855. EOF
  856. ,
  857. <<<'EOF'
  858. <?php
  859. namespace App\Foo;
  860. use Foo\Bar\App;
  861. class Baz
  862. {
  863. }
  864. EOF
  865. ],
  866. 'imported_name_is_part_of_namespace with closing tag' => [
  867. <<<'EOF'
  868. <?php
  869. namespace A\B {?>
  870. <?php
  871. require_once __DIR__.'/test2.php' ?>
  872. <?php
  873. use X\Z\Y
  874. ?>
  875. <?php
  876. $y = new Y() ?>
  877. <?php
  878. var_dump($y);}
  879. EOF
  880. ],
  881. [
  882. '<?php
  883. use App\Http\Requests\StoreRequest;
  884. class StoreController
  885. {
  886. /**
  887. * @param \App\Http\Requests\StoreRequest $request
  888. */
  889. public function __invoke(StoreRequest $request)
  890. {}
  891. }',
  892. '<?php
  893. use App\Http\Requests\StoreRequest;
  894. use Illuminate\Http\Request;
  895. class StoreController
  896. {
  897. /**
  898. * @param \App\Http\Requests\StoreRequest $request
  899. */
  900. public function __invoke(StoreRequest $request)
  901. {}
  902. }',
  903. ],
  904. 'unused import matching function call' => [
  905. '<?php
  906. namespace Foo;
  907. bar();',
  908. '<?php
  909. namespace Foo;
  910. use Bar;
  911. bar();',
  912. ],
  913. 'unused import matching function declaration' => [
  914. '<?php
  915. namespace Foo;
  916. function bar () {}',
  917. '<?php
  918. namespace Foo;
  919. use Bar;
  920. function bar () {}',
  921. ],
  922. 'unused import matching method declaration' => [
  923. '<?php
  924. namespace Foo;
  925. class Foo {
  926. public function bar () {}
  927. }',
  928. '<?php
  929. namespace Foo;
  930. use Bar;
  931. class Foo {
  932. public function bar () {}
  933. }',
  934. ],
  935. 'unused import matching constant usage' => [
  936. '<?php
  937. namespace Foo;
  938. echo BAR;',
  939. '<?php
  940. namespace Foo;
  941. use Bar;
  942. echo BAR;',
  943. ],
  944. 'unused import matching class constant' => [
  945. '<?php
  946. namespace Foo;
  947. class Foo {
  948. const BAR = 1;
  949. }',
  950. '<?php
  951. namespace Foo;
  952. use Bar;
  953. class Foo {
  954. const BAR = 1;
  955. }',
  956. ],
  957. 'unused function import matching class usage' => [
  958. '<?php
  959. namespace Foo;
  960. new Bar();
  961. Baz::method();',
  962. '<?php
  963. namespace Foo;
  964. use function bar;
  965. use function baz;
  966. new Bar();
  967. Baz::method();',
  968. ],
  969. 'unused function import matching method call' => [
  970. '<?php
  971. namespace Foo;
  972. Foo::bar();',
  973. '<?php
  974. namespace Foo;
  975. use function bar;
  976. Foo::bar();',
  977. ],
  978. 'unused function import matching method declaration' => [
  979. '<?php
  980. namespace Foo;
  981. class Foo {
  982. public function bar () {}
  983. }',
  984. '<?php
  985. namespace Foo;
  986. use function bar;
  987. class Foo {
  988. public function bar () {}
  989. }',
  990. ],
  991. 'unused function import matching constant usage' => [
  992. '<?php
  993. namespace Foo;
  994. echo BAR;',
  995. '<?php
  996. namespace Foo;
  997. use function bar;
  998. echo BAR;',
  999. ],
  1000. 'unused function import matching class constant' => [
  1001. '<?php
  1002. namespace Foo;
  1003. class Foo {
  1004. const BAR = 1;
  1005. }',
  1006. '<?php
  1007. namespace Foo;
  1008. use function bar;
  1009. class Foo {
  1010. const BAR = 1;
  1011. }',
  1012. ],
  1013. 'unused constant import matching function call' => [
  1014. '<?php
  1015. namespace Foo;
  1016. bar();',
  1017. '<?php
  1018. namespace Foo;
  1019. use const BAR;
  1020. bar();',
  1021. ],
  1022. 'unused constant import matching function declaration' => [
  1023. '<?php
  1024. namespace Foo;
  1025. function bar () {}',
  1026. '<?php
  1027. namespace Foo;
  1028. use const BAR;
  1029. function bar () {}',
  1030. ],
  1031. 'unused constant import matching method declaration' => [
  1032. '<?php
  1033. namespace Foo;
  1034. class Foo {
  1035. public function bar () {}
  1036. }',
  1037. '<?php
  1038. namespace Foo;
  1039. use const BAR;
  1040. class Foo {
  1041. public function bar () {}
  1042. }',
  1043. ],
  1044. 'unused constant import matching class constant' => [
  1045. '<?php
  1046. namespace Foo;
  1047. class Foo {
  1048. const BAR = 1;
  1049. }',
  1050. '<?php
  1051. namespace Foo;
  1052. use const BAR;
  1053. class Foo {
  1054. const BAR = 1;
  1055. }',
  1056. ],
  1057. 'attribute without braces' => [
  1058. '<?php
  1059. use Foo;
  1060. class Controller
  1061. {
  1062. #[Foo]
  1063. public function foo() {}
  1064. }',
  1065. ],
  1066. 'attribute with braces' => [
  1067. '<?php
  1068. use Foo;
  1069. class Controller
  1070. {
  1071. #[Foo()]
  1072. public function foo() {}
  1073. }',
  1074. ],
  1075. 'go to' => [
  1076. '<?php
  1077. Bar1:
  1078. Bar2:
  1079. Bar3:
  1080. ',
  1081. '<?php
  1082. use Bar1;
  1083. use const Bar2;
  1084. use function Bar3;
  1085. Bar1:
  1086. Bar2:
  1087. Bar3:
  1088. ',
  1089. ],
  1090. [
  1091. $expected = <<<'EOF'
  1092. <?php
  1093. use some\a\{ClassD};
  1094. use some\b\{ClassA, ClassB, ClassC as C};
  1095. use function some\c\{fn_a, fn_b, fn_c};
  1096. use const some\d\{ConstA, ConstB, ConstC};
  1097. new CLassD();
  1098. echo fn_a();
  1099. EOF
  1100. ],
  1101. [ // TODO test shows lot of cases where imports are not removed while could be
  1102. '<?php use A\{B,};
  1103. use some\y\{ClassA, ClassB, ClassC as C,};
  1104. use function some\a\{fn_a, fn_b, fn_c,};
  1105. use const some\Z\{ConstAA,ConstBB,ConstCC,};
  1106. use const some\X\{ConstA,ConstB,ConstC,ConstF};
  1107. use C\{D,E,};
  1108. echo ConstA.ConstB.ConstC,ConstF;
  1109. echo ConstBB.ConstCC;
  1110. fn_a(ClassA::test, new C());
  1111. ',
  1112. '<?php use A\{B,};
  1113. use some\y\{ClassA, ClassB, ClassC as C,};
  1114. use function some\a\{fn_a, fn_b, fn_c,};
  1115. use const some\Z\{ConstAA,ConstBB,ConstCC,};
  1116. use const some\X\{ConstA,ConstB,ConstC,ConstF};
  1117. use C\{D,E,};
  1118. use Z;
  1119. echo ConstA.ConstB.ConstC,ConstF;
  1120. echo ConstBB.ConstCC;
  1121. fn_a(ClassA::test, new C());
  1122. ',
  1123. ],
  1124. ];
  1125. }
  1126. /**
  1127. * @requires PHP <8.0
  1128. */
  1129. public function testFixPrePHP80(): void
  1130. {
  1131. $this->doTest(
  1132. '<?php
  1133. # 1
  1134. # 2
  1135. # 3
  1136. # 4
  1137. use /**/A\B/**/;
  1138. echo 1;
  1139. new B();
  1140. ',
  1141. '<?php
  1142. use# 1
  1143. \# 2
  1144. Exception# 3
  1145. # 4
  1146. ;
  1147. use /**/A\B/**/;
  1148. echo 1;
  1149. new B();
  1150. '
  1151. );
  1152. }
  1153. /**
  1154. * @requires PHP 8.0
  1155. *
  1156. * @dataProvider providePhp80Cases
  1157. */
  1158. public function testFix80(string $expected, ?string $input = null): void
  1159. {
  1160. $this->doTest($expected, $input);
  1161. }
  1162. public static function providePhp80Cases(): iterable
  1163. {
  1164. yield [
  1165. '<?php
  1166. $x = $foo?->bar;
  1167. $y = foo?->bar();
  1168. ',
  1169. '<?php
  1170. use Foo\Bar;
  1171. $x = $foo?->bar;
  1172. $y = foo?->bar();
  1173. ',
  1174. ];
  1175. yield 'with union type in non-capturing catch' => [
  1176. '<?php
  1177. use Foo;
  1178. use Bar;
  1179. try {} catch (Foo | Bar) {}',
  1180. ];
  1181. yield 'union return' => [
  1182. '<?php
  1183. use Foo;
  1184. use Bar;
  1185. abstract class Baz
  1186. {
  1187. abstract public function test(): Foo|Bar;
  1188. }
  1189. ',
  1190. ];
  1191. yield 'attribute' => [
  1192. "<?php
  1193. use Acme\\JsonSchemaValidationBundle\\Annotation\\JsonSchema;
  1194. use Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\IsGranted;
  1195. use Symfony\\Component\\Routing\\Annotation\\Route;
  1196. #[
  1197. Route('/basket/{uuid}/item', name: 'addBasketItem', requirements: ['uuid' => '%regex.uuid%'], methods: ['POST']),
  1198. IsGranted('ROLE_USER'),
  1199. JsonSchema('Public/Basket/addItem.json'),
  1200. ]
  1201. class Foo {}
  1202. ",
  1203. ];
  1204. yield 'attribute 2' => [
  1205. '<?php
  1206. use Psr\Log\LoggerInterface;
  1207. function f( #[Target(\'xxx\')] LoggerInterface|null $logger) {}
  1208. ',
  1209. ];
  1210. }
  1211. /**
  1212. * @requires PHP 8.1
  1213. *
  1214. * @dataProvider providePhp81Cases
  1215. */
  1216. public function testFix81(string $expected, ?string $input = null): void
  1217. {
  1218. $this->doTest($expected, $input);
  1219. }
  1220. public static function providePhp81Cases(): iterable
  1221. {
  1222. yield 'final const' => [
  1223. '<?php
  1224. class Foo
  1225. {
  1226. final public const B1 = "2";
  1227. }
  1228. ',
  1229. '<?php
  1230. use A\B1;
  1231. class Foo
  1232. {
  1233. final public const B1 = "2";
  1234. }
  1235. ',
  1236. ];
  1237. yield 'first callable class' => [
  1238. '<?php
  1239. use Foo;
  1240. Foo::method(...);',
  1241. '<?php
  1242. use Foo;
  1243. use Bar;
  1244. Foo::method(...);',
  1245. ];
  1246. yield 'New in initializers' => [
  1247. '<?php
  1248. namespace A\B\C;
  1249. use Foo1;
  1250. use Foo2;
  1251. use Foo3;
  1252. use Foo4;
  1253. use Foo5;
  1254. use Foo6;
  1255. use Foo7;
  1256. class Test {
  1257. public function __construct(
  1258. public $prop = (new Foo1),
  1259. ) {}
  1260. }
  1261. function test(
  1262. $foo = (new Foo2),
  1263. $baz = (new Foo3(x: 2)),
  1264. ) {
  1265. }
  1266. static $x = new Foo4();
  1267. const C = (new Foo5);
  1268. function test2($param = (new Foo6)) {}
  1269. const D = new Foo7(1,2);
  1270. ',
  1271. ];
  1272. }
  1273. /**
  1274. * @requires PHP 8.1
  1275. *
  1276. * @dataProvider provideFixPhp81Cases
  1277. */
  1278. public function testFixPhp81(string $expected): void
  1279. {
  1280. $this->doTest($expected);
  1281. }
  1282. public static function provideFixPhp81Cases(): iterable
  1283. {
  1284. yield [
  1285. '<?php
  1286. enum Foo: string
  1287. {
  1288. use Bar;
  1289. case Test1 = "a";
  1290. }
  1291. ',
  1292. ];
  1293. yield [
  1294. '<?php
  1295. use Foo\Class1;
  1296. use Foo\Class2;
  1297. class C
  1298. {
  1299. public function t(Class1 | Class2 $fields) {}
  1300. }
  1301. ',
  1302. ];
  1303. yield [
  1304. '<?php
  1305. use Foo\Class1;
  1306. use Foo\Class2;
  1307. class C
  1308. {
  1309. public function t(Class1 | Class2 ...$fields) {}
  1310. }
  1311. ',
  1312. ];
  1313. }
  1314. }