/** * Processes the file. * * @return void */ public function process() { if ($this->ignored === true) { return; } if ($this->configCache['cache'] === false) { return parent::process(); } $hash = md5_file($this->path); $cache = Cache::get($this->path); if ($cache !== false && $cache['hash'] === $hash) { // We can't filter metrics, so just load all of them. $this->metrics = $cache['metrics']; if ($this->configCache['recordErrors'] === true) { // Replay the cached errors and warnings to filter out the ones // we don't need for this specific run. $this->configCache['cache'] = false; $this->replayErrors($cache['errors'], $cache['warnings']); $this->configCache['cache'] = true; } else { $this->errorCount = $cache['errorCount']; $this->warningCount = $cache['warningCount']; $this->fixableCount = $cache['fixableCount']; } if (PHP_CODESNIFFER_VERBOSITY > 0 || PHP_CODESNIFFER_CBF === true && empty($this->config->files) === false) { echo "[loaded from cache]... "; } $this->numTokens = $cache['numTokens']; $this->fromCache = true; return; } //end if if (PHP_CODESNIFFER_VERBOSITY > 1) { echo PHP_EOL; } parent::process(); $cache = array('hash' => $hash, 'errors' => $this->errors, 'warnings' => $this->warnings, 'metrics' => $this->metrics, 'errorCount' => $this->errorCount, 'warningCount' => $this->warningCount, 'fixableCount' => $this->fixableCount, 'numTokens' => $this->numTokens); Cache::set($this->path, $cache); // During caching, we don't filter out errors in any way, so // we need to do that manually now by replaying them. if ($this->configCache['recordErrors'] === true) { $this->configCache['cache'] = false; $this->replayErrors($this->errors, $this->warnings); $this->configCache['cache'] = true; } }
/** * Attempt to fix the file by processing it until no fixes are made. * * @return boolean */ public function fixFile() { $fixable = $this->currentFile->getFixableCount(); if ($fixable === 0) { // Nothing to fix. return false; } $stdin = false; if (empty($this->currentFile->config->files) === true) { $stdin = true; } $this->enabled = true; $this->loops = 0; while ($this->loops < 50) { ob_start(); // Only needed once file content has changed. $contents = $this->getContents(); if (PHP_CODESNIFFER_VERBOSITY > 2) { @ob_end_clean(); echo '---START FILE CONTENT---' . PHP_EOL; $lines = explode($this->currentFile->eolChar, $contents); $max = strlen(count($lines)); foreach ($lines as $lineNum => $line) { $lineNum++; echo str_pad($lineNum, $max, ' ', STR_PAD_LEFT) . '|' . $line . PHP_EOL; } echo '--- END FILE CONTENT ---' . PHP_EOL; ob_start(); } $this->inConflict = false; $this->currentFile->ruleset->populateTokenListeners(); $this->currentFile->setContent($contents); $this->currentFile->process(); ob_end_clean(); $this->loops++; if (PHP_CODESNIFFER_CBF === true && PHP_CODESNIFFER_VERBOSITY > 0) { echo "\r" . str_repeat(' ', 80) . "\r"; echo "\t=> Fixing file: {$this->numFixes}/{$fixable} violations remaining [made {$this->loops} pass"; if ($this->loops > 1) { echo 'es'; } echo ']... '; } if ($this->numFixes === 0 && $this->inConflict === false) { // Nothing left to do. break; } else { if (PHP_CODESNIFFER_VERBOSITY > 1) { echo "\t* fixed {$this->numFixes} violations, starting loop " . ($this->loops + 1) . ' *' . PHP_EOL; } } } //end while $this->enabled = false; if ($this->numFixes > 0) { if (PHP_CODESNIFFER_VERBOSITY > 1) { @ob_end_clean(); echo "\t*** Reached maximum number of loops with {$this->numFixes} violations left unfixed ***" . PHP_EOL; ob_start(); } return false; } return true; }
/** * Processes a single file, including checking and fixing. * * @param \PHP_CodeSniffer\Files\File $file The file to be processed. * * @return void */ private function processFile($file) { if (PHP_CODESNIFFER_VERBOSITY > 0) { $startTime = microtime(true); echo 'Processing ' . basename($file->path) . ' '; if (PHP_CODESNIFFER_VERBOSITY > 1) { echo PHP_EOL; } } try { $file->process(); if (PHP_CODESNIFFER_VERBOSITY > 0) { $timeTaken = (microtime(true) - $startTime) * 1000; if ($timeTaken < 1000) { $timeTaken = round($timeTaken); echo "DONE in {$timeTaken}ms"; } else { $timeTaken = round($timeTaken / 1000, 2); echo "DONE in {$timeTaken} secs"; } if (PHP_CODESNIFFER_CBF === true) { $errors = $file->getFixableCount(); echo " ({$errors} fixable violations)" . PHP_EOL; } else { $errors = $file->getErrorCount(); $warnings = $file->getWarningCount(); echo " ({$errors} errors, {$warnings} warnings)" . PHP_EOL; } } } catch (\Exception $e) { $error = 'An error occurred during processing; checking has been aborted. The error message was: ' . $e->getMessage(); $file->addErrorOnLine($error, 1, 'Internal.Exception'); } //end try $this->reporter->cacheFileReport($file, $this->config); // Clean up the file to save (a lot of) memory. $file->cleanUp(); if ($this->config->interactive === true) { /* Running interactively. Print the error report for the current file and then wait for user input. */ // Get current violations and then clear the list to make sure // we only print violations for a single file each time. $numErrors = null; while ($numErrors !== 0) { $numErrors = $file->getErrorCount() + $file->getWarningCount(); if ($numErrors === 0) { continue; } $this->reporter->printReport('full'); echo '<ENTER> to recheck, [s] to skip or [q] to quit : '; $input = fgets(STDIN); $input = trim($input); switch ($input) { case 's': break 2; case 'q': exit(0); default: // Repopulate the sniffs because some of them save their state // and only clear it when the file changes, but we are rechecking // the same file. $file->ruleset->populateTokenListeners(); $file->reloadContent(); $file->process(); $this->reporter->cacheFileReport($file, $this->config); break; } } //end while } //end if }