PageRenderTime 46ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/fabpot/php-cs-fixer/Symfony/CS/Fixer.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 410 lines | 252 code | 74 blank | 84 comment | 33 complexity | a8db141aee9057ade3e4905ed3f3c93e MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the PHP CS utility.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this source code in the file LICENSE.
  9. */
  10. namespace Symfony\CS;
  11. use SebastianBergmann\Diff\Differ;
  12. use Symfony\Component\EventDispatcher\EventDispatcher;
  13. use Symfony\Component\Finder\Finder;
  14. use Symfony\Component\Finder\SplFileInfo as FinderSplFileInfo;
  15. use Symfony\Component\Stopwatch\Stopwatch;
  16. use Symfony\CS\Tokenizer\Tokens;
  17. /**
  18. * @author Fabien Potencier <fabien@symfony.com>
  19. * @author Dariusz RumiƄski <dariusz.ruminski@gmail.com>
  20. */
  21. class Fixer
  22. {
  23. const VERSION = '1.11.2';
  24. protected $fixers = array();
  25. protected $configs = array();
  26. /**
  27. * Differ instance.
  28. *
  29. * @var Differ
  30. */
  31. protected $diff;
  32. /**
  33. * EventDispatcher instance.
  34. *
  35. * @var EventDispatcher|null
  36. */
  37. protected $eventDispatcher;
  38. /**
  39. * ErrorsManager instance.
  40. *
  41. * @var ErrorsManager|null
  42. */
  43. protected $errorsManager;
  44. /**
  45. * LintManager instance.
  46. *
  47. * @var LintManager|null
  48. */
  49. protected $lintManager;
  50. /**
  51. * Stopwatch instance.
  52. *
  53. * @var Stopwatch|null
  54. */
  55. protected $stopwatch;
  56. public function __construct()
  57. {
  58. $this->diff = new Differ();
  59. }
  60. public function registerBuiltInFixers()
  61. {
  62. foreach (Finder::create()->files()->in(__DIR__.'/Fixer') as $file) {
  63. $relativeNamespace = $file->getRelativePath();
  64. $class = 'Symfony\\CS\\Fixer\\'.($relativeNamespace ? $relativeNamespace.'\\' : '').$file->getBasename('.php');
  65. $this->addFixer(new $class());
  66. }
  67. }
  68. /**
  69. * @param FixerInterface[] $fixers
  70. */
  71. public function registerCustomFixers(array $fixers)
  72. {
  73. foreach ($fixers as $fixer) {
  74. $this->addFixer($fixer);
  75. }
  76. }
  77. public function addFixer(FixerInterface $fixer)
  78. {
  79. $this->fixers[] = $fixer;
  80. }
  81. /**
  82. * @return FixerInterface[]
  83. */
  84. public function getFixers()
  85. {
  86. $this->fixers = $this->sortFixers($this->fixers);
  87. return $this->fixers;
  88. }
  89. public function registerBuiltInConfigs()
  90. {
  91. foreach (Finder::create()->files()->in(__DIR__.'/Config') as $file) {
  92. $relativeNamespace = $file->getRelativePath();
  93. $class = 'Symfony\\CS\\Config\\'.($relativeNamespace ? $relativeNamespace.'\\' : '').$file->getBasename('.php');
  94. $this->addConfig(new $class());
  95. }
  96. }
  97. public function addConfig(ConfigInterface $config)
  98. {
  99. $this->configs[] = $config;
  100. }
  101. public function getConfigs()
  102. {
  103. return $this->configs;
  104. }
  105. /**
  106. * Fixes all files for the given finder.
  107. *
  108. * @param ConfigInterface $config A ConfigInterface instance
  109. * @param bool $dryRun Whether to simulate the changes or not
  110. * @param bool $diff Whether to provide diff
  111. *
  112. * @return array
  113. */
  114. public function fix(ConfigInterface $config, $dryRun = false, $diff = false)
  115. {
  116. $fixers = $this->prepareFixers($config);
  117. $fixers = $this->sortFixers($fixers);
  118. $changed = array();
  119. if ($this->stopwatch) {
  120. $this->stopwatch->openSection();
  121. }
  122. $fileCacheManager = new FileCacheManager($config->usingCache(), $config->getDir(), $fixers);
  123. $finder = $config->getFinder();
  124. $finderIterator = $finder instanceof \IteratorAggregate ? $finder->getIterator() : $finder;
  125. foreach (new UniqueFileIterator($finderIterator) as $file) {
  126. if ($this->stopwatch) {
  127. $this->stopwatch->start($this->getFileRelativePathname($file));
  128. }
  129. if ($fixInfo = $this->fixFile($file, $fixers, $dryRun, $diff, $fileCacheManager)) {
  130. $changed[$this->getFileRelativePathname($file)] = $fixInfo;
  131. }
  132. if ($this->stopwatch) {
  133. $this->stopwatch->stop($this->getFileRelativePathname($file));
  134. }
  135. }
  136. if ($this->stopwatch) {
  137. $this->stopwatch->stopSection('fixFile');
  138. }
  139. return $changed;
  140. }
  141. public function fixFile(\SplFileInfo $file, array $fixers, $dryRun, $diff, FileCacheManager $fileCacheManager)
  142. {
  143. $new = $old = file_get_contents($file->getRealpath());
  144. if (
  145. '' === $old
  146. || !$fileCacheManager->needFixing($this->getFileRelativePathname($file), $old)
  147. // PHP 5.3 has a broken implementation of token_get_all when the file uses __halt_compiler() starting in 5.3.6
  148. || (PHP_VERSION_ID >= 50306 && PHP_VERSION_ID < 50400 && false !== stripos($old, '__halt_compiler()'))
  149. ) {
  150. if ($this->eventDispatcher) {
  151. $this->eventDispatcher->dispatch(
  152. FixerFileProcessedEvent::NAME,
  153. FixerFileProcessedEvent::create()->setStatus(FixerFileProcessedEvent::STATUS_SKIPPED)
  154. );
  155. }
  156. return;
  157. }
  158. if ($this->lintManager && !$this->lintManager->createProcessForFile($file->getRealpath())->isSuccessful()) {
  159. if ($this->eventDispatcher) {
  160. $this->eventDispatcher->dispatch(
  161. FixerFileProcessedEvent::NAME,
  162. FixerFileProcessedEvent::create()->setStatus(FixerFileProcessedEvent::STATUS_INVALID)
  163. );
  164. }
  165. return;
  166. }
  167. $appliedFixers = array();
  168. // we do not need Tokens to still caching previously fixed file - so clear the cache
  169. Tokens::clearCache();
  170. try {
  171. foreach ($fixers as $fixer) {
  172. if (!$fixer->supports($file)) {
  173. continue;
  174. }
  175. $newest = $fixer->fix($file, $new);
  176. if ($newest !== $new) {
  177. $appliedFixers[] = $fixer->getName();
  178. }
  179. $new = $newest;
  180. }
  181. } catch (\Exception $e) {
  182. if ($this->eventDispatcher) {
  183. $this->eventDispatcher->dispatch(
  184. FixerFileProcessedEvent::NAME,
  185. FixerFileProcessedEvent::create()->setStatus(FixerFileProcessedEvent::STATUS_EXCEPTION)
  186. );
  187. }
  188. if ($this->errorsManager) {
  189. $this->errorsManager->report(ErrorsManager::ERROR_TYPE_EXCEPTION, $this->getFileRelativePathname($file), $e->__toString());
  190. }
  191. return;
  192. }
  193. $fixInfo = null;
  194. if ($new !== $old) {
  195. if ($this->lintManager) {
  196. $lintProcess = $this->lintManager->createProcessForSource($new);
  197. if (!$lintProcess->isSuccessful()) {
  198. if ($this->eventDispatcher) {
  199. $this->eventDispatcher->dispatch(
  200. FixerFileProcessedEvent::NAME,
  201. FixerFileProcessedEvent::create()->setStatus(FixerFileProcessedEvent::STATUS_LINT)
  202. );
  203. }
  204. if ($this->errorsManager) {
  205. $this->errorsManager->report(ErrorsManager::ERROR_TYPE_LINT, $this->getFileRelativePathname($file), $lintProcess->getOutput());
  206. }
  207. return;
  208. }
  209. }
  210. if (!$dryRun) {
  211. file_put_contents($file->getRealpath(), $new);
  212. }
  213. $fixInfo = array('appliedFixers' => $appliedFixers);
  214. if ($diff) {
  215. $fixInfo['diff'] = $this->stringDiff($old, $new);
  216. }
  217. }
  218. $fileCacheManager->setFile($this->getFileRelativePathname($file), $new);
  219. if ($this->eventDispatcher) {
  220. $this->eventDispatcher->dispatch(
  221. FixerFileProcessedEvent::NAME,
  222. FixerFileProcessedEvent::create()->setStatus($fixInfo ? FixerFileProcessedEvent::STATUS_FIXED : FixerFileProcessedEvent::STATUS_NO_CHANGES)
  223. );
  224. }
  225. return $fixInfo;
  226. }
  227. private function getFileRelativePathname(\SplFileInfo $file)
  228. {
  229. if ($file instanceof FinderSplFileInfo) {
  230. return $file->getRelativePathname();
  231. }
  232. return $file->getPathname();
  233. }
  234. public static function getLevelAsString(FixerInterface $fixer)
  235. {
  236. $level = $fixer->getLevel();
  237. if (($level & FixerInterface::NONE_LEVEL) === $level) {
  238. return 'none';
  239. }
  240. if (($level & FixerInterface::PSR0_LEVEL) === $level) {
  241. return 'PSR-0';
  242. }
  243. if (($level & FixerInterface::PSR1_LEVEL) === $level) {
  244. return 'PSR-1';
  245. }
  246. if (($level & FixerInterface::PSR2_LEVEL) === $level) {
  247. return 'PSR-2';
  248. }
  249. if (($level & FixerInterface::CONTRIB_LEVEL) === $level) {
  250. return 'contrib';
  251. }
  252. return 'symfony';
  253. }
  254. protected function stringDiff($old, $new)
  255. {
  256. $diff = $this->diff->diff($old, $new);
  257. $diff = implode(
  258. PHP_EOL,
  259. array_map(
  260. function ($string) {
  261. $string = preg_replace('/^(\+){3}/', '<info>+++</info>', $string);
  262. $string = preg_replace('/^(\+){1}/', '<info>+</info>', $string);
  263. $string = preg_replace('/^(\-){3}/', '<error>---</error>', $string);
  264. $string = preg_replace('/^(\-){1}/', '<error>-</error>', $string);
  265. $string = str_repeat(' ', 6).$string;
  266. return $string;
  267. },
  268. explode(PHP_EOL, $diff)
  269. )
  270. );
  271. return $diff;
  272. }
  273. /**
  274. * @param FixerInterface[] $fixers
  275. *
  276. * @return FixerInterface[]
  277. */
  278. private function sortFixers(array $fixers)
  279. {
  280. usort($fixers, function (FixerInterface $a, FixerInterface $b) {
  281. return Utils::cmpInt($b->getPriority(), $a->getPriority());
  282. });
  283. return $fixers;
  284. }
  285. /**
  286. * @param ConfigInterface $config
  287. *
  288. * @return FixerInterface[]
  289. */
  290. private function prepareFixers(ConfigInterface $config)
  291. {
  292. $fixers = $config->getFixers();
  293. foreach ($fixers as $fixer) {
  294. if ($fixer instanceof ConfigAwareInterface) {
  295. $fixer->setConfig($config);
  296. }
  297. }
  298. return $fixers;
  299. }
  300. /**
  301. * Set EventDispatcher instance.
  302. *
  303. * @param EventDispatcher|null $eventDispatcher
  304. */
  305. public function setEventDispatcher(EventDispatcher $eventDispatcher = null)
  306. {
  307. $this->eventDispatcher = $eventDispatcher;
  308. }
  309. /**
  310. * Set ErrorsManager instance.
  311. *
  312. * @param ErrorsManager|null $errorsManager
  313. */
  314. public function setErrorsManager(ErrorsManager $errorsManager = null)
  315. {
  316. $this->errorsManager = $errorsManager;
  317. }
  318. /**
  319. * Set LintManager instance.
  320. *
  321. * @param LintManager|null $lintManager
  322. */
  323. public function setLintManager(LintManager $lintManager = null)
  324. {
  325. $this->lintManager = $lintManager;
  326. }
  327. /**
  328. * Set Stopwatch instance.
  329. *
  330. * @param Stopwatch|null $stopwatch
  331. */
  332. public function setStopwatch(Stopwatch $stopwatch = null)
  333. {
  334. $this->stopwatch = $stopwatch;
  335. }
  336. }