+++ /dev/null
-<?php
-/**
- * PHP_CodeSniffer tokenises PHP code and detects violations of a
- * defined set of coding standards.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-spl_autoload_register(array('PHP_CodeSniffer', 'autoload'));
-
-if (class_exists('PHP_CodeSniffer_Exception', true) === false) {
- throw new Exception('Class PHP_CodeSniffer_Exception not found');
-}
-
-if (class_exists('PHP_CodeSniffer_File', true) === false) {
- throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_File not found');
-}
-
-if (class_exists('PHP_CodeSniffer_Tokens', true) === false) {
- throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Tokens not found');
-}
-
-if (interface_exists('PHP_CodeSniffer_Sniff', true) === false) {
- throw new PHP_CodeSniffer_Exception('Interface PHP_CodeSniffer_Sniff not found');
-}
-
-/**
- * PHP_CodeSniffer tokenises PHP code and detects violations of a
- * defined set of coding standards.
- *
- * Standards are specified by classes that implement the PHP_CodeSniffer_Sniff
- * interface. A sniff registers what token types it wishes to listen for, then
- * PHP_CodeSniffer encounters that token, the sniff is invoked and passed
- * information about where the token was found in the stack, and the token stack
- * itself.
- *
- * Sniff files and their containing class must be prefixed with Sniff, and
- * have an extension of .php.
- *
- * Multiple PHP_CodeSniffer operations can be performed by re-calling the
- * process function with different parameters.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer
-{
-
- /**
- * The file or directory that is currently being processed.
- *
- * @var string
- */
- protected $file = array();
-
- /**
- * The directory to search for sniffs in.
- *
- * @var string
- */
- protected $standardDir = '';
-
- /**
- * The files that have been processed.
- *
- * @var array(PHP_CodeSniffer_File)
- */
- protected $files = array();
-
- /**
- * The listeners array.
- *
- * @var array(PHP_CodeSniffer_Sniff)
- */
- protected $listeners = array();
-
- /**
- * An array of patterns to use for skipping files.
- *
- * @var array()
- */
- protected $ignorePatterns = array();
-
- /**
- * An array of extensions for files we will check.
- *
- * @var array
- */
- public $allowedFileExtensions = array(
- 'php' => 'PHP',
- 'inc' => 'PHP',
- 'js' => 'JS',
- );
-
- /**
- * An array of variable types for param/var we will check.
- *
- * @var array(string)
- */
- public static $allowedTypes = array(
- 'array',
- 'boolean',
- 'float',
- 'integer',
- 'mixed',
- 'object',
- 'string',
- );
-
-
- /**
- * Constructs a PHP_CodeSniffer object.
- *
- * @param int $verbosity The verbosity level.
- * 1: Print progress information.
- * 2: Print developer debug information.
- * @param int $tabWidth The number of spaces each tab represents.
- * If greater than zero, tabs will be replaced
- * by spaces before testing each file.
- *
- * @see process()
- */
- public function __construct($verbosity=0, $tabWidth=0)
- {
- define('PHP_CODESNIFFER_VERBOSITY', $verbosity);
- define('PHP_CODESNIFFER_TAB_WIDTH', $tabWidth);
-
- // Change into a directory that we know about to stop any
- // relative path conflicts.
- chdir(dirname(__FILE__).'/CodeSniffer/');
-
- }//end __construct()
-
-
- /**
- * Autoload static method for loading classes and interfaces.
- *
- * @param string $className The name of the class or interface.
- *
- * @return void
- */
- public static function autoload($className)
- {
- if (substr($className, 0, 4) === 'PHP_') {
- $newClassName = substr($className, 4);
- } else {
- $newClassName = $className;
- }
-
- $path = str_replace('_', '/', $newClassName).'.php';
-
- if (is_file(dirname(__FILE__).'/'.$path) === true) {
- // Check standard file locations based on class name.
- include dirname(__FILE__).'/'.$path;
- } else if (is_file(dirname(__FILE__).'/CodeSniffer/Standards/'.$path) === true) {
- // Check for included sniffs.
- include dirname(__FILE__).'/CodeSniffer/Standards/'.$path;
- } else {
- // Everything else.
- @include $path;
- }
-
- }//end autoload()
-
-
- /**
- * Sets an array of file extensions that we will allow checking of.
- *
- * If the extension is one of the defaults, a specific tokenizer
- * will be used. Otherwise, the PHP tokenizer will be used for
- * all extensions passed.
- *
- * @param array $extensions An array of file extensions.
- *
- * @return void
- */
- public function setAllowedFileExtensions(array $extensions)
- {
- $newExtensions = array();
- foreach ($extensions as $ext) {
- if (isset($this->allowedFileExtensions[$ext]) === true) {
- $newExtensions[$ext] = $this->allowedFileExtensions[$ext];
- } else {
- $newExtensions[$ext] = 'PHP';
- }
- }
-
- $this->allowedFileExtensions = $newExtensions;
-
- }//end setAllowedFileExtensions()
-
-
- /**
- * Sets an array of ignore patterns that we use to skip files and folders.
- *
- * Patterns are not case sensitive.
- *
- * @param array $patterns An array of ignore patterns.
- *
- * @return void
- */
- public function setIgnorePatterns(array $patterns)
- {
- $this->ignorePatterns = $patterns;
-
- }//end setIgnorePatterns()
-
-
- /**
- * Adds a file to the list of checked files.
- *
- * Checked files are used to generate error reports after the run.
- *
- * @param PHP_CodeSniffer_File $phpcsFile The file to add.
- *
- * @return void
- */
- public function addFile(PHP_CodeSniffer_File $phpcsFile)
- {
- $this->files[] = $phpcsFile;
-
- }//end addFile()
-
-
- /**
- * Processes the files/directories that PHP_CodeSniffer was constructed with.
- *
- * @param string|array $files The files and directories to process. For
- * directories, each sub directory will also
- * be traversed for source files.
- * @param string $standard The set of code sniffs we are testing
- * against.
- * @param array $sniffs The sniff names to restrict the allowed
- * listeners to.
- * @param boolean $local If true, don't recurse into directories.
- *
- * @return void
- * @throws PHP_CodeSniffer_Exception If files or standard are invalid.
- */
- public function process($files, $standard, array $sniffs=array(), $local=false)
- {
- if (is_array($files) === false) {
- if (is_string($files) === false || $files === null) {
- throw new PHP_CodeSniffer_Exception('$file must be a string');
- }
-
- $files = array($files);
- }
-
- if (is_string($standard) === false || $standard === null) {
- throw new PHP_CodeSniffer_Exception('$standard must be a string');
- }
-
- // Reset the members.
- $this->listeners = array();
- $this->files = array();
-
- if (PHP_CODESNIFFER_VERBOSITY > 0) {
- echo "Registering sniffs in $standard standard... ";
- if (PHP_CODESNIFFER_VERBOSITY > 2) {
- echo PHP_EOL;
- }
- }
-
- $this->setTokenListeners($standard, $sniffs);
- if (PHP_CODESNIFFER_VERBOSITY > 0) {
- $numSniffs = count($this->listeners);
- echo "DONE ($numSniffs sniffs registered)".PHP_EOL;
- }
-
- foreach ($files as $file) {
- $this->file = $file;
- if (is_dir($this->file) === true) {
- $this->processFiles($this->file, $local);
- } else {
- $this->processFile($this->file);
- }
- }
-
- }//end process()
-
-
- /**
- * Gets installed sniffs in the coding standard being used.
- *
- * Traverses the standard directory for classes that implement the
- * PHP_CodeSniffer_Sniff interface asks them to register. Each of the
- * sniff's class names must be exact as the basename of the sniff file.
- *
- * Returns an array of sniff class names.
- *
- * @param string $standard The name of the coding standard we are checking.
- * @param array $sniffs The sniff names to restrict the allowed
- * listeners to.
- *
- * @return array
- * @throws PHP_CodeSniffer_Exception If any of the tests failed in the
- * registration process.
- */
- public function getTokenListeners($standard, array $sniffs=array())
- {
- if (is_dir($standard) === true) {
- // This is a custom standard.
- $this->standardDir = $standard;
- $standard = basename($standard);
- } else {
- $this->standardDir = realpath(dirname(__FILE__).'/CodeSniffer/Standards/'.$standard);
- }
-
- $files = self::getSniffFiles($this->standardDir, $standard);
-
- if (empty($sniffs) === false) {
- // Convert the allowed sniffs to lower case so
- // they are easier to check.
- foreach ($sniffs as &$sniff) {
- $sniff = strtolower($sniff);
- }
- }
-
- $listeners = array();
-
- foreach ($files as $file) {
- // Work out where the position of /StandardName/Sniffs/... is
- // so we can determine what the class will be called.
- $sniffPos = strrpos($file, DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR);
- if ($sniffPos === false) {
- continue;
- }
-
- $slashPos = strrpos(substr($file, 0, $sniffPos), DIRECTORY_SEPARATOR);
- if ($slashPos === false) {
- continue;
- }
-
- $className = substr($file, ($slashPos + 1));
- $className = substr($className, 0, -4);
- $className = str_replace(DIRECTORY_SEPARATOR, '_', $className);
-
- include_once $file;
-
- // If they have specified a list of sniffs to restrict to, check
- // to see if this sniff is allowed.
- $allowed = in_array(strtolower($className), $sniffs);
- if (empty($sniffs) === false && $allowed === false) {
- continue;
- }
-
- $listeners[] = $className;
-
- if (PHP_CODESNIFFER_VERBOSITY > 2) {
- echo "\tRegistered $className".PHP_EOL;
- }
- }//end foreach
-
- return $listeners;
-
- }//end getTokenListeners()
-
-
- /**
- * Sets installed sniffs in the coding standard being used.
- *
- * @param string $standard The name of the coding standard we are checking.
- * @param array $sniffs The sniff names to restrict the allowed
- * listeners to.
- *
- * @return null
- */
- public function setTokenListeners($standard, array $sniffs=array())
- {
- $this->listeners = $this->getTokenListeners($standard, $sniffs);
-
- }//end setTokenListeners
-
-
- /**
- * Return a list of sniffs that a coding standard has defined.
- *
- * Sniffs are found by recursing the standard directory and also by
- * asking the standard for included sniffs.
- *
- * @param string $dir The directory where to look for the files.
- * @param string $standard The name of the coding standard. If NULL, no
- * included sniffs will be checked for.
- *
- * @return array
- * @throws PHP_CodeSniffer_Exception If an included or excluded sniff does
- * not exist.
- */
- public static function getSniffFiles($dir, $standard=null)
- {
- $di = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
-
- $ownSniffs = array();
- $includedSniffs = array();
- $excludedSniffs = array();
-
- foreach ($di as $file) {
- // Skip hidden files.
- if (substr($file->getFilename(), 0, 1) === '.') {
- continue;
- }
-
- // We are only interested in PHP and sniff files.
- $fileParts = explode('.', $file);
- if (array_pop($fileParts) !== 'php') {
- continue;
- }
-
- $basename = basename($file, '.php');
- if (substr($basename, -5) !== 'Sniff') {
- continue;
- }
-
- $ownSniffs[] = $file->getPathname();
- }//end foreach
-
- // Load the standard class and ask it for a list of external
- // sniffs to include in the standard.
- if ($standard !== null && is_file("$dir/{$standard}CodingStandard.php") === true) {
- include_once "$dir/{$standard}CodingStandard.php";
- $standardClassName = "PHP_CodeSniffer_Standards_{$standard}_{$standard}CodingStandard";
- $standardClass = new $standardClassName;
-
- $included = $standardClass->getIncludedSniffs();
- foreach ($included as $sniff) {
- if (is_dir($sniff) === true) {
- // Trying to include from a custom standard.
- $sniffDir = $sniff;
- $sniff = basename($sniff);
- } else if (is_file($sniff) === true) {
- // Trying to include a custom sniff.
- $sniffDir = $sniff;
- } else {
- $sniffDir = realpath(dirname(__FILE__)."/CodeSniffer/Standards/$sniff");
- if ($sniffDir === false) {
- throw new PHP_CodeSniffer_Exception("Included sniff $sniff does not exist");
- }
- }
-
- if (is_dir($sniffDir) === true) {
- if (self::isInstalledStandard($sniff) === true) {
- // We are including a whole coding standard.
- $includedSniffs = array_merge($includedSniffs, self::getSniffFiles($sniffDir, $sniff));
- } else {
- // We are including a whole directory of sniffs.
- $includedSniffs = array_merge($includedSniffs, self::getSniffFiles($sniffDir));
- }
- } else {
- if (substr($sniffDir, -9) !== 'Sniff.php') {
- throw new PHP_CodeSniffer_Exception("Included sniff $sniff does not exist");
- }
-
- $includedSniffs[] = $sniffDir;
- }
- }//end foreach
-
- $excluded = $standardClass->getExcludedSniffs();
- foreach ($excluded as $sniff) {
- if (is_dir($sniff) === true) {
- // Trying to exclude from a custom standard.
- $sniffDir = $sniff;
- $sniff = basename($sniff);
- } else if (is_file($sniff) === true) {
- // Trying to exclude a custom sniff.
- $sniffDir = $sniff;
- } else {
- $sniffDir = realpath(dirname(__FILE__)."/CodeSniffer/Standards/$sniff");
- if ($sniffDir === false) {
- throw new PHP_CodeSniffer_Exception("Excluded sniff $sniff does not exist");
- }
- }
-
- if (is_dir($sniffDir) === true) {
- if (self::isInstalledStandard($sniff) === true) {
- // We are excluding a whole coding standard.
- $excludedSniffs = array_merge($excludedSniffs, self::getSniffFiles($sniffDir, $sniff));
- } else {
- // We are excluding a whole directory of sniffs.
- $excludedSniffs = array_merge($excludedSniffs, self::getSniffFiles($sniffDir));
- }
- } else {
- if (substr($sniffDir, -9) !== 'Sniff.php') {
- throw new PHP_CodeSniffer_Exception("Excluded sniff $sniff does not exist");
- }
-
- $excludedSniffs[] = $sniffDir;
- }
- }//end foreach
- }//end if
-
- // Merge our own sniff list with our exnternally included
- // sniff list, but filter out any excluded sniffs.
- $files = array();
- foreach (array_merge($ownSniffs, $includedSniffs) as $sniff) {
- if (in_array($sniff, $excludedSniffs) === true) {
- continue;
- } else {
- $files[] = $sniff;
- }
- }
-
- return $files;
-
- }//end getSniffFiles()
-
-
- /**
- * Run the code sniffs over each file in a given directory.
- *
- * Recusively reads the specified directory and performs the PHP_CodeSniffer
- * sniffs on each source file found within the directories.
- *
- * @param string $dir The directory to process.
- * @param boolean $local If true, only process files in this directory, not
- * sub directories.
- *
- * @return void
- * @throws Exception If there was an error opening the directory.
- */
- public function processFiles($dir, $local=false)
- {
- try {
- if ($local === true) {
- $di = new DirectoryIterator($dir);
- } else {
- $di = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
- }
-
- foreach ($di as $file) {
- $filePath = realpath($file->getPathname());
-
- if (is_dir($filePath) === true) {
- continue;
- }
-
- // Check that the file's extension is one we are checking.
- // Note that because we are doing a whole directory, we
- // are strick about checking the extension and we don't
- // let files with no extension through.
- $fileParts = explode('.', $file);
- $extension = array_pop($fileParts);
- if ($extension === $file) {
- continue;
- }
-
- if (isset($this->allowedFileExtensions[$extension]) === false) {
- continue;
- }
-
- $this->processFile($filePath);
- }//end foreach
- } catch (Exception $e) {
- $trace = $e->getTrace();
- $filename = $trace[0]['args'][0];
- $error = 'An error occurred during processing; checking has been aborted. The error message was: '.$e->getMessage();
-
- $phpcsFile = new PHP_CodeSniffer_File($filename, $this->listeners, $this->allowedFileExtensions);
- $this->addFile($phpcsFile);
- $phpcsFile->addError($error, null);
- return;
- }
-
- }//end processFiles()
-
-
- /**
- * Run the code sniffs over a single given file.
- *
- * Processes the file and runs the PHP_CodeSniffer sniffs to verify that it
- * conforms with the standard.
- *
- * @param string $file The file to process.
- * @param string $contents The contents to parse. If NULL, the content
- * is taken from the file system.
- *
- * @return void
- * @throws PHP_CodeSniffer_Exception If the file could not be processed.
- */
- public function processFile($file, $contents=null)
- {
- if (is_null($contents) === true && file_exists($file) === false) {
- throw new PHP_CodeSniffer_Exception("Source file $file does not exist");
- }
-
- // If the file's path matches one of our ignore patterns, skip it.
- foreach ($this->ignorePatterns as $pattern) {
- $replacements = array(
- '\\,' => ',',
- '*' => '.*',
- );
-
- $pattern = strtr($pattern, $replacements);
- if (preg_match("|{$pattern}|i", $file) === 1) {
- return;
- }
- }
-
- if (PHP_CODESNIFFER_VERBOSITY > 0) {
- $startTime = time();
- echo 'Processing '.basename($file).' ';
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo PHP_EOL;
- }
- }
-
- $phpcsFile = new PHP_CodeSniffer_File($file, $this->listeners, $this->allowedFileExtensions);
- $this->addFile($phpcsFile);
- $phpcsFile->start($contents);
-
- if (PHP_CODESNIFFER_VERBOSITY > 0) {
- $timeTaken = (time() - $startTime);
- if ($timeTaken === 0) {
- echo 'DONE in < 1 second';
- } else if ($timeTaken === 1) {
- echo 'DONE in 1 second';
- } else {
- echo "DONE in $timeTaken seconds";
- }
-
- $errors = $phpcsFile->getErrorCount();
- $warnings = $phpcsFile->getWarningCount();
- echo " ($errors errors, $warnings warnings)".PHP_EOL;
- }
-
- }//end processFile()
-
-
- /**
- * Pre-process and package errors and warnings for all files.
- *
- * Used by error reports to get a packaged list of all errors and
- * warnings in each file.
- *
- * @param boolean $showWarnings Show warnings as well as errors.
- *
- * @return array
- */
- public function prepareErrorReport($showWarnings=true)
- {
- $report = array(
- 'totals' => array(
- 'warnings' => 0,
- 'errors' => 0,
- ),
- 'files' => array(),
- );
-
- foreach ($this->files as $file) {
- $warnings = $file->getWarnings();
- $errors = $file->getErrors();
- $numWarnings = $file->getWarningCount();
- $numErrors = $file->getErrorCount();
- $filename = $file->getFilename();
-
- $report['files'][$filename] = array(
- 'errors' => 0,
- 'warnings' => 0,
- 'messages' => array(),
- );
-
- if ($numErrors === 0 && $numWarnings === 0) {
- // Prefect score!
- continue;
- }
-
- if ($numErrors === 0 && $showWarnings === false) {
- // Prefect score (sort of).
- continue;
- }
-
- $report['files'][$filename]['errors'] = $numErrors;
- if ($showWarnings === true) {
- $report['files'][$filename]['warnings'] = $numWarnings;
- } else {
- $report['files'][$filename]['warnings'] = 0;
- }
-
- $report['totals']['errors'] += $numErrors;
- if ($showWarnings === true) {
- $report['totals']['warnings'] += $numWarnings;
- }
-
- // Merge errors and warnings.
- foreach ($errors as $line => $lineErrors) {
- foreach ($lineErrors as $column => $colErrors) {
- $newErrors = array();
- foreach ($colErrors as $message) {
- $newErrors[] = array(
- 'message' => $message,
- 'type' => 'ERROR',
- );
- }
-
- $errors[$line][$column] = $newErrors;
- }
- }//end foreach
-
- if ($showWarnings === true) {
- foreach ($warnings as $line => $lineWarnings) {
- foreach ($lineWarnings as $column => $colWarnings) {
- $newWarnings = array();
- foreach ($colWarnings as $message) {
- $newWarnings[] = array(
- 'message' => $message,
- 'type' => 'WARNING',
- );
- }
-
- if (isset($errors[$line]) === false) {
- $errors[$line] = array();
- }
-
- if (isset($errors[$line][$column]) === true) {
- $errors[$line][$column] = array_merge($newWarnings, $errors[$line][$column]);
- } else {
- $errors[$line][$column] = $newWarnings;
- }
- }
- }//end foreach
- }//end if
-
- ksort($errors);
-
- $report['files'][$filename]['messages'] = $errors;
-
- }//end foreach
-
- return $report;
-
- }//end prepareErrorReport()
-
-
- /**
- * Prints all errors and warnings for each file processed, in an XML format.
- *
- * Errors and warnings are displayed together, grouped by file.
- *
- * @param boolean $showWarnings Show warnings as well as errors.
- *
- * @return int The number of error and warning messages shown.
- */
- public function printXMLErrorReport($showWarnings=true)
- {
- echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;
- echo '<phpcs version="1.1.0">'.PHP_EOL;
-
- $errorsShown = 0;
-
- $report = $this->prepareErrorReport($showWarnings);
- foreach ($report['files'] as $filename => $file) {
- if (empty($file['messages']) === true) {
- continue;
- }
-
- echo ' <file name="'.$filename.'" errors="'.$file['errors'].'" warnings="'.$file['warnings'].'">'.PHP_EOL;
-
- foreach ($file['messages'] as $line => $lineErrors) {
- foreach ($lineErrors as $column => $colErrors) {
- foreach ($colErrors as $error) {
- $error['type'] = strtolower($error['type']);
- echo ' <'.$error['type'].' line="'.$line.'" column="'.$column.'">';
- echo htmlspecialchars($error['message']).'</'.$error['type'].'>'.PHP_EOL;
- $errorsShown++;
- }
- }
- }//end foreach
-
- echo ' </file>'.PHP_EOL;
-
- }//end foreach
-
- echo '</phpcs>'.PHP_EOL;
-
- return $errorsShown;
-
- }//end printXMLErrorReport()
-
-
- /**
- * Prints all errors and warnings for each file processed, in a Checkstyle XML format.
- *
- * Errors and warnings are displayed together, grouped by file.
- *
- * @param boolean $showWarnings Show warnings as well as errors.
- *
- * @return int The number of error and warning messages shown.
- */
- public function printCheckstyleErrorReport($showWarnings=true)
- {
- echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;
- echo '<checkstyle version="1.1.0">'.PHP_EOL;
-
- $errorsShown = 0;
-
- $report = $this->prepareErrorReport($showWarnings);
- foreach ($report['files'] as $filename => $file) {
- echo ' <file name="'.$filename.'">'.PHP_EOL;
-
- foreach ($file['messages'] as $line => $lineErrors) {
- foreach ($lineErrors as $column => $colErrors) {
- foreach ($colErrors as $error) {
- $error['type'] = strtolower($error['type']);
- echo ' <error';
- echo ' line="'.$line.'" column="'.$column.'"';
- echo ' severity="'.$error['type'].'"';
- $message = utf8_encode(htmlspecialchars($error['message']));
- echo ' message="'.$message.'"';
- echo '/>'.PHP_EOL;
- $errorsShown++;
- }
- }
- }//end foreach
-
- echo ' </file>'.PHP_EOL;
-
- }//end foreach
-
- echo '</checkstyle>'.PHP_EOL;
-
- return $errorsShown;
-
- }//end printCheckstyleErrorReport()
-
-
- /**
- * Prints all errors and warnings for each file processed, in a CSV format.
- *
- * @param boolean $showWarnings Show warnings as well as errors.
- *
- * @return int The number of error and warning messages shown.
- */
- public function printCSVErrorReport($showWarnings=true)
- {
- echo 'File,Line,Column,Severity,Message'.PHP_EOL;
-
- $errorsShown = 0;
-
- $report = $this->prepareErrorReport($showWarnings);
- foreach ($report['files'] as $filename => $file) {
- foreach ($file['messages'] as $line => $lineErrors) {
- foreach ($lineErrors as $column => $colErrors) {
- foreach ($colErrors as $error) {
- $filename = str_replace('"', '\"', $filename);
- $message = str_replace('"', '\"', $error['message']);
- $type = strtolower($error['type']);
- echo "\"$filename\",$line,$column,$type,\"$message\"".PHP_EOL;
- $errorsShown++;
- }
- }
- }//end foreach
- }//end foreach
-
- return $errorsShown;
-
- }//end printCSVErrorReport()
-
-
- /**
- * Prints all errors and warnings for each file processed.
- *
- * Errors and warnings are displayed together, grouped by file.
- *
- * @param boolean $showWarnings Show warnings as well as errors.
- *
- * @return int The number of error and warning messages shown.
- */
- public function printErrorReport($showWarnings=true)
- {
- $errorsShown = 0;
-
- $report = $this->prepareErrorReport($showWarnings);
- foreach ($report['files'] as $filename => $file) {
- if (empty($file['messages']) === true) {
- continue;
- }
-
- echo PHP_EOL.'FILE: ';
- if (strlen($filename) <= 71) {
- echo $filename;
- } else {
- echo '...'.substr($filename, (strlen($filename) - 71));
- }
-
- echo PHP_EOL;
- echo str_repeat('-', 80).PHP_EOL;
-
- echo 'FOUND '.$file['errors'].' ERROR(S) ';
-
- if ($showWarnings === true) {
- echo 'AND '.$file['warnings'].' WARNING(S) ';
- }
-
- echo 'AFFECTING '.count($file['messages']).' LINE(S)'.PHP_EOL;
- echo str_repeat('-', 80).PHP_EOL;
-
- // Work out the max line number for formatting.
- $maxLine = 0;
- foreach ($file['messages'] as $line => $lineErrors) {
- if ($line > $maxLine) {
- $maxLine = $line;
- }
- }
-
- $maxLineLength = strlen($maxLine);
-
- // The length of the word ERROR or WARNING; used for padding.
- if ($showWarnings === true && $file['warnings'] > 0) {
- $typeLength = 7;
- } else {
- $typeLength = 5;
- }
-
- // The padding that all lines will require that are
- // printing an error message overflow.
- $paddingLine2 = str_repeat(' ', ($maxLineLength + 1));
- $paddingLine2 .= ' | ';
- $paddingLine2 .= str_repeat(' ', $typeLength);
- $paddingLine2 .= ' | ';
-
- // The maxium amount of space an error message can use.
- $maxErrorSpace = (80 - strlen($paddingLine2));
-
- foreach ($file['messages'] as $line => $lineErrors) {
- foreach ($lineErrors as $column => $colErrors) {
- foreach ($colErrors as $error) {
- // The padding that goes on the front of the line.
- $padding = ($maxLineLength - strlen($line));
- $errorMsg = wordwrap($error['message'], $maxErrorSpace, PHP_EOL."$paddingLine2");
-
- echo ' '.str_repeat(' ', $padding).$line.' | '.$error['type'];
- if ($error['type'] === 'ERROR') {
- if ($showWarnings === true && $file['warnings'] > 0) {
- echo ' ';
- }
- }
-
- echo ' | '.$errorMsg.PHP_EOL;
- $errorsShown++;
- }//end foreach
- }//end foreach
- }//end foreach
-
- echo str_repeat('-', 80).PHP_EOL.PHP_EOL;
-
- }//end foreach
-
- return $errorsShown;
-
- }//end printErrorReport()
-
-
- /**
- * Prints a summary of errors and warnings for each file processed.
- *
- * If verbose output is enabled, results are shown for all files, even if
- * they have no errors or warnings. If verbose output is disabled, we only
- * show files that have at least one warning or error.
- *
- * @param boolean $showWarnings Show warnings as well as errors.
- *
- * @return int The number of error and warning messages shown.
- */
- public function printErrorReportSummary($showWarnings=true)
- {
- $errorFiles = array();
-
- foreach ($this->files as $file) {
- $numWarnings = $file->getWarningCount();
- $numErrors = $file->getErrorCount();
- $filename = $file->getFilename();
-
- // If verbose output is enabled, we show the results for all files,
- // but if not, we only show files that had errors or warnings.
- if (PHP_CODESNIFFER_VERBOSITY > 0 || $numErrors > 0 || ($numWarnings > 0 && $showWarnings === true)) {
- $errorFiles[$filename] = array(
- 'warnings' => $numWarnings,
- 'errors' => $numErrors,
- );
- }
- }
-
- if (empty($errorFiles) === true) {
- // Nothing to print.
- return 0;
- }
-
- echo PHP_EOL.'PHP CODE SNIFFER REPORT SUMMARY'.PHP_EOL;
- echo str_repeat('-', 80).PHP_EOL;
- if ($showWarnings === true) {
- echo 'FILE'.str_repeat(' ', 60).'ERRORS WARNINGS'.PHP_EOL;
- } else {
- echo 'FILE'.str_repeat(' ', 70).'ERRORS'.PHP_EOL;
- }
-
- echo str_repeat('-', 80).PHP_EOL;
-
- $totalErrors = 0;
- $totalWarnings = 0;
- $totalFiles = 0;
-
- foreach ($errorFiles as $file => $errors) {
- if ($showWarnings === true) {
- $padding = (62 - strlen($file));
- } else {
- $padding = (72 - strlen($file));
- }
-
- if ($padding < 0) {
- $file = '...'.substr($file, (($padding * -1) + 3));
- $padding = 0;
- }
-
- echo $file.str_repeat(' ', $padding).' ';
- echo $errors['errors'];
- if ($showWarnings === true) {
- echo str_repeat(' ', (8 - strlen((string) $errors['errors'])));
- echo $errors['warnings'];
- }
-
- echo PHP_EOL;
-
- $totalErrors += $errors['errors'];
- $totalWarnings += $errors['warnings'];
- $totalFiles++;
- }//end foreach
-
- echo str_repeat('-', 80).PHP_EOL;
- echo "A TOTAL OF $totalErrors ERROR(S) ";
- if ($showWarnings === true) {
- echo "AND $totalWarnings WARNING(S) ";
- }
-
- echo "WERE FOUND IN $totalFiles FILE(S)".PHP_EOL;
- echo str_repeat('-', 80).PHP_EOL.PHP_EOL;
-
- return ($totalErrors + $totalWarnings);
-
- }//end printErrorReportSummary()
-
-
- /**
- * Generates documentation for a coding standard.
- *
- * @param string $standard The standard to generate docs for
- * @param array $sniffs A list of sniffs to limit the docs to.
- * @param string $generator The name of the generator class to use.
- *
- * @return void
- */
- public function generateDocs($standard, array $sniffs=array(), $generator='Text')
- {
- include_once 'PHP/CodeSniffer/DocGenerators/'.$generator.'.php';
-
- $class = "PHP_CodeSniffer_DocGenerators_$generator";
- $generator = new $class($standard, $sniffs);
-
- $generator->generate();
-
- }//end generateDocs()
-
-
- /**
- * Returns the PHP_CodeSniffer file objects.
- *
- * @return array(PHP_CodeSniffer_File)
- */
- public function getFiles()
- {
- return $this->files;
-
- }//end getFiles()
-
-
- /**
- * Gets the array of PHP_CodeSniffer_Sniff's.
- *
- * @return array(PHP_CodeSniffer_Sniff)
- */
- public function getSniffs()
- {
- return $this->listeners;
-
- }//end getSniffs()
-
-
- /**
- * Takes a token produced from <code>token_get_all()</code> and produces a
- * more uniform token.
- *
- * Note that this method also resolves T_STRING tokens into more descrete
- * types, therefore there is no need to call resolveTstringToken()
- *
- * @param string|array $token The token to convert.
- *
- * @return array The new token.
- */
- public static function standardiseToken($token)
- {
- if (is_array($token) === false) {
- $newToken = self::resolveSimpleToken($token);
- } else {
- // Some T_STRING tokens can be more specific.
- if ($token[0] === T_STRING) {
- $newToken = self::resolveTstringToken($token);
- } else {
- $newToken = array();
- $newToken['code'] = $token[0];
- $newToken['content'] = $token[1];
- $newToken['type'] = token_name($token[0]);
- }
- }
-
- return $newToken;
-
- }//end standardiseToken()
-
-
- /**
- * Converts T_STRING tokens into more usable token names.
- *
- * The token should be produced using the token_get_all() function.
- * Currently, not all T_STRING tokens are converted.
- *
- * @param string|array $token The T_STRING token to convert as constructed
- * by token_get_all().
- *
- * @return array The new token.
- */
- public static function resolveTstringToken(array $token)
- {
- $newToken = array();
- switch (strtolower($token[1])) {
- case 'false':
- $newToken['type'] = 'T_FALSE';
- break;
- case 'true':
- $newToken['type'] = 'T_TRUE';
- break;
- case 'null':
- $newToken['type'] = 'T_NULL';
- break;
- case 'self':
- $newToken['type'] = 'T_SELF';
- break;
- case 'parent':
- $newToken['type'] = 'T_PARENT';
- break;
- default:
- $newToken['type'] = 'T_STRING';
- break;
- }
-
- $newToken['code'] = constant($newToken['type']);
- $newToken['content'] = $token[1];
-
- return $newToken;
-
- }//end resolveTstringToken()
-
-
- /**
- * Converts simple tokens into a format that conforms to complex tokens
- * produced by token_get_all().
- *
- * Simple tokens are tokens that are not in array form when produced from
- * token_get_all().
- *
- * @param string $token The simple token to convert.
- *
- * @return array The new token in array format.
- */
- public static function resolveSimpleToken($token)
- {
- $newToken = array();
-
- switch ($token) {
- case '{':
- $newToken['type'] = 'T_OPEN_CURLY_BRACKET';
- break;
- case '}':
- $newToken['type'] = 'T_CLOSE_CURLY_BRACKET';
- break;
- case '[':
- $newToken['type'] = 'T_OPEN_SQUARE_BRACKET';
- break;
- case ']':
- $newToken['type'] = 'T_CLOSE_SQUARE_BRACKET';
- break;
- case '(':
- $newToken['type'] = 'T_OPEN_PARENTHESIS';
- break;
- case ')':
- $newToken['type'] = 'T_CLOSE_PARENTHESIS';
- break;
- case ':':
- $newToken['type'] = 'T_COLON';
- break;
- case '.':
- $newToken['type'] = 'T_STRING_CONCAT';
- break;
- case '?':
- $newToken['type'] = 'T_INLINE_THEN';
- break;
- case ';':
- $newToken['type'] = 'T_SEMICOLON';
- break;
- case '=':
- $newToken['type'] = 'T_EQUAL';
- break;
- case '*':
- $newToken['type'] = 'T_MULTIPLY';
- break;
- case '/':
- $newToken['type'] = 'T_DIVIDE';
- break;
- case '+':
- $newToken['type'] = 'T_PLUS';
- break;
- case '-':
- $newToken['type'] = 'T_MINUS';
- break;
- case '%':
- $newToken['type'] = 'T_MODULUS';
- break;
- case '^':
- $newToken['type'] = 'T_POWER';
- break;
- case '&':
- $newToken['type'] = 'T_BITWISE_AND';
- break;
- case '|':
- $newToken['type'] = 'T_BITWISE_OR';
- break;
- case '<':
- $newToken['type'] = 'T_LESS_THAN';
- break;
- case '>':
- $newToken['type'] = 'T_GREATER_THAN';
- break;
- case '!':
- $newToken['type'] = 'T_BOOLEAN_NOT';
- break;
- case ',':
- $newToken['type'] = 'T_COMMA';
- break;
- default:
- $newToken['type'] = 'T_NONE';
- break;
-
- }//end switch
-
- $newToken['code'] = constant($newToken['type']);
- $newToken['content'] = $token;
-
- return $newToken;
-
- }//end resolveSimpleToken()
-
-
- /**
- * Returns true if the specified string is in the camel caps format.
- *
- * @param string $string The string the verify.
- * @param boolean $classFormat If true, check to see if the string is in the
- * class format. Class format strings must start
- * with a capital letter and contain no
- * underscores.
- * @param boolean $public If true, the first character in the string
- * must be an a-z character. If false, the
- * character must be an underscore. This
- * argument is only applicable if $classFormat
- * is false.
- * @param boolean $strict If true, the string must not have two captial
- * letters next to each other. If false, a
- * relaxed camel caps policy is used to allow
- * for acronyms.
- *
- * @return boolean
- */
- public static function isCamelCaps($string, $classFormat=false, $public=true, $strict=true)
- {
- // Check the first character first.
- if ($classFormat === false) {
- if ($public === false) {
- $legalFirstChar = '[_][a-z]';
- } else {
- $legalFirstChar = '[a-z]';
- }
- } else {
- $legalFirstChar = '[A-Z]';
- }
-
- if (preg_match("|^$legalFirstChar|", $string) === 0) {
- return false;
- }
-
- // Check that the name only contains legal characters.
- if ($classFormat === false) {
- $legalChars = 'a-zA-Z0-9';
- } else {
- $legalChars = 'a-zA-Z';
- }
-
- if (preg_match("|[^$legalChars]|", substr($string, 1)) > 0) {
- return false;
- }
-
- if ($strict === true) {
- // Check that there are not two captial letters next to each other.
- $length = strlen($string);
- $lastCharWasCaps = $classFormat;
-
- for ($i = 1; $i < $length; $i++) {
- $ascii = ord($string{$i});
- if ($ascii >= 48 && $ascii <= 57) {
- // The character is a number, so it cant be a captial.
- $isCaps = false;
- } else {
- if (strtoupper($string{$i}) === $string{$i}) {
- $isCaps = true;
- } else {
- $isCaps = false;
- }
- }
-
- if ($isCaps === true && $lastCharWasCaps === true) {
- return false;
- }
-
- $lastCharWasCaps = $isCaps;
- }
- }//end if
-
- return true;
-
- }//end isCamelCaps()
-
-
- /**
- * Returns true if the specified string is in the underscore caps format.
- *
- * @param string $string The string to verify.
- *
- * @return boolean
- */
- public static function isUnderscoreName($string)
- {
- // If there are space in the name, it can't be valid.
- if (strpos($string, ' ') !== false) {
- return false;
- }
-
- $validName = true;
- $nameBits = explode('_', $string);
-
- if (preg_match('|^[A-Z]|', $string) === 0) {
- // Name does not begin with a capital letter.
- $validName = false;
- } else {
- foreach ($nameBits as $bit) {
- if ($bit{0} !== strtoupper($bit{0})) {
- $validName = false;
- break;
- }
- }
- }
-
- return $validName;
-
- }//end isUnderscoreName()
-
-
- /**
- * Returns a valid variable type for param/var tag.
- *
- * If type is not one of the standard type, it must be a custom type.
- * Returns the correct type name suggestion if type name is invalid.
- *
- * @param string $varType The variable type to process.
- *
- * @return string
- */
- public static function suggestType($varType)
- {
- if ($varType === '') {
- return '';
- }
-
- if (in_array($varType, self::$allowedTypes) === true) {
- return $varType;
- } else {
- $lowerVarType = strtolower($varType);
- switch ($lowerVarType) {
- case 'bool':
- return 'boolean';
- case 'double':
- case 'real':
- return 'float';
- case 'int':
- return 'integer';
- case 'array()':
- return 'array';
- }//end switch
-
- if (strpos($lowerVarType, 'array(') !== false) {
- // Valid array declaration:
- // array, array(type), array(type1 => type2).
- $matches = array();
- $pattern = '/^array\(\s*([^\s^=^>]*)(\s*=>\s*(.*))?\s*\)/i';
- if (preg_match($pattern, $varType, $matches) !== 0) {
- $type1 = '';
- if (isset($matches[1]) === true) {
- $type1 = $matches[1];
- }
-
- $type2 = '';
- if (isset($matches[3]) === true) {
- $type2 = $matches[3];
- }
-
- $type1 = self::suggestType($type1);
- $type2 = self::suggestType($type2);
- if ($type2 !== '') {
- $type2 = ' => '.$type2;
- }
-
- return "array($type1$type2)";
- } else {
- return 'array';
- }//end if
- } else if (in_array($lowerVarType, self::$allowedTypes) === true) {
- // A valid type, but not lower cased.
- return $lowerVarType;
- } else {
- // Must be a custom type name.
- return $varType;
- }//end if
- }//end if
-
- }//end suggestType()
-
-
- /**
- * Get a list of all coding standards installed.
- *
- * Coding standards are directories located in the
- * CodeSniffer/Standards directory. Valid coding standards
- * include a Sniffs subdirectory.
- *
- * @param boolean $includeGeneric If true, the special "Generic"
- * coding standard will be included
- * if installed.
- * @param string $standardsDir A specific directory to look for standards
- * in. If not specified, PHP_CodeSniffer will
- * look in its default location.
- *
- * @return array
- * @see isInstalledStandard()
- */
- public static function getInstalledStandards($includeGeneric=false, $standardsDir='')
- {
- $installedStandards = array();
-
- if ($standardsDir === '') {
- $standardsDir = dirname(__FILE__).'/CodeSniffer/Standards';
- }
-
- $di = new DirectoryIterator($standardsDir);
- foreach ($di as $file) {
- if ($file->isDir() === true && $file->isDot() === false) {
- $filename = $file->getFilename();
-
- // Ignore the special "Generic" standard.
- if ($includeGeneric === false && $filename === 'Generic') {
- continue;
- }
-
- // Valid coding standard dirs include a standard class.
- $csFile = $file->getPathname()."/{$filename}CodingStandard.php";
- if (is_file($csFile) === true) {
- // We found a coding standard directory.
- $installedStandards[] = $filename;
- }
- }
- }
-
- return $installedStandards;
-
- }//end getInstalledStandards()
-
-
- /**
- * Determine if a standard is installed.
- *
- * Coding standards are directories located in the
- * CodeSniffer/Standards directory. Valid coding standards
- * include a Sniffs subdirectory.
- *
- * @param string $standard The name of the coding standard.
- *
- * @return boolean
- * @see getInstalledStandards()
- */
- public static function isInstalledStandard($standard)
- {
- $standardDir = dirname(__FILE__);
- $standardDir .= '/CodeSniffer/Standards/'.$standard;
- if (is_file("$standardDir/{$standard}CodingStandard.php") === true) {
- return true;
- } else {
- // This could be a custom standard, installed outside our
- // standards directory.
- $standardFile = rtrim($standard, ' /\\').DIRECTORY_SEPARATOR.basename($standard).'CodingStandard.php';
- return (is_file($standardFile) === true);
- }
-
- }//end isInstalledStandard()
-
-
- /**
- * Get a single config value.
- *
- * Config data is stored in the data dir, in a file called
- * CodeSniffer.conf. It is a simple PHP array.
- *
- * @param string $key The name of the config value.
- *
- * @return string
- * @see setConfigData()
- * @see getAllConfigData()
- */
- public static function getConfigData($key)
- {
- $phpCodeSnifferConfig = self::getAllConfigData();
-
- if ($phpCodeSnifferConfig === null) {
- return null;
- }
-
- if (isset($phpCodeSnifferConfig[$key]) === false) {
- return null;
- }
-
- return $phpCodeSnifferConfig[$key];
-
- }//end getConfigData()
-
-
- /**
- * Set a single config value.
- *
- * Config data is stored in the data dir, in a file called
- * CodeSniffer.conf. It is a simple PHP array.
- *
- * @param string $key The name of the config value.
- * @param string|null $value The value to set. If null, the config
- * entry is deleted, reverting it to the
- * default value.
- * @param boolean $temp Set this config data temporarily for this
- * script run. This will not write the config
- * data to the config file.
- *
- * @return boolean
- * @see getConfigData()
- * @throws PHP_CodeSniffer_Exception If the config file can not be written.
- */
- public static function setConfigData($key, $value, $temp=false)
- {
- if ($temp === false) {
- $configFile = dirname(__FILE__).'/CodeSniffer.conf';
- if (is_file($configFile) === false) {
- $configFile = '/usr/lib/php/data/PHP_CodeSniffer/CodeSniffer.conf';
- }
-
- if (is_file($configFile) === true && is_writable($configFile) === false) {
- $error = "Config file $configFile is not writable";
- throw new PHP_CodeSniffer_Exception($error);
- }
- }
-
- $phpCodeSnifferConfig = self::getAllConfigData();
-
- if ($value === null) {
- if (isset($phpCodeSnifferConfig[$key]) === true) {
- unset($phpCodeSnifferConfig[$key]);
- }
- } else {
- $phpCodeSnifferConfig[$key] = $value;
- }
-
- if ($temp === false) {
- $output = '<'.'?php'."\n".' $phpCodeSnifferConfig = ';
- $output .= var_export($phpCodeSnifferConfig, true);
- $output .= "\n?".'>';
-
- if (file_put_contents($configFile, $output) === false) {
- return false;
- }
- }
-
- $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'] = $phpCodeSnifferConfig;
-
- return true;
-
- }//end setConfigData()
-
-
- /**
- * Get all config data in an array.
- *
- * @return string
- * @see getConfigData()
- */
- public static function getAllConfigData()
- {
- if (isset($GLOBALS['PHP_CODESNIFFER_CONFIG_DATA']) === true) {
- return $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'];
- }
-
- $configFile = dirname(__FILE__).'/CodeSniffer.conf';
- if (is_file($configFile) === false) {
- $configFile = '/usr/lib/php/data/PHP_CodeSniffer/CodeSniffer.conf';
- }
-
- if (is_file($configFile) === false) {
- return null;
- }
-
- include $configFile;
- $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'] = $phpCodeSnifferConfig;
- return $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'];
-
- }//end getAllConfigData()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * A class to process command line phpcs scripts.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (is_file(dirname(__FILE__).'/../CodeSniffer.php') === true) {
- include_once dirname(__FILE__).'/../CodeSniffer.php';
-} else {
- include_once 'PHP/CodeSniffer.php';
-}
-
-/**
- * A class to process command line phpcs scripts.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_CLI
-{
-
-
- /**
- * Exits if the minimum requirements of PHP_CodSniffer are not met.
- *
- * @return array
- */
- public function checkRequirements()
- {
- // Check the PHP version.
- if (version_compare(PHP_VERSION, '5.1.2') === -1) {
- echo 'ERROR: PHP_CodeSniffer requires PHP version 5.1.2 or greater.'.PHP_EOL;
- exit(2);
- }
-
- if (extension_loaded('tokenizer') === false) {
- echo 'ERROR: PHP_CodeSniffer requires the tokenizer extension to be enabled.'.PHP_EOL;
- exit(2);
- }
-
- }//end checkRequirements()
-
-
- /**
- * Get a list of default values for all possible command line arguments.
- *
- * @return array
- */
- public function getDefaults()
- {
- // The default values for config settings.
- $defaults['files'] = array();
- $defaults['standard'] = null;
- $defaults['verbosity'] = 0;
- $defaults['local'] = false;
- $defaults['extensions'] = array();
- $defaults['ignored'] = array();
- $defaults['generator'] = '';
-
- $defaults['report'] = PHP_CodeSniffer::getConfigData('report_format');
- if ($defaults['report'] === null) {
- $defaults['report'] = 'full';
- }
-
- $showWarnings = PHP_CodeSniffer::getConfigData('show_warnings');
- if ($showWarnings === null) {
- $defaults['showWarnings'] = true;
- } else {
- $defaults['showWarnings'] = (bool) $showWarnings;
- }
-
- $tabWidth = PHP_CodeSniffer::getConfigData('tab_width');
- if ($tabWidth === null) {
- $defaults['tabWidth'] = 0;
- } else {
- $defaults['tabWidth'] = (int) $tabWidth;
- }
-
- return $defaults;
-
- }//end getDefaults()
-
-
- /**
- * Process the command line arguments and returns the values.
- *
- * @return array
- */
- public function getCommandLineValues()
- {
- $values = $this->getDefaults();
-
- for ($i = 1; $i < $_SERVER['argc']; $i++) {
- $arg = $_SERVER['argv'][$i];
- if ($arg{0} === '-') {
- if ($arg{1} === '-') {
- $values = $this->processLongArgument(substr($arg, 2), $i, $values);
- } else {
- $switches = str_split($arg);
- foreach ($switches as $switch) {
- if ($switch === '-') {
- continue;
- }
-
- $values = $this->processShortArgument($switch, $values);
- }
- }
- } else {
- $values = $this->processUnknownArgument($arg, $i, $values);
- }
- }//end for
-
- return $values;
-
- }//end getCommandLineValues()
-
-
- /**
- * Processes a sort (-e) command line argument.
- *
- * @param string $arg The command line argument.
- * @param array $values An array of values determined from CLI args.
- *
- * @return array The updated CLI values.
- * @see getCommandLineValues()
- */
- public function processShortArgument($arg, $values)
- {
- switch ($arg) {
- case 'h':
- case '?':
- $this->printUsage();
- exit(0);
- break;
- case 'i' :
- $this->printInstalledStandards();
- exit(0);
- break;
- case 'v' :
- $values['verbosity']++;
- break;
- case 'l' :
- $values['local'] = true;
- break;
- case 'n' :
- $values['showWarnings'] = false;
- break;
- case 'w' :
- $values['showWarnings'] = true;
- break;
- default:
- $values = $this->processUnknownArgument('-'.$arg, $values);
- }//end switch
-
- return $values;
-
- }//end processShortArgument()
-
-
- /**
- * Processes a long (--example) command line argument.
- *
- * @param string $arg The command line argument.
- * @param int $pos The position of the argument on the command line.
- * @param array $values An array of values determined from CLI args.
- *
- * @return array The updated CLI values.
- * @see getCommandLineValues()
- */
- public function processLongArgument($arg, $pos, $values)
- {
- switch ($arg) {
- case 'help':
- $this->printUsage();
- exit(0);
- break;
- case 'version':
- echo 'PHP_CodeSniffer version 1.1.0 (stable) ';
- echo 'by Squiz Pty Ltd. (http://www.squiz.net)'.PHP_EOL;
- exit(0);
- break;
- case 'config-set':
- $key = $_SERVER['argv'][($pos + 1)];
- $value = $_SERVER['argv'][($pos + 2)];
- PHP_CodeSniffer::setConfigData($key, $value);
- exit(0);
- break;
- case 'config-delete':
- $key = $_SERVER['argv'][($pos + 1)];
- PHP_CodeSniffer::setConfigData($key, null);
- exit(0);
- break;
- case 'config-show':
- $data = PHP_CodeSniffer::getAllConfigData();
- print_r($data);
- exit(0);
- break;
- default:
- if (substr($arg, 0, 7) === 'report=') {
- $values['report'] = substr($arg, 7);
- $validReports = array(
- 'full',
- 'xml',
- 'checkstyle',
- 'csv',
- 'summary',
- );
-
- if (in_array($values['report'], $validReports) === false) {
- echo 'ERROR: Report type "'.$report.'" not known.'.PHP_EOL;
- exit(2);
- }
- } else if (substr($arg, 0, 9) === 'standard=') {
- $values['standard'] = substr($arg, 9);
- } else if (substr($arg, 0, 11) === 'extensions=') {
- $values['extensions'] = explode(',', substr($arg, 11));
- } else if (substr($arg, 0, 7) === 'ignore=') {
- // Split the ignore string on commas, unless the comma is escaped
- // using 1 or 3 slashes (\, or \\\,).
- $values['ignored'] = preg_split('/(?<=(?<!\\\\)\\\\\\\\),|(?<!\\\\),/', substr($arg, 7));
- } else if (substr($arg, 0, 10) === 'generator=') {
- $values['generator'] = substr($arg, 10);
- } else if (substr($arg, 0, 10) === 'tab-width=') {
- $values['tabWidth'] = (int) substr($arg, 10);
- } else {
- $values = $this->processUnknownArgument('--'.$arg, $values);
- }//end if
-
- break;
- }//end switch
-
- return $values;
-
- }//end processLongArgument()
-
-
- /**
- * Processes an unknown command line argument.
- *
- * Assumes all unknown arguments are files and folders to check.
- *
- * @param string $arg The command line argument.
- * @param int $pos The position of the argument on the command line.
- * @param array $values An array of values determined from CLI args.
- *
- * @return array The updated CLI values.
- * @see getCommandLineValues()
- */
- public function processUnknownArgument($arg, $pos, $values)
- {
- // We don't know about any additional switches; just files.
- if ($arg{0} === '-') {
- echo 'ERROR: option "'.$arg.'" not known.'.PHP_EOL.PHP_EOL;
- $this->printUsage();
- exit(2);
- }
-
- $file = realpath($arg);
- if (file_exists($file) === false) {
- echo 'ERROR: The file "'.$arg.'" does not exist.'.PHP_EOL.PHP_EOL;
- $this->printUsage();
- exit(2);
- } else {
- $values['files'][] = $file;
- }
-
- return $values;
-
- }//end processUnknownArgument()
-
-
- /**
- * Runs PHP_CodeSniffer over files are directories.
- *
- * @param array $values An array of values determined from CLI args.
- *
- * @return int The number of error and warning messages shown.
- * @see getCommandLineValues()
- */
- public function process($values=array())
- {
- if (empty($values) === true) {
- $values = $this->getCommandLineValues();
- }
-
- if ($values['generator'] !== '') {
- $phpcs = new PHP_CodeSniffer($values['verbosity']);
- $phpcs->generateDocs($values['standard'], $values['files'], $values['generator']);
- exit(0);
- }
-
- if (empty($values['files']) === true) {
- echo 'ERROR: You must supply at least one file or directory to process.'.PHP_EOL.PHP_EOL;
- $this->printUsage();
- exit(2);
- }
-
- $values['standard'] = $this->validateStandard($values['standard']);
- if (PHP_CodeSniffer::isInstalledStandard($values['standard']) === false) {
- // They didn't select a valid coding standard, so help them
- // out by letting them know which standards are installed.
- echo 'ERROR: the "'.$values['standard'].'" coding standard is not installed. ';
- $this->printInstalledStandards();
- exit(2);
- }
-
- $phpcs = new PHP_CodeSniffer($values['verbosity'], $values['tabWidth']);
-
- // Set file extensions if they were specified. Otherwise,
- // let PHP_CodeSniffer decide on the defaults.
- if (empty($values['extensions']) === false) {
- $phpcs->setAllowedFileExtensions($values['extensions']);
- }
-
- // Set ignore patterns if they were specified.
- if (empty($values['ignored']) === false) {
- $phpcs->setIgnorePatterns($values['ignored']);
- }
-
- $phpcs->process($values['files'], $values['standard'], array(), $values['local']);
- return $this->printErrorReport($phpcs, $values['report'], $values['showWarnings']);
-
- }//end process()
-
-
- /**
- * Prints the error report.
- *
- * @param PHP_CodeSniffer $phpcs The PHP_CodeSniffer object containing
- * the errors.
- * @param string $report The type of report to print.
- * @param bool $showWarnings TRUE if warnings should also be printed.
- *
- * @return int The number of error and warning messages shown.
- */
- public function printErrorReport($phpcs, $report, $showWarnings)
- {
- switch ($report) {
- case 'xml':
- $numErrors = $phpcs->printXMLErrorReport($showWarnings);
- break;
- case 'checkstyle':
- $numErrors = $phpcs->printCheckstyleErrorReport($showWarnings);
- break;
- case 'csv':
- $numErrors = $phpcs->printCSVErrorReport($showWarnings);
- break;
- case 'summary':
- $numErrors = $phpcs->printErrorReportSummary($showWarnings);
- break;
- default:
- $numErrors = $phpcs->printErrorReport($showWarnings);
- break;
- }
-
- return $numErrors;
-
- }//end printErrorReport()
-
-
- /**
- * Convert the passed standard into a valid standard.
- *
- * Checks things like default values and case.
- *
- * @param string $standard The standard to validate.
- *
- * @return string
- */
- public function validateStandard($standard)
- {
- if ($standard === null) {
- // They did not supply a standard to use.
- // Try to get the default from the config system.
- $standard = PHP_CodeSniffer::getConfigData('default_standard');
- if ($standard === null) {
- $standard = 'PEAR';
- }
- }
-
- // Check if the standard name is valid. If not, check that the case
- // was not entered incorrectly.
- if (PHP_CodeSniffer::isInstalledStandard($standard) === false) {
- $installedStandards = PHP_CodeSniffer::getInstalledStandards();
- foreach ($installedStandards as $validStandard) {
- if (strtolower($standard) === strtolower($validStandard)) {
- $standard = $validStandard;
- break;
- }
- }
- }
-
- return $standard;
-
- }//end validateStandard()
-
-
- /**
- * Prints out the usage information for this script.
- *
- * @return void
- */
- public function printUsage()
- {
- echo 'Usage: phpcs [-nwlvi] [--report=<report>] [--standard=<standard>]'.PHP_EOL;
- echo ' [--config-set key value] [--config-delete key] [--config-show]'.PHP_EOL;
- echo ' [--generator=<generator>] [--extensions=<extensions>]'.PHP_EOL;
- echo ' [--ignore=<patterns>] [--tab-width=<width>] <file> ...'.PHP_EOL;
- echo ' -n Do not print warnings'.PHP_EOL;
- echo ' -w Print both warnings and errors (on by default)'.PHP_EOL;
- echo ' -l Local directory only, no recursion'.PHP_EOL;
- echo ' -v[v][v] Print verbose output'.PHP_EOL;
- echo ' -i Show a list of installed coding standards'.PHP_EOL;
- echo ' --help Print this help message'.PHP_EOL;
- echo ' --version Print version information'.PHP_EOL;
- echo ' <file> One or more files and/or directories to check'.PHP_EOL;
- echo ' <extensions> A comma separated list of file extensions to check'.PHP_EOL;
- echo ' (only valid if checking a directory)'.PHP_EOL;
- echo ' <patterns> A comma separated list of patterns that are used'.PHP_EOL;
- echo ' to ignore directories and files'.PHP_EOL;
- echo ' <standard> The name of the coding standard to use'.PHP_EOL;
- echo ' <width> The number of spaces each tab represents'.PHP_EOL;
- echo ' <generator> The name of a doc generator to use'.PHP_EOL;
- echo ' (forces doc generation instead of checking)'.PHP_EOL;
- echo ' <report> Print either the "full", "xml", "checkstyle",'.PHP_EOL;
- echo ' "csv" or "summary" report'.PHP_EOL;
- echo ' (the "full" report is printed by default)'.PHP_EOL;
-
- }//end printUsage()
-
-
- /**
- * Prints out a list of installed coding standards.
- *
- * @return void
- */
- public function printInstalledStandards()
- {
- $installedStandards = PHP_CodeSniffer::getInstalledStandards();
- $numStandards = count($installedStandards);
-
- if ($numStandards === 0) {
- echo 'No coding standards are installed.'.PHP_EOL;
- } else {
- $lastStandard = array_pop($installedStandards);
- if ($numStandards === 1) {
- echo 'The only coding standard installed is $lastStandard'.PHP_EOL;
- } else {
- $standardList = implode(', ', $installedStandards);
- $standardList .= ' and '.$lastStandard;
- echo 'The installed coding standards are '.$standardList.PHP_EOL;
- }
- }
-
- }//end printInstalledStandards()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * A class to handle most of the parsing operations of a doc comment element.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (interface_exists('PHP_CodeSniffer_CommentParser_DocElement', true) === false) {
- $error = 'Interface PHP_CodeSniffer_CommentParser_DocElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * A class to handle most of the parsing operations of a doc comment element.
- *
- * Extending classes should implement the getSubElements method to return
- * a list of elements that the doc comment element contains, in the order that
- * they appear in the element. For example a function parameter element has a
- * type, a variable name and a comment. It should therefore implement the method
- * as follows:
- *
- * <code>
- * protected function getSubElements()
- * {
- * return array(
- * 'type',
- * 'variable',
- * 'comment',
- * );
- * }
- * </code>
- *
- * The processSubElement will be called for each of the sub elements to allow
- * the extending class to process them. So for the parameter element we would
- * have:
- *
- * <code>
- * protected function processSubElement($name, $content, $whitespaceBefore)
- * {
- * if ($name === 'type') {
- * echo 'The name of the variable was '.$content;
- * }
- * // Process other tags.
- * }
- * </code>
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-abstract class PHP_CodeSniffer_CommentParser_AbstractDocElement implements PHP_CodeSniffer_CommentParser_DocElement
-{
-
- /**
- * The element previous to this element.
- *
- * @var PHP_CodeSniffer_CommentParser_DocElement
- */
- protected $previousElement = null;
-
- /**
- * The element proceeding this element.
- *
- * @var PHP_CodeSniffer_CommentParser_DocElement
- */
- protected $nextElement = null;
-
- /**
- * The whitespace the occurs after this element and its sub elements.
- *
- * @var string
- */
- protected $afterWhitespace = '';
-
- /**
- * The tokens that comprise this element.
- *
- * @var array(string)
- */
- protected $tokens = array();
-
- /**
- * The file this element is in.
- *
- * @var array(string)
- */
- protected $phpcsFile = null;
-
- /**
- * The tag that this element represents (omiting the @ symbol).
- *
- * @var string
- */
- protected $tag = '';
-
-
- /**
- * Constructs a Doc Element.
- *
- * @param PHP_CodeSniffer_CommentParser_DocElement $previousElement The element
- * that ocurred
- * before this.
- * @param array $tokens The tokens of
- * this element.
- * @param string $tag The doc
- * element tag
- * this element
- * represents.
- * @param PHP_CodeSniffer_File $phpcsFile The file that
- * this element
- * is in.
- *
- * @throws Exception If $previousElement in not a DocElement or if
- * getSubElements() does not return an array.
- */
- public function __construct($previousElement, array $tokens, $tag, PHP_CodeSniffer_File $phpcsFile)
- {
- if ($previousElement !== null && ($previousElement instanceof PHP_CodeSniffer_CommentParser_DocElement) === false) {
- $error = '$previousElement must be an instance of DocElement';
- throw new Exception($error);
- }
-
- $this->phpcsFile = $phpcsFile;
-
- $this->previousElement = $previousElement;
- if ($previousElement !== null) {
- $this->previousElement->nextElement = $this;
- }
-
- $this->tag = $tag;
- $this->tokens = $tokens;
-
- $subElements = $this->getSubElements();
-
- if (is_array($subElements) === false) {
- throw new Exception('getSubElements() must return an array');
- }
-
- $whitespace = '';
- $currElem = 0;
- $lastElement = '';
- $lastElementWhitespace = null;
- $numSubElements = count($subElements);
-
- foreach ($this->tokens as $token) {
- if (trim($token) === '') {
- $whitespace .= $token;
- } else {
- if ($currElem < ($numSubElements - 1)) {
- $element = $subElements[$currElem];
- $this->processSubElement($element, $token, $whitespace);
- $whitespace = '';
- $currElem++;
- } else {
- if ($lastElementWhitespace === null) {
- $lastElementWhitespace = $whitespace;
- }
-
- $lastElement .= $whitespace.$token;
- $whitespace = '';
- }
- }
- }//end foreach
-
- $lastElement = ltrim($lastElement);
- $lastElementName = $subElements[($numSubElements - 1)];
-
- // Process the last element in this tag.
- $this->processSubElement($lastElementName, $lastElement, $lastElementWhitespace);
- $this->afterWhitespace = $whitespace;
-
- }//end __construct()
-
-
- /**
- * Returns the element that exists before this.
- *
- * @return PHP_CodeSniffer_CommentParser_DocElement
- */
- public function getPreviousElement()
- {
- return $this->previousElement;
-
- }//end getPreviousElement()
-
-
- /**
- * Returns the element that exists after this.
- *
- * @return PHP_CodeSniffer_CommentParser_DocElement
- */
- public function getNextElement()
- {
- return $this->nextElement;
-
- }//end getNextElement()
-
-
- /**
- * Returns the whitespace that exists before this element.
- *
- * @return string
- */
- public function getWhitespaceBefore()
- {
- if ($this->previousElement !== null) {
- return $this->previousElement->getWhitespaceAfter();
- }
-
- return '';
-
- }//end getWhitespaceBefore()
-
-
- /**
- * Returns the whitespace that exists after this element.
- *
- * @return string
- */
- public function getWhitespaceAfter()
- {
- return $this->afterWhitespace;
-
- }//end getWhitespaceAfter()
-
-
- /**
- * Returns the order that this element appears in the comment.
- *
- * @return int
- */
- public function getOrder()
- {
- if ($this->previousElement === null) {
- return 1;
- } else {
- return ($this->previousElement->getOrder() + 1);
- }
-
- }//end getOrder()
-
-
- /**
- * Returns the tag that this element represents, ommiting the @ symbol.
- *
- * @return string
- */
- public function getTag()
- {
- return $this->tag;
-
- }//end getTag()
-
-
- /**
- * Returns the raw content of this element, ommiting the tag.
- *
- * @return string
- */
- public function getRawContent()
- {
- return implode('', $this->tokens);
-
- }//end getRawContent()
-
-
- /**
- * Returns the line in which this element first occured.
- *
- * @return int
- */
- public function getLine()
- {
- if ($this->previousElement === null) {
- // First element is on line one.
- return 1;
- } else {
- $previousContent = $this->previousElement->getRawContent();
- $previousLine = $this->previousElement->getLine();
-
- return ($previousLine + substr_count($previousContent, $this->phpcsFile->eolChar));
- }
-
- }//end getLine()
-
-
- /**
- * Returns the sub element names that make up this element in the order they
- * appear in the element.
- *
- * @return array(string)
- * @see processSubElement()
- */
- abstract protected function getSubElements();
-
-
- /**
- * Called to process each sub element as sepcified in the return value
- * of getSubElements().
- *
- * @param string $name The name of the element to process.
- * @param string $content The content of the the element.
- * @param string $whitespaceBefore The whitespace found before this element.
- *
- * @return void
- * @see getSubElements()
- */
- abstract protected function processSubElement($name, $content, $whitespaceBefore);
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * Parses doc comments.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (class_exists('PHP_CodeSniffer_CommentParser_SingleElement', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_SingleElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-if (class_exists('PHP_CodeSniffer_CommentParser_CommentElement', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_CommentElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-if (class_exists('PHP_CodeSniffer_CommentParser_ParserException', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_ParserException not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * Parses doc comments.
- *
- * This abstract parser handles the following tags:
- *
- * <ul>
- * <li>The short description and the long description</li>
- * <li>@see</li>
- * <li>@link</li>
- * <li>@deprecated</li>
- * <li>@since</li>
- * </ul>
- *
- * Extending classes should implement the getAllowedTags() method to return the
- * tags that they wish to process, ommiting the tags that this base class
- * processes. When one of these tags in encountered, the process<tag_name>
- * method is called on that class. For example, if a parser's getAllowedTags()
- * method returns \@param as one of its tags, the processParam method will be
- * called so that the parser can process such a tag.
- *
- * The method is passed the tokens that comprise this tag. The tokens array
- * includes the whitespace that exists between the tokens, as seperate tokens.
- * It's up to the method to create a element that implements the DocElement
- * interface, which should be returned. The AbstractDocElement class is a helper
- * class that can be used to handle most of the parsing of the tokens into their
- * individual sub elements. It requires that you construct it with the element
- * previous to the element currently being processed, which can be acquired
- * with the protected $previousElement class member of this class.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-abstract class PHP_CodeSniffer_CommentParser_AbstractParser
-{
-
- /**
- * The comment element that appears in the doc comment.
- *
- * @var PHP_CodeSniffer_CommentParser_CommentElement
- */
- protected $comment = null;
-
- /**
- * The string content of the comment.
- *
- * @var string
- */
- protected $commentString = '';
-
- /**
- * The file that the comment exists in.
- *
- * @var PHP_CodeSniffer_File
- */
- protected $phpcsFile = null;
-
- /**
- * The word tokens that appear in the comment.
- *
- * Whitespace tokens also appear in this stack, but are separate tokens
- * from words.
- *
- * @var array(string)
- */
- protected $words = array();
-
- /**
- * The previous doc element that was processed.
- *
- * null if the current element being processed is the first element in the
- * doc comment.
- *
- * @var PHP_CodeSniffer_CommentParser_DocElement
- */
- protected $previousElement = null;
-
- /**
- * A list of see elements that appear in this doc comment.
- *
- * @var array(PHP_CodeSniffer_CommentParser_SingleElement)
- */
- protected $sees = array();
-
- /**
- * A list of see elements that appear in this doc comment.
- *
- * @var array(PHP_CodeSniffer_CommentParser_SingleElement)
- */
- protected $deprecated = null;
-
- /**
- * A list of see elements that appear in this doc comment.
- *
- * @var array(PHP_CodeSniffer_CommentParser_SingleElement)
- */
- protected $links = array();
-
- /**
- * A element to represent \@since tags.
- *
- * @var PHP_CodeSniffer_CommentParser_SingleElement
- */
- protected $since = null;
-
- /**
- * True if the comment has been parsed.
- *
- * @var boolean
- */
- private $_hasParsed = false;
-
- /**
- * The tags that this class can process.
- *
- * @var array(string)
- */
- private static $_tags = array(
- 'see' => false,
- 'link' => false,
- 'deprecated' => true,
- 'since' => true,
- );
-
- /**
- * An array of unknown tags.
- *
- * @var array(string)
- */
- public $unknown = array();
-
- /**
- * The order of tags.
- *
- * @var array(string)
- */
- public $orders = array();
-
-
- /**
- * Constructs a Doc Comment Parser.
- *
- * @param string $comment The comment to parse.
- * @param PHP_CodeSniffer_File $phpcsFile The file that this comment is in.
- */
- public function __construct($comment, PHP_CodeSniffer_File $phpcsFile)
- {
- $this->commentString = $comment;
- $this->phpcsFile = $phpcsFile;
-
- }//end __construct()
-
-
- /**
- * Initiates the parsing of the doc comment.
- *
- * @return void
- * @throws PHP_CodeSniffer_CommentParser_ParserException If the parser finds a
- * problem with the
- * comment.
- */
- public function parse()
- {
- if ($this->_hasParsed === false) {
- $this->_parse($this->commentString);
- }
-
- }//end parse()
-
-
- /**
- * Parse the comment.
- *
- * @param string $comment The doc comment to parse.
- *
- * @return void
- * @see _parseWords()
- */
- private function _parse($comment)
- {
- // Firstly, remove the comment tags and any stars from the left side.
- $lines = explode($this->phpcsFile->eolChar, $comment);
- foreach ($lines as &$line) {
- $line = trim($line);
-
- if ($line !== '') {
- if (substr($line, 0, 3) === '/**') {
- $line = substr($line, 3);
- } else if (substr($line, -2, 2) === '*/') {
- $line = substr($line, 0, -2);
- } else if ($line{0} === '*') {
- $line = substr($line, 1);
- }
-
- // Add the words to the stack, preserving newlines. Other parsers
- // might be interested in the spaces between words, so tokenize
- // spaces as well as separate tokens.
- $flags = (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
- $words = preg_split('|(\s+)|', $line.$this->phpcsFile->eolChar, -1, $flags);
- $this->words = array_merge($this->words, $words);
- }
- }//end foreach
-
- $this->_parseWords();
-
- }//end _parse()
-
-
- /**
- * Parses each word within the doc comment.
- *
- * @return void
- * @see _parse()
- * @throws PHP_CodeSniffer_CommentParser_ParserException If more than the allowed
- * number of occurances of
- * a tag is found.
- */
- private function _parseWords()
- {
- $allowedTags = (self::$_tags + $this->getAllowedTags());
- $allowedTagNames = array_keys($allowedTags);
- $foundTags = array();
- $prevTagPos = false;
- $wordWasEmpty = true;
-
- foreach ($this->words as $wordPos => $word) {
-
- if (trim($word) !== '') {
- $wordWasEmpty = false;
- }
-
- if ($word{0} === '@') {
-
- $tag = substr($word, 1);
-
- // Filter out @ tags in the comment description.
- // A real comment tag should have whitespace and a newline before it.
- if (isset($this->words[($wordPos - 1)]) === false || trim($this->words[($wordPos - 1)]) !== '') {
- continue;
- }
-
- if (isset($this->words[($wordPos - 2)]) === false || $this->words[($wordPos - 2)] !== $this->phpcsFile->eolChar) {
- continue;
- }
-
- $foundTags[] = $tag;
-
- if ($prevTagPos !== false) {
- // There was a tag before this so let's process it.
- $prevTag = substr($this->words[$prevTagPos], 1);
- $this->parseTag($prevTag, $prevTagPos, ($wordPos - 1));
- } else {
- // There must have been a comment before this tag, so
- // let's process that.
- $this->parseTag('comment', 0, ($wordPos - 1));
- }
-
- $prevTagPos = $wordPos;
-
- if (in_array($tag, $allowedTagNames) === false) {
- // This is not a tag that we process, but let's check to
- // see if it is a tag we know about. If we don't know about it,
- // we add it to a list of unknown tags.
- $knownTags = array(
- 'abstract',
- 'access',
- 'example',
- 'filesource',
- 'global',
- 'ignore',
- 'internal',
- 'name',
- 'static',
- 'staticvar',
- 'todo',
- 'tutorial',
- 'uses',
- 'package_version@',
- );
-
- if (in_array($tag, $knownTags) === false) {
- $this->unknown[] = array(
- 'tag' => $tag,
- 'line' => $this->getLine($wordPos),
- );
- }
-
- }//end if
-
- }//end if
- }//end foreach
-
- // Only process this tag if there was something to process.
- if ($wordWasEmpty === false) {
- if ($prevTagPos === false) {
- // There must only be a comment in this doc comment.
- $this->parseTag('comment', 0, count($this->words));
- } else {
- // Process the last tag element.
- $prevTag = substr($this->words[$prevTagPos], 1);
- $this->parseTag($prevTag, $prevTagPos, count($this->words));
- }
- }
-
- }//end _parseWords()
-
-
- /**
- * Returns the line that the token exists on in the doc comment.
- *
- * @param int $tokenPos The position in the words stack to find the line
- * number for.
- *
- * @return int
- */
- protected function getLine($tokenPos)
- {
- $newlines = 0;
- for ($i = 0; $i < $tokenPos; $i++) {
- $newlines += substr_count($this->phpcsFile->eolChar, $this->words[$i]);
- }
-
- return $newlines;
-
- }//end getLine()
-
-
- /**
- * Parses see tag element within the doc comment.
- *
- * @param array(string) $tokens The word tokens that comprise this element.
- *
- * @return DocElement The element that represents this see comment.
- */
- protected function parseSee($tokens)
- {
- $see = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'see', $this->phpcsFile);
- $this->sees[] = $see;
- return $see;
-
- }//end parseSee()
-
-
- /**
- * Parses the comment element that appears at the top of the doc comment.
- *
- * @param array(string) $tokens The word tokens that comprise tihs element.
- *
- * @return DocElement The element that represents this comment element.
- */
- protected function parseComment($tokens)
- {
- $this->comment = new PHP_CodeSniffer_CommentParser_CommentElement($this->previousElement, $tokens, $this->phpcsFile);
- return $this->comment;
-
- }//end parseComment()
-
-
- /**
- * Parses \@deprecated tags.
- *
- * @param array(string) $tokens The word tokens that comprise tihs element.
- *
- * @return DocElement The element that represents this deprecated tag.
- */
- protected function parseDeprecated($tokens)
- {
- $this->deprecated = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'deprecated', $this->phpcsFile);
- return $this->deprecated;
-
- }//end parseDeprecated()
-
-
- /**
- * Parses \@since tags.
- *
- * @param array(string) $tokens The word tokens that comprise this element.
- *
- * @return SingleElement The element that represents this since tag.
- */
- protected function parseSince($tokens)
- {
- $this->since = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'since', $this->phpcsFile);
- return $this->since;
-
- }//end parseSince()
-
-
- /**
- * Parses \@link tags.
- *
- * @param array(string) $tokens The word tokens that comprise this element.
- *
- * @return SingleElement The element that represents this link tag.
- */
- protected function parseLink($tokens)
- {
- $link = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'link', $this->phpcsFile);
- $this->links[] = $link;
- return $link;
-
- }//end parseLink()
-
-
- /**
- * Returns the see elements that appear in this doc comment.
- *
- * @return array(SingleElement)
- */
- public function getSees()
- {
- return $this->sees;
-
- }//end getSees()
-
-
- /**
- * Returns the comment element that appears at the top of this doc comment.
- *
- * @return CommentElement
- */
- public function getComment()
- {
- return $this->comment;
-
- }//end getComment()
-
-
- /**
- * Returns the link elements found in this comment.
- *
- * Returns an empty array if no links are found in the comment.
- *
- * @return array(SingleElement)
- */
- public function getLinks()
- {
- return $this->links;
-
- }//end getLinks()
-
-
- /**
- * Returns the deprecated element found in this comment.
- *
- * Returns null if no element exists in the comment.
- *
- * @return SingleElement
- */
- public function getDeprecated()
- {
- return $this->deprecated;
-
- }//end getDeprecated()
-
-
- /**
- * Returns the since element found in this comment.
- *
- * Returns null if no element exists in the comment.
- *
- * @return SingleElement
- */
- public function getSince()
- {
- return $this->since;
-
- }//end getSince()
-
-
- /**
- * Parses the specified tag.
- *
- * @param string $tag The tag name to parse (omitting the @ sybmol from
- * the tag)
- * @param int $start The position in the word tokens where this element
- * started.
- * @param int $end The position in the word tokens where this element
- * ended.
- *
- * @return void
- * @throws Exception If the process method for the tag cannot be found.
- */
- protected function parseTag($tag, $start, $end)
- {
- $tokens = array_slice($this->words, ($start + 1), ($end - $start));
-
- $allowedTags = (self::$_tags + $this->getAllowedTags());
- $allowedTagNames = array_keys($allowedTags);
- if ($tag === 'comment' || in_array($tag, $allowedTagNames) === true) {
- $method = 'parse'.$tag;
- if (method_exists($this, $method) === false) {
- $error = 'Method '.$method.' must be implemented to process '.$tag.' tags';
- throw new Exception($error);
- }
-
- $this->previousElement = $this->$method($tokens);
- } else {
- $this->previousElement = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, $tag, $this->phpcsFile);
- }
-
- $this->orders[] = $tag;
-
- if ($this->previousElement === null || ($this->previousElement instanceof PHP_CodeSniffer_CommentParser_DocElement) === false) {
- throw new Exception('Parse method must return a DocElement');
- }
-
- }//end parseTag()
-
-
- /**
- * Returns a list of tags that this comment parser allows for it's comment.
- *
- * Each tag should indicate if only one entry of this tag can exist in the
- * comment by specifying true as the array value, or false if more than one
- * is allowed. Each tag should ommit the @ symbol. Only tags other than
- * the standard tags should be returned.
- *
- * @return array(string => boolean)
- */
- protected abstract function getAllowedTags();
-
-
- /**
- * Returns the tag orders (index => tagName).
- *
- * @return array
- */
- public function getTagOrders()
- {
- return $this->orders;
-
- }//end getTagOrders()
-
-
- /**
- * Returns the unknown tags.
- *
- * @return array
- */
- public function getUnknown()
- {
- return $this->unknown;
-
- }//end getUnknown()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * Parses Class doc comments.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (class_exists('PHP_CodeSniffer_CommentParser_AbstractParser', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_AbstractParser not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * Parses Class doc comments.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_CommentParser_ClassCommentParser extends PHP_CodeSniffer_CommentParser_AbstractParser
-{
-
- /**
- * The package element of this class.
- *
- * @var SingleElement
- */
- private $_package = null;
-
- /**
- * The subpackage element of this class.
- *
- * @var SingleElement
- */
- private $_subpackage = null;
-
- /**
- * The version element of this class.
- *
- * @var SingleElement
- */
- private $_version = null;
-
- /**
- * The category element of this class.
- *
- * @var SingleElement
- */
- private $_category = null;
-
- /**
- * The copyright elements of this class.
- *
- * @var array(SingleElement)
- */
- private $_copyrights = array();
-
- /**
- * The licence element of this class.
- *
- * @var PairElement
- */
- private $_license = null;
-
- /**
- * The author elements of this class.
- *
- * @var array(SingleElement)
- */
- private $_authors = array();
-
-
- /**
- * Returns the allowed tags withing a class comment.
- *
- * @return array(string => int)
- */
- protected function getAllowedTags()
- {
- return array(
- 'category' => false,
- 'package' => true,
- 'subpackage' => true,
- 'author' => false,
- 'copyright' => true,
- 'license' => false,
- 'version' => true,
- );
-
- }//end getAllowedTags()
-
-
- /**
- * Parses the license tag of this class comment.
- *
- * @param array $tokens The tokens that comprise this tag.
- *
- * @return PHP_CodeSniffer_CommentParser_PairElement
- */
- protected function parseLicense($tokens)
- {
- $this->_license = new PHP_CodeSniffer_CommentParser_PairElement($this->previousElement, $tokens, 'license', $this->phpcsFile);
- return $this->_license;
-
- }//end parseLicense()
-
-
- /**
- * Parses the copyright tags of this class comment.
- *
- * @param array $tokens The tokens that comprise this tag.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- protected function parseCopyright($tokens)
- {
- $copyright = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'copyright', $this->phpcsFile);
- $this->_copyrights[] = $copyright;
- return $copyright;
-
- }//end parseCopyright()
-
-
- /**
- * Parses the category tag of this class comment.
- *
- * @param array $tokens The tokens that comprise this tag.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- protected function parseCategory($tokens)
- {
- $this->_category = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'category', $this->phpcsFile);
- return $this->_category;
-
- }//end parseCategory()
-
-
- /**
- * Parses the author tag of this class comment.
- *
- * @param array $tokens The tokens that comprise this tag.
- *
- * @return array(PHP_CodeSniffer_CommentParser_SingleElement)
- */
- protected function parseAuthor($tokens)
- {
- $author = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'author', $this->phpcsFile);
- $this->_authors[] = $author;
- return $author;
-
- }//end parseAuthor()
-
-
- /**
- * Parses the version tag of this class comment.
- *
- * @param array $tokens The tokens that comprise this tag.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- protected function parseVersion($tokens)
- {
- $this->_version = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'version', $this->phpcsFile);
- return $this->_version;
-
- }//end parseVersion()
-
-
- /**
- * Parses the package tag found in this test.
- *
- * @param array $tokens The tokens that comprise this var.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- protected function parsePackage($tokens)
- {
- $this->_package = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'package', $this->phpcsFile);
- return $this->_package;
-
- }//end parsePackage()
-
-
- /**
- * Parses the package tag found in this test.
- *
- * @param array $tokens The tokens that comprise this var.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- protected function parseSubpackage($tokens)
- {
- $this->_subpackage = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'subpackage', $this->phpcsFile);
- return $this->_subpackage;
-
- }//end parseSubpackage()
-
-
- /**
- * Returns the authors of this class comment.
- *
- * @return array(PHP_CodeSniffer_CommentParser_SingleElement)
- */
- public function getAuthors()
- {
- return $this->_authors;
-
- }//end getAuthors()
-
-
- /**
- * Returns the version of this class comment.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- public function getVersion()
- {
- return $this->_version;
-
- }//end getVersion()
-
-
- /**
- * Returns the license of this class comment.
- *
- * @return PHP_CodeSniffer_CommentParser_PairElement
- */
- public function getLicense()
- {
- return $this->_license;
-
- }//end getLicense()
-
-
- /**
- * Returns the copyrights of this class comment.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- public function getCopyrights()
- {
- return $this->_copyrights;
-
- }//end getCopyrights()
-
-
- /**
- * Returns the category of this class comment.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- public function getCategory()
- {
- return $this->_category;
-
- }//end getCategory()
-
-
- /**
- * Returns the package that this class belongs to.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- public function getPackage()
- {
- return $this->_package;
-
- }//end getPackage()
-
-
- /**
- * Returns the subpackage that this class belongs to.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- public function getSubpackage()
- {
- return $this->_subpackage;
-
- }//end getSubpackage()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * A class to represent Comments of a doc comment.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (class_exists('PHP_CodeSniffer_CommentParser_SingleElement', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_SingleElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * A class to represent Comments of a doc comment.
- *
- * Comments are in the following format.
- * <code>
- * /** <--this is the start of the comment.
- * * This is a short comment description
- * *
- * * This is a long comment description
- * * <-- this is the end of the comment
- * * @return something
- * {@/}
- * </code>
- *
- * Note that the sentence before two newlines is assumed
- * the short comment description.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_CommentParser_CommentElement extends PHP_CodeSniffer_CommentParser_SingleElement
-{
-
-
- /**
- * Constructs a PHP_CodeSniffer_CommentParser_CommentElement.
- *
- * @param PHP_CodeSniffer_CommentParser_DocElemement $previousElement The element
- * that
- * appears
- * before this
- * element.
- * @param array $tokens The tokens
- * that make
- * up this
- * element.
- * @param PHP_CodeSniffer_File $phpcsFile The file
- * that this
- * element is
- * in.
- */
- public function __construct($previousElement, $tokens, PHP_CodeSniffer_File $phpcsFile)
- {
- parent::__construct($previousElement, $tokens, 'comment', $phpcsFile);
-
- }//end __construct()
-
-
- /**
- * Returns the short comment description.
- *
- * @return string
- * @see getLongComment()
- */
- public function getShortComment()
- {
- $pos = $this->_getShortCommentEndPos();
- if ($pos === -1) {
- return '';
- }
-
- return implode('', array_slice($this->tokens, 0, ($pos + 1)));
-
- }//end getShortComment()
-
-
- /**
- * Returns the last token position of the short comment description.
- *
- * @return int The last token position of the short comment description
- * @see _getLongCommentStartPos()
- */
- private function _getShortCommentEndPos()
- {
- $found = false;
- $whiteSpace = array(
- ' ',
- "\t",
- );
-
- foreach ($this->tokens as $pos => $token) {
- $token = str_replace($whiteSpace, '', $token);
- if ($token === $this->phpcsFile->eolChar) {
- if ($found === false) {
- // Include newlines before short description.
- continue;
- } else {
- if (isset($this->tokens[($pos + 1)]) === true) {
- if ($this->tokens[($pos + 1)] === $this->phpcsFile->eolChar) {
- return ($pos - 1);
- }
- } else {
- return $pos;
- }
- }
- } else {
- $found = true;
- }
- }//end foreach
-
- return (count($this->tokens) - 1);
-
- }//end _getShortCommentEndPos()
-
-
- /**
- * Returns the long comment description.
- *
- * @return string
- * @see getShortComment
- */
- public function getLongComment()
- {
- $start = $this->_getLongCommentStartPos();
- if ($start === -1) {
- return '';
- }
-
- return implode('', array_slice($this->tokens, $start));
-
- }//end getLongComment()
-
-
- /**
- * Returns the start position of the long comment description.
- *
- * Returns -1 if there is no long comment.
- *
- * @return int The start position of the long comment description.
- * @see _getShortCommentEndPos()
- */
- private function _getLongCommentStartPos()
- {
- $pos = ($this->_getShortCommentEndPos() + 1);
- if ($pos === (count($this->tokens) - 1)) {
- return -1;
- }
-
- $count = count($this->tokens);
- for ($i = $pos; $i < $count; $i++) {
- $content = trim($this->tokens[$i]);
- if ($content !== '') {
- if ($content{0} === '@') {
- return -1;
- }
-
- return $i;
- }
- }
-
- return -1;
-
- }//end _getLongCommentStartPos()
-
-
- /**
- * Returns the whitespace that exists between
- * the short and the long comment description.
- *
- * @return string
- */
- public function getWhiteSpaceBetween()
- {
- $endShort = ($this->_getShortCommentEndPos() + 1);
- $startLong = ($this->_getLongCommentStartPos() - 1);
- if ($startLong === -1) {
- return '';
- }
-
- return implode('', array_slice($this->tokens, $endShort, ($startLong - $endShort)));
-
- }//end getWhiteSpaceBetween()
-
-
- /**
- * Returns the number of newlines that exist before the tags.
- *
- * @return int
- */
- public function getNewlineAfter()
- {
- $long = $this->getLongComment();
- if ($long !== '') {
- $long = rtrim($long, ' ');
- $long = strrev($long);
- $newlines = strspn($long, $this->phpcsFile->eolChar);
- } else {
- $endShort = ($this->_getShortCommentEndPos() + 1);
- $after = implode('', array_slice($this->tokens, $endShort));
- $after = trim($after, ' ');
- $newlines = strspn($after, $this->phpcsFile->eolChar);
- }
-
- return ($newlines / strlen($this->phpcsFile->eolChar));
-
- }//end getNewlineAfter()
-
-
- /**
- * Returns true if there is no comment.
- *
- * @return boolean
- */
- public function isEmpty()
- {
- return (trim($this->getContent()) === '');
-
- }//end isEmpty()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * A DocElement represents a logical element within a Doc Comment.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-/**
- * A DocElement represents a logical element within a Doc Comment.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-interface PHP_CodeSniffer_CommentParser_DocElement
-{
-
-
- /**
- * Returns the name of the tag this element represents, omitting the @ symbol.
- *
- * @return string
- */
- public function getTag();
-
-
- /**
- * Returns the whitespace that exists before this element.
- *
- * @return string
- * @see getWhitespaceAfter()
- */
- public function getWhitespaceBefore();
-
-
- /**
- * Returns the whitespace that exists after this element.
- *
- * @return string
- * @see getWhitespaceBefore()
- */
- public function getWhitespaceAfter();
-
-
- /**
- * Returns the order that this element appears in the doc comment.
- *
- * The first element in the comment should have an order of 1.
- *
- * @return int
- */
- public function getOrder();
-
-
- /**
- * Returns the element that appears before this element.
- *
- * @return PHP_CodeSniffer_CommentParser_DocElement
- * @see getNextElement()
- */
- public function getPreviousElement();
-
-
- /**
- * Returns the element that appears after this element.
- *
- * @return PHP_CodeSniffer_CommentParser_DocElement
- * @see getPreviousElement()
- */
- public function getNextElement();
-
-
- /**
- * Returns the line that this element started on.
- *
- * @return int
- */
- public function getLine();
-
-
- /**
- * Returns the raw content of this element, ommiting the tag.
- *
- * @return string
- */
- public function getRawContent();
-
-
-}//end interface
-
-?>
+++ /dev/null
-<?php
-/**
- * Parses function doc comments.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (class_exists('PHP_CodeSniffer_CommentParser_AbstractParser', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_AbstractParser not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-if (class_exists('PHP_CodeSniffer_CommentParser_ParameterElement', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_ParameterElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-if (class_exists('PHP_CodeSniffer_CommentParser_PairElement', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_PairElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-if (class_exists('PHP_CodeSniffer_CommentParser_SingleElement', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_SingleElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * Parses function doc comments.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_CommentParser_FunctionCommentParser extends PHP_CodeSniffer_CommentParser_AbstractParser
-{
-
- /**
- * The parameter elements within this function comment.
- *
- * @var array(PHP_CodeSniffer_CommentParser_ParameterElement)
- */
- private $_params = array();
-
- /**
- * The return element in this function comment.
- *
- * @var PHP_CodeSniffer_CommentParser_PairElement.
- */
- private $_return = null;
-
- /**
- * The throws element list for this function comment.
- *
- * @var array(PHP_CodeSniffer_CommentParser_PairElement)
- */
- private $_throws = array();
-
-
- /**
- * Constructs a PHP_CodeSniffer_CommentParser_FunctionCommentParser.
- *
- * @param string $comment The comment to parse.
- * @param PHP_CodeSniffer_File $phpcsFile The file that this comment is in.
- */
- public function __construct($comment, PHP_CodeSniffer_File $phpcsFile)
- {
- parent::__construct($comment, $phpcsFile);
-
- }//end __construct()
-
-
- /**
- * Parses parameter elements.
- *
- * @param array(string) $tokens The tokens that conmpise this sub element.
- *
- * @return PHP_CodeSniffer_CommentParser_ParameterElement
- */
- protected function parseParam($tokens)
- {
- $param = new PHP_CodeSniffer_CommentParser_ParameterElement($this->previousElement, $tokens, $this->phpcsFile);
- $this->_params[] = $param;
- return $param;
-
- }//end parseParam()
-
-
- /**
- * Parses return elements.
- *
- * @param array(string) $tokens The tokens that conmpise this sub element.
- *
- * @return PHP_CodeSniffer_CommentParser_PairElement
- */
- protected function parseReturn($tokens)
- {
- $return = new PHP_CodeSniffer_CommentParser_PairElement($this->previousElement, $tokens, 'return', $this->phpcsFile);
- $this->_return = $return;
- return $return;
-
- }//end parseReturn()
-
-
- /**
- * Parses throws elements.
- *
- * @param array(string) $tokens The tokens that conmpise this sub element.
- *
- * @return PHP_CodeSniffer_CommentParser_PairElement
- */
- protected function parseThrows($tokens)
- {
- $throws = new PHP_CodeSniffer_CommentParser_PairElement($this->previousElement, $tokens, 'throws', $this->phpcsFile);
- $this->_throws[] = $throws;
- return $throws;
-
- }//end parseThrows()
-
-
- /**
- * Returns the parameter elements that this function comment contains.
- *
- * Returns an empty array if no parameter elements are contained within
- * this function comment.
- *
- * @return array(PHP_CodeSniffer_CommentParser_ParameterElement)
- */
- public function getParams()
- {
- return $this->_params;
-
- }//end getParams()
-
-
- /**
- * Returns the return element in this fucntion comment.
- *
- * Returns null if no return element exists in the comment.
- *
- * @return PHP_CodeSniffer_CommentParser_PairElement
- */
- public function getReturn()
- {
- return $this->_return;
-
- }//end getReturn()
-
-
- /**
- * Returns the throws elements in this fucntion comment.
- *
- * Returns empty array if no throws elements in the comment.
- *
- * @return array(PHP_CodeSniffer_CommentParser_PairElement)
- */
- public function getThrows()
- {
- return $this->_throws;
-
- }//end getThrows()
-
-
- /**
- * Returns the allowed tags that can exist in a function comment.
- *
- * @return array(string => boolean)
- */
- protected function getAllowedTags()
- {
- return array(
- 'param' => false,
- 'return' => true,
- 'throws' => false,
- );
-
- }//end getAllowedTags()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * Parses class member comments.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (class_exists('PHP_CodeSniffer_CommentParser_ClassCommentParser', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_ClassCommentParser not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * Parses class member comments.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_CommentParser_MemberCommentParser extends PHP_CodeSniffer_CommentParser_ClassCommentParser
-{
-
- /**
- * Represents a \@var tag in a member comment.
- *
- * @var PHP_CodeSniffer_CommentParser_SingleElement
- */
- private $_var = null;
-
-
- /**
- * Parses Var tags.
- *
- * @param array $tokens The tokens that represent this tag.
- *
- * @return PHP_CodeSniffer_CommentParser_SingleElement
- */
- protected function parseVar($tokens)
- {
- $this->_var = new PHP_CodeSniffer_CommentParser_SingleElement($this->previousElement, $tokens, 'var', $this->phpcsFile);
- return $this->_var;
-
- }//end parseVar()
-
-
- /**
- * Returns the var tag found in the member comment.
- *
- * @return PHP_CodeSniffer_CommentParser_PairElement
- */
- public function getVar()
- {
- return $this->_var;
-
- }//end getVar()
-
-
- /**
- * Returns the allowed tags for this parser.
- *
- * @return array
- */
- protected function getAllowedTags()
- {
- return array('var' => true);
-
- }//end getAllowedTags()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * A class to represent elements that have a value => comment format.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (class_exists('PHP_CodeSniffer_CommentParser_AbstractDocElement', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_AbstractDocElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * A class to represent elements that have a value => comment format.
- *
- * An example of a pair element tag is the \@throws as it has an exception type
- * and a comment on the circumstance of when the exception is thrown.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_CommentParser_PairElement extends PHP_CodeSniffer_CommentParser_AbstractDocElement
-{
-
- /**
- * The value of the tag.
- *
- * @var string
- */
- private $_value = '';
-
- /**
- * The comment of the tag.
- *
- * @var string
- */
- private $_comment = '';
-
- /**
- * The whitespace that exists before the value elem.
- *
- * @var string
- */
- private $_valueWhitespace = '';
-
- /**
- * The whitespace that exists before the comment elem.
- *
- * @var string
- */
- private $_commentWhitespace = '';
-
-
- /**
- * Constructs a PHP_CodeSniffer_CommentParser_PairElement doc tag.
- *
- * @param PHP_CodeSniffer_CommentParser_DocElement $previousElement The element
- * before this
- * one.
- * @param array $tokens The tokens
- * that comprise
- * this element.
- * @param string $tag The tag that
- * this element
- * represents.
- * @param PHP_CodeSniffer_File $phpcsFile The file that
- * this element
- * is in.
- */
- public function __construct($previousElement, $tokens, $tag, PHP_CodeSniffer_File $phpcsFile)
- {
- parent::__construct($previousElement, $tokens, $tag, $phpcsFile);
-
- }//end __construct()
-
-
- /**
- * Returns the element names that this tag is comprised of, in the order
- * that they appear in the tag.
- *
- * @return array(string)
- * @see processSubElement()
- */
- protected function getSubElements()
- {
- return array(
- 'value',
- 'comment',
- );
-
- }//end getSubElements()
-
-
- /**
- * Processes the sub element with the specified name.
- *
- * @param string $name The name of the sub element to process.
- * @param string $content The content of this sub element.
- * @param string $whitespaceBefore The whitespace that exists before the
- * sub element.
- *
- * @return void
- * @see getSubElements()
- */
- protected function processSubElement($name, $content, $whitespaceBefore)
- {
- $element = '_'.$name;
- $whitespace = $element.'Whitespace';
- $this->$element = $content;
- $this->$whitespace = $whitespaceBefore;
-
- }//end processSubElement()
-
-
- /**
- * Returns the value of the tag.
- *
- * @return string
- */
- public function getValue()
- {
- return $this->_value;
-
- }//end getValue()
-
-
- /**
- * Returns the comment associated with the value of this tag.
- *
- * @return string
- */
- public function getComment()
- {
- return $this->_comment;
-
- }//end getComment()
-
-
- /**
- * Returns the witespace before the content of this tag.
- *
- * @return string
- */
- public function getWhitespaceBeforeValue()
- {
- return $this->_valueWhitespace;
-
- }//end getWhitespaceBeforeValue()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * A class to represent param tags within a function comment.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (class_exists('PHP_CodeSniffer_CommentParser_AbstractDocElement', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_AbstractDocElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * A class to represent param tags within a function comment.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_CommentParser_ParameterElement extends PHP_CodeSniffer_CommentParser_AbstractDocElement
-{
-
- /**
- * The variable name of this parameter name, including the $ sign.
- *
- * @var string
- */
- private $_varName = '';
-
- /**
- * The comment of this parameter tag.
- *
- * @var string
- */
- private $_comment = '';
-
- /**
- * The variable type of this parameter tag.
- *
- * @var string
- */
- private $_type = '';
-
- /**
- * The whitespace that exists before the variable name.
- *
- * @var string
- */
- private $_varNameWhitespace = '';
-
- /**
- * The whitespace that exists before the comment.
- *
- * @var string
- */
- private $_commentWhitespace = null;
-
- /**
- * The whitespace that exists before the variable type.
- *
- * @var string
- */
- private $_typeWhitespace = '';
-
-
- /**
- * Constructs a PHP_CodeSniffer_CommentParser_ParameterElement.
- *
- * @param PHP_CodeSniffer_CommentParser_DocElement $previousElement The element
- * previous to
- * this one.
- * @param array $tokens The tokens
- * that make up
- * this element.
- * @param PHP_CodeSniffer_File $phpcsFile The file that
- * this element
- * is in.
- */
- public function __construct($previousElement, $tokens, PHP_CodeSniffer_File $phpcsFile)
- {
- parent::__construct($previousElement, $tokens, 'param', $phpcsFile);
-
- // Handle special variable type: array(x => y).
- $type = strtolower($this->_type);
- if ($this->_varName === '=>' && strpos($type, 'array(') !== false) {
- $rawContent = $this->getRawContent();
- $matches = array();
- if (preg_match('/^(\s+)(array\(.*\))(\s+)(\$\S*)(\s+)(.*)/i', $rawContent, $matches) !== 0) {
- // Process the sub elements correctly for this special case.
- if (count($matches) === 7) {
- $this->processSubElement('type', $matches[2], $matches[1]);
- $this->processSubElement('varName', $matches[4], $matches[3]);
- $this->processSubElement('comment', $matches[6], $matches[5]);
- }
- }
- }
-
- }//end __construct()
-
-
- /**
- * Returns the element names that this tag is comprised of, in the order
- * that they appear in the tag.
- *
- * @return array(string)
- * @see processSubElement()
- */
- protected function getSubElements()
- {
- return array(
- 'type',
- 'varName',
- 'comment',
- );
-
- }//end getSubElements()
-
-
- /**
- * Processes the sub element with the specified name.
- *
- * @param string $name The name of the sub element to process.
- * @param string $content The content of this sub element.
- * @param string $beforeWhitespace The whitespace that exists before the
- * sub element.
- *
- * @return void
- * @see getSubElements()
- */
- protected function processSubElement($name, $content, $beforeWhitespace)
- {
- $element = '_'.$name;
- $whitespace = $element.'Whitespace';
- $this->$element = $content;
- $this->$whitespace = $beforeWhitespace;
-
- }//end processSubElement()
-
-
- /**
- * Returns the variable name that this parameter tag represents.
- *
- * @return string
- */
- public function getVarName()
- {
- return $this->_varName;
-
- }//end getVarName()
-
-
- /**
- * Returns the variable type that this string represents.
- *
- * @return string
- */
- public function getType()
- {
- return $this->_type;
-
- }//end getType()
-
-
- /**
- * Returns the comment of this comment for this parameter.
- *
- * @return string
- */
- public function getComment()
- {
- return $this->_comment;
-
- }//end getComment()
-
-
- /**
- * Returns the whitespace before the variable type.
- *
- * @return stirng
- * @see getWhiteSpaceBeforeVarName()
- * @see getWhiteSpaceBeforeComment()
- */
- public function getWhiteSpaceBeforeType()
- {
- return $this->_typeWhitespace;
-
- }//end getWhiteSpaceBeforeType()
-
-
- /**
- * Returns the whitespace before the variable name.
- *
- * @return string
- * @see getWhiteSpaceBeforeComment()
- * @see getWhiteSpaceBeforeType()
- */
- public function getWhiteSpaceBeforeVarName()
- {
- return $this->_varNameWhitespace;
-
- }//end getWhiteSpaceBeforeVarName()
-
-
- /**
- * Returns the whitespace before the comment.
- *
- * @return string
- * @see getWhiteSpaceBeforeVarName()
- * @see getWhiteSpaceBeforeType()
- */
- public function getWhiteSpaceBeforeComment()
- {
- return $this->_commentWhitespace;
-
- }//end getWhiteSpaceBeforeComment()
-
-
- /**
- * Returns the postition of this parameter are it appears in the comment.
- *
- * This method differs from getOrder as it is only relative to method
- * parameters.
- *
- * @return int
- */
- public function getPosition()
- {
- if (($this->getPreviousElement() instanceof PHP_CodeSniffer_CommentParser_ParameterElement) === false) {
- return 1;
- } else {
- return ($this->getPreviousElement()->getPosition() + 1);
- }
-
- }//end getPosition()
-
-
- /**
- * Returns true if this parameter's variable aligns with the other's.
- *
- * @param PHP_CodeSniffer_CommentParser_ParameterElement $other The other param
- * to check
- * alignment with.
- *
- * @return boolean
- */
- public function alignsVariableWith(PHP_CodeSniffer_CommentParser_ParameterElement $other)
- {
- // Format is:
- // @param type $variable Comment.
- // @param <-a-><---b---->
- // Compares the index before param variable.
- $otherVar = (strlen($other->_type) + strlen($other->_varNameWhitespace));
- $thisVar = (strlen($this->_type) + strlen($this->_varNameWhitespace));
- if ($otherVar !== $thisVar) {
- return false;
- }
-
- return true;
-
- }//end alignsVariableWith()
-
-
- /**
- * Returns true if this parameter's comment aligns with the other's.
- *
- * @param PHP_CodeSniffer_CommentParser_ParameterElement $other The other param
- * to check
- * alignment with.
- *
- * @return boolean
- */
- public function alignsCommentWith(PHP_CodeSniffer_CommentParser_ParameterElement $other)
- {
- // Compares the index before param comment.
- $otherComment = (strlen($other->_varName) + strlen($other->_commentWhitespace));
- $thisComment = (strlen($this->_varName) + strlen($this->_commentWhitespace));
- if ($otherComment !== $thisComment) {
- return false;
- }
-
- return true;
-
- }//end alignsCommentWith()
-
-
- /**
- * Returns true if this parameter aligns with the other paramter.
- *
- * @param PHP_CodeSniffer_CommentParser_ParameterElement $other The other param
- * to check
- * alignment with.
- *
- * @return boolean
- */
- public function alignsWith(PHP_CodeSniffer_CommentParser_ParameterElement $other)
- {
- if ($this->alignsVariableWith($other) === false) {
- return false;
- }
-
- if ($this->alignsCommentWith($other) === false) {
- return false;
- }
-
- return true;
-
- }//end alignsWith()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * An exception to be thrown when a DocCommentParser finds an anomilty in a
- * doc comment.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-/**
- * An exception to be thrown when a DocCommentParser finds an anomilty in a
- * doc comment.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_CommentParser_ParserException extends Exception
-{
-
- /**
- * The line where the exception occured, in relation to the doc comment.
- *
- * @var int
- */
- private $_line = 0;
-
-
- /**
- * Constructs a DocCommentParserException.
- *
- * @param string $message The message of the exception.
- * @param int $line The position in comment where the error occured.
- * A position of 0 indicates that the error occured
- * at the opening line of the doc comment.
- */
- public function __construct($message, $line)
- {
- parent::__construct($message);
- $this->_line = $line;
-
- }//end __construct()
-
-
- /**
- * Returns the line number within the comment where the exception occured.
- *
- * @return int
- */
- public function getLineWithinComment()
- {
- return $this->_line;
-
- }//end getLineWithinComment()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * A class to represent single element doc tags.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (class_exists('PHP_CodeSniffer_CommentParser_AbstractDocElement', true) === false) {
- $error = 'Class PHP_CodeSniffer_CommentParser_AbstractDocElement not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * A class to represent single element doc tags.
- *
- * A single element doc tag contains only one value after the tag itself. An
- * example would be the \@package tag.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_CommentParser_SingleElement extends PHP_CodeSniffer_CommentParser_AbstractDocElement
-{
-
- /**
- * The content that exists after the tag.
- *
- * @var string
- * @see getContent()
- */
- protected $content = '';
-
- /**
- * The whitespace that exists before the content.
- *
- * @var string
- * @see getWhitespaceBeforeContent()
- */
- protected $contentWhitespace = '';
-
-
- /**
- * Constructs a SingleElement doc tag.
- *
- * @param PHP_CodeSniffer_CommentParser_DocElement $previousElement The element
- * before this
- * one.
- * @param array $tokens The tokens
- * that comprise
- * this element.
- * @param string $tag The tag that
- * this element
- * represents.
- * @param PHP_CodeSniffer_File $phpcsFile The file that
- * this element
- * is in.
- */
- public function __construct($previousElement, $tokens, $tag, PHP_CodeSniffer_File $phpcsFile)
- {
- parent::__construct($previousElement, $tokens, $tag, $phpcsFile);
-
- }//end __construct()
-
-
- /**
- * Returns the element names that this tag is comprised of, in the order
- * that they appear in the tag.
- *
- * @return array(string)
- * @see processSubElement()
- */
- protected function getSubElements()
- {
- return array('content');
-
- }//end getSubElements()
-
-
- /**
- * Processes the sub element with the specified name.
- *
- * @param string $name The name of the sub element to process.
- * @param string $content The content of this sub element.
- * @param string $whitespaceBefore The whitespace that exists before the
- * sub element.
- *
- * @return void
- * @see getSubElements()
- */
- protected function processSubElement($name, $content, $whitespaceBefore)
- {
- $this->content = $content;
- $this->contentWhitespace = $whitespaceBefore;
-
- }//end processSubElement()
-
-
- /**
- * Returns the content of this tag.
- *
- * @return string
- */
- public function getContent()
- {
- return $this->content;
-
- }//end getContent()
-
-
- /**
- * Returns the witespace before the content of this tag.
- *
- * @return string
- */
- public function getWhitespaceBeforeContent()
- {
- return $this->contentWhitespace;
-
- }//end getWhitespaceBeforeContent()
-
-
- /**
- * Processes a content check for single doc element.
- *
- * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
- * @param int $commentStart The line number where
- * the error occurs.
- * @param string $docBlock Whether this is a file or
- * class comment doc.
- *
- * @return void
- */
- public function process(PHP_CodeSniffer_File $phpcsFile, $commentStart, $docBlock)
- {
- if ($this->content === '') {
- $errorPos = ($commentStart + $this->getLine());
- $error = "Content missing for $this->tag tag in $docBlock comment";
- $phpcsFile->addError($error, $errorPos);
- }
-
- }//end process()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * The base class for all PHP_CodeSniffer documentation generators.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-/**
- * The base class for all PHP_CodeSniffer documentation generators.
- *
- * Documentation generators are used to print documentation about code sniffs
- * in a standard.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_DocGenerators_Generator
-{
-
- /**
- * The name of the coding standard we are generating docs for.
- *
- * @var string
- */
- private $_standard = '';
-
- /**
- * An array of sniffs that we are limiting the generated docs to.
- *
- * If this array is empty, docs are generated for all sniffs in the
- * supplied coding standard.
- *
- * @var string
- */
- private $_sniffs = array();
-
-
- /**
- * Constructs a PHP_CodeSniffer_DocGenerators_Generator object.
- *
- * @param string $standard The name of the coding standard to generate
- * docs for.
- * @param array $sniffs An array of sniffs that we are limiting the
- * generated docs to.
- *
- * @see generate()
- */
- public function __construct($standard, array $sniffs=array())
- {
- $this->_standard = $standard;
- $this->_sniffs = $sniffs;
-
- }//end __construct()
-
-
- /**
- * Retrieves the title of the sniff from the DOMNode supplied.
- *
- * @param DOMNode $doc The DOMNode object for the sniff.
- * It represents the "documentation" tag in the XML
- * standard file.
- *
- * @return string
- */
- protected function getTitle(DOMNode $doc)
- {
- return $doc->getAttribute('title');
-
- }//end getTitle()
-
-
- /**
- * Retrieves the name of the standard we are generating docs for.
- *
- * @return string
- */
- protected function getStandard()
- {
- return $this->_standard;
-
- }//end getStandard()
-
-
- /**
- * Generates the documentation for a standard.
- *
- * It's probably wise for doc generators to override this method so they
- * have control over how the docs are produced. Otherwise, the processSniff
- * method should be overridden to output content for each sniff.
- *
- * @return void
- * @see processSniff()
- */
- public function generate()
- {
- $standardFiles = $this->getStandardFiles();
-
- foreach ($standardFiles as $standard) {
- $doc = new DOMDocument();
- $doc->load($standard);
- $documentation = $doc->getElementsByTagName('documentation')->item(0);
- $this->processSniff($documentation);
- }
-
- }//end generate()
-
-
- /**
- * Returns a list of paths to XML standard files for all sniffs in a standard.
- *
- * Any sniffs that do not have an XML standard file are obviously not included
- * in the returned array. If documentation is only being generated for some
- * sniffs (ie. $this->_sniffs is not empty) then all others sniffs will
- * be filtered from the results as well.
- *
- * @return array(string)
- */
- protected function getStandardFiles()
- {
- if (is_dir($this->_standard) === true) {
- // This is a custom standard.
- $standardDir = $this->_standard;
- $standard = basename($this->_standard);
- } else {
- $standardDir = realpath(dirname(__FILE__).'/../Standards/'.$this->_standard);
- $standard = $this->_standard;
- }
-
- $sniffs = PHP_CodeSniffer::getSniffFiles($standardDir, $standard);
-
- $standardFiles = array();
- foreach ($sniffs as $sniff) {
- if (empty($this->_sniffs) === false) {
- // We are limiting the docs to certain sniffs only, so filter
- // out any unwanted sniffs.
- $sniffName = substr($sniff, (strrpos($sniff, '/') + 1));
- $sniffName = substr($sniffName, 0, -9);
- if (in_array($sniffName, $this->_sniffs) === false) {
- continue;
- }
- }
-
- $standardFile = str_replace(DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR.'Docs'.DIRECTORY_SEPARATOR, $sniff);
- $standardFile = str_replace('Sniff.php', 'Standard.xml', $standardFile);
-
- if (is_file($standardFile) === true) {
- $standardFiles[] = $standardFile;
- }
- }
-
- return $standardFiles;
-
- }//end getStandardFiles()
-
-
- /**
- * Process the documentation for a single sniff.
- *
- * Doc generators should override this function to produce output.
- *
- * @param DOMNode $doc The DOMNode object for the sniff.
- * It represents the "documentation" tag in the XML
- * standard file.
- *
- * @return void
- * @see generate()
- */
- protected function processSniff(DOMNode $doc)
- {
-
- }//end processSniff()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * A doc generator that outputs documentation in one big HTML file.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-require_once 'PHP/CodeSniffer/DocGenerators/Generator.php';
-
-/**
- * A doc generator that outputs documentation in one big HTML file.
- *
- * Output is in one large HTML file and is designed for you to style with
- * your own stylesheet. It contains a table of contents at the top with anchors
- * to each sniff.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_DocGenerators_HTML extends PHP_CodeSniffer_DocGenerators_Generator
-{
-
-
- /**
- * Generates the documentation for a standard.
- *
- * @return void
- * @see processSniff()
- */
- public function generate()
- {
- ob_start();
- $this->printHeader();
-
- $standardFiles = $this->getStandardFiles();
- $this->printToc($standardFiles);
-
- foreach ($standardFiles as $standard) {
- $doc = new DOMDocument();
- $doc->load($standard);
- $documentation = $doc->getElementsByTagName('documentation')->item(0);
- $this->processSniff($documentation);
- }
-
- $this->printFooter();
-
- $content = ob_get_contents();
- ob_end_clean();
-
- echo $content;
-
- }//end generate()
-
-
- /**
- * Print the header of the HTML page.
- *
- * @return void
- */
- protected function printHeader()
- {
- $standard = $this->getStandard();
- echo '<html>'.PHP_EOL;
- echo ' <head>'.PHP_EOL;
- echo " <title>$standard Coding Standards</title>".PHP_EOL;
- echo ' <style>
- body {
- background-color: #FFFFFF;
- font-size: 14px;
- font-family: Arial, Helvetica, sans-serif;
- color: #000000;
- }
-
- h1 {
- color: #666666;
- font-size: 20px;
- font-weight: bold;
- margin-top: 0px;
- background-color: #E6E7E8;
- padding: 20px;
- border: 1px solid #BBBBBB;
- }
-
- h2 {
- color: #00A5E3;
- font-size: 16px;
- font-weight: normal;
- margin-top: 50px;
- }
-
- .code-comparison {
- width: 100%;
- }
-
- .code-comparison td {
- border: 1px solid #CCCCCC;
- }
-
- .code-comparison-title, .code-comparison-code {
- font-family: Arial, Helvetica, sans-serif;
- font-size: 12px;
- color: #000000;
- vertical-align: top;
- padding: 4px;
- width: 50%;
- background-color: #F1F1F1;
- line-height: 15px;
- }
-
- .code-comparison-code {
- font-family: Courier;
- background-color: #F9F9F9;
- }
-
- .code-comparison-highlight {
- background-color: #DDF1F7;
- border: 1px solid #00A5E3;
- line-height: 15px;
- }
-
- .tag-line {
- text-align: center;
- width: 100%;
- margin-top: 30px;
- font-size: 12px;
- }
-
- .tag-line a {
- color: #000000;
- }
- </style>'.PHP_EOL;
- echo ' </head>'.PHP_EOL;
- echo ' <body>'.PHP_EOL;
- echo " <h1>$standard Coding Standards</h1>".PHP_EOL;
-
- }//end printHeader()
-
-
- /**
- * Print the table of contents for the standard.
- *
- * The TOC is just an unordered list of bookmarks to sniffs on the page.
- *
- * @param array $standardFiles An array of paths to the XML standard files.
- *
- * @return void
- */
- protected function printToc($standardFiles)
- {
- echo ' <h2>Table of Contents</h2>'.PHP_EOL;
- echo ' <ul class="toc">'.PHP_EOL;
-
- foreach ($standardFiles as $standard) {
- $doc = new DOMDocument();
- $doc->load($standard);
- $documentation = $doc->getElementsByTagName('documentation')->item(0);
- $title = $this->getTitle($documentation);
- echo ' <li><a href="#'.str_replace(' ', '-', $title)."\">$title</a></li>".PHP_EOL;
- }
-
- echo ' </ul>'.PHP_EOL;
-
- }//end printToc()
-
-
- /**
- * Print the footer of the HTML page.
- *
- * @return void
- */
- protected function printFooter()
- {
- // Turn off strict errors so we don't get timezone warnings if people
- // don't have their timezone set.
- error_reporting(E_ALL);
- echo ' <div class="tag-line">';
- echo 'Documentation generated on '.date('r');
- echo ' by <a href="http://pear.php.net/package/PHP_CodeSniffer">PHP_CodeSniffer 1.1.0</a>';
- echo '</div>'.PHP_EOL;
- error_reporting(E_ALL | E_STRICT);
-
- echo ' </body>'.PHP_EOL;
- echo '</html>'.PHP_EOL;
-
- }//end printFooter()
-
-
- /**
- * Process the documentation for a single sniff.
- *
- * @param DOMNode $doc The DOMNode object for the sniff.
- * It represents the "documentation" tag in the XML
- * standard file.
- *
- * @return void
- */
- public function processSniff(DOMNode $doc)
- {
- $title = $this->getTitle($doc);
- echo ' <a name="'.str_replace(' ', '-', $title).'" />'.PHP_EOL;
- echo " <h2>$title</h2>".PHP_EOL;
-
- foreach ($doc->childNodes as $node) {
- if ($node->nodeName === 'standard') {
- $this->printTextBlock($node);
- } else if ($node->nodeName === 'code_comparison') {
- $this->printCodeComparisonBlock($node);
- }
- }
-
- }//end processSniff()
-
-
- /**
- * Print a text block found in a standard.
- *
- * @param DOMNode $node The DOMNode object for the text block.
- *
- * @return void
- */
- protected function printTextBlock($node)
- {
- $content = trim($node->nodeValue);
- $content = htmlspecialchars($content);
-
- // Allow em tags only.
- $content = str_replace('<em>', '<em>', $content);
- $content = str_replace('</em>', '</em>', $content);
-
- echo " <p class=\"text\">$content</p>".PHP_EOL;
-
- }//end printTextBlock()
-
-
- /**
- * Print a code comparison block found in a standard.
- *
- * @param DOMNode $node The DOMNode object for the code comparison block.
- *
- * @return void
- */
- protected function printCodeComparisonBlock($node)
- {
- $codeBlocks = $node->getElementsByTagName('code');
-
- $firstTitle = $codeBlocks->item(0)->getAttribute('title');
- $first = trim($codeBlocks->item(0)->nodeValue);
- $first = str_replace("\n", '</br>', $first);
- $first = str_replace(' ', ' ', $first);
- $first = str_replace('<em>', '<span class="code-comparison-highlight">', $first);
- $first = str_replace('</em>', '</span>', $first);
-
- $secondTitle = $codeBlocks->item(1)->getAttribute('title');
- $second = trim($codeBlocks->item(1)->nodeValue);
- $second = str_replace("\n", '</br>', $second);
- $second = str_replace(' ', ' ', $second);
- $second = str_replace('<em>', '<span class="code-comparison-highlight">', $second);
- $second = str_replace('</em>', '</span>', $second);
-
- echo ' <table class="code-comparison">'.PHP_EOL;
- echo ' <tr>'.PHP_EOL;
- echo " <td class=\"code-comparison-title\">$firstTitle</td>".PHP_EOL;
- echo " <td class=\"code-comparison-title\">$secondTitle</td>".PHP_EOL;
- echo ' </tr>'.PHP_EOL;
- echo ' <tr>'.PHP_EOL;
- echo " <td class=\"code-comparison-code\">$first</td>".PHP_EOL;
- echo " <td class=\"code-comparison-code\">$second</td>".PHP_EOL;
- echo ' </tr>'.PHP_EOL;
- echo ' </table>'.PHP_EOL;
-
- }//end printCodeComparisonBlock()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * A doc generator that outputs text-based documentation.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-require_once 'PHP/CodeSniffer/DocGenerators/Generator.php';
-
-/**
- * A doc generator that outputs text-based documentation.
- *
- * Output is designed to be displayed in a terminal and is wrapped to 100 characters.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_DocGenerators_Text extends PHP_CodeSniffer_DocGenerators_Generator
-{
-
-
- /**
- * Process the documentation for a single sniff.
- *
- * @param DOMNode $doc The DOMNode object for the sniff.
- * It represents the "documentation" tag in the XML
- * standard file.
- *
- * @return void
- */
- public function processSniff(DOMNode $doc)
- {
- $this->printTitle($doc);
-
- foreach ($doc->childNodes as $node) {
- if ($node->nodeName === 'standard') {
- $this->printTextBlock($node);
- } else if ($node->nodeName === 'code_comparison') {
- $this->printCodeComparisonBlock($node);
- }
- }
-
- }//end processSniff()
-
-
- /**
- * Prints the title area for a single sniff.
- *
- * @param DOMNode $doc The DOMNode object for the sniff.
- * It represents the "documentation" tag in the XML
- * standard file.
- *
- * @return void
- */
- protected function printTitle(DOMNode $doc)
- {
- $title = $this->getTitle($doc);
- $standard = $this->getStandard();
-
- echo PHP_EOL;
- echo str_repeat('-', (strlen("$standard CODING STANDARD: $title") + 4));
- echo strtoupper(PHP_EOL."| $standard CODING STANDARD: $title |".PHP_EOL);
- echo str_repeat('-', (strlen("$standard CODING STANDARD: $title") + 4));
- echo PHP_EOL.PHP_EOL;
-
- }//end printTitle()
-
-
- /**
- * Print a text block found in a standard.
- *
- * @param DOMNode $node The DOMNode object for the text block.
- *
- * @return void
- */
- protected function printTextBlock($node)
- {
- $text = trim($node->nodeValue);
- $text = str_replace('<em>', '*', $text);
- $text = str_replace('</em>', '*', $text);
-
- $lines = array();
- $tempLine = '';
- $words = explode(' ', $text);
-
- foreach ($words as $word) {
- if (strlen($tempLine.$word) >= 99) {
- if (strlen($tempLine.$word) === 99) {
- // Adding the extra space will push us to the edge
- // so we are done.
- $lines[] = $tempLine.$word;
- $tempLine = '';
- } else if (strlen($tempLine.$word) === 100) {
- // We are already at the edge, so we are done.
- $lines[] = $tempLine.$word;
- $tempLine = '';
- } else {
- $lines[] = rtrim($tempLine);
- $tempLine = $word.' ';
- }
- } else {
- $tempLine .= $word.' ';
- }
- }//end foreach
-
- if ($tempLine !== '') {
- $lines[] = rtrim($tempLine);
- }
-
- echo implode(PHP_EOL, $lines).PHP_EOL.PHP_EOL;
-
- }//end printTextBlock()
-
-
- /**
- * Print a code comparison block found in a standard.
- *
- * @param DOMNode $node The DOMNode object for the code comparison block.
- *
- * @return void
- */
- protected function printCodeComparisonBlock($node)
- {
- $codeBlocks = $node->getElementsByTagName('code');
- $first = trim($codeBlocks->item(0)->nodeValue);
- $firstTitle = $codeBlocks->item(0)->getAttribute('title');
-
- $firstTitleLines = array();
- $tempTitle = '';
- $words = explode(' ', $firstTitle);
-
- foreach ($words as $word) {
- if (strlen($tempTitle.$word) >= 45) {
- if (strlen($tempTitle.$word) === 45) {
- // Adding the extra space will push us to the edge
- // so we are done.
- $firstTitleLines[] = $tempTitle.$word;
- $tempTitle = '';
- } else if (strlen($tempTitle.$word) === 46) {
- // We are already at the edge, so we are done.
- $firstTitleLines[] = $tempTitle.$word;
- $tempTitle = '';
- } else {
- $firstTitleLines[] = $tempTitle;
- $tempTitle = $word;
- }
- } else {
- $tempTitle .= $word.' ';
- }
- }//end foreach
-
- if ($tempTitle !== '') {
- $firstTitleLines[] = $tempTitle;
- }
-
- $first = str_replace('<em>', '', $first);
- $first = str_replace('</em>', '', $first);
- $firstLines = explode("\n", $first);
-
- $second = trim($codeBlocks->item(1)->nodeValue);
- $secondTitle = $codeBlocks->item(1)->getAttribute('title');
-
- $secondTitleLines = array();
- $tempTitle = '';
- $words = explode(' ', $secondTitle);
-
- foreach ($words as $word) {
- if (strlen($tempTitle.$word) >= 45) {
- if (strlen($tempTitle.$word) === 45) {
- // Adding the extra space will push us to the edge
- // so we are done.
- $secondTitleLines[] = $tempTitle.$word;
- $tempTitle = '';
- } else if (strlen($tempTitle.$word) === 46) {
- // We are already at the edge, so we are done.
- $secondTitleLines[] = $tempTitle.$word;
- $tempTitle = '';
- } else {
- $secondTitleLines[] = $tempTitle;
- $tempTitle = $word;
- }
- } else {
- $tempTitle .= $word.' ';
- }
- }//end foreach
-
- if ($tempTitle !== '') {
- $secondTitleLines[] = $tempTitle;
- }
-
- $second = str_replace('<em>', '', $second);
- $second = str_replace('</em>', '', $second);
- $secondLines = explode("\n", $second);
-
- $maxCodeLines = max(count($firstLines), count($secondLines));
- $maxTitleLines = max(count($firstTitleLines), count($secondTitleLines));
-
- echo str_repeat('-', 41);
- echo ' CODE COMPARISON ';
- echo str_repeat('-', 42).PHP_EOL;
-
- for ($i = 0; $i < $maxTitleLines; $i++) {
- if (isset($firstTitleLines[$i]) === true) {
- $firstLineText = $firstTitleLines[$i];
- } else {
- $firstLineText = '';
- }
-
- if (isset($secondTitleLines[$i]) === true) {
- $secondLineText = $secondTitleLines[$i];
- } else {
- $secondLineText = '';
- }
-
- echo '| ';
- echo $firstLineText.str_repeat(' ', (46 - strlen($firstLineText)));
- echo ' | ';
- echo $secondLineText.str_repeat(' ', (47 - strlen($secondLineText)));
- echo ' |'.PHP_EOL;
- }//end for
-
- echo str_repeat('-', 100).PHP_EOL;
-
- for ($i = 0; $i < $maxCodeLines; $i++) {
- if (isset($firstLines[$i]) === true) {
- $firstLineText = $firstLines[$i];
- } else {
- $firstLineText = '';
- }
-
- if (isset($secondLines[$i]) === true) {
- $secondLineText = $secondLines[$i];
- } else {
- $secondLineText = '';
- }
-
- echo '| ';
- echo $firstLineText.str_repeat(' ', (47 - strlen($firstLineText)));
- echo '| ';
- echo $secondLineText.str_repeat(' ', (48 - strlen($secondLineText)));
- echo '|'.PHP_EOL;
- }//end for
-
- echo str_repeat('-', 100).PHP_EOL.PHP_EOL;
-
- }//end printCodeComparisonBlock()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-/**
- * An exception thrown by PHP_CodeSniffer when it encounters an unrecoverable error.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-require_once 'PEAR/Exception.php';
-
-/**
- * An exception thrown by PHP_CodeSniffer when it encounters an unrecoverable error.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_Exception extends PEAR_Exception
-{
-
-}//end class
-
-?>
\ No newline at end of file
+++ /dev/null
-<?php
-/**
- * A PHP_CodeSniffer_File object represents a PHP source file and the tokens
- * associated with it.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-/**
- * A PHP_CodeSniffer_File object represents a PHP source file and the tokens
- * associated with it.
- *
- * It provides a means for traversing the token stack, along with
- * other token related operations. If a PHP_CodeSniffer_Sniff finds and error or
- * warning within a PHP_CodeSniffer_File, you can raise an error using the
- * addError() or addWarning() methods.
- *
- * <b>Token Information</b>
- *
- * Each token within the stack contains information about itself:
- *
- * <code>
- * array(
- * 'code' => 301, // the token type code (see token_get_all())
- * 'content' => 'if', // the token content
- * 'type' => 'T_IF', // the token name
- * 'line' => 56, // the line number when the token is located
- * 'column' => 12, // the column in the line where this token
- * // starts (starts from 1)
- * 'level' => 2 // the depth a token is within the scopes open
- * 'conditions' => array( // a list of scope condition token
- * // positions => codes that
- * 2 => 50, // openened the scopes that this token exists
- * 9 => 353, // in (see conditional tokens section below)
- * ),
- * );
- * </code>
- *
- * <b>Conditional Tokens</b>
- *
- * In addition to the standard token fields, conditions contain information to
- * determine where their scope begins and ends:
- *
- * <code>
- * array(
- * 'scope_condition' => 38, // the token position of the condition
- * 'scope_opener' => 41, // the token position that started the scope
- * 'scope_closer' => 70, // the token position that ended the scope
- * );
- * </code>
- *
- * The condition, the scope opener and the scope closer each contain this
- * information.
- *
- * <b>Parenthesis Tokens</b>
- *
- * Each parenthesis token (T_OPEN_PARENTHESIS and T_CLOSE_PARENTHESIS) has a
- * reference to their opening and closing parenthesis, one being itself, the
- * other being its oposite.
- *
- * <code>
- * array(
- * 'parenthesis_opener' => 34,
- * 'parenthesis_closer' => 40,
- * );
- * </code>
- *
- * Some tokens can "own" a set of parethesis. For example a T_FUNCTION token
- * has parenthesis around its argument list. These tokens also have the
- * parenthesis_opener and and parenthesis_closer indicies. Not all parethesis
- * have owners, for example parenthesis used for arithmetic operations and
- * function calls. The parenthesis tokens that have an owner have the following
- * auxilery array indicies.
- *
- * <code>
- * array(
- * 'parenthesis_opener' => 34,
- * 'parenthesis_closer' => 40,
- * 'parenthesis_owner' => 33,
- * );
- * </code>
- *
- * Each token within a set of parenthesis also has an array indicy
- * 'nested_parenthesis' which is an array of the
- * left parenthesis => right parenthesis token positions.
- *
- * <code>
- * 'nested_parentheisis' => array(
- * 12 => 15
- * 11 => 14
- * );
- * </code>
- *
- * <b>Extended Tokens</b>
- *
- * PHP_CodeSniffer extends and augments some of the tokens created by
- * <i>token_get_all()</i>. A full list of these tokens can be seen in the
- * <i>Tokens.php</i> file.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-class PHP_CodeSniffer_File
-{
-
- /**
- * The absolute path to the file associated with this object.
- *
- * @var string
- */
- private $_file = '';
-
- /**
- * The EOL character this file uses.
- *
- * @var string
- */
- public $eolChar = '';
-
- /**
- * The tokenizer being used for this file.
- *
- * @var object
- */
- public $tokenizer = null;
-
- /**
- * The tokenizer being used for this file.
- *
- * @var string
- */
- public $tokenizerType = 'PHP';
-
- /**
- * The number of tokens in this file.
- *
- * Stored here to save calling count() everywhere.
- *
- * @var int
- */
- public $numTokens = 0;
-
- /**
- * The tokens stack map.
- *
- * Note that the tokens in this array differ in format to the tokens
- * produced by token_get_all(). Tokens are initially produced with
- * token_get_all(), then augmented so that it's easier to process them.
- *
- * @var array()
- * @see Tokens.php
- */
- private $_tokens = array();
-
- /**
- * The errors raised from PHP_CodeSniffer_Sniffs.
- *
- * @var array()
- * @see getErrors()
- */
- private $_errors = array();
-
- /**
- * The warnings raised form PHP_CodeSniffer_Sniffs.
- *
- * @var array()
- * @see getWarnings()
- */
- private $_warnings = array();
-
- /**
- * The total number of errors raised.
- *
- * @var int
- */
- private $_errorCount = 0;
-
- /**
- * The total number of warnings raised.
- *
- * @var int
- */
- private $_warningCount = 0;
-
- /**
- * An array of sniffs listening to this file's processing.
- *
- * @var array(PHP_CodeSniffer_Sniff)
- */
- private $_listeners = array();
-
- /**
- * A constant to represent an error in PHP_CodeSniffer.
- *
- * @var int
- */
- const ERROR = 0;
-
- /**
- * A constant to represent a warning in PHP_CodeSniffer.
- *
- * @var int
- */
- const WARNING = 1;
-
- /**
- * An array of extensions mapping to the tokenizer to use.
- *
- * This value gets set by PHP_CodeSniffer when the object is created.
- *
- * @var array
- */
- protected $tokenizers = array();
-
-
- /**
- * Constructs a PHP_CodeSniffer_File.
- *
- * @param string $file The absolute path to the file
- * to process.
- * @param array(string) $listeners The initial listeners listening
- * to processing of this file.
- * @param array $tokenizers An array of extensions mapping
- * to the tokenizer to use.
- *
- * @throws PHP_CodeSniffer_Exception If the register() method does
- * not return an array.
- */
- public function __construct($file, array $listeners, array $tokenizers)
- {
- foreach ($listeners as $listenerClass) {
- $listener = new $listenerClass();
- $tokens = $listener->register();
-
- if (is_array($tokens) === false) {
- $msg = "Sniff $listenerClass register() method must return an array";
- throw new PHP_CodeSniffer_Exception($msg);
- }
-
- $this->addTokenListener($listener, $tokens);
- }
-
- $this->_file = trim($file);
- $this->tokenizers = $tokenizers;
-
- }//end __construct()
-
-
- /**
- * Adds a listener to the token stack that listens to the specific tokens.
- *
- * When PHP_CodeSniffer encounters on the the tokens specified in $tokens, it
- * invokes the process method of the sniff.
- *
- * @param PHP_CodeSniffer_Sniff $listener The listener to add to the
- * listener stack.
- * @param array(int) $tokens The token types the listener wishes to
- * listen to.
- *
- * @return void
- */
- public function addTokenListener(PHP_CodeSniffer_Sniff $listener, array $tokens)
- {
- foreach ($tokens as $token) {
- if (isset($this->_listeners[$token]) === false) {
- $this->_listeners[$token] = array();
- }
-
- if (in_array($listener, $this->_listeners[$token], true) === false) {
- $this->_listeners[$token][] = $listener;
- }
- }
-
- }//end addTokenListener()
-
-
- /**
- * Removes a listener from listening from the specified tokens.
- *
- * @param PHP_CodeSniffer_Sniff $listener The listener to remove from the
- * listener stack.
- * @param array(int) $tokens The token types the listener wishes to
- * stop listen to.
- *
- * @return void
- */
- public function removeTokenListener(PHP_CodeSniffer_Sniff $listener, array $tokens)
- {
- foreach ($tokens as $token) {
- if (isset($this->_listeners[$token]) === false) {
- continue;
- }
-
- if (in_array($listener, $this->_listeners[$token]) === true) {
- foreach ($this->_listeners[$token] as $pos => $value) {
- if ($value === $listener) {
- unset($this->_listeners[$token][$pos]);
- }
- }
- }
- }
-
- }//end removeTokenListener()
-
-
- /**
- * Returns the token stack for this file.
- *
- * @return array()
- */
- public function getTokens()
- {
- return $this->_tokens;
-
- }//end getTokens()
-
-
- /**
- * Starts the stack traversal and tells listeners when tokens are found.
- *
- * @param string $contents The contents to parse. If NULL, the content
- * is taken from the file system.
- *
- * @return void
- */
- public function start($contents=null)
- {
- $this->_parse($contents);
-
- if (PHP_CODESNIFFER_VERBOSITY > 2) {
- echo "\t*** START TOKEN PROCESSING ***".PHP_EOL;
- }
-
- // Foreach of the listeners that have registed to listen for this
- // token, get them to process it.
- foreach ($this->_tokens as $stackPtr => $token) {
- if (PHP_CODESNIFFER_VERBOSITY > 2) {
- $type = $token['type'];
- $content = str_replace($this->eolChar, '\n', $token['content']);
- echo "\t\tProcess token $stackPtr: $type => $content".PHP_EOL;
- }
-
- $tokenType = $token['code'];
- if (isset($this->_listeners[$tokenType]) === true) {
- foreach ($this->_listeners[$tokenType] as $listener) {
- // Make sure this sniff supports the tokenizer
- // we are currently using.
- $vars = get_class_vars(get_class($listener));
- if (isset($vars['supportedTokenizers']) === true) {
- if (in_array($this->tokenizerType, $vars['supportedTokenizers']) === false) {
- continue;
- }
- } else {
- // The default supported tokenizer is PHP.
- if ($this->tokenizerType !== 'PHP') {
- continue;
- }
- }
-
- if (PHP_CODESNIFFER_VERBOSITY > 2) {
- $startTime = microtime(true);
- echo "\t\t\tProcessing ".get_class($listener).'... ';
- }
-
- $listener->process($this, $stackPtr);
-
- if (PHP_CODESNIFFER_VERBOSITY > 2) {
- $timeTaken = round((microtime(true) - $startTime), 4);
- echo "DONE in $timeTaken seconds".PHP_EOL;
- }
- }//end foreach
- }//end if
- }//end foreach
-
- if (PHP_CODESNIFFER_VERBOSITY > 2) {
- echo "\t*** END TOKEN PROCESSING ***".PHP_EOL;
- }
-
- // We don't need the tokens any more, so get rid of them
- // to save some memory.
- $this->_tokens = null;
- $this->_listeners = null;
-
- }//end start()
-
-
- /**
- * Tokenizes the file and preapres it for the test run.
- *
- * @param string $contents The contents to parse. If NULL, the content
- * is taken from the file system.
- *
- * @return void
- */
- private function _parse($contents=null)
- {
- $this->eolChar = self::detectLineEndings($this->_file, $contents);
-
- // Determine the tokenizer from the file extension.
- $fileParts = explode('.', $this->_file);
- $extension = array_pop($fileParts);
- if (isset($this->tokenizers[$extension]) === true) {
- $tokenizerClass = 'PHP_CodeSniffer_Tokenizers_'.$this->tokenizers[$extension];
- $this->tokenizerType = $this->tokenizers[$extension];
- } else {
- // Revert to default.
- $tokenizerClass = 'PHP_CodeSniffer_Tokenizers_'.$this->tokenizerType;
- }
-
- $tokenizer = new $tokenizerClass();
- $this->tokenizer = $tokenizer;
-
- if ($contents === null) {
- $contents = file_get_contents($this->_file);
- }
-
- $this->_tokens = self::tokenizeString($contents, $tokenizer, $this->eolChar);
- $this->numTokens = count($this->_tokens);
-
- if (PHP_CODESNIFFER_VERBOSITY > 0) {
- if ($this->numTokens === 0) {
- $numLines = 0;
- } else {
- $numLines = $this->_tokens[($this->numTokens - 1)]['line'];
- }
-
- echo "[$this->numTokens tokens in $numLines lines]... ";
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo PHP_EOL;
- }
- }
-
- }//end _parse()
-
-
- /**
- * Opens a file and detects the EOL character being used.
- *
- * @param string $file The full path to the file.
- * @param string $contents The contents to parse. If NULL, the content
- * is taken from the file system.
- *
- * @return string
- * @throws PHP_CodeSniffer_Exception If $file could not be opened.
- */
- public static function detectLineEndings($file, $contents=null)
- {
- if ($contents === null) {
- // Determine the newline character being used in this file.
- // Will be either \r, \r\n or \n.
- $handle = fopen($file, 'r');
- if ($handle === false) {
- $error = 'File could not be opened; could not auto-detect line endings';
- throw new PHP_CodeSniffer_Exception($error);
- }
-
- $firstLine = fgets($handle);
- fclose($handle);
-
- $eolChar = substr($firstLine, -1);
- if ($eolChar === "\n") {
- $secondLastChar = substr($firstLine, -2, 1);
- if ($secondLastChar === "\r") {
- $eolChar = "\r\n";
- }
- }
- } else {
- if (preg_match("/\r\n?|\n/", $contents, $matches) !== 1) {
- $error = 'Could not auto-detect line endings from content';
- throw new PHP_CodeSniffer_Exception($error);
- }
-
- $eolChar = $matches[0];
- }//end if
-
- return $eolChar;
-
- }//end detectLineEndings()
-
-
- /**
- * Adds an error to the error stack.
- *
- * @param string $error The error message.
- * @param int $stackPtr The stack position where the error occured.
- *
- * @return void
- */
- public function addError($error, $stackPtr)
- {
- if ($stackPtr === null) {
- $lineNum = 1;
- $column = 1;
- } else {
- $lineNum = $this->_tokens[$stackPtr]['line'];
- $column = $this->_tokens[$stackPtr]['column'];
- }
-
- if (isset($this->_errors[$lineNum]) === false) {
- $this->errors[$lineNum] = array();
- }
-
- if (isset($this->_errors[$lineNum][$column]) === false) {
- $this->errors[$lineNum][$column] = array();
- }
-
- $this->_errors[$lineNum][$column][] = $error;
- $this->_errorCount++;
-
- }//end addError()
-
-
- /**
- * Adds an warning to the warning stack.
- *
- * @param string $warning The error message.
- * @param int $stackPtr The stack position where the error occured.
- *
- * @return void
- */
- public function addWarning($warning, $stackPtr)
- {
- if ($stackPtr === null) {
- $lineNum = 1;
- $column = 1;
- } else {
- $lineNum = $this->_tokens[$stackPtr]['line'];
- $column = $this->_tokens[$stackPtr]['column'];
- }
-
- if (isset($this->_warnings[$lineNum]) === false) {
- $this->_warnings[$lineNum] = array();
- }
-
- if (isset($this->_warnings[$lineNum][$column]) === false) {
- $this->_warnings[$lineNum][$column] = array();
- }
-
- $this->_warnings[$lineNum][$column][] = $warning;
- $this->_warningCount++;
-
- }//end addWarning()
-
-
- /**
- * Returns the number of errors raised.
- *
- * @return int
- */
- public function getErrorCount()
- {
- return $this->_errorCount;
-
- }//end getErrorCount()
-
-
- /**
- * Returns the number of warnings raised.
- *
- * @return int
- */
- public function getWarningCount()
- {
- return $this->_warningCount;
-
- }//end getWarningCount()
-
-
- /**
- * Returns the errors raised from processing this file.
- *
- * @return array
- */
- public function getErrors()
- {
- return $this->_errors;
-
- }//end getErrors()
-
-
- /**
- * Returns the warnings raised from processing this file.
- *
- * @return array
- */
- public function getWarnings()
- {
- return $this->_warnings;
-
- }//end getWarnings()
-
-
- /**
- * Returns the absolute filename of this file.
- *
- * @return string
- */
- public function getFilename()
- {
- return $this->_file;
-
- }//end getFilename()
-
-
- /**
- * Creates an array of tokens when given some PHP code.
- *
- * Starts by using token_get_all() but does a lot of extra processing
- * to insert information about the context of the token.
- *
- * @param string $string The string to tokenize.
- * @param object $tokenizer A tokenizer class to use to tokenize the string.
- * @param string $eolChar The EOL character to use for splitting strings.
- *
- * @return array
- */
- public static function tokenizeString($string, $tokenizer, $eolChar='\n')
- {
- $tokens = $tokenizer->tokenizeString($string, $eolChar);
-
- self::_createLineMap($tokens, $tokenizer, $eolChar);
- self::_createBracketMap($tokens, $tokenizer, $eolChar);
- self::_createParenthesisMap($tokens, $tokenizer, $eolChar);
- self::_createParenthesisNestingMap($tokens, $tokenizer, $eolChar);
- self::_createScopeMap($tokens, $tokenizer, $eolChar);
-
- // If we know the width of each tab, convert tabs
- // into spaces so sniffs can use one method of checking.
- if (PHP_CODESNIFFER_TAB_WIDTH > 0) {
- self::_convertTabs($tokens, $tokenizer, $eolChar);
- }
-
- // Column map requires the line map to be complete.
- self::_createColumnMap($tokens, $tokenizer, $eolChar);
- self::_createLevelMap($tokens, $tokenizer, $eolChar);
-
- return $tokens;
-
- }//end tokenizeString()
-
-
- /**
- * Creates a map of tokens => line numbers for each token.
- *
- * @param array &$tokens The array of tokens to process.
- * @param object $tokenizer The tokenizer being used to process this file.
- * @param string $eolChar The EOL character to use for splitting strings.
- *
- * @return void
- */
- private static function _createLineMap(&$tokens, $tokenizer, $eolChar)
- {
- $lineNumber = 1;
- $count = count($tokens);
-
- for ($i = 0; $i < $count; $i++) {
- $tokens[$i]['line'] = $lineNumber;
- $lineNumber += substr_count($tokens[$i]['content'], $eolChar);
- }
-
- }//end _createLineMap()
-
-
- /**
- * Converts tabs into spaces.
- *
- * Each tab can represent between 1 and $width spaces, so
- * this cannot be a straight string replace.
- *
- * @param array &$tokens The array of tokens to process.
- * @param object $tokenizer The tokenizer being used to process this file.
- * @param string $eolChar The EOL character to use for splitting strings.
- *
- * @return void
- */
- private static function _convertTabs(&$tokens, $tokenizer, $eolChar)
- {
- $currColumn = 1;
- $count = count($tokens);
-
- for ($i = 0; $i < $count; $i++) {
- $tokenContent = $tokens[$i]['content'];
-
- if (strpos($tokenContent, "\t") === false) {
- // There are no tabs in this content.
- $currColumn += (strlen($tokenContent) - 1);
- } else {
- // We need to determine the length of each tab.
- $tabs = preg_split("|(\t)|", $tokenContent, -1, PREG_SPLIT_DELIM_CAPTURE);
- $tabNum = 0;
- $adjustedTab = false;
- $tabsToSpaces = array();
- $newContent = '';
-
- foreach ($tabs as $content) {
- if ($content === '') {
- continue;
- }
-
- if (strpos($content, "\t") === false) {
- // This piece of content is not a tab.
- $currColumn += strlen($content);
- $newContent .= $content;
- } else {
- $lastCurrColumn = $currColumn;
- $tabNum++;
-
- // Move the pointer to the next tab stop.
- if (($currColumn % PHP_CODESNIFFER_TAB_WIDTH) === 0) {
- // This is the first tab, and we are already at a
- // tab stop, so this tab counts as a single space.
- $currColumn++;
- $adjustedTab = true;
- } else {
- $currColumn++;
- while (($currColumn % PHP_CODESNIFFER_TAB_WIDTH) != 0) {
- $currColumn++;
- }
-
- $currColumn++;
- }
-
- $newContent .= str_repeat(' ', ($currColumn - $lastCurrColumn));
- }//end if
- }//end foreach
-
- if ($tabNum === 1 && $adjustedTab === true) {
- $currColumn--;
- }
-
- $tokens[$i]['content'] = $newContent;
- }//end if
-
- if (isset($tokens[($i + 1)]['line']) === true && $tokens[($i + 1)]['line'] !== $tokens[$i]['line']) {
- $currColumn = 1;
- } else {
- $currColumn++;
- }
- }//end for
-
- }//end _convertTabs()
-
-
- /**
- * Creates a column map.
- *
- * The column map indicates where the token started on the line where it
- * exists.
- *
- * @param array &$tokens The array of tokens to process.
- * @param object $tokenizer The tokenizer being used to process this file.
- * @param string $eolChar The EOL character to use for splitting strings.
- *
- * @return void
- */
- private static function _createColumnMap(&$tokens, $tokenizer, $eolChar)
- {
- $currColumn = 1;
- $count = count($tokens);
-
- for ($i = 0; $i < $count; $i++) {
- $tokens[$i]['column'] = $currColumn;
- if (isset($tokens[($i + 1)]['line']) === true && $tokens[($i + 1)]['line'] !== $tokens[$i]['line']) {
- $currColumn = 1;
- } else {
- $currColumn += strlen($tokens[$i]['content']);
- }
- }
-
- }//end _createColumnMap()
-
-
- /**
- * Creates a map for opening and closing of square brackets.
- *
- * Each bracket token (T_OPEN_SQUARE_BRACKET and T_CLOSE_SQUARE_BRACKET)
- * has a reference to their opening and closing bracket
- * (bracket_opener and bracket_closer).
- *
- * @param array &$tokens The array of tokens to process.
- * @param object $tokenizer The tokenizer being used to process this file.
- * @param string $eolChar The EOL character to use for splitting strings.
- *
- * @return void
- */
- private static function _createBracketMap(&$tokens, $tokenizer, $eolChar)
- {
- $openers = array();
- $numTokens = count($tokens);
- $owners = array();
-
- for ($i = 0; $i < $numTokens; $i++) {
- if ($tokens[$i]['code'] === T_OPEN_SQUARE_BRACKET) {
- $openers[] = $i;
- } else if ($tokens[$i]['code'] === T_CLOSE_SQUARE_BRACKET) {
- if (empty($openers) === false) {
- $opener = array_pop($openers);
- $tokens[$i]['bracket_opener'] = $opener;
- $tokens[$i]['bracket_closer'] = $i;
- $tokens[$opener]['bracket_opener'] = $opener;
- $tokens[$opener]['bracket_closer'] = $i;
- }
- }
- }
-
- }//end _createBracketMap()
-
-
- /**
- * Creates a map for opening and closing of parenthesis.
- *
- * Each parenthesis token (T_OPEN_PARENTHESIS and T_CLOSE_PARENTHESIS) has a
- * reference to their opening and closing parenthesis (parenthesis_opener
- * and parenthesis_closer).
- *
- * @param array &$tokens The array of tokens to process.
- * @param object $tokenizer The tokenizer being used to process this file.
- * @param string $eolChar The EOL character to use for splitting strings.
- *
- * @return void
- */
- private static function _createParenthesisMap(&$tokens, $tokenizer, $eolChar)
- {
- $openers = array();
- $numTokens = count($tokens);
- $openOwner = null;
-
- for ($i = 0; $i < $numTokens; $i++) {
- if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$parenthesisOpeners) === true) {
- $tokens[$i]['parenthesis_opener'] = null;
- $tokens[$i]['parenthesis_closer'] = null;
- $tokens[$i]['parenthesis_owner'] = $i;
- $openOwner = $i;
- } else if ($tokens[$i]['code'] === T_OPEN_PARENTHESIS) {
- $openers[] = $i;
- $tokens[$i]['parenthesis_opener'] = $i;
- if ($openOwner !== null) {
- $tokens[$openOwner]['parenthesis_opener'] = $i;
- $tokens[$i]['parenthesis_owner'] = $openOwner;
- $openOwner = null;
- }
- } else if ($tokens[$i]['code'] === T_CLOSE_PARENTHESIS) {
- // Did we set an owner for this set of parenthesis?
- $numOpeners = count($openers);
- if ($numOpeners !== 0) {
- $opener = array_pop($openers);
- if (isset($tokens[$opener]['parenthesis_owner']) === true) {
- $owner = $tokens[$opener]['parenthesis_owner'];
-
- $tokens[$owner]['parenthesis_closer'] = $i;
- $tokens[$i]['parenthesis_owner'] = $owner;
- }
-
- $tokens[$i]['parenthesis_opener'] = $opener;
- $tokens[$i]['parenthesis_closer'] = $i;
- $tokens[$opener]['parenthesis_closer'] = $i;
- }
- }//end if
- }//end for
-
- }//end _createParenthesisMap()
-
-
- /**
- * Creates a map for the parenthesis tokens that surround other tokens.
- *
- * @param array &$tokens The array of tokens to process.
- * @param object $tokenizer The tokenizer being used to process this file.
- * @param string $eolChar The EOL character to use for splitting strings.
- *
- * @return void
- */
- private static function _createParenthesisNestingMap(&$tokens, $tokenizer, $eolChar)
- {
- $numTokens = count($tokens);
- $map = array();
- for ($i = 0; $i < $numTokens; $i++) {
- if (isset($tokens[$i]['parenthesis_opener']) === true && $i === $tokens[$i]['parenthesis_opener']) {
- if (empty($map) === false) {
- $tokens[$i]['nested_parenthesis'] = $map;
- }
-
- if (isset($tokens[$i]['parenthesis_closer']) === true) {
- $map[$tokens[$i]['parenthesis_opener']] = $tokens[$i]['parenthesis_closer'];
- }
- } else if (isset($tokens[$i]['parenthesis_closer']) === true && $i === $tokens[$i]['parenthesis_closer']) {
- array_pop($map);
- if (empty($map) === false) {
- $tokens[$i]['nested_parenthesis'] = $map;
- }
- } else {
- if (empty($map) === false) {
- $tokens[$i]['nested_parenthesis'] = $map;
- }
- }
- }
-
- }//end _createParenthesisNestingMap()
-
-
- /**
- * Creates a scope map of tokens that open scopes.
- *
- * @param array &$tokens The array of tokens to process.
- * @param object $tokenizer The tokenizer being used to process this file.
- * @param string $eolChar The EOL character to use for splitting strings.
- *
- * @return void
- * @see _recurseScopeMap()
- */
- private static function _createScopeMap(&$tokens, $tokenizer, $eolChar)
- {
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo "\t*** START SCOPE MAP ***".PHP_EOL;
- }
-
- $numTokens = count($tokens);
- for ($i = 0; $i < $numTokens; $i++) {
- // Check to see if the current token starts a new scope.
- if (isset($tokenizer->scopeOpeners[$tokens[$i]['code']]) === true) {
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$i]['type'];
- $content = str_replace($eolChar, '\n', $tokens[$i]['content']);
- echo "\tStart scope map at $i: $type => $content".PHP_EOL;
- }
-
- $i = self::_recurseScopeMap($tokens, $numTokens, $tokenizer, $eolChar, $i);
- }
- }
-
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo "\t*** END SCOPE MAP ***".PHP_EOL;
- }
-
- }//end _createScopeMap()
-
-
- /**
- * Recurses though the scope openers to build a scope map.
- *
- * @param array &$tokens The array of tokens to process.
- * @param int $numTokens The size of the tokens array.
- * @param object $tokenizer The tokenizer being used to process this file.
- * @param string $eolChar The EOL character to use for splitting strings.
- * @param int $stackPtr The position in the stack of the token that
- * opened the scope (eg. an IF token or FOR token).
- * @param int $depth How many scope levels down we are.
- *
- * @return int The position in the stack that closed the scope.
- */
- private static function _recurseScopeMap(&$tokens, $numTokens, $tokenizer, $eolChar, $stackPtr, $depth=1)
- {
- $opener = null;
- $currType = $tokens[$stackPtr]['code'];
- $startLine = $tokens[$stackPtr]['line'];
- $ignore = false;
-
- // If the start token for this scope opener is the same as
- // the scope token, we have already found our opener.
- if ($currType === $tokenizer->scopeOpeners[$currType]['start']) {
- $opener = $stackPtr;
- }
-
- for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
- $tokenType = $tokens[$i]['code'];
-
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$i]['type'];
- $content = str_replace($eolChar, '\n', $tokens[$i]['content']);
- echo str_repeat("\t", $depth);
- echo "Process token $i [";
- if ($opener !== null) {
- echo "opener:$opener;";
- }
-
- if ($ignore === true) {
- echo 'ignore;';
- }
-
- echo "]: $type => $content".PHP_EOL;
- }
-
- // Is this an opening condition ?
- if (isset($tokenizer->scopeOpeners[$tokenType]) === true) {
- if ($opener === null) {
- // Found another opening condition but still haven't
- // found our opener, so we are never going to find one.
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$stackPtr]['type'];
- echo str_repeat("\t", $depth);
- echo "=> Couldn't find scope opener for $stackPtr ($type), bailing".PHP_EOL;
- }
-
- return $stackPtr;
- }
-
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", $depth);
- echo '* token is an opening condition *'.PHP_EOL;
- }
-
- $isShared = ($tokenizer->scopeOpeners[$tokenType]['shared'] === true);
-
- if (isset($tokens[$i]['scope_condition']) === true) {
- // We've been here before.
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", $depth);
- echo '* already processed, skipping *'.PHP_EOL;
- }
-
- if ($isShared === false && isset($tokens[$i]['scope_closer']) === true) {
- $i = $tokens[$i]['scope_closer'];
- }
-
- continue;
- } else if ($currType === $tokenType && $isShared === false && $opener === null) {
- // We haven't yet found our opener, but we have found another
- // scope opener which is the same type as us, and we don't
- // share openers, so we will never find one.
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", $depth);
- echo '* it was another token\'s opener, bailing *'.PHP_EOL;
- }
-
- return $stackPtr;
- } else {
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", $depth);
- echo '* searching for opener *'.PHP_EOL;
- }
-
- $i = self::_recurseScopeMap($tokens, $numTokens, $tokenizer, $eolChar, $i, ($depth + 1));
- }//end if
- }//end if start scope
-
- if ($tokenType === $tokenizer->scopeOpeners[$currType]['start'] && $opener === null) {
- if ($tokenType === T_OPEN_CURLY_BRACKET) {
- // Make sure this is actually an opener and not a
- // string offset (e.g., $var{0}).
- for ($x = ($i - 1); $x > 0; $x--) {
- if (in_array($tokens[$x]['code'], PHP_CodeSniffer_Tokens::$emptyTokens) === true) {
- continue;
- } else {
- // If the first non-whitespace/comment token is a
- // variable or object operator then this is an opener
- // for a string offset and not a scope.
- if ($tokens[$x]['code'] === T_VARIABLE || $tokens[$x]['code'] === T_OBJECT_OPERATOR) {
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", $depth);
- echo '* ignoring curly brace *'.PHP_EOL;
- }
-
- $ignore = true;
- }//end if
-
- break;
- }//end if
- }//end for
- }//end if
-
- if ($ignore === false) {
- // We found the opening scope token for $currType.
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$stackPtr]['type'];
- echo str_repeat("\t", $depth);
- echo "=> Found scope opener for $stackPtr ($type)".PHP_EOL;
- }
-
- $opener = $i;
- }
- } else if ($tokenType === $tokenizer->scopeOpeners[$currType]['end'] && $opener !== null) {
- if ($ignore === true && $tokenType === T_CLOSE_CURLY_BRACKET) {
- // The last opening bracket must have been for a string
- // offset or alike, so let's ignore it.
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", $depth);
- echo '* finished ignoring curly brace *'.PHP_EOL;
- }
-
- $ignore = false;
- } else {
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$stackPtr]['type'];
- echo str_repeat("\t", $depth);
- echo "=> Found scope closer for $stackPtr ($type)".PHP_EOL;
- }
-
- foreach (array($stackPtr, $opener, $i) as $token) {
- $tokens[$token]['scope_condition'] = $stackPtr;
- $tokens[$token]['scope_opener'] = $opener;
- $tokens[$token]['scope_closer'] = $i;
- }
-
- if ($tokenizer->scopeOpeners[$tokens[$stackPtr]['code']]['shared'] === true) {
- return $opener;
- } else {
- return $i;
- }
- }//end if
- } else if ($tokenType === T_OPEN_PARENTHESIS) {
- if (isset($tokens[$i]['parenthesis_owner']) === true) {
- $owner = $tokens[$i]['parenthesis_owner'];
- if (in_array($tokens[$owner]['code'], PHP_CodeSniffer_Tokens::$scopeOpeners) === true && isset($tokens[$i]['parenthesis_closer']) === true) {
- // If we get into here, then we opened a parenthesis for
- // a scope (eg. an if or else if). We can just skip to
- // the closing parenthesis.
- $i = $tokens[$i]['parenthesis_closer'];
-
- // Update the start of the line so that when we check to see
- // if the closing parenthesis is more than 3 lines away from
- // the statement, we check from the closing parenthesis.
- $startLine = $tokens[$tokens[$i]['parenthesis_closer']]['line'];
-
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", $depth);
- echo '* skipping parenthesis *'.PHP_EOL;
- }
- }
- }
- } else if ($tokenType === T_OPEN_CURLY_BRACKET && $opener !== null) {
- // We opened something that we don't have a scope opener for.
- // Examples of this are curly brackets for string offsets etc.
- // We want to ignore this so that we don't have an invalid scope
- // map.
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", $depth);
- echo '* ignoring curly brace *'.PHP_EOL;
- }
-
- $ignore = true;
- } else if ($opener === null && isset($tokenizer->scopeOpeners[$currType]) === true) {
- // If we still haven't found the opener after 3 lines,
- // we're not going to find it, unless we know it requires
- // an opener, in which case we better keep looking.
- if ($tokens[$i]['line'] >= ($startLine + 3)) {
- if ($tokenizer->scopeOpeners[$currType]['strict'] === true) {
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$stackPtr]['type'];
- $lines = ($tokens[$i]['line'] - $startLine);
- echo str_repeat("\t", $depth);
- echo "=> Still looking for $stackPtr ($type) scope opener after $lines lines".PHP_EOL;
- }
- } else {
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$stackPtr]['type'];
- echo str_repeat("\t", $depth);
- echo "=> Couldn't find scope opener for $stackPtr ($type), bailing".PHP_EOL;
- }
-
- return $stackPtr;
- }
- }
- } else if ($opener !== null && $tokenType !== T_BREAK && in_array($tokenType, $tokenizer->endScopeTokens) === true) {
- if (isset($tokens[$i]['scope_condition']) === false) {
- if ($ignore === true) {
- // We found the end token for the opener we were ignoring.
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", $depth);
- echo '* finished ignoring curly brace *'.PHP_EOL;
- }
-
- $ignore = false;
- } else {
- // We found a token that closes the scope but it doesn't
- // have a condition, so it belongs to another token and
- // our token doesn't have a closer, so pretend this is
- // the closer.
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$stackPtr]['type'];
- echo str_repeat("\t", $depth);
- echo "=> Found (unexpected) scope closer for $stackPtr ($type)".PHP_EOL;
- }
-
- foreach (array($stackPtr, $opener) as $token) {
- $tokens[$token]['scope_condition'] = $stackPtr;
- $tokens[$token]['scope_opener'] = $opener;
- $tokens[$token]['scope_closer'] = $i;
- }
-
- return ($i - 1);
- }//end if
- }//end if
- }//end if
- }//end for
-
- return $stackPtr;
-
- }//end _recurseScopeMap()
-
-
- /**
- * Constructs the level map.
- *
- * The level map adds a 'level' indice to each token which indicates the
- * depth that a token within a set of scope blocks. It also adds a
- * 'condition' indice which is an array of the scope conditions that opened
- * each of the scopes - position 0 being the first scope opener.
- *
- * @param array &$tokens The array of tokens to process.
- * @param object $tokenizer The tokenizer being used to process this file.
- * @param string $eolChar The EOL character to use for splitting strings.
- *
- * @return void
- */
- private static function _createLevelMap(&$tokens, $tokenizer, $eolChar)
- {
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo "\t*** START LEVEL MAP ***".PHP_EOL;
- }
-
- $numTokens = count($tokens);
- $level = 0;
- $conditions = array();
- $lastOpener = null;
- $openers = array();
-
- for ($i = 0; $i < $numTokens; $i++) {
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$i]['type'];
- $line = $tokens[$i]['line'];
- $content = str_replace($eolChar, '\n', $tokens[$i]['content']);
- echo str_repeat("\t", ($level + 1));
- echo "Process token $i on line $line [lvl:$level;";
- if (empty($conditions) !== true) {
- $condString = 'conds;';
- foreach ($conditions as $condition) {
- $condString .= token_name($condition).',';
- }
-
- echo rtrim($condString, ',').';';
- }
-
- echo "]: $type => $content".PHP_EOL;
- }
-
- $tokens[$i]['level'] = $level;
- $tokens[$i]['conditions'] = $conditions;
-
- if (isset($tokens[$i]['scope_condition']) === true) {
- // Check to see if this token opened the scope.
- if ($tokens[$i]['scope_opener'] === $i) {
- $stackPtr = $tokens[$i]['scope_condition'];
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$stackPtr]['type'];
- echo str_repeat("\t", ($level + 1));
- echo "=> Found scope opener for $stackPtr ($type)".PHP_EOL;
- }
-
- $stackPtr = $tokens[$i]['scope_condition'];
-
- // If we find a scope opener that has a shared closer,
- // then we need to go back over the condition map that we
- // just created and fix ourselves as we just added some
- // conditions where there was none. This happens for T_CASE
- // statements that are using the same break statement.
- if ($lastOpener !== null && $tokens[$lastOpener]['scope_closer'] === $tokens[$i]['scope_closer']) {
- // This opener shares its closer with the previous opener,
- // but we still need to check if the two openers share their
- // closer with each other directly (like CASE and DEFAULT)
- // or if they are just sharing because one doesn't have a
- // closer (like CASE with no BREAK using a SWITCHes closer).
- $thisType = $tokens[$tokens[$i]['scope_condition']]['code'];
- $opener = $tokens[$lastOpener]['scope_condition'];
- if (in_array($tokens[$opener]['code'], $tokenizer->scopeOpeners[$thisType]['with']) === true) {
- $badToken = $tokens[$lastOpener]['scope_condition'];
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$badToken]['type'];
- echo str_repeat("\t", ($level + 1));
- echo "* shared closer, cleaning up $badToken ($type) *".PHP_EOL;
- }
-
- for ($x = $tokens[$i]['scope_condition']; $x <= $i; $x++) {
- $oldConditions = $tokens[$x]['conditions'];
- $oldLevel = $tokens[$x]['level'];
- $tokens[$x]['level']--;
- unset($tokens[$x]['conditions'][$badToken]);
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$x]['type'];
- $oldConds = '';
- foreach ($oldConditions as $condition) {
- $oldConds .= token_name($condition).',';
- }
-
- $oldConds = rtrim($oldConds, ',');
-
- $newConds = '';
- foreach ($tokens[$x]['conditions'] as $condition) {
- $newConds .= token_name($condition).',';
- }
-
- $newConds = rtrim($newConds, ',');
-
- $newLevel = $tokens[$x]['level'];
- echo str_repeat("\t", ($level + 1));
- echo "* cleaned $x ($type) *".PHP_EOL;
- echo str_repeat("\t", ($level + 2));
- echo "=> level changed from $oldLevel to $newLevel".PHP_EOL;
- echo str_repeat("\t", ($level + 2));
- echo "=> conditions changed from $oldConds to $newConds".PHP_EOL;
- }//end if
- }//end for
-
- unset($conditions[$badToken]);
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$badToken]['type'];
- echo str_repeat("\t", ($level + 1));
- echo "* token $badToken ($type) removed from conditions array *".PHP_EOL;
- }
-
- unset ($openers[$lastOpener]);
-
- $level--;
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", ($level + 2));
- echo '* level decreased *'.PHP_EOL;
- }
- }//end if
- }//end if
-
- $level++;
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", ($level + 1));
- echo '* level increased *'.PHP_EOL;
- }
-
- $conditions[$stackPtr] = $tokens[$stackPtr]['code'];
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$stackPtr]['type'];
- echo str_repeat("\t", ($level + 1));
- echo "* token $stackPtr ($type) added to conditions array *".PHP_EOL;
- }
-
- $lastOpener = $tokens[$i]['scope_opener'];
- if ($lastOpener !== null) {
- $openers[$lastOpener] = $lastOpener;
- }
- } else if ($tokens[$i]['scope_closer'] === $i) {
- $removedCondition = false;
- foreach (array_reverse($openers) as $opener) {
- if ($tokens[$opener]['scope_closer'] === $i) {
- $oldOpener = array_pop($openers);
- if (empty($openers) === false) {
- $lastOpener = array_pop($openers);
- $openers[$lastOpener] = $lastOpener;
- } else {
- $lastOpener = null;
- }
-
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- $type = $tokens[$oldOpener]['type'];
- echo str_repeat("\t", ($level + 1));
- echo "=> Found scope closer for $oldOpener ($type)".PHP_EOL;
- }
-
- if ($removedCondition === false) {
- $oldCondition = array_pop($conditions);
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", ($level + 1));
- echo '* token '.token_name($oldCondition).' removed from conditions array *'.PHP_EOL;
- }
-
- $level--;
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo str_repeat("\t", ($level + 2));
- echo '* level decreased *'.PHP_EOL;
- }
- }
-
- $tokens[$i]['level'] = $level;
- $tokens[$i]['conditions'] = $conditions;
- }//end if
- }//end foreach
- }//end if
- }//end if
- }//end for
-
- if (PHP_CODESNIFFER_VERBOSITY > 1) {
- echo "\t*** END LEVEL MAP ***".PHP_EOL;
- }
-
- }//end _createLevelMap()
-
-
- /**
- * Returns the declaration names for T_CLASS, T_INTERFACE and T_FUNCTION tokens.
- *
- * @param int $stackPtr The position of the declaration token which
- * declared the class, interface or function.
- *
- * @return string The name of the class, interface or function.
- * @throws PHP_CodeSniffer_Exception If the specified token is not of type
- * T_FUNCTION, T_CLASS or T_INTERFACE.
- */
- public function getDeclarationName($stackPtr)
- {
- $tokenCode = $this->_tokens[$stackPtr]['code'];
- if ($tokenCode !== T_FUNCTION && $tokenCode !== T_CLASS && $tokenCode !== T_INTERFACE) {
- throw new PHP_CodeSniffer_Exception('Token type is not T_FUNCTION, T_CLASS OR T_INTERFACE');
- }
-
- $token = $this->findNext(T_STRING, $stackPtr);
- return $this->_tokens[$token]['content'];
-
- }//end getDeclarationName()
-
-
- /**
- * Returns the method parameters for the specified T_FUNCTION token.
- *
- * Each parameter is in the following format:
- *
- * <code>
- * 0 => array(
- * 'name' => '$var', // The variable name.
- * 'pass_by_reference' => false, // Passed by reference.
- * 'type_hint' => string, // Type hint for array or custom type
- * )
- * </code>
- *
- * Parameters with default values have and additional array indice of
- * 'default' with the value of the default as a string.
- *
- * @param int $stackPtr The position in the stack of the T_FUNCTION token
- * to acquire the parameters for.
- *
- * @return array()
- * @throws PHP_CodeSniffer_Exception If the specified $stackPtr is not of
- * type T_FUNCTION.
- */
- public function getMethodParameters($stackPtr)
- {
- if ($this->_tokens[$stackPtr]['code'] !== T_FUNCTION) {
- throw new PHP_CodeSniffer_Exception('$stackPtr must be of type T_FUNCTION');
- }
-
- $opener = $this->_tokens[$stackPtr]['parenthesis_opener'];
- $closer = $this->_tokens[$stackPtr]['parenthesis_closer'];
-
- $vars = array();
- $currVar = null;
- $defaultStart = null;
- $paramCount = 0;
- $passByReference = false;
- $typeHint = '';
-
- for ($i = ($opener + 1); $i <= $closer; $i++) {
- // Check to see if this token has a parenthesis opener. If it does
- // its likely to be an array, which might have arguments in it, which
- // we cause problems in our parsing below, so lets just skip to the
- // end of it.
- if (isset($this->_tokens[$i]['parenthesis_opener']) === true) {
- // Don't do this if its the close parenthesis for the method.
- if ($i !== $this->_tokens[$i]['parenthesis_closer']) {
- $i = ($this->_tokens[$i]['parenthesis_closer'] + 1);
- }
- }
-
- switch ($this->_tokens[$i]['code']) {
- case T_BITWISE_AND:
- $passByReference = true;
- break;
- case T_VARIABLE:
- $currVar = $i;
- break;
- case T_ARRAY_HINT:
- $typeHint = $this->_tokens[$i]['content'];
- break;
- case T_STRING:
- // This is a string, so it may be a type hint, but it could
- // also be a constant used as a default value.
- $prevComma = $this->findPrevious(T_COMMA, $i, $opener);
- if ($prevComma !== false) {
- $nextEquals = $this->findNext(T_EQUAL, $prevComma, $i);
- if ($nextEquals !== false) {
- break;
- }
- }
-
- $typeHint = $this->_tokens[$i]['content'];
- break;
- case T_CLOSE_PARENTHESIS:
- case T_COMMA:
- // If it's null, then there must be no parameters for this
- // method.
- if ($currVar === null) {
- continue;
- }
-
- $vars[$paramCount] = array();
- $vars[$paramCount]['name'] = $this->_tokens[$currVar]['content'];
-
- if ($defaultStart !== null) {
- $vars[$paramCount]['default'] = $this->getTokensAsString($defaultStart, ($i - $defaultStart));
- }
-
- $vars[$paramCount]['pass_by_reference'] = $passByReference;
- $vars[$paramCount]['type_hint'] = $typeHint;
-
- // Reset the vars, as we are about to process the next parameter.
- $defaultStart = null;
- $passByReference = false;
- $typeHint = '';
-
- $paramCount++;
- break;
- case T_EQUAL:
- $defaultStart = ($i + 1);
- break;
- }//end switch
- }//end for
-
- return $vars;
-
- }//end getMethodParameters()
-
-
- /**
- * Returns the visibility and implementation properies of a method.
- *
- * The format of the array is:
- * <code>
- * array(
- * 'scope' => 'public', // public private or protected
- * 'scope_specified' => true, // true is scope keyword was found.
- * 'is_abstract' => false, // true if the abstract keyword was found.
- * 'is_final' => false, // true if the final keyword was found.
- * 'is_static' => false, // true if the static keyword was found.
- * );
- * </code>
- *
- * @param int $stackPtr The position in the stack of the T_FUNCTION token to
- * acquire the properties for.
- *
- * @return array
- * @throws PHP_CodeSniffer_Exception If the specified position is not a
- * T_FUNCTION token.
- */
- public function getMethodProperties($stackPtr)
- {
- if ($this->_tokens[$stackPtr]['code'] !== T_FUNCTION) {
- throw new PHP_CodeSniffer_Exception('$stackPtr must be of type T_FUNCTION');
- }
-
- $valid = array(
- T_PUBLIC,
- T_PRIVATE,
- T_PROTECTED,
- T_STATIC,
- T_FINAL,
- T_ABSTRACT,
- T_WHITESPACE,
- T_COMMENT,
- T_DOC_COMMENT,
- );
-
- $scope = 'public';
- $scopeSpecified = false;
- $isAbstract = false;
- $isFinal = false;
- $isStatic = false;
-
- for ($i = ($stackPtr - 1); $i > 0; $i--) {
- if (in_array($this->_tokens[$i]['code'], $valid) === false) {
- break;
- }
-
- switch ($this->_tokens[$i]['code']) {
- case T_PUBLIC:
- $scope = 'public';
- $scopeSpecified = true;
- break;
- case T_PRIVATE:
- $scope = 'private';
- $scopeSpecified = true;
- break;
- case T_PROTECTED:
- $scope = 'protected';
- $scopeSpecified = true;
- break;
- case T_ABSTRACT:
- $isAbstract = true;
- break;
- case T_FINAL:
- $isFinal = true;
- break;
- case T_STATIC:
- $isStatic = true;
- break;
- }//end switch
- }//end for
-
- return array(
- 'scope' => $scope,
- 'scope_specified' => $scopeSpecified,
- 'is_abstract' => $isAbstract,
- 'is_final' => $isFinal,
- 'is_static' => $isStatic,
- );
-
- }//end getMethodProperties()
-
-
- /**
- * Returns the visibility and implementation properies of the class member
- * variable found at the specified position in the stack.
- *
- * The format of the array is:
- *
- * <code>
- * array(
- * 'scope' => 'public', // public private or protected
- * 'is_static' => false, // true if the static keyword was found.
- * );
- * </code>
- *
- * @param int $stackPtr The position in the stack of the T_VARIABLE token to
- * acquire the properties for.
- *
- * @return array
- * @throws PHP_CodeSniffer_Exception If the specified position is not a
- * T_VARIABLE token, or if the position is not
- * a class member variable.
- */
- public function getMemberProperties($stackPtr)
- {
- if ($this->_tokens[$stackPtr]['code'] !== T_VARIABLE) {
- throw new PHP_CodeSniffer_Exception('$stackPtr must be of type T_VARIABLE');
- }
-
- end($this->_tokens[$stackPtr]['conditions']);
- $ptr = key($this->_tokens[$stackPtr]['conditions']);
- if (isset($this->_tokens[$ptr]) === false || $this->_tokens[$ptr]['code'] !== T_CLASS) {
- if (isset($this->_tokens[$ptr]) === true && $this->_tokens[$ptr]['code'] === T_INTERFACE) {
- $error = 'Possible parse error: interfaces may not include member vars';
- $this->addWarning($error, $stackPtr);
- return array();
- } else {
- throw new PHP_CodeSniffer_Exception('$stackPtr is not a class member var');
- }
- }
-
- $valid = array(
- T_PUBLIC,
- T_PRIVATE,
- T_PROTECTED,
- T_STATIC,
- T_WHITESPACE,
- T_COMMENT,
- T_DOC_COMMENT,
- );
-
- $scope = 'public';
- $scopeSpecified = false;
- $isStatic = false;
-
- for ($i = ($stackPtr - 1); $i > 0; $i--) {
- if (in_array($this->_tokens[$i]['code'], $valid) === false) {
- break;
- }
-
- switch ($this->_tokens[$i]['code']) {
- case T_PUBLIC:
- $scope = 'public';
- $scopeSpecified = true;
- break;
- case T_PRIVATE:
- $scope = 'private';
- $scopeSpecified = true;
- break;
- case T_PROTECTED:
- $scope = 'protected';
- $scopeSpecified = true;
- break;
- case T_STATIC:
- $isStatic = true;
- break;
- }
- }//end for
-
- return array(
- 'scope' => $scope,
- 'scope_specified' => $scopeSpecified,
- 'is_static' => $isStatic,
- );
-
- }//end getMemberProperties()
-
-
- /**
- * Determine if the passed token is a reference operator.
- *
- * Returns true if the specified token position represents a reference.
- * Returns false if the token represents a bitwise operator.
- *
- * @param int $stackPtr The position of the T_BITWISE_AND token.
- *
- * @return boolean
- */
- public function isReference($stackPtr)
- {
- if ($this->_tokens[$stackPtr]['code'] !== T_BITWISE_AND) {
- return false;
- }
-
- $tokenBefore = $this->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true);
-
- if ($this->_tokens[$tokenBefore]['code'] === T_FUNCTION) {
- // Function returns a reference.
- return true;
- }
-
- if ($this->_tokens[$tokenBefore]['code'] === T_DOUBLE_ARROW) {
- // Inside a foreach loop, this is a reference.
- return true;
- }
-
- if ($this->_tokens[$tokenBefore]['code'] === T_AS) {
- // Inside a foreach loop, this is a reference.
- return true;
- }
-
- if (in_array($this->_tokens[$tokenBefore]['code'], PHP_CodeSniffer_Tokens::$assignmentTokens) === true) {
- // This is directly after an assignment. It's a reference. Even if
- // it is part of an operation, the other tests will handle it.
- return true;
- }
-
- if (isset($this->_tokens[$stackPtr]['nested_parenthesis']) === true) {
- $brackets = $this->_tokens[$stackPtr]['nested_parenthesis'];
- $lastBracket = array_pop($brackets);
- if (isset($this->_tokens[$lastBracket]['parenthesis_owner']) === true) {
- $owner = $this->_tokens[$this->_tokens[$lastBracket]['parenthesis_owner']];
- if ($owner['code'] === T_FUNCTION) {
- // Inside a function declaration, this is a reference.
- return true;
- }
- }
- }
-
- return false;
-
- }//end isReference()
-
-
- /**
- * Returns the content of the tokens from the specified start position in
- * the token stack for the specified legnth.
- *
- * @param int $start The position to start from in the token stack.
- * @param int $length The length of tokens to traverse from the start pos.
- *
- * @return string The token contents.
- */
- public function getTokensAsString($start, $length)
- {
- $str = '';
- $end = ($start + $length);
- for ($i = $start; $i < $end; $i++) {
- $str .= $this->_tokens[$i]['content'];
- }
-
- return $str;
-
- }//end getTokensAsString()
-
-
- /**
- * Returns the position of the next specified token(s).
- *
- * If a value is specified, the next token of the specified type(s)
- * containing the specified value will be returned.
- *
- * Returns false if no token can be found.
- *
- * @param int|array $types The type(s) of tokens to search for.
- * @param int $start The position to start searching from in the
- * token stack.
- * @param int $end The end position to fail if no token is found.
- * if not specified or null, end will default to
- * the start of the token stack.
- * @param bool $exclude If true, find the next token that are NOT of
- * the types specified in $types.
- * @param string $value The value that the token(s) must be equal to.
- * If value is ommited, tokens with any value will
- * be returned.
- * @param bool $local If true, tokens outside the current statement
- * will not be cheked. IE. checking will stop
- * at the next semi-colon found.
- *
- * @return int | bool
- * @see findNext()
- */
- public function findPrevious($types, $start, $end=null, $exclude=false, $value=null, $local=false)
- {
- $types = (array) $types;
-
- if ($end === null) {
- $end = 0;
- }
-
- for ($i = $start; $i >= $end; $i--) {
- $found = (bool) $exclude;
- foreach ($types as $type) {
- if ($this->_tokens[$i]['code'] === $type) {
- $found = !$exclude;
- break;
- }
- }
-
- if ($found === true) {
- if ($value === null) {
- return $i;
- } else if ($this->_tokens[$i]['content'] === $value) {
- return $i;
- }
- }
-
- if ($local === true && $this->_tokens[$i]['code'] === T_SEMICOLON) {
- break;
- }
- }//end for
-
- return false;
-
- }//end findPrevious()
-
-
- /**
- * Returns the position of the next specified token(s).
- *
- * If a value is specified, the next token of the specified type(s)
- * containing the specified value will be returned.
- *
- * Returns false if no token can be found.
- *
- * @param int|array $types The type(s) of tokens to search for.
- * @param int $start The position to start searching from in the
- * token stack.
- * @param int $end The end position to fail if no token is found.
- * if not specified or null, end will default to
- * the end of the token stack.
- * @param bool $exclude If true, find the next token that is NOT of
- * a type specified in $types.
- * @param string $value The value that the token(s) must be equal to.
- * If value is ommited, tokens with any value will
- * be returned.
- * @param bool $local If true, tokens outside the current statement
- * will not be cheked. IE. checking will stop
- * at the next semi-colon found.
- *
- * @return int | bool
- * @see findPrevious()
- */
- public function findNext($types, $start, $end=null, $exclude=false, $value=null, $local=false)
- {
- $types = (array) $types;
-
- if ($end === null || $end > $this->numTokens) {
- $end = $this->numTokens;
- }
-
- for ($i = $start; $i < $end; $i++) {
- $found = (bool) $exclude;
- foreach ($types as $type) {
- if ($this->_tokens[$i]['code'] === $type) {
- $found = !$exclude;
- break;
- }
- }
-
- if ($found === true) {
- if ($value === null) {
- return $i;
- } else if ($this->_tokens[$i]['content'] === $value) {
- return $i;
- }
- }
-
- if ($local === true && $this->_tokens[$i]['code'] === T_SEMICOLON) {
- break;
- }
- }//end for
-
- return false;
-
- }//end findNext()
-
-
- /**
- * Returns the position of the first token on a line, matching given type.
- *
- * Returns false if no token can be found.
- *
- * @param int|array $types The type(s) of tokens to search for.
- * @param int $start The position to start searching from in the
- * token stack. The first token matching on
- * this line before this token will be returned.
- * @param bool $exclude If true, find the token that is NOT of
- * the types specified in $types.
- * @param string $value The value that the token must be equal to.
- * If value is ommited, tokens with any value will
- * be returned.
- *
- * @return int | bool
- */
- public function findFirstOnLine($types, $start, $exclude=false, $value=null)
- {
- if (is_array($types) === false) {
- $types = array($types);
- }
-
- $foundToken = false;
-
- for ($i = $start; $i >= 0; $i--) {
- if ($this->_tokens[$i]['line'] < $this->_tokens[$start]['line']) {
- break;
- }
-
- $found = $exclude;
- foreach ($types as $type) {
- if ($exclude === false) {
- if ($this->_tokens[$i]['code'] === $type) {
- $found = true;
- break;
- }
- } else {
- if ($this->_tokens[$i]['code'] === $type) {
- $found = false;
- break;
- }
- }
- }
-
- if ($found === true) {
- if ($value === null) {
- $foundToken = $i;
- } else if ($this->_tokens[$i]['content'] === $value) {
- $foundToken = $i;
- }
- }
- }//end for
-
- return $foundToken;
-
- }//end findFirstOnLine()
-
-
- /**
- * Determine if the passed token has a condition of one of the passed types.
- *
- * @param int $stackPtr The position of the token we are checking.
- * @param int|array $types The type(s) of tokens to search for.
- *
- * @return boolean
- */
- public function hasCondition($stackPtr, $types)
- {
- // Check for the existence of the token.
- if (isset($this->_tokens[$stackPtr]) === false) {
- return false;
- }
-
- // Make sure the token has conditions.
- if (isset($this->_tokens[$stackPtr]['conditions']) === false) {
- return false;
- }
-
- $types = (array) $types;
- $conditions = $this->_tokens[$stackPtr]['conditions'];
-
- foreach ($types as $type) {
- if (in_array($type, $conditions) === true) {
- // We found a token with the required type.
- return true;
- }
- }
-
- return false;
-
- }//end hasCondition()
-
-
-}//end class
-
-?>
+++ /dev/null
-<?php
-
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
-/**
- * Subclass of lib/pear/PHP/CodeSniffer/CLI.php
- *
- * Simple modifications to the CLI class to only use the Moodle Standard
- *
- * @package lib-pear-php-codesniffer
- * @copyright 2009 Nicolas Connault
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require_once('PHP/MoodleCodeSniffer.php');
-require_once('PHP/CodeSniffer/CLI.php');
-
-/**
- * A class to process command line runsniffer scripts. Modified for use within Moodle
- *
- * @category lib-pear-php-codesniffer
- * @copyright 2009 Nicolas Connault
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class moodle_codesniffer_cli extends php_codesniffer_cli {
- /**
- * Modified to return Moodle only
- *
- * @param string $standard The standard to validate.
- *
- * @return string
- */
- public function validatestandard($standard) {
- return 'Moodle';
- }
-
- /**
- * Prints out the usage information for this script.
- *
- * Modified by removing the --standard option
- *
- * @return void
- */
- public function printusage() {
- echo 'Usage: runsniffer [-nwlvi] [--report=<report>]'.PHP_EOL;
- echo ' [--config-set key value] [--config-delete key] [--config-show]'.PHP_EOL;
- echo ' [--generator=<generator>] [--extensions=<extensions>]'.PHP_EOL;
- echo ' [--ignore=<patterns>] [--tab-width=<width>] <file> ...'.PHP_EOL;
- echo ' -n Do not print warnings'.PHP_EOL;
- echo ' -w Print both warnings and errors (on by default)'.PHP_EOL;
- echo ' -l Local directory only, no recursion'.PHP_EOL;
- echo ' -v[v][v] Print verbose output'.PHP_EOL;
- echo ' -i Show a list of installed coding standards'.PHP_EOL;
- echo ' --help Print this help message'.PHP_EOL;
- echo ' --version Print version information'.PHP_EOL;
- echo ' <file> One or more files and/or directories to check'.PHP_EOL;
- echo ' <extensions> A comma separated list of file extensions to check'.PHP_EOL;
- echo ' (only valid if checking a directory)'.PHP_EOL;
- echo ' <patterns> A comma separated list of patterns that are used'.PHP_EOL;
- echo ' to ignore directories and files'.PHP_EOL;
- echo ' <width> The number of spaces each tab represents'.PHP_EOL;
- echo ' <generator> The name of a doc generator to use'.PHP_EOL;
- echo ' (forces doc generation instead of checking)'.PHP_EOL;
- echo ' <report> Print either the "full", "xml", "checkstyle",'.PHP_EOL;
- echo ' "csv" or "summary" report'.PHP_EOL;
- echo ' (the "full" report is printed by default)'.PHP_EOL;
-
- }
-
- /**
- * Processes an unknown command line argument.
- *
- * Overriding CLI method to allow for dynamic loading of path to requested file/directory
- *
- * @param string $arg The command line argument.
- * @param int $pos The position of the argument on the command line.
- * @param array $values An array of values determined from CLI args.
- *
- * @return array The updated CLI values.
- * @see getCommandLineValues()
- */
- public function processunknownargument($arg, $pos, $values) {
- global $args, $argv, $argc;
-
- // We don't know about any additional switches; just files.
- if ($arg{0} === '-') {
- echo 'ERROR: option "'.$arg.'" not known.'.PHP_EOL.PHP_EOL;
- $this->printUsage();
- exit(2);
- }
-
- $file = $_SERVER['PWD'] . '/' . $arg;
-
- if (file_exists($file) === false) {
- echo 'ERROR: The file "'.$arg.'" does not exist.'.PHP_EOL.PHP_EOL;
- $this->printUsage();
- exit(2);
- } else {
- $values['files'][] = $file;
- }
-
- return $values;
- }
-}
+++ /dev/null
-<?php
-/**
- * Represents a PHP_CodeSniffer sniff for sniffing coding standards.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-/**
- * Represents a PHP_CodeSniffer sniff for sniffing coding standards.
- *
- * A sniff registers what token types it wishes to listen for, then, when
- * PHP_CodeSniffer encounters that token, the sniff is invoked and passed
- * information about where the token was found in the stack, and the
- * PHP_CodeSniffer file in which the token was found.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-interface PHP_CodeSniffer_Sniff
-{
-
-
- /**
- * Registers the tokens that this sniff wants to listen for.
- *
- * An example return value for a sniff that wants to listen for whitespace
- * and any comments would be:
- *
- * <code>
- * return array(
- * T_WHITESPACE,
- * T_DOC_COMMENT,
- * T_COMMENT,
- * );
- * </code>
- *
- * @return array(int)
- * @see Tokens.php
- */
- public function register();
-
-
- /**
- * Called when one of the token types that this sniff is listening for
- * is found.
- *
- * The stackPtr variable indicates where in the stack the token was found.
- * A sniff can acquire information this token, along with all the other
- * tokens within the stack by first acquiring the token stack:
- *
- * <code>
- * $tokens = $phpcsFile->getTokens();
- * echo 'Encountered a '.$tokens[$stackPtr]['type'].' token';
- * echo 'token information: ';
- * print_r($tokens[$stackPtr]);
- * </code>
- *
- * If the sniff discovers an anomilty in the code, they can raise an error
- * by calling addError() on the PHP_CodeSniffer_File object, specifying an error
- * message and the position of the offending token:
- *
- * <code>
- * $phpcsFile->addError('Encountered an error', $stackPtr);
- * </code>
- *
- * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where the
- * token was found.
- * @param int $stackPtr The position in the PHP_CodeSniffer
- * file's token stack where the token
- * was found.
- *
- * @return void
- */
- public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr);
-
-
-}//end interface
-
-?>
+++ /dev/null
-<?php
-/**
- * Processes pattern strings and checks that the code conforms to the pattern.
- *
- * PHP version 5
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version CVS: $Id$
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-
-if (class_exists('PHP_CodeSniffer_Standards_IncorrectPatternException', true) === false) {
- $error = 'Class PHP_CodeSniffer_Standards_IncorrectPatternException not found';
- throw new PHP_CodeSniffer_Exception($error);
-}
-
-/**
- * Processes pattern strings and checks that the code conforms to the pattern.
- *
- * This test essentially checks that code is correctly formatted with whitespace.
- *
- * @category PHP
- * @package PHP_CodeSniffer
- * @author Greg Sherwood <gsherwood@squiz.net>
- * @author Marc McIntyre <mmcintyre@squiz.net>
- * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
- * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
- * @version Release: 1.1.0
- * @link http://pear.php.net/package/PHP_CodeSniffer
- */
-abstract class PHP_CodeSniffer_Standards_AbstractPatternSniff implements PHP_CodeSniffer_Sniff
-{
-
- /**
- * The parsed patterns array.
- *
- * @var array
- */
- private $_parsedPatterns = array();
-
- /**
- * Tokens that wish this sniff wishes to process outside of the patterns.
- *
- * @var array(int)
- * @see registerSupplementary()
- * @see processSupplementary()
- */
- private $_supplementaryTokens = array();
-
- /**
- * If true, comments will be ignored if they are found in the code.
- *
- * @var boolean
- */
- private $_ignoreComments = false;
-
- /**
- * Positions in the stack where errors have occured.
- *
- * @var array()
- */
- private $_errorPos = array();
-
-
- /**
- * Constructs a PHP_CodeSniffer_Standards_AbstractPatternSniff.
- *
- * @param boolean $ignoreComments If true, comments will be ignored.
- */
- public function __construct($ignoreComments=false)
- {
- $this->_ignoreComments = $ignoreComments;
- $this->_supplementaryTokens = $this->registerSupplementary();
-
- }//end __construct()
-
-
- /**
- * Registers the tokens to listen to.
- *
- * Classes extending <i>AbstractPatternTest</i> should implement the
- * <i>getPatterns()</i> method to register the patterns they wish to test.
- *
- * @return array(int)
- * @see process()
- */
- public final function register()
- {
- $listenTypes = array();
- $patterns = $this->getPatterns();
-
- foreach ($patterns as $pattern) {
-
- $parsedPattern = $this->_parse($pattern);
-
- // Find a token position in the pattern that we can use for a listener
- // token.
- $pos = $this->_getListenerTokenPos($parsedPattern);
- $tokenType = $parsedPattern[$pos]['token'];
- $listenTypes[] = $tokenType;
-
- $patternArray = array(
- 'listen_pos' => $pos,
- 'pattern' => $parsedPattern,
- 'pattern_code' => $pattern,
- );
-
- if (isset($this->_parsedPatterns[$tokenType]) === false) {
- $this->_parsedPatterns[$tokenType] = array();
- }
-
- $this->_parsedPatterns[$tokenType][] = $patternArray;
-
- }//end foreach
-
- return array_unique(array_merge($listenTypes, $this->_supplementaryTokens));
-
- }//end register()
-
-
- /**
- * Returns the token types that the specified pattern is checking for.
- *
- * Returned array is in the format:
- * <code>
- * array(
- * T_WHITESPACE => 0, // 0 is the position where the T_WHITESPACE token
- * // should occur in the pattern.
- * );
- * </code>
- *
- * @param array $pattern The parsed pattern to find the acquire the token
- * types from.
- *
- * @return array(int => int)
- */
- private function _getPatternTokenTypes($pattern)
- {
- $tokenTypes = array();
- foreach ($pattern as $pos => $patternInfo) {
- if ($patternInfo['type'] === 'token') {
- if (isset($tokenTypes[$patternInfo['token']]) === false) {
- $tokenTypes[$patternInfo['token']] = $pos;
- }
- }
- }
-
- return $tokenTypes;
-
- }//end _getPatternTokenTypes()
-
-
- /**
- * Returns the position in the pattern that this test should register as
- * a listener for the pattern.
- *
- * @param array $pattern The pattern to acquire the listener for.
- *
- * @return int The postition in the pattern that this test should register
- * as the listener.
- * @throws PHP_CodeSniffer_Exception If we could not determine a token
- * to listen for.
- */
- private function _getListenerTokenPos($pattern)
- {
- $tokenTypes = $this->_getPatternTokenTypes($pattern);
- $tokenCodes = array_keys($tokenTypes);
- $token = PHP_CodeSniffer_Tokens::getHighestWeightedToken($tokenCodes);
-
- // If we could not get a token.
- if ($token === false) {
- $error = 'Could not determine a token to listen for';
- throw new PHP_CodeSniffer_Exception($error);
- }
-
- return $tokenTypes[$token];
-
- }//end _getListenerTokenPos()
-
-
- /**
- * Processes the test.
- *
- * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where the
- * token occured.
- * @param int $stackPtr The postion in the tokens stack
- * where the listening token type was
- * found.
- *
- * @return void
- * @see register()
- */
- public final function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
- {
- $tokens = $phpcsFile->getTokens();
-
- if (in_array($tokens[$stackPtr]['code'], $this->_supplementaryTokens) === true) {
- $this->processSupplementary($phpcsFile, $stackPtr);
- }
-
- $type = $tokens[$stackPtr]['code'];
-
- // If the type is not set, then it must have been a token registered
- // with registerSupplementary().
- if (isset($this->_parsedPatterns[$type]) === false) {
- return;
- }
-
- $allErrors = array();
-
- // Loop over each pattern that is listening to the current token type
- // that we are processing.
- foreach ($this->_parsedPatterns[$type] as $patternInfo) {
-
- // If processPattern returns false, then the pattern that we are
- // checking the code with must not be design to check that code.
- $errors = $this->processPattern($patternInfo, $phpcsFile, $stackPtr);
- if ($errors === false) {
- // The pattern didn't match.
- continue;
- } else if (empty($errors) === true) {
- // The pattern matched, but there were no errors.
- break;
- }
-
- foreach ($errors as $stackPtr => $error) {
- if (isset($this->_errorPos[$stackPtr]) === false) {
- $this->_errorPos[$stackPtr] = true;
- $allErrors[$stackPtr] = $error;
- }
- }
- }
-
- foreach ($allErrors as $stackPtr => $error) {
- $phpcsFile->addError($error, $stackPtr);
- }
-
- }//end process()
-
-
- /**
- * Processes the pattern and verifies the code at $stackPtr.
- *
- * @param array $patternInfo Information about the pattern used
- * for checking, which includes are
- * parsed token representation of the
- * pattern.
- * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where the
- * token occured.
- * @param int $stackPtr The postion in the tokens stack where
- * the listening token type was found.
- *
- * @return array(errors)
- */
- protected function processPattern($patternInfo, PHP_CodeSniffer_File $phpcsFile, $stackPtr)
- {
- $tokens = $phpcsFile->getTokens();
- $pattern = $patternInfo['pattern'];
- $patternCode = $patternInfo['pattern_code'];
- $errors = array();
- $found = '';
-
- $ignoreTokens = array(T_WHITESPACE);
-
- if ($this->_ignoreComments === true) {
- $ignoreTokens = array_merge($ignoreTokens, PHP_CodeSniffer_Tokens::$commentTokens);
- }
-
- $origStackPtr = $stackPtr;
- $hasError = false;
-
- if ($patternInfo['listen_pos'] > 0) {
- $stackPtr--;
-
- for ($i = ($patternInfo['listen_pos'] - 1); $i >= 0; $i--) {
-
- if ($pattern[$i]['type'] === 'token') {
-
- if ($pattern[$i]['token'] === T_WHITESPACE) {
-
- if ($tokens[$stackPtr]['code'] === T_WHITESPACE) {
- $found = $tokens[$stackPtr]['content'].$found;
- &nb