MDL-29914 remove unused CodeSniffer lib
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,474 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* A class to process command line phpcs scripts.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,327 +0,0 @@
|
||||
<?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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,586 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Parses doc comments.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,300 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Parses Class doc comments.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,240 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* A class to represent Comments of a doc comment.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,105 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* A DocElement represents a logical element within a Doc Comment.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,196 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Parses function doc comments.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Parses class member comments.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,168 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* A class to represent elements that have a value => comment format.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,326 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* A class to represent param tags within a function comment.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,72 +0,0 @@
|
||||
<?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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,161 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* A class to represent single element doc tags.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,191 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The base class for all PHP_CodeSniffer documentation generators.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,291 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* A doc generator that outputs documentation in one big HTML file.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,266 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* A doc generator that outputs text-based documentation.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* An exception thrown by PHP_CodeSniffer when it encounters an unrecoverable error.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,116 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Represents a PHP_CodeSniffer sniff for sniffing coding standards.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
|
||||
?>
|
||||
@@ -1,779 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Processes pattern strings and checks that the code conforms to the pattern.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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;
|
||||
}
|
||||
|
||||
// Only check the size of the whitespace if this is not
|
||||
// not the first token. We don't care about the size of
|
||||
// leading whitespace, just that there is some.
|
||||
if ($i !== 0) {
|
||||
if ($tokens[$stackPtr]['content'] !== $pattern[$i]['value']) {
|
||||
$hasError = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Check to see if this important token is the same as the
|
||||
// previous important token in the pattern. If it is not,
|
||||
// then the pattern cannot be for this piece of code.
|
||||
$prev = $phpcsFile->findPrevious($ignoreTokens, $stackPtr, null, true);
|
||||
if ($prev === false || $tokens[$prev]['code'] !== $pattern[$i]['token']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we skipped past some whitespace tokens, then add them
|
||||
// to the found string.
|
||||
if (($stackPtr - $prev) > 1) {
|
||||
for ($j = ($stackPtr - 1); $j > $prev; $j--) {
|
||||
$found = $tokens[$j]['content'].$found;
|
||||
}
|
||||
}
|
||||
|
||||
$found = $tokens[$prev]['content'].$found;
|
||||
|
||||
if (isset($pattern[($i - 1)]) === true && $pattern[($i - 1)]['type'] === 'skip') {
|
||||
$stackPtr = $prev;
|
||||
} else {
|
||||
$stackPtr = ($prev - 1);
|
||||
}
|
||||
|
||||
}//end if
|
||||
} else if ($pattern[$i]['type'] === 'skip') {
|
||||
// Skip to next piece of relevant code.
|
||||
if ($pattern[$i]['to'] === 'parenthesis_closer') {
|
||||
$to = 'parenthesis_opener';
|
||||
} else {
|
||||
$to = 'scope_opener';
|
||||
}
|
||||
|
||||
// Find the previous opener.
|
||||
$next = $phpcsFile->findPrevious($ignoreTokens, $stackPtr, null, true);
|
||||
if ($next === false || isset($tokens[$next][$to]) === false) {
|
||||
// If there was not opener, then we must be
|
||||
// using the wrong pattern.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($to === 'parenthesis_opener') {
|
||||
$found = '{'.$found;
|
||||
} else {
|
||||
$found = '('.$found;
|
||||
}
|
||||
|
||||
$found = '...'.$found;
|
||||
|
||||
// Skip to the opening token.
|
||||
$stackPtr = ($tokens[$next][$to] - 1);
|
||||
} else if ($pattern[$i]['type'] === 'string') {
|
||||
$found = 'abc';
|
||||
} else if ($pattern[$i]['type'] === 'newline') {
|
||||
$found = 'EOL';
|
||||
}//end if
|
||||
}//end for
|
||||
}//end if
|
||||
|
||||
$stackPtr = $origStackPtr;
|
||||
$lastAddedStackPtr = null;
|
||||
$patternLen = count($pattern);
|
||||
|
||||
for ($i = $patternInfo['listen_pos']; $i < $patternLen; $i++) {
|
||||
|
||||
if ($pattern[$i]['type'] === 'token') {
|
||||
|
||||
if ($pattern[$i]['token'] === T_WHITESPACE) {
|
||||
|
||||
if ($this->_ignoreComments === true) {
|
||||
// If we are ignoring comments, check to see if this current
|
||||
// token is a comment. If so skip it.
|
||||
if (in_array($tokens[$stackPtr]['code'], PHP_CodeSniffer_Tokens::$commentTokens) === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the next token is a comment, the we need to skip the
|
||||
// current token as we should allow a space before a
|
||||
// comment for readability.
|
||||
if (in_array($tokens[($stackPtr + 1)]['code'], PHP_CodeSniffer_Tokens::$commentTokens) === true) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$tokenContent = '';
|
||||
if ($tokens[$stackPtr]['code'] === T_WHITESPACE) {
|
||||
if (isset($pattern[($i + 1)]) === false) {
|
||||
// This is the last token in the pattern, so just compare
|
||||
// the next token of content.
|
||||
$tokenContent = $tokens[$stackPtr]['content'];
|
||||
} else {
|
||||
// Get all the whitespace to the next token.
|
||||
$next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr, null, true);
|
||||
$tokenContent = $phpcsFile->getTokensAsString($stackPtr, ($next - $stackPtr));
|
||||
$lastAddedStackPtr = $stackPtr;
|
||||
$stackPtr = $next;
|
||||
}
|
||||
|
||||
if ($stackPtr !== $lastAddedStackPtr) {
|
||||
$found .= $tokenContent;
|
||||
}
|
||||
} else {
|
||||
if ($stackPtr !== $lastAddedStackPtr) {
|
||||
$found .= $tokens[$stackPtr]['content'];
|
||||
$lastAddedStackPtr = $stackPtr;
|
||||
}
|
||||
}//end if
|
||||
|
||||
if (isset($pattern[($i + 1)]) === true && $pattern[($i + 1)]['type'] === 'skip') {
|
||||
// The next token is a skip token, so we just need to make
|
||||
// sure the whitespace we found has *at least* the
|
||||
// whitespace required.
|
||||
if (strpos($tokenContent, $pattern[$i]['value']) !== 0) {
|
||||
$hasError = true;
|
||||
}
|
||||
} else {
|
||||
if ($tokenContent !== $pattern[$i]['value']) {
|
||||
$hasError = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Check to see if this important token is the same as the
|
||||
// next important token in the pattern. If it is not, then
|
||||
// the pattern cannot be for this piece of code.
|
||||
$next = $phpcsFile->findNext($ignoreTokens, $stackPtr, null, true);
|
||||
if ($next === false || $tokens[$next]['code'] !== $pattern[$i]['token']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we skipped past some whitespace tokens, then add them
|
||||
// to the found string.
|
||||
if (($next - $stackPtr) > 0) {
|
||||
$hasComment = false;
|
||||
for ($j = $stackPtr; $j < $next; $j++) {
|
||||
$found .= $tokens[$j]['content'];
|
||||
if (in_array($tokens[$j]['code'], PHP_CodeSniffer_Tokens::$commentTokens) === true) {
|
||||
$hasComment = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are not ignoring comments, this additional
|
||||
// whitespace or comment is not allowed. If we are
|
||||
// ignoring comments, there needs to be at least one
|
||||
// comment for this to be allowed.
|
||||
if ($this->_ignoreComments === false || ($this->_ignoreComments === true && $hasComment === false)) {
|
||||
$hasError = true;
|
||||
}
|
||||
|
||||
// Even when ignoring comments, we are not allowed to include
|
||||
// newlines without the pattern specifying them, so
|
||||
// everything should be on the same line.
|
||||
if ($tokens[$next]['line'] !== $tokens[$stackPtr]['line']) {
|
||||
$hasError = true;
|
||||
}
|
||||
}//end if
|
||||
|
||||
if ($next !== $lastAddedStackPtr) {
|
||||
$found .= $tokens[$next]['content'];
|
||||
$lastAddedStackPtr = $next;
|
||||
}
|
||||
|
||||
if (isset($pattern[($i + 1)]) === true && $pattern[($i + 1)]['type'] === 'skip') {
|
||||
$stackPtr = $next;
|
||||
} else {
|
||||
$stackPtr = ($next + 1);
|
||||
}
|
||||
}//end if
|
||||
|
||||
} else if ($pattern[$i]['type'] === 'skip') {
|
||||
// Find the previous opener.
|
||||
$next = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$blockOpeners, $stackPtr, null);
|
||||
if ($next === false || isset($tokens[$next][$pattern[$i]['to']]) === false) {
|
||||
// If there was not opener, then we must
|
||||
// be using the wrong pattern.
|
||||
return false;
|
||||
}
|
||||
|
||||
$found .= '...';
|
||||
if ($pattern[$i]['to'] === 'parenthesis_closer') {
|
||||
$found .= ')';
|
||||
} else {
|
||||
$found .= '}';
|
||||
}
|
||||
|
||||
// Skip to the closing token.
|
||||
$stackPtr = ($tokens[$next][$pattern[$i]['to']] + 1);
|
||||
} else if ($pattern[$i]['type'] === 'string') {
|
||||
if ($tokens[$stackPtr]['code'] !== T_STRING) {
|
||||
$hasError = true;
|
||||
}
|
||||
|
||||
if ($stackPtr !== $lastAddedStackPtr) {
|
||||
$found .= 'abc';
|
||||
$lastAddedStackPtr = $stackPtr;
|
||||
}
|
||||
|
||||
$stackPtr++;
|
||||
} else if ($pattern[$i]['type'] === 'newline') {
|
||||
// Find the next token that contains a newline character.
|
||||
$newline = 0;
|
||||
for ($j = $stackPtr; $j < $phpcsFile->numTokens; $j++) {
|
||||
if (strpos($tokens[$j]['content'], $phpcsFile->eolChar) !== false) {
|
||||
$newline = $j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($newline === 0) {
|
||||
// We didn't find a newline character in the rest of the file.
|
||||
$next = ($phpcsFile->numTokens - 1);
|
||||
$hasError = true;
|
||||
} else {
|
||||
if ($this->_ignoreComments === false) {
|
||||
// The newline character cannot be part of a comment.
|
||||
if (in_array($tokens[$newline]['code'], PHP_CodeSniffer_Tokens::$commentTokens) === true) {
|
||||
$hasError = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($newline === $stackPtr) {
|
||||
$next = ($stackPtr + 1);
|
||||
} else {
|
||||
// Check that there were no significant tokens that we
|
||||
// skipped over to find our newline character.
|
||||
$next = $phpcsFile->findNext($ignoreTokens, $stackPtr, null, true);
|
||||
if ($next < $newline) {
|
||||
// We skipped a non-ignored token.
|
||||
$hasError = true;
|
||||
} else {
|
||||
$next = ($newline + 1);
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
|
||||
if ($stackPtr !== $lastAddedStackPtr) {
|
||||
$found .= $phpcsFile->getTokensAsString($stackPtr, ($next - $stackPtr));
|
||||
$diff = ($next - $stackPtr);
|
||||
$lastAddedStackPtr = ($next - 1);
|
||||
}
|
||||
|
||||
$stackPtr = $next;
|
||||
}//end if
|
||||
}//end for
|
||||
|
||||
if ($hasError === true) {
|
||||
$error = $this->prepareError($found, $patternCode);
|
||||
$errors[$origStackPtr] = $error;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
|
||||
}//end processPattern()
|
||||
|
||||
|
||||
/**
|
||||
* Prepares an error for the specified patternCode.
|
||||
*
|
||||
* @param string $found The actual found string in the code.
|
||||
* @param string $patternCode The expected pattern code.
|
||||
*
|
||||
* @return string The error message.
|
||||
*/
|
||||
protected function prepareError($found, $patternCode)
|
||||
{
|
||||
$found = str_replace("\r\n", '\n', $found);
|
||||
$found = str_replace("\n", '\n', $found);
|
||||
$found = str_replace("\r", '\n', $found);
|
||||
$found = str_replace('EOL', '\n', $found);
|
||||
$expected = str_replace('EOL', '\n', $patternCode);
|
||||
|
||||
$error = "Expected \"$expected\"; found \"$found\"";
|
||||
|
||||
return $error;
|
||||
|
||||
}//end prepareError()
|
||||
|
||||
|
||||
/**
|
||||
* Returns the patterns that should be checked.
|
||||
*
|
||||
* @return array(string)
|
||||
*/
|
||||
protected abstract function getPatterns();
|
||||
|
||||
|
||||
/**
|
||||
* Registers any supplementary tokens that this test might wish to process.
|
||||
*
|
||||
* A sniff may wish to register supplementary tests when it wishes to group
|
||||
* an arbitary validation that cannot be performed using a pattern, with
|
||||
* other pattern tests.
|
||||
*
|
||||
* @return array(int)
|
||||
* @see processSupplementary()
|
||||
*/
|
||||
protected function registerSupplementary()
|
||||
{
|
||||
return array();
|
||||
|
||||
}//end registerSupplementary()
|
||||
|
||||
|
||||
/**
|
||||
* Processes any tokens registered with registerSupplementary().
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where to
|
||||
* process the skip.
|
||||
* @param int $stackPtr The position in the tokens stack to
|
||||
* process.
|
||||
*
|
||||
* @return void
|
||||
* @see registerSupplementary()
|
||||
*/
|
||||
protected function processSupplementary(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
|
||||
{
|
||||
return;
|
||||
|
||||
}//end processSupplementary()
|
||||
|
||||
|
||||
/**
|
||||
* Parses a pattern string into an array of pattern steps.
|
||||
*
|
||||
* @param string $pattern The pattern to parse.
|
||||
*
|
||||
* @return array The parsed pattern array.
|
||||
* @see _createSkipPattern()
|
||||
* @see _createTokenPattern()
|
||||
*/
|
||||
private function _parse($pattern)
|
||||
{
|
||||
$patterns = array();
|
||||
$length = strlen($pattern);
|
||||
$lastToken = 0;
|
||||
$firstToken = 0;
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
|
||||
$specialPattern = false;
|
||||
$isLastChar = ($i === ($length - 1));
|
||||
$oldFirstToken = $firstToken;
|
||||
|
||||
if (substr($pattern, $i, 3) === '...') {
|
||||
// It's a skip pattern. The skip pattern requires the
|
||||
// content of the token in the "from" position and the token
|
||||
// to skip to.
|
||||
$specialPattern = $this->_createSkipPattern($pattern, ($i - 1));
|
||||
$lastToken = ($i - $firstToken);
|
||||
$firstToken = ($i + 4);
|
||||
$i = ($i + 3);
|
||||
} else if (substr($pattern, $i, 3) === 'abc') {
|
||||
$specialPattern = array('type' => 'string');
|
||||
$lastToken = ($i - $firstToken);
|
||||
$firstToken = ($i + 3);
|
||||
$i = ($i + 2);
|
||||
} else if (substr($pattern, $i, 3) === 'EOL') {
|
||||
$specialPattern = array('type' => 'newline');
|
||||
$lastToken = ($i - $firstToken);
|
||||
$firstToken = ($i + 3);
|
||||
$i = ($i + 2);
|
||||
}
|
||||
|
||||
if ($specialPattern !== false || $isLastChar === true) {
|
||||
|
||||
// If we are at the end of the string, don't worry about a limit.
|
||||
if ($isLastChar === true) {
|
||||
// Get the string from the end of the last skip pattern, if any,
|
||||
// to the end of the pattern string.
|
||||
$str = substr($pattern, $oldFirstToken);
|
||||
} else {
|
||||
// Get the string from the end of the last special pattern,
|
||||
// if any, to the start of this special pattern.
|
||||
$str = substr($pattern, $oldFirstToken, $lastToken);
|
||||
}
|
||||
|
||||
$tokenPatterns = $this->_createTokenPattern($str);
|
||||
|
||||
// Make sure we don't skip the last token.
|
||||
if ($isLastChar === false && $i === ($length - 1)) {
|
||||
$i--;
|
||||
}
|
||||
|
||||
foreach ($tokenPatterns as $tokenPattern) {
|
||||
$patterns[] = $tokenPattern;
|
||||
}
|
||||
}//end if
|
||||
|
||||
// Add the skip pattern *after* we have processed
|
||||
// all the tokens from the end of the last skip pattern
|
||||
// to the start of this skip pattern.
|
||||
if ($specialPattern !== false) {
|
||||
$patterns[] = $specialPattern;
|
||||
}
|
||||
|
||||
}//end for
|
||||
|
||||
return $patterns;
|
||||
|
||||
}//end _parse()
|
||||
|
||||
|
||||
/**
|
||||
* Creates a skip pattern.
|
||||
*
|
||||
* @param string $pattern The pattern being parsed.
|
||||
* @param string $from The token content that the skip pattern starts from.
|
||||
*
|
||||
* @return array The pattern step.
|
||||
* @see _createTokenPattern()
|
||||
* @see _parse()
|
||||
*/
|
||||
private function _createSkipPattern($pattern, $from)
|
||||
{
|
||||
$skip = array('type' => 'skip');
|
||||
|
||||
for ($from; $from >= 0; $from--) {
|
||||
switch ($pattern[$from]) {
|
||||
case '(':
|
||||
$skip['to'] = 'parenthesis_closer';
|
||||
break;
|
||||
case '{':
|
||||
$skip['to'] = 'scope_closer';
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($skip['to']) === true) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($skip['to']) === false) {
|
||||
$skip['to'] = 'unknown';
|
||||
}
|
||||
|
||||
return $skip;
|
||||
|
||||
}//end _createSkipPattern()
|
||||
|
||||
|
||||
/**
|
||||
* Creates a token pattern.
|
||||
*
|
||||
* @param string $str The tokens string that the pattern should match.
|
||||
*
|
||||
* @return array The pattern step.
|
||||
* @see _createSkipPattern()
|
||||
* @see _parse()
|
||||
*/
|
||||
private function _createTokenPattern($str)
|
||||
{
|
||||
// Don't add a space after the closing php tag as it will add a new
|
||||
// whitespace token.
|
||||
$tokens = token_get_all('<?php '.$str.'?>');
|
||||
|
||||
// Remove the <?php tag from the front and the end php tag from the back.
|
||||
$tokens = array_slice($tokens, 1, (count($tokens) - 2));
|
||||
|
||||
foreach ($tokens as &$token) {
|
||||
$token = PHP_CodeSniffer::standardiseToken($token);
|
||||
}
|
||||
|
||||
$patterns = array();
|
||||
foreach ($tokens as $patternInfo) {
|
||||
$patterns[] = array(
|
||||
'type' => 'token',
|
||||
'token' => $patternInfo['code'],
|
||||
'value' => $patternInfo['content'],
|
||||
);
|
||||
}
|
||||
|
||||
return $patterns;
|
||||
|
||||
}//end _createTokenPattern()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -1,213 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* An AbstractScopeTest allows for tests that extend from this class to
|
||||
* listen for tokens within a particluar scope.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 AbstractScopeTest allows for tests that extend from this class to
|
||||
* listen for tokens within a particluar scope.
|
||||
*
|
||||
* Below is a test that listens to methods that exist only within classes:
|
||||
* <code>
|
||||
* class ClassScopeTest extends PHP_CodeSniffer_Standards_AbstractScopeSniff
|
||||
* {
|
||||
* public function __construct()
|
||||
* {
|
||||
* parent::__construct(array(T_CLASS), array(T_FUNCTION));
|
||||
* }
|
||||
*
|
||||
* protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $)
|
||||
* {
|
||||
* $className = $phpcsFile->getDeclarationName($currScope);
|
||||
* echo 'encountered a method within class '.$className;
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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_AbstractScopeSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
/**
|
||||
* The token types that this test wishes to listen to within the scope.
|
||||
*
|
||||
* @var array()
|
||||
*/
|
||||
private $_tokens = array();
|
||||
|
||||
/**
|
||||
* The type of scope opener tokens that this test wishes to listen to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_scopeTokens = array();
|
||||
|
||||
/**
|
||||
* The position in the tokens array that opened the current scope.
|
||||
*
|
||||
* @var array()
|
||||
*/
|
||||
protected $currScope = null;
|
||||
|
||||
/**
|
||||
* True if this test should fire on tokens outside of the scope.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_listenOutside = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new AbstractScopeTest.
|
||||
*
|
||||
* @param array $scopeTokens The type of scope the test wishes to listen to.
|
||||
* @param array $tokens The tokens that the test wishes to listen to
|
||||
* within the scope.
|
||||
* @param boolean $listenOutside If true this test will also alert the
|
||||
* extending class when a token is found outside
|
||||
* the scope, by calling the
|
||||
* processTokenOutideScope method.
|
||||
*
|
||||
* @see PHP_CodeSniffer.getValidScopeTokeners()
|
||||
* @throws PHP_CodeSniffer_Test_Exception If the specified tokens array is empty.
|
||||
*/
|
||||
public function __construct(array $scopeTokens, array $tokens, $listenOutside=false)
|
||||
{
|
||||
if (empty($scopeTokens) === true) {
|
||||
$error = 'The scope tokens list cannot be empty';
|
||||
throw new PHP_CodeSniffer_Test_Exception($error);
|
||||
}
|
||||
|
||||
if (empty($tokens) === true) {
|
||||
$error = 'The tokens list cannot be empty';
|
||||
throw new PHP_CodeSniffer_Test_Exception($error);
|
||||
}
|
||||
|
||||
$invalidScopeTokens = array_intersect($scopeTokens, $tokens);
|
||||
if (empty($invalidScopeTokens) === false) {
|
||||
$invalid = implode(', ', $invalidScopeTokens);
|
||||
$error = "Scope tokens [$invalid] cant be in the tokens array";
|
||||
throw new PHP_CodeSniffer_Test_Exception($error);
|
||||
}
|
||||
|
||||
$this->_listenOutside = $listenOutside;
|
||||
$this->_scopeTokens = $scopeTokens;
|
||||
$this->_tokens = $tokens;
|
||||
|
||||
}//end __construct()
|
||||
|
||||
|
||||
/**
|
||||
* The method that is called to register the tokens this test wishes to
|
||||
* listen to.
|
||||
*
|
||||
* DO NOT OVERRIDE THIS METHOD. Use the constructor of this class to register
|
||||
* for the desired tokens and scope.
|
||||
*
|
||||
* @return array(int)
|
||||
* @see __constructor()
|
||||
*/
|
||||
public final function register()
|
||||
{
|
||||
if ($this->_listenOutside === false) {
|
||||
return $this->_scopeTokens;
|
||||
} else {
|
||||
return array_merge($this->_scopeTokens, $this->_tokens);
|
||||
}
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes the tokens that this test is listening for.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
|
||||
* @param int $stackPtr The position in the stack where this
|
||||
* token was found.
|
||||
*
|
||||
* @return void
|
||||
* @see processTokenWithinScope()
|
||||
*/
|
||||
public final function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
|
||||
{
|
||||
$tokens = $phpcsFile->getTokens();
|
||||
|
||||
if (in_array($tokens[$stackPtr]['code'], $this->_scopeTokens) === true) {
|
||||
$this->currScope = $stackPtr;
|
||||
$phpcsFile->addTokenListener($this, $this->_tokens);
|
||||
} else if ($this->currScope !== null && isset($tokens[$this->currScope]['scope_closer']) === true && $stackPtr > $tokens[$this->currScope]['scope_closer']) {
|
||||
$this->currScope = null;
|
||||
if ($this->_listenOutside === true) {
|
||||
// This is a token outside the current scope, so notify the
|
||||
// extender as they wish to know about this.
|
||||
$this->processTokenOutsideScope($phpcsFile, $stackPtr);
|
||||
} else {
|
||||
// Don't remove the listener if the extender wants to know about
|
||||
// tokens that live outside the current scope.
|
||||
$phpcsFile->removeTokenListener($this, $this->_tokens);
|
||||
}
|
||||
} else if ($this->currScope !== null) {
|
||||
$this->processTokenWithinScope($phpcsFile, $stackPtr, $this->currScope);
|
||||
} else {
|
||||
$this->processTokenOutsideScope($phpcsFile, $stackPtr);
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
/**
|
||||
* Processes a token that is found within the scope that this test is
|
||||
* listening to.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
|
||||
* @param int $stackPtr The position in the stack where this
|
||||
* token was found.
|
||||
* @param int $currScope The position in the tokens array that
|
||||
* opened the scope that this test is
|
||||
* listening for.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected abstract function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope);
|
||||
|
||||
|
||||
/**
|
||||
* Processes a token that is found within the scope that this test is
|
||||
* listening to.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
|
||||
* @param int $stackPtr The position in the stack where this
|
||||
* token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processTokenOutsideScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
|
||||
{
|
||||
return;
|
||||
|
||||
}//end processTokenOutsideScope()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -1,217 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* A class to find T_VARIABLE tokens.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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_AbstractScopeSniff', true) === false) {
|
||||
$error = 'Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found';
|
||||
throw new PHP_CodeSniffer_Exception($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to find T_VARIABLE tokens.
|
||||
*
|
||||
* This class can distingush between normal T_VARIABLE tokens, and those tokens
|
||||
* that represent class members. If a class member is encountered, then then
|
||||
* processMemberVar method is called so the extending class can process it. If
|
||||
* the token is found to be a normal T_VARIABLE token, then processVariable is
|
||||
* called.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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_AbstractVariableSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff
|
||||
{
|
||||
|
||||
/**
|
||||
* The end token of the current function that we are in.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_endFunction = -1;
|
||||
|
||||
/**
|
||||
* true if a function is currently open.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_functionOpen = false;
|
||||
|
||||
/**
|
||||
* The current PHP_CodeSniffer file that we are processing.
|
||||
*
|
||||
* @var PHP_CodeSniffer_File
|
||||
*/
|
||||
protected $currentFile = null;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an AbstractVariableTest.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$listen = array(
|
||||
T_CLASS,
|
||||
T_INTERFACE,
|
||||
);
|
||||
|
||||
$scopes = array(
|
||||
T_FUNCTION,
|
||||
T_VARIABLE,
|
||||
T_DOUBLE_QUOTED_STRING,
|
||||
);
|
||||
|
||||
parent::__construct($listen, $scopes, true);
|
||||
|
||||
}//end __construct()
|
||||
|
||||
|
||||
/**
|
||||
* Processes the token in the specified PHP_CodeSniffer_File.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
||||
* token was found.
|
||||
* @param int $stackPtr The position where the token was found.
|
||||
* @param array $currScope The current scope opener token.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected final function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope)
|
||||
{
|
||||
if ($this->currentFile !== $phpcsFile) {
|
||||
$this->currentFile = $phpcsFile;
|
||||
$this->_functionOpen = false;
|
||||
$this->_endFunction = -1;
|
||||
}
|
||||
|
||||
$tokens = $phpcsFile->getTokens();
|
||||
|
||||
if ($stackPtr > $this->_endFunction) {
|
||||
$this->_functionOpen = false;
|
||||
}
|
||||
|
||||
if ($tokens[$stackPtr]['code'] === T_FUNCTION && $this->_functionOpen === false) {
|
||||
|
||||
$this->_functionOpen = true;
|
||||
|
||||
$methodProps = $phpcsFile->getMethodProperties($stackPtr);
|
||||
|
||||
// If the function is abstract, or is in an interface,
|
||||
// then set the end of the function to it's closing semicolon.
|
||||
if ($methodProps['is_abstract'] === true || $tokens[$currScope]['code'] === T_INTERFACE) {
|
||||
$this->_endFunction = $phpcsFile->findNext(array(T_SEMICOLON), $stackPtr);
|
||||
} else {
|
||||
if (isset($tokens[$stackPtr]['scope_closer']) === false) {
|
||||
$error = 'Possible parse error: non-abstract method defined as abstract';
|
||||
$phpcsFile->addWarning($error, $stackPtr);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->_endFunction = $tokens[$stackPtr]['scope_closer'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($this->_functionOpen === true) {
|
||||
if ($tokens[$stackPtr]['code'] === T_VARIABLE) {
|
||||
$this->processVariable($phpcsFile, $stackPtr);
|
||||
} else if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING) {
|
||||
// Check to see if this string has a variable in it.
|
||||
$pattern = '|[^\\\]\$[a-zA-Z0-9_]+|';
|
||||
if (preg_match($pattern, $tokens[$stackPtr]['content']) !== 0) {
|
||||
$this->processVariableInString($phpcsFile, $stackPtr);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
// What if we assign a member variable to another?
|
||||
// ie. private $_count = $this->_otherCount + 1;.
|
||||
$this->processMemberVar($phpcsFile, $stackPtr);
|
||||
}
|
||||
|
||||
}//end processTokenWithinScope()
|
||||
|
||||
|
||||
/**
|
||||
* Processes the token outside the scope in the file.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
||||
* token was found.
|
||||
* @param int $stackPtr The position where the token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected final function processTokenOutsideScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
|
||||
{
|
||||
$tokens = $phpcsFile->getTokens();
|
||||
// These variables are not member vars.
|
||||
if ($tokens[$stackPtr]['code'] === T_VARIABLE) {
|
||||
$this->processVariable($phpcsFile, $stackPtr);
|
||||
} else {
|
||||
$this->processVariableInString($phpcsFile, $stackPtr);
|
||||
}
|
||||
|
||||
}//end processTokenOutsideScope()
|
||||
|
||||
|
||||
/**
|
||||
* Called to process class member vars.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
||||
* token was found.
|
||||
* @param int $stackPtr The position where the token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr);
|
||||
|
||||
|
||||
/**
|
||||
* Called to process normal member vars.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
||||
* token was found.
|
||||
* @param int $stackPtr The position where the token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function processVariable(PHP_CodeSniffer_File $phpcsFile, $stackPtr);
|
||||
|
||||
|
||||
/**
|
||||
* Called to process variables found in duoble quoted strings.
|
||||
*
|
||||
* Note that there may be more than one variable in the string, which will
|
||||
* result only in one call for the string.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
||||
* token was found.
|
||||
* @param int $stackPtr The position where the double quoted
|
||||
* string was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function processVariableInString(PHP_CodeSniffer_File $phpcsFile, $stackPtr);
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Bass Coding Standard class.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base Coding Standard class.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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_Standards_CodingStandard
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Return a list of external sniffs to include with this standard.
|
||||
*
|
||||
* External locations can be single sniffs, a whole directory of sniffs, or
|
||||
* an entire coding standard. Locations start with the standard name. For
|
||||
* example:
|
||||
* PEAR => include all sniffs in this standard
|
||||
* PEAR/Sniffs/Files => include all sniffs in this dir
|
||||
* PEAR/Sniffs/Files/LineLengthSniff => include this single sniff
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getIncludedSniffs()
|
||||
{
|
||||
return array();
|
||||
|
||||
}//end getIncludedSniffs()
|
||||
|
||||
|
||||
/**
|
||||
* Return a list of external sniffs to exclude from this standard.
|
||||
*
|
||||
* External locations can be single sniffs, a whole directory of sniffs, or
|
||||
* an entire coding standard. Locations start with the standard name. For
|
||||
* example:
|
||||
* PEAR => exclude all sniffs in this standard
|
||||
* PEAR/Sniffs/Files => exclude all sniffs in this dir
|
||||
* PEAR/Sniffs/Files/LineLengthSniff => exclude this single sniff
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getExcludedSniffs()
|
||||
{
|
||||
return array();
|
||||
|
||||
}//end getExcludedSniffs()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* An exception thrown if the pattern being processed is not supposed to be
|
||||
* validating the code in question.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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 thrown if the pattern being processed is not supposed to be
|
||||
* validating the code in question.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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_Standards_IncorrectPatternException extends Exception
|
||||
{
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -1,54 +0,0 @@
|
||||
<?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-standards-moodle
|
||||
* @copyright 2008 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
if (class_exists('PHP_CodeSniffer_Standards_CodingStandard', true) === false) {
|
||||
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_CodingStandard not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Moodle Coding Standard.
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class php_codesniffer_standards_moodle_moodlecodingstandard extends php_codesniffer_standards_codingstandard {
|
||||
/**
|
||||
* To include additional sniffs in this standard, add their paths to this method's return array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getincludedsniffs() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* To exclude included sniffs from this standard, add their paths to this method's return array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getexcludedsniffs() {
|
||||
return array('Moodle/Sniffs/CodeAnalysis');
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* File containing the Class Declaration Test.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-classes
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Declaration Test.
|
||||
*
|
||||
* Checks the declaration of the class is correct.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_classes_classdeclarationsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_CLASS, T_INTERFACE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
if (isset($tokens[$stackptr]['scope_opener']) === false) {
|
||||
$error = 'possible parse error: ';
|
||||
$error .= $tokens[$stackptr]['content'];
|
||||
$error .= ' missing opening or closing brace';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
$curlybrace = $tokens[$stackptr]['scope_opener'];
|
||||
$lastcontent = $phpcsfile->findprevious(T_WHITESPACE, ($curlybrace - 1), $stackptr, true);
|
||||
$classline = $tokens[$lastcontent]['line'];
|
||||
$braceline = $tokens[$curlybrace]['line'];
|
||||
|
||||
if ($braceline != $classline) {
|
||||
$error = 'Opening brace of a ';
|
||||
$error .= $tokens[$stackptr]['content'];
|
||||
$error .= ' must be on the same line as the definition';
|
||||
$phpcsfile->adderror($error, $curlybrace);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($tokens[($curlybrace - 1)]['code'] === T_WHITESPACE) {
|
||||
$prevcontent = $tokens[($curlybrace - 1)]['content'];
|
||||
|
||||
if ($prevcontent !== $phpcsfile->eolChar) {
|
||||
$blankspace = substr($prevcontent, strpos($prevcontent, $phpcsfile->eolChar));
|
||||
$spaces = strlen($blankspace);
|
||||
|
||||
if ($spaces !== 1) {
|
||||
$error = "Expected 1 space before opening brace; $spaces found";
|
||||
$phpcsfile->adderror($error, $curlybrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* File containing the moodle_sniffs_codeanalysis_emptystatementsniff Class
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-codeanalysis
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* This sniff class detected empty statement.
|
||||
*
|
||||
* This sniff implements the common algorithm for empty statement body detection.
|
||||
* A body is considered as empty if it is completely empty or it only contains
|
||||
* whitespace characters and|or comments.
|
||||
*
|
||||
* <code>
|
||||
* stmt {
|
||||
* // foo
|
||||
* }
|
||||
* stmt (conditions) {
|
||||
* // foo
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* Statements covered by this sniff are <b>catch</b>, <b>do</b>, <b>else</b>,
|
||||
* <b>elsif</b>, <b>for</b>, <b>foreach<b>, <b>if</b>, <b>switch</b>, <b>try</b>
|
||||
* and <b>while</b>.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_codeanalysis_emptystatementsniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* List of block tokens that this sniff covers.
|
||||
*
|
||||
* The key of this hash identifies the required token while the boolean
|
||||
* value says mark an error or mark a warning.
|
||||
*
|
||||
* @type array<boolean>
|
||||
* @var array(integer=>boolean) $_tokens
|
||||
*/
|
||||
private $_tokens = array(
|
||||
T_CATCH => true,
|
||||
T_DO => false,
|
||||
T_ELSE => false,
|
||||
T_ELSEIF => false,
|
||||
T_FOR => false,
|
||||
T_FOREACH => false,
|
||||
T_IF => false,
|
||||
T_SWITCH => false,
|
||||
T_TRY => false,
|
||||
T_WHILE => false,
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Registers the tokens that this sniff wants to listen for.
|
||||
*
|
||||
* @return array(integer)
|
||||
*/
|
||||
public function register() {
|
||||
return array_keys($this->_tokens);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$token = $tokens[$stackptr];
|
||||
|
||||
// Skip for-statements without body.
|
||||
if (isset($token['scope_opener']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$next = ++$token['scope_opener'];
|
||||
$end = --$token['scope_closer'];
|
||||
|
||||
$emptybody = true;
|
||||
|
||||
for (; $next <= $end; ++$next) {
|
||||
|
||||
if (in_array($tokens[$next]['code'], PHP_CodeSniffer_tokens::$emptyTokens) === false) {
|
||||
$emptybody = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($emptybody === true) {
|
||||
// Get token identifier.
|
||||
$name = $phpcsfile->gettokensAsString($stackptr, 1);
|
||||
$error = sprintf('Empty %s statement detected', strtoupper($name));
|
||||
|
||||
if ($this->_tokens[$token['code']] === true) {
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
|
||||
} else {
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* This file is part of the CodeAnalysis addon for PHP_CodeSniffer.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-codeanalysis
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Detects for-loops that can be simplified to a while-loop.
|
||||
*
|
||||
* This rule is based on the PMD rule catalog. Detects for-loops that can be
|
||||
* simplified as a while-loop.
|
||||
*
|
||||
* <code>
|
||||
* class Foo
|
||||
* {
|
||||
* public function bar($x)
|
||||
* {
|
||||
* for (;true;) true; // No Init or Update part, may as well be: while (true)
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_codeanalysis_forloopshouldbewhileloopsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Registers the tokens that this sniff wants to listen for.
|
||||
*
|
||||
* @return array(integer)
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_FOR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$token = $tokens[$stackptr];
|
||||
|
||||
// Skip invalid statement.
|
||||
if (isset($token['parenthesis_opener']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$next = ++$token['parenthesis_opener'];
|
||||
$end = --$token['parenthesis_closer'];
|
||||
|
||||
$parts = array(0, 0, 0);
|
||||
$index = 0;
|
||||
|
||||
for (; $next <= $end; ++$next) {
|
||||
$code = $tokens[$next]['code'];
|
||||
|
||||
if ($code === T_SEMICOLON) {
|
||||
++$index;
|
||||
|
||||
} else if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === false) {
|
||||
++$parts[$index];
|
||||
}
|
||||
}
|
||||
|
||||
if ($parts[0] === 0 && $parts[2] === 0 && $parts[1] > 0) {
|
||||
$error = 'This FOR loop can be simplified to a WHILE loop';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* This file is part of the CodeAnalysis addon for PHP_CodeSniffer.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-codeanalysis
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Detects for-loops that use a function call in the test expression.
|
||||
*
|
||||
* This rule is based on the PMD rule catalog. Detects for-loops that use a
|
||||
* function call in the test expression.
|
||||
*
|
||||
* <code>
|
||||
* class Foo
|
||||
* {
|
||||
* public function bar($x)
|
||||
* {
|
||||
* $a = array(1, 2, 3, 4);
|
||||
* for ($i = 0; $i < count($a); $i++) {
|
||||
* $a[$i] *= $i;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_codeanalysis_forloopwithtestfunctioncallsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Registers the tokens that this sniff wants to listen for.
|
||||
*
|
||||
* @return array(integer)
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_FOR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$token = $tokens[$stackptr];
|
||||
|
||||
// Skip invalid statement.
|
||||
if (isset($token['parenthesis_opener']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$next = ++$token['parenthesis_opener'];
|
||||
$end = --$token['parenthesis_closer'];
|
||||
|
||||
$position = 0;
|
||||
|
||||
for (; $next <= $end; ++$next) {
|
||||
$code = $tokens[$next]['code'];
|
||||
|
||||
if ($code === T_SEMICOLON) {
|
||||
++$position;
|
||||
}
|
||||
|
||||
if ($position < 1) {
|
||||
continue;
|
||||
|
||||
} else if ($position > 1) {
|
||||
break;
|
||||
|
||||
} else if ($code !== T_VARIABLE && $code !== T_STRING) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find next non empty token, if it is a open curly brace we have a
|
||||
// function call.
|
||||
$index = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($next + 1), null, true);
|
||||
|
||||
if ($tokens[$index]['code'] === T_OPEN_PARENTHESIS) {
|
||||
$error = 'Avoid function calls in a FOR loop test part';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* This file is part of the CodeAnalysis addon for PHP_CodeSniffer.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-codeanalysis
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Detects incrementer jumbling in for loops.
|
||||
*
|
||||
* This rule is based on the PMD rule catalog. The jumbling incrementer sniff
|
||||
* detects the usage of one and the same incrementer into an outer and an inner
|
||||
* loop. Even it is intended this is confusing code.
|
||||
*
|
||||
* <code>
|
||||
* class Foo
|
||||
* {
|
||||
* public function bar($x)
|
||||
* {
|
||||
* for ($i = 0; $i < 10; $i++)
|
||||
* {
|
||||
* for ($k = 0; $k < 20; $i++)
|
||||
* {
|
||||
* echo 'Hello';
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_codeanalysis_jumbledincrementersniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Registers the tokens that this sniff wants to listen for.
|
||||
*
|
||||
* @return array(integer)
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_FOR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$token = $tokens[$stackptr];
|
||||
|
||||
// Skip for-loop without body.
|
||||
if (isset($token['scope_opener']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find incrementors for outer loop.
|
||||
$outer = $this->findincrementers($tokens, $token);
|
||||
|
||||
// Skip if empty.
|
||||
if (count($outer) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find nested for loops.
|
||||
$start = ++$token['scope_opener'];
|
||||
$end = --$token['scope_closer'];
|
||||
|
||||
for (; $start <= $end; ++$start) {
|
||||
|
||||
if ($tokens[$start]['code'] !== T_FOR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$inner = $this->findincrementers($tokens, $tokens[$start]);
|
||||
$diff = array_intersect($outer, $inner);
|
||||
|
||||
if (count($diff) !== 0) {
|
||||
$error = sprintf('Loop incrementor (%s) jumbling with inner loop', join(', ', $diff));
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all used variables in the incrementer part of a for statement.
|
||||
*
|
||||
* @param array(integer=>array) $tokens Array with all code sniffer tokens.
|
||||
* @param array(string=>mixed) $token Current for loop token
|
||||
*
|
||||
* @return array(string) List of all found incrementer variables.
|
||||
*/
|
||||
protected function findincrementers(array $tokens, array $token) {
|
||||
// Skip invalid statement.
|
||||
if (isset($token['parenthesis_opener']) === false) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$start = ++$token['parenthesis_opener'];
|
||||
$end = --$token['parenthesis_closer'];
|
||||
|
||||
$incrementers = array();
|
||||
$semicolons = 0;
|
||||
|
||||
for ($next = $start; $next <= $end; ++$next) {
|
||||
$code = $tokens[$next]['code'];
|
||||
|
||||
if ($code === T_SEMICOLON) {
|
||||
++$semicolons;
|
||||
|
||||
} else if ($semicolons === 2 && $code === T_VARIABLE) {
|
||||
$incrementers[] = $tokens[$next]['content'];
|
||||
}
|
||||
}
|
||||
|
||||
return $incrementers;
|
||||
|
||||
}
|
||||
}
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* This file is part of the CodeAnalysis addon for PHP_CodeSniffer.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-codeanalysis
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Detects unconditional if- and elseif-statements.
|
||||
*
|
||||
* This rule is based on the PMD rule catalog. The Unconditional If Statment
|
||||
* sniff detects statement conditions that are only set to one of the constant
|
||||
* values <b>true</b> or <b>false</b>
|
||||
*
|
||||
* <code>
|
||||
* class Foo
|
||||
* {
|
||||
* public function close()
|
||||
* {
|
||||
* if (true)
|
||||
* {
|
||||
* // ...
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_codeanalysis_unconditionalifstatementsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Registers the tokens that this sniff wants to listen for.
|
||||
*
|
||||
* @return array(integer)
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_IF, T_ELSEIF);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$token = $tokens[$stackptr];
|
||||
|
||||
// Skip for-loop without body.
|
||||
if (isset($token['parenthesis_opener']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$next = ++$token['parenthesis_opener'];
|
||||
$end = --$token['parenthesis_closer'];
|
||||
|
||||
$goodcondition = false;
|
||||
|
||||
for (; $next <= $end; ++$next) {
|
||||
$code = $tokens[$next]['code'];
|
||||
|
||||
if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === true) {
|
||||
continue;
|
||||
|
||||
} else if ($code !== T_TRUE && $code !== T_FALSE) {
|
||||
$goodcondition = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($goodcondition === false) {
|
||||
$error = 'Avoid IF statements that are always true or false';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* This file is part of the CodeAnalysis addon for PHP_CodeSniffer.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-codeanalysis
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Detects unnecessary final modifiers inside of final classes.
|
||||
*
|
||||
* This rule is based on the PMD rule catalog. The Unnecessary Final Modifier
|
||||
* sniff detects the use of the final modifier inside of a final class which
|
||||
* is unnecessary.
|
||||
*
|
||||
* <code>
|
||||
* final class Foo
|
||||
* {
|
||||
* public final function bar()
|
||||
* {
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_codeanalysis_unnecessaryfinalmodifiersniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Registers the tokens that this sniff wants to listen for.
|
||||
*
|
||||
* @return array(integer)
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_CLASS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$token = $tokens[$stackptr];
|
||||
|
||||
// Skip for-statements without body.
|
||||
if (isset($token['scope_opener']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch previous token.
|
||||
$prev = $phpcsfile->findprevious(PHP_CodeSniffer_tokens::$emptyTokens, ($stackptr - 1), null, true);
|
||||
|
||||
// Skip for non final class.
|
||||
if ($prev === false || $tokens[$prev]['code'] !== T_FINAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
$next = ++$token['scope_opener'];
|
||||
$end = --$token['scope_closer'];
|
||||
|
||||
for (; $next <= $end; ++$next) {
|
||||
|
||||
if ($tokens[$next]['code'] === T_FINAL) {
|
||||
$error = 'Unnecessary FINAL modifier in FINAL class';
|
||||
$phpcsfile->addwarning($error, $next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-143
@@ -1,143 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* This file is part of the CodeAnalysis addon for PHP_CodeSniffer.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-codeanalysis
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks the for unused function parameters.
|
||||
*
|
||||
* This sniff checks that all function parameters are used in the function body.
|
||||
* One exception is made for empty function bodies or function bodies that only
|
||||
* contain comments. This could be usefull for the classes that implement an
|
||||
* interface that defines multiple methods but the implementation only needs some
|
||||
* of them.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_codeanalysis_unusedfunctionparametersniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$token = $tokens[$stackptr];
|
||||
|
||||
// Skip broken function declarations.
|
||||
if (isset($token['scope_opener']) === false || isset($token['parenthesis_opener']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$params = array();
|
||||
|
||||
foreach ($phpcsfile->getmethodparameters($stackptr) as $param) {
|
||||
$params[$param['name']] = $stackptr;
|
||||
}
|
||||
|
||||
$next = ++$token['scope_opener'];
|
||||
$end = --$token['scope_closer'];
|
||||
|
||||
$emptybody = true;
|
||||
|
||||
for (; $next <= $end; ++$next) {
|
||||
$token = $tokens[$next];
|
||||
$code = $token['code'];
|
||||
|
||||
// Ingorable tokens.
|
||||
if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === true) {
|
||||
continue;
|
||||
|
||||
} else if ($code === T_THROW && $emptybody === true) {
|
||||
// Throw statement and an empty body indicate an interface method.
|
||||
return;
|
||||
|
||||
} else if ($code === T_RETURN && $emptybody === true) {
|
||||
// Return statement and an empty body indicate an interface method.
|
||||
$tmp = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($next + 1), null, true);
|
||||
|
||||
if ($tmp === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a return.
|
||||
if ($tokens[$tmp] === T_SEMICOLON) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tmp = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($tmp + 1), null, true);
|
||||
|
||||
// There is a return <token>.
|
||||
if ($tmp !== false && $tokens[$tmp] === T_SEMICOLON) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$emptybody = false;
|
||||
|
||||
if ($code === T_VARIABLE && isset($params[$token['content']]) === true) {
|
||||
unset($params[$token['content']]);
|
||||
|
||||
} else if ($code === T_DOUBLE_QUOTED_STRING) {
|
||||
// tokenize double quote string.
|
||||
$strtokens = token_get_all(sprintf('<?php %s;?>', $token['content']));
|
||||
|
||||
foreach ($strtokens as $tok) {
|
||||
|
||||
if (is_array($tok) === false || $tok[0] !== T_VARIABLE ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($params[$tok[1]]) === true) {
|
||||
unset($params[$tok[1]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($emptybody === false && count($params) > 0) {
|
||||
|
||||
foreach ($params as $paramname => $position) {
|
||||
$error = 'The method parameter '.$paramname.' is never used';
|
||||
$phpcsfile->addwarning($error, $position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-185
@@ -1,185 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* This file is part of the CodeAnalysis addon for PHP_CodeSniffer.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-codeanalysis
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Detects unnecessary final modifiers inside of final classes.
|
||||
*
|
||||
* This rule is based on the PMD rule catalog. The Unnecessary Final Modifier
|
||||
* sniff detects the use of the final modifier inside of a final class which
|
||||
* is unnecessary.
|
||||
*
|
||||
* <code>
|
||||
* final class Foo
|
||||
* {
|
||||
* public final function bar()
|
||||
* {
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_codeanalysis_uselessoverridingmethodsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Registers the tokens that this sniff wants to listen for.
|
||||
*
|
||||
* @return array(integer)
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$token = $tokens[$stackptr];
|
||||
|
||||
// Skip function without body.
|
||||
if (isset($token['scope_opener']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get function name.
|
||||
$methodname = $phpcsfile->getdeclarationname($stackptr);
|
||||
|
||||
// Get all parameters from method signature.
|
||||
$signature = array();
|
||||
|
||||
foreach ($phpcsfile->getmethodparameters($stackptr) as $param) {
|
||||
$signature[] = $param['name'];
|
||||
}
|
||||
|
||||
$next = ++$token['scope_opener'];
|
||||
$end = --$token['scope_closer'];
|
||||
|
||||
for (; $next <= $end; ++$next) {
|
||||
$code = $tokens[$next]['code'];
|
||||
|
||||
if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === true) {
|
||||
continue;
|
||||
|
||||
} else if ($code === T_RETURN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Any token except 'parent' indicates correct code.
|
||||
if ($tokens[$next]['code'] !== T_PARENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find next non empty token index, should be double colon.
|
||||
$next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($next + 1), null, true);
|
||||
|
||||
// Skip for invalid code.
|
||||
if ($next === false || $tokens[$next]['code'] !== T_DOUBLE_COLON) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find next non empty token index, should be the function name.
|
||||
$next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($next + 1), null, true);
|
||||
|
||||
// Skip for invalid code or other method.
|
||||
if ($next === false || $tokens[$next]['content'] !== $methodname) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find next non empty token index, should be the open parenthesis.
|
||||
$next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($next + 1), null, true);
|
||||
|
||||
// Skip for invalid code.
|
||||
if ($next === false || $tokens[$next]['code'] !== T_OPEN_PARENTHESIS) {
|
||||
return;
|
||||
}
|
||||
|
||||
$validparametertypes = array(
|
||||
T_VARIABLE,
|
||||
T_LNUMBER,
|
||||
T_CONSTANT_ENCAPSED_STRING,
|
||||
);
|
||||
|
||||
$parameters = array('');
|
||||
$parenthesiscount = 1;
|
||||
$count = count($tokens);
|
||||
|
||||
for (++$next; $next < $count; ++$next) {
|
||||
$code = $tokens[$next]['code'];
|
||||
|
||||
if ($code === T_OPEN_PARENTHESIS) {
|
||||
++$parenthesiscount;
|
||||
|
||||
} else if ($code === T_CLOSE_PARENTHESIS) {
|
||||
--$parenthesiscount;
|
||||
|
||||
} else if ($parenthesiscount === 1 && $code === T_COMMA) {
|
||||
$parameters[] = '';
|
||||
|
||||
} else if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === false) {
|
||||
$parameters[(count($parameters) - 1)] .= $tokens[$next]['content'];
|
||||
}
|
||||
|
||||
if ($parenthesiscount === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($next + 1), null, true);
|
||||
|
||||
if ($next === false || $tokens[$next]['code'] !== T_SEMICOLON) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check rest of the scope.
|
||||
for (++$next; $next <= $end; ++$next) {
|
||||
$code = $tokens[$next]['code'];
|
||||
// Skip for any other content.
|
||||
|
||||
if (in_array($code, PHP_CodeSniffer_tokens::$emptyTokens) === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$parameters = array_map('trim', $parameters);
|
||||
$parameters = array_filter($parameters);
|
||||
|
||||
if (count($parameters) === count($signature) && $parameters === $signature) {
|
||||
$phpcsfile->addwarning('Useless method overriding detected', $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* Parses and verifies the doc comments for classes.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-commenting
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
if (class_exists('PHP_CodeSniffer_CommentParser_ClassCommentParser', true) === false) {
|
||||
$error = 'Class PHP_CodeSniffer_CommentParser_ClassCommentParser not found';
|
||||
throw new PHP_CodeSniffer_Exception($error);
|
||||
}
|
||||
|
||||
if (class_exists('moodle_sniffs_commenting_filecommentsniff', true) === false) {
|
||||
$error = 'Class moodle_sniffs_commenting_filecommentsniff not found';
|
||||
throw new PHP_CodeSniffer_Exception($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and verifies the doc comments for classes.
|
||||
*
|
||||
* Verifies that :
|
||||
* <ul>
|
||||
* <li>A doc comment exists.</li>
|
||||
* <li>There is a blank newline after the short description.</li>
|
||||
* <li>There is a blank newline between the long and short description.</li>
|
||||
* <li>There is a blank newline between the long description and tags.</li>
|
||||
* <li>Check the order of the tags.</li>
|
||||
* <li>Check the indentation of each tag.</li>
|
||||
* <li>Check required and optional tags and the format of their content.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_commenting_classcommentsniff extends moodle_sniffs_commenting_filecommentsniff {
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_CLASS, T_INTERFACE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
// Modify array of required tags
|
||||
$this->tags['package']['required'] = false;
|
||||
$this->tags['copyright']['required'] = false;
|
||||
$this->tags['author']['required'] = false;
|
||||
|
||||
$this->currentfile = $phpcsfile;
|
||||
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$type = strtolower($tokens[$stackptr]['content']);
|
||||
$find = array(
|
||||
T_ABSTRACT,
|
||||
T_WHITESPACE,
|
||||
T_FINAL,
|
||||
);
|
||||
|
||||
// Extract the class comment docblock.
|
||||
$commentend = $phpcsfile->findprevious($find, ($stackptr - 1), null, true);
|
||||
|
||||
if ($commentend !== false && $tokens[$commentend]['code'] === T_COMMENT) {
|
||||
$phpcsfile->adderror("You must use \"/**\" style comments for a $type comment", $stackptr);
|
||||
return;
|
||||
|
||||
} else if ($commentend === false || $tokens[$commentend]['code'] !== T_DOC_COMMENT) {
|
||||
$phpcsfile->adderror("Missing $type doc comment", $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
$commentstart = ($phpcsfile->findprevious(T_DOC_COMMENT, ($commentend - 1), null, true) + 1);
|
||||
$commentnext = $phpcsfile->findprevious(T_WHITESPACE, ($commentend + 1), $stackptr, false, $phpcsfile->eolChar);
|
||||
|
||||
// Distinguish file and class comment.
|
||||
$prevclasstoken = $phpcsfile->findprevious(T_CLASS, ($stackptr - 1));
|
||||
|
||||
if ($prevclasstoken === false) {
|
||||
// This is the first class token in this file, need extra checks.
|
||||
$prevnoncomment = $phpcsfile->findprevious(T_DOC_COMMENT, ($commentstart - 1), null, true);
|
||||
|
||||
if ($prevnoncomment !== false) {
|
||||
$prevcomment = $phpcsfile->findprevious(T_DOC_COMMENT, ($prevnoncomment - 1));
|
||||
|
||||
if ($prevcomment === false) {
|
||||
// There is only 1 doc comment between open tag and class token.
|
||||
$newlinetoken = $phpcsfile->findnext(T_WHITESPACE, ($commentend + 1), $stackptr, false, $phpcsfile->eolChar);
|
||||
|
||||
if ($newlinetoken !== false) {
|
||||
$newlinetoken = $phpcsfile->findnext(T_WHITESPACE, ($newlinetoken + 1), $stackptr, false, $phpcsfile->eolChar);
|
||||
|
||||
if ($newlinetoken !== false) {
|
||||
// Blank line between the class and the doc block.
|
||||
// The doc block is most likely a file comment.
|
||||
$phpcsfile->adderror("Missing $type doc comment", ($stackptr + 1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$comment = $phpcsfile->gettokensAsString($commentstart, ($commentend - $commentstart + 1));
|
||||
|
||||
// Parse the class comment.docblock.
|
||||
try {
|
||||
$this->commentparser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsfile);
|
||||
$this->commentparser->parse();
|
||||
|
||||
} catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
|
||||
$line = ($e->getlinewithinComment() + $commentstart);
|
||||
$phpcsfile->adderror($e->getMessage(), $line);
|
||||
return;
|
||||
}
|
||||
|
||||
$comment = $this->commentparser->getComment();
|
||||
|
||||
if (is_null($comment) === true) {
|
||||
$error = ucfirst($type).' doc comment is empty';
|
||||
$phpcsfile->adderror($error, $commentstart);
|
||||
return;
|
||||
}
|
||||
|
||||
// No extra newline before short description.
|
||||
$short = $comment->getShortComment();
|
||||
$newlinecount = 0;
|
||||
$newlinespan = strspn($short, $phpcsfile->eolChar);
|
||||
|
||||
if ($short !== '' && $newlinespan > 0) {
|
||||
$line = ($newlinespan > 1) ? 'newlines' : 'newline';
|
||||
$error = "Extra $line found before $type comment short description";
|
||||
$phpcsfile->adderror($error, ($commentstart + 1));
|
||||
}
|
||||
|
||||
$newlinecount = (substr_count($short, $phpcsfile->eolChar) + 1);
|
||||
|
||||
// Exactly one blank line between short and long description.
|
||||
$long = $comment->getlongcomment();
|
||||
|
||||
if (empty($long) === false) {
|
||||
$between = $comment->getWhiteSpacebetween();
|
||||
$newlinebetween = substr_count($between, $phpcsfile->eolChar);
|
||||
|
||||
if ($newlinebetween !== 2) {
|
||||
$error = "There must be exactly one blank line between descriptions in $type comments";
|
||||
$phpcsfile->adderror($error, ($commentstart + $newlinecount + 1));
|
||||
}
|
||||
|
||||
$newlinecount += $newlinebetween;
|
||||
}
|
||||
|
||||
// Exactly one blank line before tags.
|
||||
$tags = $this->commentparser->gettagOrders();
|
||||
|
||||
if (count($tags) > 1) {
|
||||
$newlinespan = $comment->getNewlineAfter();
|
||||
|
||||
if ($newlinespan !== 2) {
|
||||
$error = "There must be exactly one blank line before the tags in $type comments";
|
||||
|
||||
if ($long !== '') {
|
||||
$newlinecount += (substr_count($long, $phpcsfile->eolChar) - $newlinespan + 1);
|
||||
}
|
||||
|
||||
$phpcsfile->addwarning($error, ($commentstart + $newlinecount));
|
||||
$short = rtrim($short, $phpcsfile->eolChar.' ');
|
||||
}
|
||||
}
|
||||
|
||||
// Check each tag.
|
||||
$this->processtags($commentstart, $commentend);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the version tag.
|
||||
*
|
||||
* @param int $errorpos The line number where the error occurs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processversion($errorpos) {
|
||||
$version = $this->commentparser->getVersion();
|
||||
|
||||
if ($version !== null) {
|
||||
$content = $version->getcontent();
|
||||
$matches = array();
|
||||
|
||||
if (empty($content) === true) {
|
||||
$error = 'content missing for @version tag in doc comment';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
|
||||
} else if ((strstr($content, 'Release:') === false)) {
|
||||
$error = "Invalid version \"$content\" in doc comment; consider \"Release: <package_version>\" instead";
|
||||
$this->currentfile->addwarning($error, $errorpos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,805 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* Parses and verifies the doc comments for files.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-commenting
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
if (class_exists('PHP_CodeSniffer_CommentParser_ClassCommentParser', true) === false) {
|
||||
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_CommentParser_ClassCommentParser not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and verifies the doc comments for files.
|
||||
*
|
||||
* Verifies that :
|
||||
* <ul>
|
||||
* <li>A doc comment exists.</li>
|
||||
* <li>There is a blank newline after the short description.</li>
|
||||
* <li>There is a blank newline between the long and short description.</li>
|
||||
* <li>There is a blank newline between the long description and tags.</li>
|
||||
* <li>A PHP version is specified.</li>
|
||||
* <li>Check the order of the tags.</li>
|
||||
* <li>Check the indentation of each tag.</li>
|
||||
* <li>Check required and optional tags and the format of their content.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
class moodle_sniffs_commenting_filecommentsniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* The header comment parser for the current file.
|
||||
*
|
||||
* @var PHP_CodeSniffer_Comment_Parser_ClassCommentParser
|
||||
*/
|
||||
protected $commentparser = null;
|
||||
|
||||
/**
|
||||
* The current PHP_CodeSniffer_File object we are processing.
|
||||
*
|
||||
* @var PHP_CodeSniffer_File
|
||||
*/
|
||||
protected $currentfile = null;
|
||||
|
||||
/**
|
||||
* Tags in correct order and related info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tags = array(
|
||||
'category' => array(
|
||||
'required' => false,
|
||||
'allow_multiple' => false,
|
||||
'order_text' => 'precedes @subpackage',
|
||||
),
|
||||
'package' => array(
|
||||
'required' => true,
|
||||
'allow_multiple' => false,
|
||||
'order_text' => 'follows @category',
|
||||
),
|
||||
'subpackage' => array(
|
||||
'required' => false,
|
||||
'allow_multiple' => false,
|
||||
'order_text' => 'follows @subpackage',
|
||||
),
|
||||
'author' => array(
|
||||
'required' => false,
|
||||
'allow_multiple' => true,
|
||||
'order_text' => 'follows @subsubpackage (if used) or @subpackage',
|
||||
),
|
||||
'copyright' => array(
|
||||
'required' => true,
|
||||
'allow_multiple' => true,
|
||||
'order_text' => 'follows @author',
|
||||
),
|
||||
'license' => array(
|
||||
'required' => true,
|
||||
'allow_multiple' => false,
|
||||
'order_text' => 'follows @copyright (if used) or @author',
|
||||
),
|
||||
'version' => array(
|
||||
'required' => false,
|
||||
'allow_multiple' => false,
|
||||
'order_text' => 'follows @licence',
|
||||
),
|
||||
'link' => array(
|
||||
'required' => false,
|
||||
'allow_multiple' => true,
|
||||
'order_text' => 'follows @version',
|
||||
),
|
||||
'see' => array(
|
||||
'required' => false,
|
||||
'allow_multiple' => true,
|
||||
'order_text' => 'follows @link',
|
||||
),
|
||||
'since' => array(
|
||||
'required' => false,
|
||||
'allow_multiple' => false,
|
||||
'order_text' => 'follows @see (if used) or @link',
|
||||
),
|
||||
'deprecated' => array(
|
||||
'required' => false,
|
||||
'allow_multiple' => false,
|
||||
'order_text' => 'follows @since (if used) or @see (if used) or @link',
|
||||
),
|
||||
);
|
||||
|
||||
protected $core_folders = array('admin', 'backup', 'blog', 'calendar', 'course',
|
||||
'error', 'group', 'iplookup', 'lib', 'login',
|
||||
'message', 'mnet', 'my', 'notes', 'pix', 'rss',
|
||||
'tag', 'user', 'userpix');
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_OPEN_TAG);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$this->currentfile = $phpcsfile;
|
||||
|
||||
// We are only interested if this is the first open tag.
|
||||
if ($stackptr !== 0) {
|
||||
|
||||
if ($phpcsfile->findprevious(T_OPEN_TAG, ($stackptr - 1)) !== false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
// Find the next non whitespace token.
|
||||
$commentstart = $phpcsfile->findnext(T_WHITESPACE, ($stackptr + 1), null, true);
|
||||
|
||||
// Look for $Id$ and boilerplate
|
||||
if ($tokens[$commentstart]['code'] != T_COMMENT) {
|
||||
$phpcsfile->adderror('File must begin with License boilerplate', ($stackptr + 1));
|
||||
return;
|
||||
|
||||
} else if (preg_match('|\$Id|i', $tokens[$commentstart]['content'])) {
|
||||
$phpcsfile->addwarning("\$Id\$ tag is no longer required, please remove.", ($stackptr + 1));
|
||||
return;
|
||||
}
|
||||
|
||||
// now look for boilerplate, must be immediately after the first line
|
||||
$boilerplate = '// 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/>.';
|
||||
|
||||
$nexttoken = $phpcsfile->findnext(T_WHITESPACE, ($stackptr + 1), null, true);
|
||||
$boilerplate_lines = preg_split('/[\n\r]+/', $boilerplate);
|
||||
|
||||
if (rtrim($tokens[$nexttoken]['content']) != $boilerplate_lines[0]) {
|
||||
$phpcsfile->adderror('You must include the Moodle boilerplate at the top of the file', ($nexttoken));
|
||||
return;
|
||||
}
|
||||
|
||||
$boilerplate_index = 0;
|
||||
|
||||
foreach ($boilerplate_lines as $line) {
|
||||
$nexttoken = $phpcsfile->findnext(T_COMMENT, ($nexttoken));
|
||||
|
||||
if (rtrim($tokens[$nexttoken]['content']) != $boilerplate_lines[$boilerplate_index]) {
|
||||
$phpcsfile->adderror('Badly formatted boilerplate. Please copy-paste exactly', ($nexttoken));
|
||||
return;
|
||||
}
|
||||
$nexttoken++;
|
||||
$boilerplate_index++;
|
||||
}
|
||||
|
||||
$filedoctoken = $phpcsfile->findnext(T_WHITESPACE, ($nexttoken + 1), null, true);
|
||||
|
||||
if ($tokens[$filedoctoken]['code'] === T_CLOSE_TAG) {
|
||||
// We are only interested if this is the first open tag.
|
||||
return;
|
||||
|
||||
} else if ($tokens[$filedoctoken]['code'] === T_COMMENT) {
|
||||
$phpcsfile->adderror('You must use "/**" style comments for a file comment', ($filedoctoken + 1));
|
||||
return;
|
||||
|
||||
} else if ($filedoctoken === false || $tokens[$filedoctoken]['code'] !== T_DOC_COMMENT) {
|
||||
$phpcsfile->adderror('Missing file doc comment', ($filedoctoken + 1));
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
// Extract the header comment docblock.
|
||||
$commentend = ($phpcsfile->findnext(T_DOC_COMMENT, ($filedoctoken + 1), null, true) - 1);
|
||||
|
||||
// Check if there is only 1 doc comment between the open tag and class token.
|
||||
$nexttoken = array(
|
||||
T_ABSTRACT,
|
||||
T_CLASS,
|
||||
T_FUNCTION,
|
||||
T_DOC_COMMENT,
|
||||
);
|
||||
$commentnext = $phpcsfile->findnext($nexttoken, ($commentend + 1));
|
||||
|
||||
if ($commentnext !== false && $tokens[$commentnext]['code'] !== T_DOC_COMMENT) {
|
||||
// Found a class token right after comment doc block.
|
||||
$newlinetoken = $phpcsfile->findnext(T_WHITESPACE, ($commentend + 1),
|
||||
$commentnext, false, $phpcsfile->eolChar);
|
||||
|
||||
if ($newlinetoken !== false) {
|
||||
$newlinetoken = $phpcsfile->findnext(T_WHITESPACE, ($newlinetoken + 1),
|
||||
$commentnext, false, $phpcsfile->eolChar);
|
||||
|
||||
if ($newlinetoken === false) {
|
||||
// No blank line between the class token and the doc block.
|
||||
// The doc block is most likely a class comment.
|
||||
$phpcsfile->adderror('Missing file doc comment', ($stackptr + 1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$comment = $phpcsfile->gettokensAsString($filedoctoken, ($commentend - $filedoctoken + 1));
|
||||
|
||||
// Parse the header comment docblock.
|
||||
try {
|
||||
$this->commentparser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsfile);
|
||||
$this->commentparser->parse();
|
||||
|
||||
} catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
|
||||
$line = ($e->getlinewithinComment() + $filedoctoken);
|
||||
$phpcsfile->adderror($e->getMessage(), $line);
|
||||
return;
|
||||
}
|
||||
|
||||
$comment = $this->commentparser->getComment();
|
||||
|
||||
if (is_null($comment) === true) {
|
||||
$error = 'File doc comment is empty';
|
||||
$phpcsfile->adderror($error, $filedoctoken);
|
||||
return;
|
||||
}
|
||||
|
||||
// No extra newline before short description.
|
||||
$short = $comment->getShortComment();
|
||||
$newlinecount = 0;
|
||||
$newlinespan = strspn($short, $phpcsfile->eolChar);
|
||||
|
||||
if ($short !== '' && $newlinespan > 0) {
|
||||
$line = ($newlinespan > 1) ? 'newlines' : 'newline';
|
||||
$error = "Extra $line found before file comment short description";
|
||||
$phpcsfile->adderror($error, ($filedoctoken + 1));
|
||||
}
|
||||
|
||||
$newlinecount = (substr_count($short, $phpcsfile->eolChar) + 1);
|
||||
|
||||
// Exactly one blank line between short and long description.
|
||||
$long = $comment->getlongcomment();
|
||||
|
||||
if (empty($long) === false) {
|
||||
$between = $comment->getWhiteSpacebetween();
|
||||
$newlinebetween = substr_count($between, $phpcsfile->eolChar);
|
||||
|
||||
if ($newlinebetween !== 2) {
|
||||
$error = 'There should be exactly one blank line between descriptions in file comment';
|
||||
$phpcsfile->addwarning($error, ($filedoctoken + $newlinecount + 1));
|
||||
}
|
||||
|
||||
$newlinecount += $newlinebetween;
|
||||
}
|
||||
|
||||
// Exactly one blank line before tags.
|
||||
$tags = $this->commentparser->gettagOrders();
|
||||
|
||||
if (count($tags) > 1) {
|
||||
$newlinespan = $comment->getNewlineAfter();
|
||||
|
||||
if ($newlinespan !== 2) {
|
||||
$error = 'There must be exactly one blank line before the tags in file comment';
|
||||
|
||||
if ($long !== '') {
|
||||
$newlinecount += (substr_count($long, $phpcsfile->eolChar) - $newlinespan + 1);
|
||||
}
|
||||
|
||||
$phpcsfile->addwarning($error, ($filedoctoken + $newlinecount));
|
||||
$short = rtrim($short, $phpcsfile->eolChar.' ');
|
||||
}
|
||||
}
|
||||
|
||||
// Check the PHP Version.
|
||||
/*
|
||||
if (strstr(strtolower($long), 'php version') === false) {
|
||||
$error = 'PHP version not specified';
|
||||
$phpcsfile->addwarning($error, $commentend);
|
||||
}
|
||||
*/
|
||||
|
||||
// Check each tag.
|
||||
$this->processtags($filedoctoken, $commentend);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes each required or optional tag.
|
||||
*
|
||||
* @param int $commentstart The position in the stack where the comment started.
|
||||
* @param int $commentend The position in the stack where the comment ended.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processtags($commentstart, $commentend) {
|
||||
$docblock = (get_class($this) === 'moodle_sniffs_commenting_filecommentsniff') ? 'file' : 'class';
|
||||
$foundtags = $this->commentparser->gettagOrders();
|
||||
$orderindex = 0;
|
||||
$indentation = array();
|
||||
$longesttag = 0;
|
||||
$errorpos = 0;
|
||||
|
||||
foreach ($this->tags as $tag => $info) {
|
||||
|
||||
// Required tag missing.
|
||||
if ($info['required'] === true && in_array($tag, $foundtags) === false) {
|
||||
$error = "Missing @$tag tag in $docblock comment";
|
||||
$this->currentfile->adderror($error, $commentend);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the line number for current tag.
|
||||
$tagname = ucfirst($tag);
|
||||
|
||||
if ($info['allow_multiple'] === true) {
|
||||
$tagname .= 's';
|
||||
}
|
||||
|
||||
$getmethod = 'get'.$tagname;
|
||||
$tagelement = $this->commentparser->$getmethod();
|
||||
|
||||
if (is_null($tagelement) === true || empty($tagelement) === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$errorpos = $commentstart;
|
||||
|
||||
if (is_array($tagelement) === false) {
|
||||
$errorpos = ($commentstart + $tagelement->getline());
|
||||
}
|
||||
|
||||
// Get the tag order.
|
||||
$foundindexes = array_keys($foundtags, $tag);
|
||||
|
||||
if (count($foundindexes) > 1) {
|
||||
// Multiple occurance not allowed.
|
||||
if ($info['allow_multiple'] === false) {
|
||||
$error = "Only 1 @$tag tag is allowed in a $docblock comment";
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
|
||||
} else {
|
||||
// Make sure same tags are grouped together.
|
||||
$i = 0;
|
||||
$count = $foundindexes[0];
|
||||
|
||||
foreach ($foundindexes as $index) {
|
||||
|
||||
if ($index !== $count) {
|
||||
$errorposindex = ($errorpos + $tagelement[$i]->getline());
|
||||
$error = "@$tag tags must be grouped together";
|
||||
$this->currentfile->adderror($error, $errorposindex);
|
||||
}
|
||||
|
||||
$i++;
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check tag order.
|
||||
if ($foundindexes[0] > $orderindex) {
|
||||
$orderindex = $foundindexes[0];
|
||||
|
||||
} else {
|
||||
|
||||
if (is_array($tagelement) === true && empty($tagelement) === false) {
|
||||
$errorpos += $tagelement[0]->getline();
|
||||
}
|
||||
|
||||
$ordertext = $info['order_text'];
|
||||
$error = "The @$tag tag is in the wrong order; the tag $ordertext";
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
// Store the indentation for checking.
|
||||
$len = strlen($tag);
|
||||
|
||||
if ($len > $longesttag) {
|
||||
$longesttag = $len;
|
||||
}
|
||||
|
||||
if (is_array($tagelement) === true) {
|
||||
|
||||
foreach ($tagelement as $key => $element) {
|
||||
$indentation[] = array(
|
||||
'tag' => $tag,
|
||||
'space' => $this->getIndentation($tag, $element),
|
||||
'line' => $element->getline(),
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
$indentation[] = array(
|
||||
'tag' => $tag,
|
||||
'space' => $this->getIndentation($tag, $tagelement),
|
||||
);
|
||||
}
|
||||
|
||||
$method = 'process'.$tagname;
|
||||
|
||||
if (method_exists($this, $method) === true) {
|
||||
// Process each tag if a method is defined.
|
||||
call_user_func(array($this, $method), $errorpos);
|
||||
|
||||
} else {
|
||||
|
||||
if (is_array($tagelement) === true) {
|
||||
|
||||
foreach ($tagelement as $key => $element) {
|
||||
$element->process($this->currentfile, $commentstart, $docblock);
|
||||
}
|
||||
|
||||
} else {
|
||||
$tagelement->process($this->currentfile, $commentstart, $docblock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($indentation as $indentinfo) {
|
||||
|
||||
if ($indentinfo['space'] !== 0 && $indentinfo['space'] !== ($longesttag + 1)) {
|
||||
$expected = (($longesttag - strlen($indentinfo['tag'])) + 1);
|
||||
$space = ($indentinfo['space'] - strlen($indentinfo['tag']));
|
||||
$error = "@$indentinfo[tag] tag comment indented incorrectly. ";
|
||||
$error .= "Expected $expected spaces but found $space.";
|
||||
$gettagmethod = 'get'.ucfirst($indentinfo['tag']);
|
||||
|
||||
if ($this->tags[$indentinfo['tag']]['allow_multiple'] === true) {
|
||||
$line = $indentinfo['line'];
|
||||
|
||||
} else {
|
||||
$tagelem = $this->commentparser->$gettagmethod();
|
||||
$line = $tagelem->getline();
|
||||
}
|
||||
|
||||
$this->currentfile->addwarning($error, ($commentstart + $line));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the indentation information of each tag.
|
||||
*
|
||||
* @param string $tagname The name of the doc comment element.
|
||||
* @param PHP_CodeSniffer_CommentParser_Docelement $tagelement The doc comment element.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function getindentation($tagname, $tagelement) {
|
||||
|
||||
if ($tagelement instanceof PHP_CodeSniffer_CommentParser_Singleelement) {
|
||||
|
||||
if ($tagelement->getcontent() !== '') {
|
||||
return (strlen($tagname) + substr_count($tagelement->getwhitespacebeforecontent(), ' '));
|
||||
}
|
||||
|
||||
} else if ($tagelement instanceof PHP_CodeSniffer_CommentParser_Pairelement) {
|
||||
|
||||
if ($tagelement->getValue() !== '') {
|
||||
return (strlen($tagname) + substr_count($tagelement->getwhitespacebeforevalue(), ' '));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the category tag.
|
||||
*
|
||||
* @param int $errorpos The line number where the error occurs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processcategory($errorpos) {
|
||||
$category = $this->commentparser->getCategory();
|
||||
|
||||
if ($category !== null) {
|
||||
$content = $category->getcontent();
|
||||
|
||||
if ($content !== '') {
|
||||
|
||||
if (PHP_CodeSniffer::isUnderscorename($content) !== true) {
|
||||
$newcontent = str_replace(' ', '_', $content);
|
||||
$namebits = explode('_', $newcontent);
|
||||
$firstbit = array_shift($namebits);
|
||||
$newname = ucfirst($firstbit).'_';
|
||||
|
||||
foreach ($namebits as $bit) {
|
||||
$newname .= ucfirst($bit).'_';
|
||||
}
|
||||
|
||||
$validname = trim($newname, '_');
|
||||
$error = "Category name \"$content\" is not valid; consider \"$validname\" instead";
|
||||
// $this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
} else {
|
||||
$error = '@category tag must contain a name';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the package tag.
|
||||
*
|
||||
* @param int $errorpos The line number where the error occurs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processpackage($errorpos) {
|
||||
global $CFG;
|
||||
$package = $this->commentparser->getPackage();
|
||||
|
||||
$filename = str_replace($CFG->dirroot, '', $this->currentfile->getfilename());
|
||||
$path_parts = explode('/', $filename);
|
||||
|
||||
if (in_array($path_parts[1], $this->core_folders)) {
|
||||
$expected_package = 'moodlecore';
|
||||
|
||||
} else {
|
||||
|
||||
// Replace slashes or backslashes in file path with dashes
|
||||
$expected_package = strtolower(str_replace('/', '-', $filename));
|
||||
|
||||
if (strpos($expected_package, '-')) {
|
||||
$expected_package = strtolower(str_replace('\\', '-', $filename));
|
||||
}
|
||||
|
||||
// Strip off last part: the name of the searched file
|
||||
$expected_package = substr($expected_package, 0, strrpos($expected_package, '-'));
|
||||
|
||||
// Remove first dash if present
|
||||
$expected_package = ltrim($expected_package, '-');
|
||||
}
|
||||
|
||||
if ($package !== null) {
|
||||
$content = $package->getcontent();
|
||||
|
||||
if ($content !== $expected_package) {
|
||||
$error = "Package name \"$content\" is not valid; \"$expected_package\" expected.";
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
|
||||
} else if ($content !== '') {
|
||||
|
||||
if (!preg_match('/^[a-z\-]*$/', $content)) {
|
||||
$error = "Package name \"$content\" is not valid; must be lower-case with optional hyphens.";
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
} else {
|
||||
$error = '@subpackage tag must contain a name';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the subpackage tag.
|
||||
*
|
||||
* @param int $errorpos The line number where the error occurs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processsubpackage($errorpos) {
|
||||
$package = $this->commentparser->getSubpackage();
|
||||
|
||||
if ($package !== null) {
|
||||
$content = $package->getcontent();
|
||||
|
||||
if ($content !== '') {
|
||||
|
||||
if (PHP_CodeSniffer::isUnderscorename($content) !== true) {
|
||||
$newcontent = str_replace(' ', '_', $content);
|
||||
$namebits = explode('_', $newcontent);
|
||||
$firstbit = array_shift($namebits);
|
||||
$newname = strtoupper($firstbit{0}).substr($firstbit, 1).'_';
|
||||
|
||||
foreach ($namebits as $bit) {
|
||||
$newname .= strtoupper($bit{0}).substr($bit, 1).'_';
|
||||
}
|
||||
|
||||
$validname = trim($newname, '_');
|
||||
$error = "Subpackage name \"$content\" is not valid; consider \"$validname\" instead";
|
||||
// $this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
} else {
|
||||
$error = '@subpackage tag must contain a name';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the author tag(s) that this header comment has.
|
||||
*
|
||||
* This function is different from other _process functions
|
||||
* as $authors is an array of Singleelements, so we work out
|
||||
* the errorpos for each element separately
|
||||
*
|
||||
* @param int $commentstart The position in the stack where
|
||||
* the comment started.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processauthors($commentstart) {
|
||||
$authors = $this->commentparser->getAuthors();
|
||||
// Report missing return.
|
||||
if (empty($authors) === false) {
|
||||
|
||||
foreach ($authors as $author) {
|
||||
$errorpos = ($commentstart + $author->getline());
|
||||
$content = $author->getcontent();
|
||||
|
||||
if ($content !== '') {
|
||||
$local = '\da-zA-Z-_+';
|
||||
// Dot character cannot be the first or last character in the local-part.
|
||||
$localmiddle = $local.'.\w';
|
||||
|
||||
if (preg_match('/^([^<]*)\s+<(['.$local.']['.$localmiddle.']*['.$local.']@[\da-zA-Z][-.\w]*[\da-zA-Z]\.[a-zA-Z]{2,7})>$/', $content) === 0) {
|
||||
$error = 'content of the @author tag must be in the form "Display name <[email protected]>"';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
} else {
|
||||
$docblock = (get_class($this) === 'moodle_sniffs_commenting_filecommentsniff') ? 'file' : 'class';
|
||||
$error = "content missing for @author tag in $docblock comment";
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the copyright tags.
|
||||
*
|
||||
* @param int $commentstart The position in the stack where
|
||||
* the comment started.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processcopyrights($commentstart) {
|
||||
$copyrights = $this->commentparser->getCopyrights();
|
||||
|
||||
foreach ($copyrights as $copyright) {
|
||||
$errorpos = ($commentstart + $copyright->getline());
|
||||
$content = $copyright->getcontent();
|
||||
|
||||
if ($content !== '') {
|
||||
$matches = array();
|
||||
|
||||
if (preg_match('/^([0-9]{4})((.{1})([0-9]{4}))? (.+)$/', $content, $matches) !== 0) {
|
||||
// Check earliest-latest year order.
|
||||
|
||||
if ($matches[3] !== '') {
|
||||
|
||||
if ($matches[3] !== '-') {
|
||||
$error = 'A hyphen must be used between the earliest and latest year';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
if ($matches[4] !== '' && $matches[4] < $matches[1]) {
|
||||
$error = "Invalid year span \"$matches[1]$matches[3]$matches[4]\" found; consider \"$matches[4]-$matches[1]\" instead";
|
||||
$this->currentfile->addwarning($error, $errorpos);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$error = '@copyright tag must contain a year and the name of the copyright holder';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
} else {
|
||||
$error = '@copyright tag must contain a year and the name of the copyright holder';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the license tag.
|
||||
*
|
||||
* @param int $errorpos The line number where the error occurs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processlicense($errorpos) {
|
||||
$license = $this->commentparser->getLicense();
|
||||
|
||||
if ($license !== null) {
|
||||
$value = $license->getValue();
|
||||
$comment = $license->getComment();
|
||||
|
||||
if ($value === '' || $comment === '') {
|
||||
$error = '@license tag must contain a URL and a license name';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
if ($comment != 'GNU GPL v3 or later') {
|
||||
$this->currentfile->adderror('License must be "GNU GPL v3 or later", found "'.$comment.'"', $errorpos);
|
||||
}
|
||||
|
||||
if ($value != 'http://www.gnu.org/copyleft/gpl.html') {
|
||||
$this->currentfile->adderror('License must be "GNU GPL v3 or later"', $errorpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the version tag.
|
||||
*
|
||||
* @param int $errorpos The line number where the error occurs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processversion($errorpos) {
|
||||
$version = $this->commentparser->getVersion();
|
||||
|
||||
if ($version !== null) {
|
||||
$content = $version->getcontent();
|
||||
$matches = array();
|
||||
|
||||
if (empty($content) === true) {
|
||||
$error = 'content missing for @version tag in file comment';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
|
||||
} else if (strstr($content, 'CVS:') === false && strstr($content, 'SVN:') === false) {
|
||||
$error = "Invalid version \"$content\" in file comment; consider \"CVS: <cvs_id>\" or \"SVN: <svn_id>\" instead";
|
||||
$this->currentfile->addwarning($error, $errorpos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,467 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* Parses and verifies the doc comments for functions.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-commenting
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
if (class_exists('PHP_CodeSniffer_CommentParser_FunctionCommentParser', true) === false) {
|
||||
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_CommentParser_FunctionCommentParser not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and verifies the doc comments for functions.
|
||||
*
|
||||
* Verifies that :
|
||||
* <ul>
|
||||
* <li>A comment exists</li>
|
||||
* <li>There is a blank newline after the short description.</li>
|
||||
* <li>There is a blank newline between the long and short description.</li>
|
||||
* <li>There is a blank newline between the long description and tags.</li>
|
||||
* <li>parameter names represent those in the method.</li>
|
||||
* <li>parameter comments are in the correct order</li>
|
||||
* <li>parameter comments are complete</li>
|
||||
* <li>A space is present before the first and after the last parameter</li>
|
||||
* <li>A return type exists</li>
|
||||
* <li>There must be one blank line between body and headline comments.</li>
|
||||
* <li>Any throw tag must have an exception class.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_commenting_functioncommentsniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* The name of the method that we are currently processing.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_methodname = '';
|
||||
|
||||
/**
|
||||
* The position in the stack where the fucntion token was found.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_functiontoken = null;
|
||||
|
||||
/**
|
||||
* The position in the stack where the class token was found.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_classtoken = null;
|
||||
|
||||
/**
|
||||
* The function comment parser for the current method.
|
||||
*
|
||||
* @var PHP_CodeSniffer_Comment_Parser_FunctionCommentParser
|
||||
*/
|
||||
protected $commentparser = null;
|
||||
|
||||
/**
|
||||
* The current PHP_CodeSniffer_File object we are processing.
|
||||
*
|
||||
* @var PHP_CodeSniffer_File
|
||||
*/
|
||||
protected $currentfile = null;
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_FUNCTION);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$find = array(
|
||||
T_COMMENT,
|
||||
T_DOC_COMMENT,
|
||||
T_CLASS,
|
||||
T_FUNCTION,
|
||||
T_OPEN_TAG,
|
||||
);
|
||||
|
||||
$commentend = $phpcsfile->findprevious($find, ($stackptr - 1));
|
||||
|
||||
if ($commentend === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->currentfile = $phpcsfile;
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
// If the token that we found was a class or a function, then this
|
||||
// function has no doc comment.
|
||||
$code = $tokens[$commentend]['code'];
|
||||
|
||||
if ($code === T_COMMENT) {
|
||||
$error = 'You must use "/**" style comments for a function comment';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
|
||||
} else if ($code !== T_DOC_COMMENT) {
|
||||
$phpcsfile->adderror('Missing function doc comment', $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is any code between the function keyword and the doc block
|
||||
// then the doc block is not for us.
|
||||
$ignore = PHP_CodeSniffer_tokens::$scopeModifiers;
|
||||
$ignore[] = T_STATIC;
|
||||
$ignore[] = T_WHITESPACE;
|
||||
$ignore[] = T_ABSTRACT;
|
||||
$ignore[] = T_FINAL;
|
||||
$prevtoken = $phpcsfile->findprevious($ignore, ($stackptr - 1), null, true);
|
||||
|
||||
if ($prevtoken !== $commentend) {
|
||||
$phpcsfile->adderror('Missing function doc comment', $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->_functiontoken = $stackptr;
|
||||
|
||||
foreach ($tokens[$stackptr]['conditions'] as $condptr => $condition) {
|
||||
|
||||
if ($condition === T_CLASS || $condition === T_INTERFACE) {
|
||||
$this->_classtoken = $condptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the first T_OPEN_TAG is right before the comment, it is probably
|
||||
// a file comment.
|
||||
$commentstart = ($phpcsfile->findprevious(T_DOC_COMMENT, ($commentend - 1), null, true) + 1);
|
||||
$prevtoken = $phpcsfile->findprevious(T_WHITESPACE, ($commentstart - 1), null, true);
|
||||
|
||||
if ($tokens[$prevtoken]['code'] === T_OPEN_TAG) {
|
||||
// Is this the first open tag?
|
||||
|
||||
if ($stackptr === 0 || $phpcsfile->findprevious(T_OPEN_TAG, ($prevtoken - 1)) === false) {
|
||||
$phpcsfile->adderror('Missing function doc comment', $stackptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$comment = $phpcsfile->gettokensAsString($commentstart, ($commentend - $commentstart + 1));
|
||||
$this->_methodname = $phpcsfile->getDeclarationname($stackptr);
|
||||
|
||||
try {
|
||||
$this->commentparser = new PHP_CodeSniffer_CommentParser_FunctionCommentParser($comment, $phpcsfile);
|
||||
$this->commentparser->parse();
|
||||
|
||||
} catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
|
||||
$line = ($e->getlinewithinComment() + $commentstart);
|
||||
$phpcsfile->adderror($e->getMessage(), $line);
|
||||
return;
|
||||
}
|
||||
|
||||
$comment = $this->commentparser->getComment();
|
||||
|
||||
if (is_null($comment) === true) {
|
||||
$error = 'Function doc comment is empty';
|
||||
$phpcsfile->adderror($error, $commentstart);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->processparams($commentstart);
|
||||
$this->processreturn($commentstart, $commentend);
|
||||
$this->processthrows($commentstart);
|
||||
|
||||
// No extra newline before short description.
|
||||
$short = $comment->getShortComment();
|
||||
$newlinecount = 0;
|
||||
$newlinespan = strspn($short, $phpcsfile->eolChar);
|
||||
|
||||
if ($short !== '' && $newlinespan > 0) {
|
||||
$line = ($newlinespan > 1) ? 'newlines' : 'newline';
|
||||
$error = "Extra $line found before function comment short description";
|
||||
$phpcsfile->adderror($error, ($commentstart + 1));
|
||||
}
|
||||
|
||||
$newlinecount = (substr_count($short, $phpcsfile->eolChar) + 1);
|
||||
|
||||
// Exactly one blank line between short and long description.
|
||||
$long = $comment->getlongcomment();
|
||||
|
||||
if (empty($long) === false) {
|
||||
$between = $comment->getWhiteSpacebetween();
|
||||
$newlinebetween = substr_count($between, $phpcsfile->eolChar);
|
||||
|
||||
if ($newlinebetween !== 2) {
|
||||
$error = 'There must be exactly one blank line between descriptions in function comment';
|
||||
$phpcsfile->adderror($error, ($commentstart + $newlinecount + 1));
|
||||
}
|
||||
|
||||
$newlinecount += $newlinebetween;
|
||||
}
|
||||
|
||||
// Exactly one blank line before tags.
|
||||
$params = $this->commentparser->gettagOrders();
|
||||
|
||||
if (count($params) > 1) {
|
||||
$newlinespan = $comment->getNewlineAfter();
|
||||
|
||||
if ($newlinespan !== 2) {
|
||||
$error = 'There must be exactly one blank line before the tags in function comment';
|
||||
|
||||
if ($long !== '') {
|
||||
$newlinecount += (substr_count($long, $phpcsfile->eolChar) - $newlinespan + 1);
|
||||
}
|
||||
|
||||
$phpcsfile->addwarning($error, ($commentstart + $newlinecount));
|
||||
$short = rtrim($short, $phpcsfile->eolChar.' ');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process any throw tags that this function comment has.
|
||||
*
|
||||
* @param int $commentstart The position in the stack where the
|
||||
* comment started.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processthrows($commentstart) {
|
||||
|
||||
if (count($this->commentparser->getthrows()) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->commentparser->getthrows() as $throw) {
|
||||
|
||||
$exception = $throw->getvalue();
|
||||
$errorpos = ($commentstart + $throw->getline());
|
||||
|
||||
if ($exception === '') {
|
||||
$error = '@throws tag must contain the exception class name';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the return comment of this function comment.
|
||||
*
|
||||
* @param int $commentstart The position in the stack where the comment started.
|
||||
* @param int $commentend The position in the stack where the comment ended.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processreturn($commentstart, $commentend) {
|
||||
// Skip constructor and destructor.
|
||||
$classname = '';
|
||||
|
||||
if ($this->_classtoken !== null) {
|
||||
$classname = $this->currentfile->getdeclarationname($this->_classtoken);
|
||||
$classname = strtolower(ltrim($classname, '_'));
|
||||
}
|
||||
|
||||
$methodname = strtolower(ltrim($this->_methodname, '_'));
|
||||
$isspecialmethod = ($this->_methodname === '__construct' || $this->_methodname === '__destruct');
|
||||
|
||||
if ($isspecialmethod === false && $methodname !== $classname) {
|
||||
// Report missing return tag.
|
||||
if ($this->commentparser->getreturn() === null) {
|
||||
$error = 'Missing @return tag in function comment';
|
||||
$this->currentfile->adderror($error, $commentend);
|
||||
|
||||
} else if (trim($this->commentparser->getreturn()->getrawcontent()) === '') {
|
||||
$error = '@return tag is empty in function comment';
|
||||
$errorpos = ($commentstart + $this->commentparser->getreturn()->getline());
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the function parameter comments.
|
||||
*
|
||||
* @param int $commentstart The position in the stack where
|
||||
* the comment started.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processparams($commentstart) {
|
||||
$realparams = $this->currentfile->getmethodparameters($this->_functiontoken);
|
||||
|
||||
$params = $this->commentparser->getparams();
|
||||
$foundparams = array();
|
||||
|
||||
if (empty($params) === false) {
|
||||
|
||||
$lastparm = (count($params) - 1);
|
||||
|
||||
if (substr_count($params[$lastparm]->getwhitespaceafter(), $this->currentfile->eolChar) !== 2) {
|
||||
$error = 'Last parameter comment requires a blank newline after it';
|
||||
$errorpos = ($params[$lastparm]->getline() + $commentstart);
|
||||
$this->currentfile->addwarning($error, $errorpos);
|
||||
}
|
||||
|
||||
$previousparam = null;
|
||||
$spacebeforevar = 10000;
|
||||
$spacebeforecomment = 10000;
|
||||
$longesttype = 0;
|
||||
$longestvar = 0;
|
||||
|
||||
foreach ($params as $param) {
|
||||
|
||||
$paramcomment = trim($param->getcomment());
|
||||
$errorpos = ($param->getline() + $commentstart);
|
||||
|
||||
// Make sure that there is only one space before the var type.
|
||||
if ($param->getwhitespacebeforetype() !== ' ') {
|
||||
$error = 'Expected 1 space before variable type';
|
||||
$this->currentfile->addwarning($error, $errorpos);
|
||||
}
|
||||
|
||||
$spacecount = substr_count($param->getwhitespacebeforevarname(), ' ');
|
||||
|
||||
if ($spacecount < $spacebeforevar) {
|
||||
$spacebeforevar = $spacecount;
|
||||
$longesttype = $errorpos;
|
||||
}
|
||||
|
||||
$spacecount = substr_count($param->getwhitespacebeforecomment(), ' ');
|
||||
|
||||
if ($spacecount < $spacebeforecomment && $paramcomment !== '') {
|
||||
$spacebeforecomment = $spacecount;
|
||||
$longestvar = $errorpos;
|
||||
}
|
||||
|
||||
// Make sure they are in the correct order,
|
||||
// and have the correct name.
|
||||
$pos = $param->getposition();
|
||||
|
||||
$paramname = ($param->getvarname() !== '') ? $param->getvarname() : '[ UNKNOWN ]';
|
||||
|
||||
if ($previousparam !== null) {
|
||||
$previousname = ($previousparam->getvarname() !== '') ? $previousparam->getvarname() : 'UNKNOWN';
|
||||
|
||||
// Check to see if the parameters align properly.
|
||||
if ($param->alignsvariablewith($previousparam) === false) {
|
||||
$error = 'The variable names for parameters '.$previousname.' ('.($pos - 1).') and '.$paramname.' ('.$pos.') do not align';
|
||||
$this->currentfile->addwarning($error, $errorpos);
|
||||
}
|
||||
|
||||
if ($param->alignsCommentWith($previousparam) === false) {
|
||||
$error = 'The comments for parameters '.$previousname.' ('.($pos - 1).') and '.$paramname.' ('.$pos.') do not align';
|
||||
$this->currentfile->addwarning($error, $errorpos);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the names of the parameter comment matches the
|
||||
// actual parameter.
|
||||
if (isset($realparams[($pos - 1)]) === true) {
|
||||
$realname = $realparams[($pos - 1)]['name'];
|
||||
$foundparams[] = $realname;
|
||||
// Append ampersand to name if passing by reference.
|
||||
if ($realparams[($pos - 1)]['pass_by_reference'] === true) {
|
||||
$realname = '&'.$realname;
|
||||
}
|
||||
|
||||
if ($realname !== $param->getvarname()) {
|
||||
$error = 'Doc comment var "'.$paramname;
|
||||
$error .= '" does not match actual variable name "'.$realname;
|
||||
$error .= '" at position '.$pos;
|
||||
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
} else {
|
||||
// We must have an extra parameter comment.
|
||||
$error = 'Superfluous doc comment at position '.$pos;
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
if ($param->getvarname() === '') {
|
||||
$error = 'Missing parameter name at position '.$pos;
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
if ($param->gettype() === '') {
|
||||
$error = 'Missing type at position '.$pos;
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
if ($paramcomment === '') {
|
||||
$error = 'Missing comment for param "'.$paramname.'" at position '.$pos;
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
|
||||
$previousparam = $param;
|
||||
|
||||
}
|
||||
|
||||
if ($spacebeforevar !== 1 && $spacebeforevar !== 10000 && $spacebeforecomment !== 10000) {
|
||||
$error = 'Expected 1 space after the longest type';
|
||||
$this->currentfile->adderror($error, $longesttype);
|
||||
}
|
||||
|
||||
if ($spacebeforecomment !== 1 && $spacebeforecomment !== 10000) {
|
||||
$error = 'Expected 1 space after the longest variable name';
|
||||
$this->currentfile->adderror($error, $longestvar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$realnames = array();
|
||||
|
||||
foreach ($realparams as $realparam) {
|
||||
$realnames[] = $realparam['name'];
|
||||
}
|
||||
|
||||
// Report and missing comments.
|
||||
$diff = array_diff($realnames, $foundparams);
|
||||
|
||||
foreach ($diff as $neededparam) {
|
||||
|
||||
if (count($params) !== 0) {
|
||||
$errorpos = ($params[(count($params) - 1)]->getline() + $commentstart);
|
||||
|
||||
} else {
|
||||
$errorpos = $commentstart;
|
||||
}
|
||||
|
||||
$error = 'Doc comment for "'.$neededparam.'" missing';
|
||||
$this->currentfile->adderror($error, $errorpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* php_codesniffer_sniffs_moodle_commenting_inlinecommentsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-commenting
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* php_codesniffer_sniffs_moodle_commenting_inlinecommentsniff.
|
||||
*
|
||||
* Checks that no perl-style comments are used.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_commenting_inlinecommentsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_COMMENT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
if ($tokens[$stackptr]['content']{0} === '#') {
|
||||
$error = 'Perl-style comments are not allowed. Use "// Comment."';
|
||||
$error .= ' or "/* comment */" instead.';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* Verifies that control statements conform to their coding standards.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-controlstructures
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
if (class_exists('PHP_CodeSniffer_Standards_AbstractPatternSniff', true) === false) {
|
||||
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractPatternSniff not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that control statements conform to their coding standards.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_controlstructures_controlsignaturesniff extends php_codesniffer_standards_abstractpatternsniff {
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a moodle_sniffs_controlstructures_controlsignaturesniff.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the patterns that this test wishes to verify.
|
||||
*
|
||||
* @return array(string)
|
||||
*/
|
||||
protected function getpatterns() {
|
||||
return array('do {EOL...} while (...);EOL',
|
||||
'while (...) {EOL',
|
||||
'for (...) {EOL',
|
||||
'if (...) {EOL',
|
||||
'foreach (...) {EOL',
|
||||
'} else if (...) {EOL',
|
||||
'} else {EOL',
|
||||
'do {EOL',
|
||||
'try {EOL...} catch (...) {EOL...}');
|
||||
}
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_controlstructures_elseifdeclarationsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-controlstructures
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_controlstructures_elseifdeclarationsniff.
|
||||
*
|
||||
* Verifies that there are not elseif statements. The else and the if should
|
||||
* be separated by a space.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_controlstructures_elseifdeclarationsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_ELSEIF);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$error = 'Usage of ELSEIF not allowed. Use ELSE IF instead.';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_controlstructures_inlinecontrolstructuresniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-controlstructures
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_controlstructures_inlinecontrolstructuresniff.
|
||||
*
|
||||
* Verifies that inline control statements are not present.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_controlstructures_inlinecontrolstructuresniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* A list of tokenizers this sniff supports.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $supportedtokenizers = array('PHP', 'JS');
|
||||
|
||||
/**
|
||||
* If true, an error will be thrown; otherwise a warning.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $error = true;
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_IF,
|
||||
T_ELSE,
|
||||
T_FOREACH,
|
||||
T_WHILE,
|
||||
T_DO,
|
||||
T_SWITCH,
|
||||
T_FOR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
if (isset($tokens[$stackptr]['scope_opener']) === false) {
|
||||
// Ignore the ELSE in ELSE IF. We'll process the IF part later.
|
||||
if (($tokens[$stackptr]['code'] === T_ELSE) && ($tokens[($stackptr + 2)]['code'] === T_IF)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($tokens[$stackptr]['code'] === T_WHILE) {
|
||||
// This could be from a DO WHILE, which doesn't have an opening brace.
|
||||
$lastcontent = $phpcsfile->findprevious(T_WHITESPACE, ($stackptr - 1), null, true);
|
||||
|
||||
if ($tokens[$lastcontent]['code'] === T_CLOSE_CURLY_BRACKET) {
|
||||
$brace = $tokens[$lastcontent];
|
||||
|
||||
if (isset($brace['scope_condition']) === true) {
|
||||
$condition = $tokens[$brace['scope_condition']];
|
||||
|
||||
if ($condition['code'] === T_DO) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is a control structure without an opening brace,
|
||||
// so it is an inline statement.
|
||||
if ($this->error === true) {
|
||||
$phpcsfile->adderror('Inline control structures are not allowed', $stackptr);
|
||||
} else {
|
||||
$phpcsfile->addwarning('Inline control structures are discouraged', $stackptr);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* File including class for sniffing out the closing PHP tag
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-files
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for sniffing out the closing PHP tag
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_files_closingphptagsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_CLOSE_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
$last_token = end($tokens);
|
||||
|
||||
if ($last_token['code'] === T_CLOSE_TAG) {
|
||||
$error = 'Closing PHP tag is not required at the end of the file. Please remove.';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_files_includingfilesniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-files
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_files_includingfilesniff.
|
||||
*
|
||||
* Checks that the include_once is used in conditional situations, and
|
||||
* require_once is used elsewhere. Also checks that brackets do not surround
|
||||
* the file being included.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_files_includingfilesniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* Conditions that should use include_once
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
private static $_conditions = array(T_IF, T_ELSE, T_ELSEIF, T_SWITCH);
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_INCLUDE_ONCE, T_REQUIRE_ONCE, T_REQUIRE, T_INCLUDE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
//$nexttoken = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($stackptr + 1), null, true);
|
||||
//if ($tokens[$nexttoken]['code'] === T_OPEN_PARENTHESIS) {
|
||||
// $error = '"'.$tokens[$stackptr]['content'].'"';
|
||||
// $error .= ' is a statement, not a function; ';
|
||||
// $error .= 'no parentheses are required';
|
||||
// $phpcsfile->adderror($error, $stackptr);
|
||||
//}
|
||||
|
||||
$incondition = (count($tokens[$stackptr]['conditions']) !== 0) ? true : false;
|
||||
|
||||
// Check to see if this including statement is within the parenthesis of a condition.
|
||||
// If that's the case then we need to process it as being within a condition, as they
|
||||
// are checking the return value.
|
||||
if (isset($tokens[$stackptr]['nested_parenthesis']) === true) {
|
||||
|
||||
foreach ($tokens[$stackptr]['nested_parenthesis'] as $left => $right) {
|
||||
|
||||
if (isset($tokens[$left]['parenthesis_owner']) === true) {
|
||||
$incondition = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if they are assigning the return value of this including call.
|
||||
// If they are then they are probably checking it, so its conditional.
|
||||
$previous = $phpcsfile->findprevious(PHP_CodeSniffer_tokens::$emptyTokens, ($stackptr - 1), null, true);
|
||||
|
||||
if (in_array($tokens[$previous]['code'], PHP_CodeSniffer_tokens::$assignmentTokens) === true) {
|
||||
// The have assigned the return value to it, so its conditional.
|
||||
$incondition = true;
|
||||
}
|
||||
|
||||
$tokencode = $tokens[$stackptr]['code'];
|
||||
|
||||
if ($incondition === true) {
|
||||
// We are inside a conditional statement. We need an include_once.
|
||||
if ($tokencode === T_REQUIRE_ONCE) {
|
||||
$error = 'File is being conditionally included; ';
|
||||
$error .= 'use "include_once" instead';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
|
||||
} else if ($tokencode === T_REQUIRE) {
|
||||
$error = 'File is being conditionally included; ';
|
||||
$error .= 'use "include" instead';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
} else {
|
||||
// We are unconditionally including, we need a require_once.
|
||||
if ($tokencode === T_INCLUDE_ONCE) {
|
||||
$error = 'File is being unconditionally included; ';
|
||||
$error .= 'use "require_once" instead';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
|
||||
} else if ($tokencode === T_INCLUDE) {
|
||||
$error = 'File is being unconditionally included; ';
|
||||
$error .= 'use "require" instead';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_files_lineendingssniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-files
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_files_lineendingssniff.
|
||||
*
|
||||
* Checks that end of line characters are correct.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_files_lineendingssniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* The valid EOL character.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eolChar = "\n";
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_OPEN_TAG);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this sniff, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
// We are only interested if this is the first open tag.
|
||||
if ($stackptr !== 0) {
|
||||
|
||||
if ($phpcsfile->findprevious(T_OPEN_TAG, ($stackptr - 1)) !== false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($phpcsfile->eolChar !== $this->eolChar) {
|
||||
$expected = $this->eolChar;
|
||||
$expected = str_replace("\n", '\n', $expected);
|
||||
$expected = str_replace("\r", '\r', $expected);
|
||||
$found = $phpcsfile->eolChar;
|
||||
$found = str_replace("\n", '\n', $found);
|
||||
$found = str_replace("\r", '\r', $found);
|
||||
$error = "end of line character is invalid; expected \"$expected\" but found \"$found\"";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_files_linelengthsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-files
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_files_linelengthsniff.
|
||||
*
|
||||
* Checks all lines in the file, and throws warnings if they are over 80
|
||||
* characters in length and errors if they are over 100. Both these
|
||||
* figures can be changed by extending this sniff in your own standard.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_files_linelengthsniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* The limit that the length of a line should not exceed.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $linelimit = 120;
|
||||
|
||||
/**
|
||||
* The limit that the length of a line must not exceed.
|
||||
*
|
||||
* Set to zero (0) to disable.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $absolutelinelimit = 200;
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_OPEN_TAG);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
// Make sure this is the first open tag.
|
||||
$previousopentag = $phpcsfile->findprevious(array(T_OPEN_TAG), ($stackptr - 1));
|
||||
|
||||
if ($previousopentag !== false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tokencount = 0;
|
||||
$currentlinecontent = '';
|
||||
$currentline = 1;
|
||||
|
||||
for (; $tokencount < $phpcsfile->numTokens; $tokencount++) {
|
||||
|
||||
if ($tokens[$tokencount]['line'] === $currentline) {
|
||||
$currentlinecontent .= $tokens[$tokencount]['content'];
|
||||
|
||||
} else {
|
||||
$currentlinecontent = trim($currentlinecontent, $phpcsfile->eolChar);
|
||||
$this->checklinelength($phpcsfile, ($tokencount - 1), $currentlinecontent);
|
||||
$currentlinecontent = $tokens[$tokencount]['content'];
|
||||
$currentline++;
|
||||
}
|
||||
}
|
||||
|
||||
$this->checklinelength($phpcsfile, ($tokencount - 1), $currentlinecontent);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a line is too long.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The token at the end of the line.
|
||||
* @param string $linecontent The content of the line.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function checklinelength(PHP_CodeSniffer_File $phpcsfile, $stackptr, $linecontent) {
|
||||
// If the content is a CVS or SVN id in a version tag, or it is
|
||||
// a license tag with a name and URL, there is nothing the
|
||||
// developer can do to shorten the line, so don't throw errors.
|
||||
if (preg_match('|@version[^\$]+\$Id|', $linecontent) === 0 && preg_match('|@license|', $linecontent) === 0) {
|
||||
$linelength = strlen($linecontent);
|
||||
|
||||
if ($this->absolutelinelimit > 0 && $linelength > $this->absolutelinelimit) {
|
||||
$error = 'line exceeds maximum limit of '.$this->absolutelinelimit." characters; contains $linelength characters";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
|
||||
} else if ($linelength > $this->linelimit) {
|
||||
$warning = 'line exceeds '.$this->linelimit." characters; contains $linelength characters";
|
||||
$phpcsfile->addwarning($warning, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_formatting_spaceaftercastsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-formatting
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_formatting_spaceaftercastsniff.
|
||||
*
|
||||
* Ensures there is a single space after cast tokens.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_formatting_spaceaftercastsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return PHP_CodeSniffer_tokens::$castTokens;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in
|
||||
* the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
if ($tokens[($stackptr + 1)]['code'] !== T_WHITESPACE) {
|
||||
$error = 'A cast statement must be followed by a single space';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($tokens[($stackptr + 1)]['content'] !== ' ') {
|
||||
$error = 'A cast statement must be followed by a single space';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_functions_functioncallargumentspacingsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-functions
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_functions_functioncallargumentspacingsniff.
|
||||
*
|
||||
* Checks that calls to methods and functions are spaced correctly.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_functions_functioncallargumentspacingsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_STRING);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
// Skip tokens that are the names of functions or classes
|
||||
// within their definitions. For example:
|
||||
// function myFunction...
|
||||
// "myFunction" is T_STRING but we should skip because it is not a
|
||||
// function or method *call*.
|
||||
$functionname = $stackptr;
|
||||
$functionkeyword = $phpcsfile->findprevious(PHP_CodeSniffer_tokens::$emptyTokens, ($stackptr - 1), null, true);
|
||||
|
||||
if ($tokens[$functionkeyword]['code'] === T_FUNCTION || $tokens[$functionkeyword]['code'] === T_CLASS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the next non-whitespace token after the function or method call
|
||||
// is not an opening parenthesis then it cant really be a *call*.
|
||||
$openbracket = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($functionname + 1), null, true);
|
||||
if ($tokens[$openbracket]['code'] !== T_OPEN_PARENTHESIS) {
|
||||
return;
|
||||
}
|
||||
|
||||
$closebracket = $tokens[$openbracket]['parenthesis_closer'];
|
||||
|
||||
$nextseparator = $openbracket;
|
||||
|
||||
while (($nextseparator = $phpcsfile->findnext(array(T_COMMA, T_VARIABLE), ($nextseparator + 1), $closebracket)) !== false) {
|
||||
// Make sure the comma or variable belongs directly to this function call,
|
||||
// and is not inside a nested function call or array.
|
||||
$brackets = $tokens[$nextseparator]['nested_parenthesis'];
|
||||
$lastbracket = array_pop($brackets);
|
||||
|
||||
if ($lastbracket !== $closebracket) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($tokens[$nextseparator]['code'] === T_COMMA) {
|
||||
|
||||
if ($tokens[($nextseparator - 1)]['code'] === T_WHITESPACE) {
|
||||
$error = 'Space found before comma in function call';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
|
||||
if ($tokens[($nextseparator + 1)]['code'] !== T_WHITESPACE) {
|
||||
$error = 'No space found after comma in function call';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
|
||||
} else {
|
||||
// If there is a newline in the space, then the must be formatting
|
||||
// each argument on a newline, which is valid, so ignore it.
|
||||
if (strpos($tokens[($nextseparator + 1)]['content'], $phpcsfile->eolChar) === false) {
|
||||
$space = strlen($tokens[($nextseparator + 1)]['content']);
|
||||
|
||||
if ($space > 1) {
|
||||
$error = 'Expected 1 space after comma in function call; ';
|
||||
$error .= $space.' found';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// token is a variable.
|
||||
$nexttoken = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($nextseparator + 1), $closebracket, true);
|
||||
|
||||
if ($nexttoken !== false) {
|
||||
|
||||
if ($tokens[$nexttoken]['code'] === T_EQUAL) {
|
||||
|
||||
if (($tokens[($nexttoken - 1)]['code']) !== T_WHITESPACE) {
|
||||
$error = 'Expected 1 space before = sign of default value';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
|
||||
if ($tokens[($nexttoken + 1)]['code'] !== T_WHITESPACE) {
|
||||
$error = 'Expected 1 space after = sign of default value';
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_functions_functioncallsignaturesniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-functions
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_functions_functioncallsignaturesniff.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_functions_functioncallsignaturesniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_STRING);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
// Find the next non-empty token.
|
||||
$next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($stackptr + 1), null, true);
|
||||
|
||||
if ($tokens[$next]['code'] !== T_OPEN_PARENTHESIS) {
|
||||
// Not a function call.
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($tokens[$next]['parenthesis_closer']) === false) {
|
||||
// Not a function call.
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the previous non-empty token.
|
||||
$previous = $phpcsfile->findprevious(PHP_CodeSniffer_tokens::$emptyTokens, ($stackptr - 1), null, true);
|
||||
|
||||
if ($tokens[$previous]['code'] === T_FUNCTION) {
|
||||
// It's a function definition, not a function call.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($tokens[$previous]['code'] === T_NEW) {
|
||||
// We are creating an object, not calling a function.
|
||||
return;
|
||||
}
|
||||
|
||||
if (($stackptr + 1) !== $next) {
|
||||
// Checking this: $value = my_function[*](...).
|
||||
$error = 'Space before opening parenthesis of function call prohibited';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
if ($tokens[($next + 1)]['code'] === T_WHITESPACE) {
|
||||
// Checking this: $value = my_function([*]...).
|
||||
$error = 'Space after opening parenthesis of function call prohibited';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
$closer = $tokens[$next]['parenthesis_closer'];
|
||||
|
||||
if ($tokens[($closer - 1)]['code'] === T_WHITESPACE) {
|
||||
// Checking this: $value = my_function(...[*]).
|
||||
$between = $phpcsfile->findnext(T_WHITESPACE, ($next + 1), null, true);
|
||||
|
||||
// Only throw an error if there is some content between the parenthesis.
|
||||
// IE. Checking for this: $value = my_function().
|
||||
// If there is no content, then we would have thrown an error in the
|
||||
// previous IF statement because it would look like this:
|
||||
// $value = my_function( ).
|
||||
if ($between !== $closer) {
|
||||
$error = 'Space before closing parenthesis of function call prohibited';
|
||||
$phpcsfile->adderror($error, $closer);
|
||||
}
|
||||
}
|
||||
|
||||
$next = $phpcsfile->findnext(T_WHITESPACE, ($closer + 1), null, true);
|
||||
|
||||
if ($tokens[$next]['code'] === T_SEMICOLON) {
|
||||
|
||||
if (in_array($tokens[($closer + 1)]['code'], PHP_CodeSniffer_tokens::$emptyTokens) === true) {
|
||||
$error = 'Space after closing parenthesis of function call prohibited';
|
||||
$phpcsfile->adderror($error, $closer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_functions_functiondeclarationsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-functions
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
if (class_exists('PHP_CodeSniffer_Standards_AbstractPatternSniff', true) === false) {
|
||||
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractPatternSniff not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* moodle_sniffs_functions_functiondeclarationsniff.
|
||||
*
|
||||
* Checks the function declaration is correct.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_functions_functiondeclarationsniff extends php_codesniffer_standards_abstractpatternsniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of patterns to check are correct.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getpatterns() {
|
||||
return array(
|
||||
'function abc(...) {',
|
||||
'abstract function abc(...);'
|
||||
);
|
||||
}
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_functions_lowercasefunctionkeywordssniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-functions
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_functions_lowercasefunctionkeywordssniff.
|
||||
*
|
||||
* Ensures all class keywords are lowercase.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_functions_lowercasefunctionkeywordssniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_FUNCTION, T_PUBLIC, T_PRIVATE, T_PROTECTED, T_STATIC);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in
|
||||
* the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
$content = $tokens[$stackptr]['content'];
|
||||
|
||||
if ($content !== strtolower($content)) {
|
||||
$type = strtoupper($content);
|
||||
$expected = strtolower($content);
|
||||
$error = "$type keyword must be lowercase; expected \"$expected\" but found \"$content\"";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_functions_validdefaultvaluesniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-functions
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_functions_validdefaultvaluesniff.
|
||||
*
|
||||
* A Sniff to ensure that parameters defined for a function that have a default
|
||||
* value come at the end of the function signature.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_functions_validdefaultvaluesniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
$argstart = $tokens[$stackptr]['parenthesis_opener'];
|
||||
$argend = $tokens[$stackptr]['parenthesis_closer'];
|
||||
|
||||
// Flag for when we have found a default in our arg list.
|
||||
// If there is a value without a default after this, it is an error.
|
||||
$defaultfound = false;
|
||||
|
||||
$nextarg = $argstart;
|
||||
|
||||
while (($nextarg = $phpcsfile->findnext(T_VARIABLE, ($nextarg + 1), $argend)) !== false) {
|
||||
$arghasdefault = self::_arghasdefault($phpcsfile, $nextarg);
|
||||
|
||||
if (($arghasdefault === false) && ($defaultfound === true)) {
|
||||
$error = 'Arguments with default values must be at the end';
|
||||
$error .= ' of the argument list';
|
||||
$phpcsfile->adderror($error, $nextarg);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($arghasdefault === true) {
|
||||
$defaultfound = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the passed argument has a default value.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $argptr The position of the argument
|
||||
* in the stack.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function _arghasdefault(PHP_CodeSniffer_File $phpcsfile, $argptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$nexttoken = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($argptr + 1), null, true);
|
||||
|
||||
if ($tokens[$nexttoken]['code'] !== T_EQUAL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-147
@@ -1,147 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_namingconventions_uppercaseconstantnamesniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-namingconventions
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_namingconventions_uppercaseconstantnamesniff.
|
||||
*
|
||||
* Ensures that constant names are all uppercase.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_namingconventions_uppercaseconstantnamesniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_STRING);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$constname = $tokens[$stackptr]['content'];
|
||||
|
||||
// If this token is in a heredoc, ignore it.
|
||||
if ($phpcsfile->hasCondition($stackptr, T_START_HEREDOC) === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the next non-whitespace token after this token
|
||||
// is not an opening parenthesis then it is not a function call.
|
||||
$openbracket = $phpcsfile->findnext(array(T_WHITESPACE), ($stackptr + 1), null, true);
|
||||
|
||||
if ($tokens[$openbracket]['code'] !== T_OPEN_PARENTHESIS) {
|
||||
$functionkeyword = $phpcsfile->findprevious(array(T_WHITESPACE, T_COMMA, T_COMMENT, T_STRING),
|
||||
($stackptr - 1), null, true);
|
||||
|
||||
$declarations = array(T_FUNCTION, T_CLASS, T_INTERFACE, T_IMPLEMENTS, T_EXTENDS, T_INSTANCEOF, T_NEW);
|
||||
|
||||
if (in_array($tokens[$functionkeyword]['code'], $declarations) === true) {
|
||||
// This is just a declaration; no constants here.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($tokens[$functionkeyword]['code'] === T_CONST) {
|
||||
// This is a class constant.
|
||||
if (strtoupper($constname) !== $constname) {
|
||||
$error = 'Class constants must be uppercase; expected '.strtoupper($constname).
|
||||
" but found $constname";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Is this a class name?
|
||||
$nextptr = $phpcsfile->findnext(array(T_WHITESPACE), ($stackptr + 1), null, true);
|
||||
|
||||
if ($tokens[$nextptr]['code'] === T_DOUBLE_COLON) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Is this a type hint?
|
||||
if ($tokens[$nextptr]['code'] === T_VARIABLE) {
|
||||
return;
|
||||
|
||||
} else if ($phpcsfile->isReference($nextptr) === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Is this a member var name?
|
||||
$prevptr = $phpcsfile->findprevious(array(T_WHITESPACE), ($stackptr - 1), null, true);
|
||||
|
||||
if ($tokens[$prevptr]['code'] === T_OBJECT_OPERATOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Is this an instance of declare()
|
||||
$prevptr = $phpcsfile->findprevious(array(T_WHITESPACE, T_OPEN_PARENTHESIS), ($stackptr - 1), null, true);
|
||||
|
||||
if ($tokens[$prevptr]['code'] === T_DECLARE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a real constant.
|
||||
if (strtoupper($constname) !== $constname) {
|
||||
$error = 'Constants must be uppercase; expected '.strtoupper($constname)." but found $constname";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
} else if (strtolower($constname) === 'define' || strtolower($constname) === 'constant') {
|
||||
|
||||
/*
|
||||
This may be a "define" or "constant" function call.
|
||||
*/
|
||||
|
||||
// The next non-whitespace token must be the constant name.
|
||||
$constptr = $phpcsfile->findnext(array(T_WHITESPACE), ($openbracket + 1), null, true);
|
||||
|
||||
if ($tokens[$constptr]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
|
||||
return;
|
||||
}
|
||||
|
||||
$constname = $tokens[$constptr]['content'];
|
||||
|
||||
if (strtoupper($constname) !== $constname) {
|
||||
$error = 'Constants must be uppercase; expected '.strtoupper($constname)." but found $constname";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_namingconventions_validclassnamesniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-namingconventions
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_namingconventions_validclassnamesniff.
|
||||
*
|
||||
* Ensures class and interface names start with a capital letter
|
||||
* and use _ separators.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_namingconventions_validclassnamesniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_CLASS, T_INTERFACE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The current file being processed.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
$classname = $phpcsfile->findnext(T_STRING, $stackptr);
|
||||
$name = trim($tokens[$classname]['content']);
|
||||
|
||||
// Make sure that the word is all lowercase
|
||||
|
||||
if (!preg_match('/[a-z]?/', $name)) {
|
||||
$error = ucfirst($tokens[$stackptr]['content']).' name is not valid, must be all lower-case';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
-193
@@ -1,193 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_namingconventions_validfunctionnamesniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-namingconventions
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) {
|
||||
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* moodle_sniffs_namingconventions_validfunctionnamesniff.
|
||||
*
|
||||
* Ensures method names are correct depending on whether they are public
|
||||
* or private, and that functions are named correctly.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_namingconventions_validfunctionnamesniff extends php_codesniffer_standards_abstractscopesniff {
|
||||
|
||||
/**
|
||||
* A list of all PHP magic methods.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_magicmethods = array(
|
||||
'construct',
|
||||
'destruct',
|
||||
'call',
|
||||
'callStatic',
|
||||
'get',
|
||||
'set',
|
||||
'isset',
|
||||
'unset',
|
||||
'sleep',
|
||||
'wakeup',
|
||||
'toString',
|
||||
'set_state',
|
||||
'clone',
|
||||
);
|
||||
|
||||
/**
|
||||
* A list of all PHP magic functions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_magicfunctions = array('autoload');
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a moodle_sniffs_namingconventions_validfunctionnamesniff.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct(array(T_CLASS, T_INTERFACE), array(T_FUNCTION), true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes the tokens within the scope.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being processed.
|
||||
* @param int $stackptr The position where this token was
|
||||
* found.
|
||||
* @param int $currscope The position of the current scope.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processtokenwithinscope(PHP_CodeSniffer_File $phpcsfile, $stackptr, $currscope) {
|
||||
$classname = $phpcsfile->getdeclarationname($currscope);
|
||||
$methodname = $phpcsfile->getdeclarationname($stackptr);
|
||||
|
||||
// Is this a magic method. IE. is prefixed with "__".
|
||||
if (preg_match('|^__|', $methodname) !== 0) {
|
||||
$magicpart = substr($methodname, 2);
|
||||
|
||||
if (in_array($magicpart, $this->_magicmethods) === false) {
|
||||
$error = "method name \"$classname::$methodname\" is invalid; " .
|
||||
'only PHP magic methods should be prefixed with a double underscore';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// PHP4 constructors are allowed to break our rules.
|
||||
if ($methodname === $classname) {
|
||||
return;
|
||||
}
|
||||
|
||||
// PHP4 destructors are allowed to break our rules.
|
||||
if ($methodname === '_'.$classname) {
|
||||
return;
|
||||
}
|
||||
|
||||
$methodprops = $phpcsfile->getmethodproperties($stackptr);
|
||||
$ispublic = ($methodprops['scope'] === 'private') ? false : true;
|
||||
$scope = $methodprops['scope'];
|
||||
$scopespecified = $methodprops['scope_specified'];
|
||||
|
||||
// Only lower-case accepted
|
||||
if (preg_match('/[A-Z]+/', $methodname)) {
|
||||
|
||||
if ($scopespecified === true) {
|
||||
$error = ucfirst($scope)." method name \"$classname::$methodname\" must be in lower-case letters only";
|
||||
} else {
|
||||
$error = "method name \"$classname::$methodname\" must be in lower-case letters only";
|
||||
}
|
||||
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// No numbers accepted
|
||||
if (preg_match('/[0-9]+/', $methodname)) {
|
||||
|
||||
if ($scopespecified === true) {
|
||||
$error = ucfirst($scope)." method name \"$classname::$methodname\" must only contain letters";
|
||||
} else {
|
||||
$error = "Method name \"$classname::$methodname\" must only contain letters";
|
||||
}
|
||||
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes the tokens outside the scope.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being processed.
|
||||
* @param int $stackptr The position where this token was
|
||||
* found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processtokenoutsidescope(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$functionname = $phpcsfile->getdeclarationname($stackptr);
|
||||
|
||||
// Is this a magic function. IE. is prefixed with "__".
|
||||
if (preg_match('|^__|', $functionname) !== 0) {
|
||||
$magicpart = substr($functionname, 2);
|
||||
|
||||
if (in_array($magicpart, $this->_magicfunctions) === false) {
|
||||
$error = "Function name \"$functionname\" is invalid; " .
|
||||
'only PHP magic methods should be prefixed with a double underscore';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Only lower-case accepted
|
||||
if (preg_match('/[A-Z]+/', $functionname)) {
|
||||
$error = "function name \"$functionname\" must be lower-case letters only";
|
||||
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only letters accepted
|
||||
if (preg_match('/[0-9]+/', $functionname)) {
|
||||
$error = "function name \"$functionname\" must only contain letters";
|
||||
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_namingconventions_validvariablenamesniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-namingconventions
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
if (class_exists('PHP_CodeSniffer_Standards_AbstractVariableSniff', true) === false) {
|
||||
$error = 'Class PHP_CodeSniffer_Standards_AbstractVariableSniff not found';
|
||||
throw new PHP_CodeSniffer_Exception($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* moodle_sniffs_namingconventions_validvariablenamesniff.
|
||||
*
|
||||
* Checks the naming of member variables.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_namingconventions_validvariablenamesniff extends php_codesniffer_standards_abstractvariablesniff {
|
||||
|
||||
private $allowed_global_vars = array('CFG', 'SESSION', 'USER', 'COURSE', 'SITE', 'PAGE', 'DB', 'THEME',
|
||||
'_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION',
|
||||
'_ENV', '_COOKIE', '_HTTP_RAW_POST_DATA');
|
||||
|
||||
/**
|
||||
* Processes class member variables.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processmembervar(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$membername = ltrim($tokens[$stackptr]['content'], '$');
|
||||
|
||||
if (preg_match('/[A-Z]+/', $membername)) {
|
||||
$error = "Member variable \"$membername\" must be all lower-case";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Must not be preceded by 'var' keyword
|
||||
$keyword = $phpcsfile->findprevious(T_VAR, $stackptr);
|
||||
|
||||
if ($tokens[$keyword]['line'] == $tokens[$stackptr]['line']) {
|
||||
$error = "The 'var' keyword is not permitted." .
|
||||
'Visibility must be explicitly declared with public, private or protected';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes normal variables.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file where this token was found.
|
||||
* @param int $stackptr The position where the token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processvariable(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$membername = ltrim($tokens[$stackptr]['content'], '$');
|
||||
|
||||
if (preg_match('/[A-Z]+/', $membername)) {
|
||||
|
||||
if (!in_array($membername, $this->allowed_global_vars)) {
|
||||
$error = "Member variable \"$membername\" must be all lower-case";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes variables in double quoted strings.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file where this token was found.
|
||||
* @param int $stackptr The position where the token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processvariableinstring(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
if (preg_match('/\$([A-Za-z0-9_]+)(\-\>([A-Za-z0-9_]+))?/i', $tokens[$stackptr]['content'], $matches)) {
|
||||
$firstvar = $matches[1];
|
||||
$objectvar = (empty($matches[3])) ? null : $matches[3];
|
||||
$membername = $firstvar . $objectvar;
|
||||
|
||||
if (preg_match('/[A-Z]+/', $firstvar, $matches)) {
|
||||
|
||||
if (!in_array($firstvar, $this->allowed_global_vars)) {
|
||||
$error = "Member variable \"$firstvar\" must be all lower-case";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($objectvar) && preg_match('/[A-Z]+/', $objectvar, $matches)) {
|
||||
$error = "Member variable \"$objectvar\" must be all lower-case";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_php_disallowshortopentagsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-php
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_php_disallowshortopentagsniff.
|
||||
*
|
||||
* Makes sure that shorthand PHP open tags are not used.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_php_disallowshortopentagsniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_OPEN_TAG, T_OPEN_TAG_WITH_ECHO);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
// If short open tags are off, then any short open tags will be converted
|
||||
// to inline_html tags so we can just ignore them.
|
||||
// If its on, then we want to ban the use of them.
|
||||
$option = ini_get('short_open_tag');
|
||||
|
||||
// Ini_get returns a string "0" if short open tags is off.
|
||||
if ($option === '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$opentag = $tokens[$stackptr];
|
||||
|
||||
if ($opentag['content'] === '<?') {
|
||||
$error = 'Short PHP opening tag used. Found "'.$opentag['content'].'" Expected "<?php".';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
if ($opentag['code'] === T_OPEN_TAG_WITH_ECHO) {
|
||||
$nextvar = $tokens[$phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($stackptr + 1), null, true)];
|
||||
$error = 'Short PHP opening tag used with echo. Found "';
|
||||
$error .= $opentag['content'].' '.$nextvar['content'].' ..." but expected "<?php echo '.
|
||||
$nextvar['content'].' ...".';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_php_lowercaseconstantsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-php
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_php_lowercaseconstantsniff.
|
||||
*
|
||||
* Checks that all uses of true, false and null are lowerrcase.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_php_lowercaseconstantsniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* A list of tokenizers this sniff supports.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $supportedtokenizers = array('PHP', 'JS');
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_TRUE, T_FALSE, T_NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this sniff, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
$keyword = $tokens[$stackptr]['content'];
|
||||
|
||||
if (strtolower($keyword) !== $keyword) {
|
||||
$error = 'TRUE, FALSE and NULL must be lowercase; expected "'.
|
||||
strtolower($keyword).'" but found "'.$keyword.'"';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_php_lowercasephpfunctionssniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-php
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_php_lowercasephpfunctionssniff.
|
||||
*
|
||||
* Ensures all calls to inbuilt PHP functions are lowercase.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_php_lowercasephpfunctionssniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(
|
||||
T_ISSET,
|
||||
T_ECHO,
|
||||
T_PRINT,
|
||||
T_RETURN,
|
||||
T_BREAK,
|
||||
T_CONTINUE,
|
||||
T_EMPTY,
|
||||
T_EVAL,
|
||||
T_EXIT,
|
||||
T_LIST,
|
||||
T_UNSET,
|
||||
T_INCLUDE,
|
||||
T_INCLUDE_ONCE,
|
||||
T_REQUIRE,
|
||||
T_REQUIRE_ONCE,
|
||||
T_NEW,
|
||||
T_DECLARE,
|
||||
T_STRING,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in
|
||||
* the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
if ($tokens[$stackptr]['code'] !== T_STRING) {
|
||||
$content = $tokens[$stackptr]['content'];
|
||||
|
||||
if ($content !== strtolower($content)) {
|
||||
$type = strtoupper($content);
|
||||
$expected = strtolower($content);
|
||||
$error = "$type keyword must be lowercase; expected \"$expected\" but found \"$content\"";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure this is a function call.
|
||||
$next = $phpcsfile->findnext(T_WHITESPACE, ($stackptr + 1), null, true);
|
||||
|
||||
if ($next === false) {
|
||||
// Not a function call.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($tokens[$next]['code'] !== T_OPEN_PARENTHESIS) {
|
||||
// Not a function call.
|
||||
return;
|
||||
}
|
||||
|
||||
$prev = $phpcsfile->findprevious(T_WHITESPACE, ($stackptr - 1), null, true);
|
||||
|
||||
if ($tokens[$prev]['code'] === T_FUNCTION) {
|
||||
// Function declaration, not a function call.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($tokens[$prev]['code'] === T_OBJECT_OPERATOR) {
|
||||
// Not an inbuilt function.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($tokens[$prev]['code'] === T_DOUBLE_COLON) {
|
||||
// Not an inbuilt function.
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure it is an inbuilt PHP function.
|
||||
// PHP_CodeSniffer doesn't include/require any files, so no
|
||||
// user defined global functions can exist, except for
|
||||
// PHP_CodeSniffer ones.
|
||||
$content = $tokens[$stackptr]['content'];
|
||||
|
||||
if (function_exists($content) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($content !== strtolower($content)) {
|
||||
$expected = strtolower($content);
|
||||
$error = "Calls to inbuilt PHP functions must be lowercase; expected \"$expected\" but found \"$content\"";
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_strings_doublequoteusagesniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-strings
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_strings_doublequoteusagesniff.
|
||||
*
|
||||
* Makes sure that any use of Double Quotes ("") are warranted.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_strings_doublequoteusagesniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_CONSTANT_ENCAPSED_STRING);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
$workingstring = $tokens[$stackptr]['content'];
|
||||
|
||||
// Check if it's a double quoted string.
|
||||
if (strpos($workingstring, '"') === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure it's not a part of a string started above.
|
||||
// If it is, then we have already checked it.
|
||||
if ($workingstring[0] !== '"') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Work through the following tokens, in case this string is stretched
|
||||
// over multiple Lines.
|
||||
for ($i = ($stackptr + 1); $i < $phpcsfile->numTokens; $i++) {
|
||||
|
||||
if ($tokens[$i]['type'] !== 'T_CONSTANT_ENCAPSED_STRING') {
|
||||
break;
|
||||
}
|
||||
$workingstring .= $tokens[$i]['content'];
|
||||
}
|
||||
|
||||
$allowedchars = array(
|
||||
'\n',
|
||||
'\r',
|
||||
'\f',
|
||||
'\t',
|
||||
'\v',
|
||||
'\x',
|
||||
'\'',
|
||||
'$'
|
||||
);
|
||||
|
||||
foreach ($allowedchars as $testchar) {
|
||||
|
||||
if (strpos($workingstring, $testchar) !== false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$error = "String $workingstring does not require double quotes; use single quotes instead";
|
||||
$phpcsfile->addwarning($error, $stackptr);
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_strings_echoedstringssniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-strings
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_strings_echoedstringssniff.
|
||||
*
|
||||
* Makes sure that any strings that are "echoed" are not enclosed in brackets
|
||||
* like a function call.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_strings_echoedstringssniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_ECHO);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
$firstcontent = $phpcsfile->findnext(array(T_WHITESPACE), ($stackptr + 1), null, true);
|
||||
// If the first non-whitespace token is not an opening parenthesis, then we are not concerned.
|
||||
if ($tokens[$firstcontent]['code'] !== T_OPEN_PARENTHESIS) {
|
||||
return;
|
||||
}
|
||||
|
||||
$endofstatement = $phpcsfile->findnext(array(T_SEMICOLON), $stackptr, null, false);
|
||||
|
||||
// If the token before the semi-colon is not a closing parenthesis, then we are not concerned.
|
||||
if ($tokens[($endofstatement - 1)]['code'] !== T_CLOSE_PARENTHESIS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (($phpcsfile->findnext(PHP_CodeSniffer_tokens::$operators, $stackptr, $endofstatement, false)) === false) {
|
||||
// There are no arithmetic operators in this.
|
||||
$error = 'Echoed strings should not be bracketed';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_whitespace_controlstructureblanklinesniff
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-whitespace
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_controlstructureblanklinesniff
|
||||
*
|
||||
* Checks that there is a blank line before control structures
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_whitespace_controlstructureblanklinesniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_IF, T_FOR, T_FOREACH, T_WHILE, T_SWITCH, T_TRY, T_CATCH);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile All the tokens found in the document.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
$previoustoken = $stackptr - 1;
|
||||
|
||||
// Move back until we find the previous non-whitespace, non-comment token
|
||||
do {
|
||||
$previoustoken = $phpcsfile->findprevious(array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT),
|
||||
($previoustoken - 1), null, true);
|
||||
|
||||
} while ($tokens[$previoustoken]['line'] == $tokens[$stackptr]['line']);
|
||||
|
||||
$previous_non_ws_token = $tokens[$previoustoken];
|
||||
|
||||
// If this token is immediately on the line before this control structure, print a warning
|
||||
if ($previous_non_ws_token['line'] == ($tokens[$stackptr]['line'] - 1)) {
|
||||
// Exception: do {EOL...} while (...);
|
||||
if ($tokens[$stackptr]['code'] == T_WHILE && $tokens[($stackptr - 1)]['code'] == T_CLOSE_CURLY_BRACKET) {
|
||||
// Ignore do...while (see above)
|
||||
} else {
|
||||
$phpcsfile->addWarning('You should add a blank line before control structures', $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_whitespace_disallowtabindentsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-whitespace
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_whitespace_disallowtabindentsniff.
|
||||
*
|
||||
* Throws errors if tabs are used for indentation.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_whitespace_disallowtabindentsniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* A list of tokenizers this sniff supports.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $supportedtokenizers = array('PHP', 'JS');
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return array(T_WHITESPACE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile All the tokens found in the document.
|
||||
* @param int $stackptr The position of the current token in
|
||||
* the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
// Make sure this is whitespace used for indentation.
|
||||
$line = $tokens[$stackptr]['line'];
|
||||
|
||||
if ($stackptr > 0 && $tokens[($stackptr - 1)]['line'] === $line) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strpos($tokens[$stackptr]['content'], "\t") !== false) {
|
||||
$error = 'Spaces must be used to indent lines; tabs are not allowed';
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
-119
@@ -1,119 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* Verifies that class members are spaced correctly.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-whitespace
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
if (class_exists('PHP_CodeSniffer_Standards_AbstractVariableSniff', true) === false) {
|
||||
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractVariableSniff not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that class members are spaced correctly.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_whitespace_membervarspacingsniff extends php_codesniffer_standards_abstractvariablesniff {
|
||||
|
||||
|
||||
/**
|
||||
* Processes the function tokens within the class.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file where this token was found.
|
||||
* @param int $stackptr The position where the token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processmembervar(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
// There needs to be 1 blank line before the var, not counting comments.
|
||||
$prevlinetoken = null;
|
||||
|
||||
for ($i = ($stackptr - 1); $i > 0; $i--) {
|
||||
|
||||
if (in_array($tokens[$i]['code'], PHP_CodeSniffer_tokens::$commentTokens) === true) {
|
||||
// Skip comments.
|
||||
continue;
|
||||
|
||||
} else if (strpos($tokens[$i]['content'], $phpcsfile->eolChar) === false) {
|
||||
// Not the end of the line.
|
||||
continue;
|
||||
|
||||
} else {
|
||||
// If this is a WHITESPACE token, and the token right before
|
||||
// it is a DOC_COMMENT, then it is just the newline after the
|
||||
// member var's comment, and can be skipped.
|
||||
if ($tokens[$i]['code'] === T_WHITESPACE &&
|
||||
in_array($tokens[($i - 1)]['code'], PHP_CodeSniffer_tokens::$commentTokens) === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$prevlinetoken = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($prevlinetoken) === true) {
|
||||
// Never found the previous line, which means
|
||||
// there are 0 blank lines before the member var.
|
||||
$foundlines = 0;
|
||||
|
||||
} else {
|
||||
$prevcontent = $phpcsfile->findprevious(array(T_WHITESPACE, T_DOC_COMMENT), $prevlinetoken, null, true);
|
||||
$foundlines = ($tokens[$prevlinetoken]['line'] - $tokens[$prevcontent]['line']);
|
||||
}
|
||||
|
||||
if ($foundlines !== 1) {
|
||||
// $phpcsfile->adderror("Expected 1 blank line before member var; $foundlines found", $stackptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes normal variables.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file where this token was found.
|
||||
* @param int $stackptr The position where the token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processvariable(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
// We don't care about normal variables.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes variables in double quoted strings.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile The file where this token was found.
|
||||
* @param int $stackptr The position where the token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processvariableinstring(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
// We don't care about normal variables.
|
||||
return;
|
||||
}
|
||||
}
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_whitespace_scopeclosingbracesniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-whitespace
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_whitespace_scopeclosingbracesniff.
|
||||
*
|
||||
* Checks that the closing braces of scopes are aligned correctly.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_whitespace_scopeclosingbracesniff implements php_codesniffer_sniff {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return PHP_CodeSniffer_tokens::$scopeOpeners;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile All the tokens found in the document.
|
||||
* @param int $stackptr The position of the current token in the
|
||||
* stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
// If this is an inline condition (ie. there is no scope opener), then
|
||||
// return, as this is not a new scope.
|
||||
if (isset($tokens[$stackptr]['scope_closer']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to actually find the first piece of content on this line,
|
||||
// as if this is a method with tokens before it (public, static etc)
|
||||
// or an if with an else before it, then we need to start the scope
|
||||
// checking from there, rather than the current token.
|
||||
$linestart = ($stackptr - 1);
|
||||
|
||||
for ($linestart; $linestart > 0; $linestart--) {
|
||||
|
||||
if (strpos($tokens[$linestart]['content'], $phpcsfile->eolChar) !== false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We found a new line, now go forward and find the first non-whitespace
|
||||
// token.
|
||||
$linestart = $phpcsfile->findnext(array(T_WHITESPACE), ($linestart + 1), null, true);
|
||||
|
||||
$startcolumn = $tokens[$linestart]['column'];
|
||||
$scopestart = $tokens[$stackptr]['scope_opener'];
|
||||
$scopeend = $tokens[$stackptr]['scope_closer'];
|
||||
|
||||
// Check that the closing brace is on its own line.
|
||||
$lastcontent = $phpcsfile->findprevious(array(T_WHITESPACE), ($scopeend - 1), $scopestart, true);
|
||||
|
||||
if ($tokens[$lastcontent]['line'] === $tokens[$scopeend]['line']) {
|
||||
$error = 'Closing brace must be on a line by itself';
|
||||
$phpcsfile->adderror($error, $scopeend);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check now that the closing brace is lined up correctly.
|
||||
$braceindent = $tokens[$scopeend]['column'];
|
||||
$isbreakcloser = ($tokens[$scopeend]['code'] === T_BREAK);
|
||||
|
||||
if (in_array($tokens[$stackptr]['code'], array(T_CASE, T_DEFAULT)) === true && $isbreakcloser === true) {
|
||||
// BREAK statements should be indented 4 spaces from the
|
||||
// CASE or DEFAULT statement.
|
||||
if ($braceindent !== ($startcolumn + 4)) {
|
||||
$error = 'Break statement indented incorrectly; expected '.($startcolumn + 3).' spaces, found '.
|
||||
($braceindent - 1);
|
||||
$phpcsfile->adderror($error, $scopeend);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (in_array($tokens[$stackptr]['code'], array(T_CASE, T_DEFAULT))) {
|
||||
$startcolumn -= 4;
|
||||
}
|
||||
|
||||
if ($braceindent !== $startcolumn) {
|
||||
$error = 'Closing brace indented incorrectly; expected '.($startcolumn - 1).' spaces, found '.
|
||||
($braceindent - 1);
|
||||
$phpcsfile->adderror($error, $scopeend);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,303 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* moodle_sniffs_whitespace_scopeindentsniff.
|
||||
*
|
||||
* @package moodlecore
|
||||
* @subpackage lib-pear-php-codesniffer-standards-moodle-sniffs-whitespace
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* moodle_sniffs_whitespace_scopeindentsniff.
|
||||
*
|
||||
* Checks that control structures are structured correctly, and their content
|
||||
* is indented correctly. This sniff will throw errors if tabs are used
|
||||
* for indentation rather than spaces.
|
||||
*
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class moodle_sniffs_whitespace_scopeindentsniff implements php_codesniffer_sniff {
|
||||
|
||||
/**
|
||||
* The number of spaces code should be indented.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $indent = 4;
|
||||
|
||||
/**
|
||||
* Does the indent need to be exactly right.
|
||||
*
|
||||
* If TRUE, indent needs to be exactly $ident spaces. If FALSE,
|
||||
* indent needs to be at least $ident spaces (but can be more).
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $exact = false;
|
||||
|
||||
/**
|
||||
* Any scope openers that should not cause an indent.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
protected $nonindentingscopes = array();
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register() {
|
||||
return PHP_CodeSniffer_tokens::$scopeOpeners;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsfile All the tokens found in the document.
|
||||
* @param int $stackptr The position of the current token
|
||||
* in the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr) {
|
||||
$tokens = $phpcsfile->gettokens();
|
||||
|
||||
// If this is an inline condition (ie. there is no scope opener), then
|
||||
// return, as this is not a new scope.
|
||||
if (isset($tokens[$stackptr]['scope_opener']) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($tokens[$stackptr]['code'] === T_ELSE) {
|
||||
$next = $phpcsfile->findnext(PHP_CodeSniffer_tokens::$emptyTokens, ($stackptr + 1), null, true);
|
||||
// We will handle the T_IF token in another call to process.
|
||||
|
||||
if ($tokens[$next]['code'] === T_IF) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the first token on this line.
|
||||
$firsttoken = $stackptr;
|
||||
|
||||
for ($i = $stackptr; $i >= 0; $i--) {
|
||||
// Record the first code token on the line.
|
||||
if (in_array($tokens[$i]['code'], PHP_CodeSniffer_tokens::$emptyTokens) === false) {
|
||||
$firsttoken = $i;
|
||||
}
|
||||
|
||||
// It's the start of the line, so we've found our first php token.
|
||||
if ($tokens[$i]['column'] === 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Based on the conditions that surround this token, determine the
|
||||
// indent that we expect this current content to be.
|
||||
$expectedindent = $this->calculateexpectedindent($tokens, $firsttoken);
|
||||
|
||||
if ($tokens[$firsttoken]['column'] !== $expectedindent) {
|
||||
$error = 'line indented incorrectly; expected ';
|
||||
$error .= ($expectedindent - 1).' spaces, found ';
|
||||
$error .= ($tokens[$firsttoken]['column'] - 1);
|
||||
$phpcsfile->adderror($error, $stackptr);
|
||||
}
|
||||
|
||||
$scopeopener = $tokens[$stackptr]['scope_opener'];
|
||||
$scopecloser = $tokens[$stackptr]['scope_closer'];
|
||||
|
||||
// Some scopes are expected not to have indents.
|
||||
if (in_array($tokens[$firsttoken]['code'], $this->nonindentingscopes) === false) {
|
||||
$indent = ($expectedindent + $this->indent);
|
||||
|
||||
} else {
|
||||
$indent = $expectedindent;
|
||||
}
|
||||
|
||||
$newline = false;
|
||||
$commentopen = false;
|
||||
$inheredoc = false;
|
||||
|
||||
// Only loop over the content beween the opening and closing brace, not
|
||||
// the braces themselves.
|
||||
for ($i = ($scopeopener + 1); $i < $scopecloser; $i++) {
|
||||
|
||||
// If this token is another scope, skip it as it will be handled by
|
||||
// another call to this sniff.
|
||||
if (in_array($tokens[$i]['code'], PHP_CodeSniffer_tokens::$scopeOpeners) === true) {
|
||||
|
||||
if (isset($tokens[$i]['scope_opener']) === true) {
|
||||
$i = $tokens[$i]['scope_closer'];
|
||||
|
||||
} else {
|
||||
// If this token does not have a scope_opener indice, then
|
||||
// it's probably an inline scope, so let's skip to the next
|
||||
// semicolon. Inline scopes include inline if's, abstract methods etc.
|
||||
$nexttoken = $phpcsfile->findnext(T_SEMICOLON, $i, $scopecloser);
|
||||
|
||||
if ($nexttoken !== false) {
|
||||
$i = $nexttoken;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is a HEREDOC then we need to ignore it as the whitespace
|
||||
// before the contents within the HEREDOC are considered part of the content.
|
||||
if ($tokens[$i]['code'] === T_START_HEREDOC) {
|
||||
$inheredoc = true;
|
||||
continue;
|
||||
|
||||
} else if ($inheredoc === true) {
|
||||
|
||||
if ($tokens[$i]['code'] === T_END_HEREDOC) {
|
||||
$inheredoc = false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($tokens[$i]['column'] === 1) {
|
||||
// We started a newline.
|
||||
$newline = true;
|
||||
}
|
||||
|
||||
if ($newline === true && $tokens[$i]['code'] !== T_WHITESPACE) {
|
||||
// If we started a newline and we find a token that is not
|
||||
// whitespace, then this must be the first token on the line that
|
||||
// must be indented.
|
||||
$newline = false;
|
||||
$firsttoken = $i;
|
||||
|
||||
$column = $tokens[$firsttoken]['column'];
|
||||
|
||||
// Special case for non-PHP code.
|
||||
if ($tokens[$firsttoken]['code'] === T_INLINE_HTML) {
|
||||
$trimmedcontentlength = strlen(ltrim($tokens[$firsttoken]['content']));
|
||||
|
||||
if ($trimmedcontentlength === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$contentlength = strlen($tokens[$firsttoken]['content']);
|
||||
$column = ($contentlength - $trimmedcontentlength + 1);
|
||||
}
|
||||
|
||||
// Check to see if this constant string spans multiple lines.
|
||||
// If so, then make sure that the strings on lines other than the
|
||||
// first line are indented appropriately, based on their whitespace.
|
||||
if (in_array($tokens[$firsttoken]['code'], PHP_CodeSniffer_tokens::$stringTokens) === true) {
|
||||
|
||||
if (in_array($tokens[($firsttoken - 1)]['code'], PHP_CodeSniffer_tokens::$stringTokens) === true) {
|
||||
// If we find a string that directly follows another string
|
||||
// then its just a string that spans multiple lines, so we
|
||||
// don't need to check for indenting.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// This is a special condition for T_DOC_COMMENT and C-style
|
||||
// comments, which contain whitespace between each line.
|
||||
if (in_array($tokens[$firsttoken]['code'], array(T_COMMENT, T_DOC_COMMENT)) === true) {
|
||||
$content = trim($tokens[$firsttoken]['content']);
|
||||
|
||||
if (preg_match('|^/\*|', $content) !== 0) {
|
||||
// Check to see if the end of the comment is on the same line
|
||||
// as the start of the comment. If it is, then we don't
|
||||
// have to worry about opening a comment.
|
||||
if (preg_match('|\*/$|', $content) === 0) {
|
||||
// We don't have to calculate the column for the start
|
||||
// of the comment as there is a whitespace token before it.
|
||||
$commentopen = true;
|
||||
}
|
||||
|
||||
} else if ($commentopen === true) {
|
||||
|
||||
if ($content === '') {
|
||||
// We are in a comment, but this line has nothing on it
|
||||
// so let's skip it.
|
||||
continue;
|
||||
}
|
||||
|
||||
$contentlength = strlen($tokens[$firsttoken]['content']);
|
||||
$trimmedcontentlength = strlen(ltrim($tokens[$firsttoken]['content']));
|
||||
$column = ($contentlength - $trimmedcontentlength + 1);
|
||||
|
||||
if (preg_match('|\*/$|', $content) !== 0) {
|
||||
$commentopen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The token at the start of the line, needs to have its' column
|
||||
// greater than the relative indent we set above. If it is less,
|
||||
// an error should be shown.
|
||||
if ($column !== $indent) {
|
||||
|
||||
if ($this->exact === true || $column < $indent) {
|
||||
$error = 'line indented incorrectly; expected ';
|
||||
|
||||
if ($this->exact === false) {
|
||||
$error .= 'at least ';
|
||||
}
|
||||
|
||||
$error .= ($indent - 1).' spaces, found ';
|
||||
$error .= ($column - 1);
|
||||
$phpcsfile->adderror($error, $firsttoken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the expected indent of a token.
|
||||
*
|
||||
* @param array $tokens The stack of tokens for this file.
|
||||
* @param int $stackptr The position of the token to get indent for.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateexpectedindent(array $tokens, $stackptr) {
|
||||
$conditionstack = array();
|
||||
|
||||
// Empty conditions array (top level structure).
|
||||
if (empty($tokens[$stackptr]['conditions']) === true) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$tokenconditions = $tokens[$stackptr]['conditions'];
|
||||
|
||||
foreach ($tokenconditions as $id => $condition) {
|
||||
// If it's an indenting scope ie. it's not in our array of
|
||||
// scopes that don't indent, add it to our condition stack.
|
||||
if (in_array($condition, $this->nonindentingscopes) === false) {
|
||||
$conditionstack[$id] = $condition;
|
||||
}
|
||||
}
|
||||
|
||||
return ((count($conditionstack) * $this->indent) + 1);
|
||||
}
|
||||
}
|
||||
@@ -1,718 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Tokenizes JS code.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tokenizes JS code.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @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_Tokenizers_JS
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of tokens that are allowed to open a scope.
|
||||
*
|
||||
* This array also contains information about what kind of token the scope
|
||||
* opener uses to open and close the scope, if the token strictly requires
|
||||
* an opener, if the token can share a scope closer, and who it can be shared
|
||||
* with. An example of a token that shares a scope closer is a CASE scope.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $scopeOpeners = array(
|
||||
T_IF => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_TRY => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_CATCH => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_ELSE => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_FOR => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_FUNCTION => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_WHILE => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_DO => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_SWITCH => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_CASE => array(
|
||||
'start' => T_COLON,
|
||||
'end' => T_BREAK,
|
||||
'strict' => true,
|
||||
'shared' => true,
|
||||
'with' => array(
|
||||
T_DEFAULT,
|
||||
T_CASE,
|
||||
),
|
||||
),
|
||||
T_DEFAULT => array(
|
||||
'start' => T_COLON,
|
||||
'end' => T_BREAK,
|
||||
'strict' => true,
|
||||
'shared' => true,
|
||||
'with' => array(T_CASE),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* A list of tokens that end the scope.
|
||||
*
|
||||
* This array is just a unique collection of the end tokens
|
||||
* from the _scopeOpeners array. The data is duplicated here to
|
||||
* save time during parsing of the file.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $endScopeTokens = array(
|
||||
T_CLOSE_CURLY_BRACKET,
|
||||
T_BREAK,
|
||||
);
|
||||
|
||||
/**
|
||||
* A list of special JS tokens and their types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tokenValues = array(
|
||||
'function' => 'T_FUNCTION',
|
||||
'prototype' => 'T_PROTOTYPE',
|
||||
'try' => 'T_TRY',
|
||||
'catch' => 'T_CATCH',
|
||||
'return' => 'T_RETURN',
|
||||
'if' => 'T_IF',
|
||||
'else' => 'T_ELSE',
|
||||
'do' => 'T_DO',
|
||||
'while' => 'T_WHILE',
|
||||
'for' => 'T_FOR',
|
||||
'var' => 'T_VAR',
|
||||
'true' => 'T_TRUE',
|
||||
'false' => 'T_FALSE',
|
||||
'null' => 'T_NULL',
|
||||
'this' => 'T_THIS',
|
||||
'(' => 'T_OPEN_PARENTHESIS',
|
||||
')' => 'T_CLOSE_PARENTHESIS',
|
||||
'{' => 'T_OPEN_CURLY_BRACKET',
|
||||
'}' => 'T_CLOSE_CURLY_BRACKET',
|
||||
'[' => 'T_OPEN_SQUARE_BRACKET',
|
||||
']' => 'T_CLOSE_SQUARE_BRACKET',
|
||||
'?' => 'T_INLINE_THEN',
|
||||
'.' => 'T_OBJECT_OPERATOR',
|
||||
'+' => 'T_PLUS',
|
||||
'-' => 'T_MINUS',
|
||||
'*' => 'T_MULTIPLY',
|
||||
'%' => 'T_MODULUS',
|
||||
'/' => 'T_DIVIDE',
|
||||
',' => 'T_COMMA',
|
||||
';' => 'T_SEMICOLON',
|
||||
':' => 'T_COLON',
|
||||
'<' => 'T_LESS_THAN',
|
||||
'>' => 'T_GREATER_THAN',
|
||||
'<=' => 'T_IS_SMALLER_OR_EQUAL',
|
||||
'>=' => 'T_IS_GREATER_OR_EQUAL',
|
||||
'!' => 'T_BOOLEAN_NOT',
|
||||
'!=' => 'T_IS_NOT_EQUAL',
|
||||
'!==' => 'T_IS_NOT_IDENTICAL',
|
||||
'=' => 'T_EQUAL',
|
||||
'==' => 'T_IS_EQUAL',
|
||||
'===' => 'T_IS_IDENTICAL',
|
||||
'-=' => 'T_MINUS_EQUAL',
|
||||
'+=' => 'T_PLUS_EQUAL',
|
||||
'++' => 'T_INC',
|
||||
'--' => 'T_DEC',
|
||||
'//' => 'T_COMMENT',
|
||||
'/*' => 'T_COMMENT',
|
||||
'/**' => 'T_DOC_COMMENT',
|
||||
'*/' => 'T_COMMENT',
|
||||
);
|
||||
|
||||
/**
|
||||
* A list string delimiters.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $stringTokens = array(
|
||||
'\'',
|
||||
'"',
|
||||
);
|
||||
|
||||
/**
|
||||
* A list tokens that start and end comments.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commentTokens = array(
|
||||
'//' => null,
|
||||
'/*' => '*/',
|
||||
'/**' => '*/',
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 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 string $eolChar The EOL character to use for splitting strings.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokenizeString($string, $eolChar='\n')
|
||||
{
|
||||
$tokenTypes = array_keys($this->tokenValues);
|
||||
|
||||
$maxTokenLength = 0;
|
||||
foreach ($tokenTypes as $token) {
|
||||
if (strlen($token) > $maxTokenLength) {
|
||||
$maxTokenLength = strlen($token);
|
||||
}
|
||||
}
|
||||
|
||||
$tokens = array();
|
||||
$inString = '';
|
||||
$inComment = '';
|
||||
$buffer = '';
|
||||
$cleanBuffer = false;
|
||||
|
||||
$tokens[] = array(
|
||||
'code' => T_OPEN_TAG,
|
||||
'type' => 'T_OPEN_TAG',
|
||||
'content' => '',
|
||||
);
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
echo "\t*** START TOKENIZING ***".PHP_EOL;
|
||||
}
|
||||
|
||||
$chars = str_split($string);
|
||||
foreach ($chars as $i => $char) {
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
$content = str_replace($eolChar, '\n', $char);
|
||||
if ($inString !== '') {
|
||||
echo "\t";
|
||||
}
|
||||
|
||||
if ($inComment !== '') {
|
||||
echo "\t";
|
||||
}
|
||||
|
||||
echo "Process char $i => $content".PHP_EOL;
|
||||
}
|
||||
|
||||
if ($inString === '' && $inComment === '' && $buffer !== '') {
|
||||
// If the buffer only has whitespace and we are about to
|
||||
// add a character, store the whitespace first.
|
||||
if (trim($char) !== '' && trim($buffer) === '') {
|
||||
$tokens[] = array(
|
||||
'code' => T_WHITESPACE,
|
||||
'type' => 'T_WHITESPACE',
|
||||
'content' => $buffer,
|
||||
);
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
$content = str_replace($eolChar, '\n', $buffer);
|
||||
echo "=> Added token T_WHITESPACE ($content)".PHP_EOL;
|
||||
}
|
||||
|
||||
$buffer = '';
|
||||
}
|
||||
|
||||
// If the buffer is not whitespace and we are about to
|
||||
// add a whitespace character, store the content first.
|
||||
if ($inString === '' && $inComment === '' && trim($char) === '' && trim($buffer) !== '') {
|
||||
$tokens[] = array(
|
||||
'code' => T_STRING,
|
||||
'type' => 'T_STRING',
|
||||
'content' => $buffer,
|
||||
);
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
$content = str_replace($eolChar, '\n', $buffer);
|
||||
echo "=> Added token T_STRING ($content)".PHP_EOL;
|
||||
}
|
||||
|
||||
$buffer = '';
|
||||
}
|
||||
}//end if
|
||||
|
||||
// Process strings.
|
||||
if ($inComment === '' && in_array($char, $this->stringTokens) === true) {
|
||||
if ($inString === $char) {
|
||||
// This could be the end of the string, but make sure it
|
||||
// is not escaped first.
|
||||
$escapes = 0;
|
||||
for ($x = ($i - 1); $x >= 0; $x--) {
|
||||
if ($chars[$x] !== '\\') {
|
||||
break;
|
||||
}
|
||||
|
||||
$escapes++;
|
||||
}
|
||||
|
||||
if ($escapes === 0 || ($escapes % 2) === 0) {
|
||||
// There is an even number escape chars,
|
||||
// so this is not escaped, it is the end of the string.
|
||||
$tokens[] = array(
|
||||
'code' => T_CONSTANT_ENCAPSED_STRING,
|
||||
'type' => 'T_CONSTANT_ENCAPSED_STRING',
|
||||
'content' => $buffer.$char,
|
||||
);
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
echo "\t* found end of string *".PHP_EOL;
|
||||
$content = str_replace($eolChar, '\n', $buffer.$char);
|
||||
echo "=> Added token T_CONSTANT_ENCAPSED_STRING $content)".PHP_EOL;
|
||||
}
|
||||
|
||||
$buffer = '';
|
||||
$inString = '';
|
||||
continue;
|
||||
}
|
||||
} else if ($inString === '') {
|
||||
$inString = $char;
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
echo "\t* looking for string closer *".PHP_EOL;
|
||||
}
|
||||
}//end if
|
||||
}//end if
|
||||
|
||||
$buffer .= $char;
|
||||
|
||||
// We don't look for special tokens inside strings,
|
||||
// so if we are in a string, we can continue here now
|
||||
// that the current char is in the buffer.
|
||||
if ($inString !== '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for known tokens, but ignore tokens found that are not at
|
||||
// the end of a string, like FOR and this.FORmat.
|
||||
if (in_array(strtolower($buffer), $tokenTypes) === true && (preg_match('|[a-zA-z0-9_]|', $char) === 0 || preg_match('|[a-zA-z0-9_]|', $chars[($i + 1)]) === 0)) {
|
||||
$matchedToken = false;
|
||||
$lookAheadLength = ($maxTokenLength - strlen($buffer));
|
||||
|
||||
if ($lookAheadLength > 0) {
|
||||
// The buffer contains a token type, but we need
|
||||
// to look ahead at the next chars to see if this is
|
||||
// actually part of a larger token. For example,
|
||||
// FOR and FOREACH.
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
echo "\t* buffer possibly contains token, looking ahead $lookAheadLength chars *".PHP_EOL;
|
||||
}
|
||||
|
||||
$charBuffer = $buffer;
|
||||
for ($x = 1; $x <= $lookAheadLength; $x++) {
|
||||
if (isset($chars[($i + $x)]) === false) {
|
||||
break;
|
||||
}
|
||||
|
||||
$charBuffer .= $chars[($i + $x)];
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
$content = str_replace($eolChar, '\n', $charBuffer);
|
||||
echo "\t=> Looking ahead $x chars => $content".PHP_EOL;
|
||||
}
|
||||
|
||||
if (in_array(strtolower($charBuffer), $tokenTypes) === true) {
|
||||
// We've found something larger that matches
|
||||
// so we can ignore this char.
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
$type = $this->tokenValues[strtolower($charBuffer)];
|
||||
echo "\t* look ahead found more specific token ($type), ignoring $i *".PHP_EOL;
|
||||
}
|
||||
|
||||
$matchedToken = true;
|
||||
break;
|
||||
}
|
||||
}//end for
|
||||
}//end if
|
||||
|
||||
if ($matchedToken === false) {
|
||||
$value = $this->tokenValues[strtolower($buffer)];
|
||||
$tokens[] = array(
|
||||
'code' => constant($value),
|
||||
'type' => $value,
|
||||
'content' => $buffer,
|
||||
);
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
if ($lookAheadLength > 0) {
|
||||
echo "\t* look ahead found nothing *".PHP_EOL;
|
||||
}
|
||||
|
||||
$content = str_replace($eolChar, '\n', $buffer);
|
||||
echo "=> Added token $value ($content)".PHP_EOL;
|
||||
}
|
||||
|
||||
$cleanBuffer = true;
|
||||
}
|
||||
} else if (in_array(strtolower($char), $tokenTypes) === true) {
|
||||
// No matter what token we end up using, we don't
|
||||
// need the content in the buffer any more because we have
|
||||
// found a valid token.
|
||||
$tokens[] = array(
|
||||
'code' => T_STRING,
|
||||
'type' => 'T_STRING',
|
||||
'content' => substr($buffer, 0, -1),
|
||||
);
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
$content = str_replace($eolChar, '\n', substr($buffer, 0, -1));
|
||||
echo "=> Added token T_STRING ($content)".PHP_EOL;
|
||||
}
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
echo "\t* char is token, looking ahead ".($maxTokenLength - 1).' chars *'.PHP_EOL;
|
||||
}
|
||||
|
||||
// The char is a token type, but we need to look ahead at the
|
||||
// next chars to see if this is actually part of a larger token.
|
||||
// For example, = and ===.
|
||||
$charBuffer = $char;
|
||||
$matchedToken = false;
|
||||
for ($x = 1; $x <= $maxTokenLength; $x++) {
|
||||
if (isset($chars[($i + $x)]) === false) {
|
||||
break;
|
||||
}
|
||||
|
||||
$charBuffer .= $chars[($i + $x)];
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
$content = str_replace($eolChar, '\n', $charBuffer);
|
||||
echo "\t=> Looking ahead $x chars => $content".PHP_EOL;
|
||||
}
|
||||
|
||||
if (in_array(strtolower($charBuffer), $tokenTypes) === true) {
|
||||
// We've found something larger that matches
|
||||
// so we can ignore this char.
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
$type = $this->tokenValues[strtolower($charBuffer)];
|
||||
echo "\t* look ahead found more specific token ($type), ignoring $i *".PHP_EOL;
|
||||
}
|
||||
|
||||
$matchedToken = true;
|
||||
break;
|
||||
}
|
||||
}//end for
|
||||
|
||||
if ($matchedToken === false) {
|
||||
$value = $this->tokenValues[strtolower($char)];
|
||||
$tokens[] = array(
|
||||
'code' => constant($value),
|
||||
'type' => $value,
|
||||
'content' => $char,
|
||||
);
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
echo "\t* look ahead found nothing *".PHP_EOL;
|
||||
$content = str_replace($eolChar, '\n', $char);
|
||||
echo "=> Added token $value ($content)".PHP_EOL;
|
||||
}
|
||||
|
||||
$cleanBuffer = true;
|
||||
} else {
|
||||
$buffer = $char;
|
||||
}
|
||||
}//end if
|
||||
|
||||
// Keep track of content inside comments.
|
||||
if ($inComment === '' && array_key_exists($buffer, $this->commentTokens) === true) {
|
||||
// We have started a comment.
|
||||
$inComment = $buffer;
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
echo "\t* looking for end of comment *".PHP_EOL;
|
||||
}
|
||||
} else if ($inComment !== '') {
|
||||
if ($this->commentTokens[$inComment] === null) {
|
||||
// Comment ends at the next newline.
|
||||
if (strpos($buffer, $eolChar) !== false) {
|
||||
$inComment = '';
|
||||
}
|
||||
} else {
|
||||
if ($this->commentTokens[$inComment] === $buffer) {
|
||||
$inComment = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
if ($inComment === '') {
|
||||
echo "\t* found end of comment *".PHP_EOL;
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
|
||||
if ($cleanBuffer === true) {
|
||||
$buffer = '';
|
||||
$cleanBuffer = false;
|
||||
}
|
||||
}//end foreach
|
||||
|
||||
$tokens[] = array(
|
||||
'code' => T_CLOSE_TAG,
|
||||
'type' => 'T_CLOSE_TAG',
|
||||
'content' => '',
|
||||
);
|
||||
|
||||
/*
|
||||
Now that we have done some basic tokenizing, we need to
|
||||
modify the tokens to join some together and split some apart
|
||||
so they match what the PHP tokenizer does.
|
||||
*/
|
||||
|
||||
$finalTokens = array();
|
||||
$newStackPtr = 0;
|
||||
$numTokens = count($tokens);
|
||||
for ($stackPtr = 0; $stackPtr < $numTokens; $stackPtr++) {
|
||||
$token = $tokens[$stackPtr];
|
||||
|
||||
/*
|
||||
Look for regular expressions and join the tokens together.
|
||||
*/
|
||||
|
||||
if ($token['code'] === T_DIVIDE) {
|
||||
$beforeTokens = array(
|
||||
T_EQUAL,
|
||||
T_OPEN_PARENTHESIS,
|
||||
);
|
||||
|
||||
$afterTokens = array(
|
||||
T_COMMA,
|
||||
T_CLOSE_PARENTHESIS,
|
||||
T_SEMICOLON,
|
||||
T_WHITESPACE,
|
||||
);
|
||||
|
||||
for ($prev = ($stackPtr - 1); $prev >= 0; $prev--) {
|
||||
if (in_array($tokens[$prev]['code'], PHP_CodeSniffer_Tokens::$emptyTokens) === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Token needs to be one of the standard allowed or the replace()
|
||||
// method that can be called on string: string.replace(/abc/...).
|
||||
if (in_array($tokens[$prev]['code'], $beforeTokens) === true || $tokens[$prev]['content'] === 'replace') {
|
||||
// This might be a regular expression.
|
||||
$regexTokens = array(
|
||||
T_STRING,
|
||||
T_WHITESPACE,
|
||||
T_OBJECT_OPERATOR,
|
||||
);
|
||||
|
||||
for ($next = ($stackPtr + 1); $next < $numTokens; $next++) {
|
||||
if (in_array($tokens[$next]['code'], $regexTokens) === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($tokens[$next]['code'] === T_DIVIDE) {
|
||||
if ($tokens[($next + 1)]['code'] === T_STRING) {
|
||||
// The token directly after the end of the regex can
|
||||
// be modifiers like global and case insensitive
|
||||
// (.e.g, /pattern/gi).
|
||||
$next++;
|
||||
}
|
||||
|
||||
$regexEnd = $next;
|
||||
|
||||
for ($next = ($next + 1); $next < $numTokens; $next++) {
|
||||
if (in_array($tokens[$next]['code'], PHP_CodeSniffer_Tokens::$emptyTokens) === false) {
|
||||
break;
|
||||
} else if (strpos($tokens[$next]['content'], $eolChar) !== false) {
|
||||
// If this is the last token on the line.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($tokens[$next]['code'], $afterTokens) === true) {
|
||||
// This is a regular expression, so join all the
|
||||
// tokens together.
|
||||
for ($i = ($stackPtr + 1); $i <= $regexEnd; $i++) {
|
||||
$token['content'] .= $tokens[$i]['content'];
|
||||
}
|
||||
|
||||
$token['code'] = T_REGULAR_EXPRESSION;
|
||||
$token['type'] ='T_REGULAR_EXPRESSION';
|
||||
$stackPtr = $regexEnd;
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
}//end if
|
||||
|
||||
/*
|
||||
Look for comments and join the tokens together.
|
||||
*/
|
||||
|
||||
if (array_key_exists($token['content'], $this->commentTokens) === true) {
|
||||
$newContent = '';
|
||||
$tokenContent = $token['content'];
|
||||
$endContent = $this->commentTokens[$tokenContent];
|
||||
while ($tokenContent !== $endContent) {
|
||||
if ($endContent === null && strpos($tokenContent, $eolChar) !== false) {
|
||||
// A null end token means the comment ends at the end of
|
||||
// the line so we look for newlines and split the token.
|
||||
$tokens[$stackPtr]['content'] = substr($tokenContent, (strpos($tokenContent, $eolChar) + strlen($eolChar)));
|
||||
|
||||
$tokenContent = substr($tokenContent, 0, (strpos($tokenContent, $eolChar) + strlen($eolChar)));
|
||||
|
||||
// If the substr failed, skip the token as the content
|
||||
// will now be blank.
|
||||
if ($tokens[$stackPtr]['content'] !== false) {
|
||||
$stackPtr--;
|
||||
}
|
||||
|
||||
break;
|
||||
}//end if
|
||||
|
||||
$stackPtr++;
|
||||
$newContent .= $tokenContent;
|
||||
if (isset($tokens[$stackPtr]) === false) {
|
||||
break;
|
||||
}
|
||||
|
||||
$tokenContent = $tokens[$stackPtr]['content'];
|
||||
}//end while
|
||||
|
||||
// Save the new content in the current token so
|
||||
// the code below can chop it up on newlines.
|
||||
$token['content'] = $newContent.$tokenContent;
|
||||
}//end if
|
||||
|
||||
/*
|
||||
If this token has newlines in its content, split each line up
|
||||
and create a new token for each line. We do this so it's easier
|
||||
to asertain where errors occur on a line.
|
||||
Note that $token[1] is the token's content.
|
||||
*/
|
||||
|
||||
if (strpos($token['content'], $eolChar) !== false) {
|
||||
$tokenLines = explode($eolChar, $token['content']);
|
||||
$numLines = count($tokenLines);
|
||||
|
||||
for ($i = 0; $i < $numLines; $i++) {
|
||||
$newToken['content'] = $tokenLines[$i];
|
||||
if ($i === ($numLines - 1)) {
|
||||
if ($tokenLines[$i] === '') {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$newToken['content'] .= $eolChar;
|
||||
}
|
||||
|
||||
$newToken['type'] = $token['type'];
|
||||
$newToken['code'] = $token['code'];
|
||||
$finalTokens[$newStackPtr] = $newToken;
|
||||
$newStackPtr++;
|
||||
}
|
||||
} else {
|
||||
$finalTokens[$newStackPtr] = $token;
|
||||
$newStackPtr++;
|
||||
}//end if
|
||||
|
||||
// Convert numbers, including decimals.
|
||||
if ($token['code'] === T_STRING || $token['code'] === T_OBJECT_OPERATOR) {
|
||||
$newContent = '';
|
||||
$oldStackPtr = $stackPtr;
|
||||
while (preg_match('|^[0-9\.]+$|', $tokens[$stackPtr]['content']) !== 0) {
|
||||
$newContent .= $tokens[$stackPtr]['content'];
|
||||
$stackPtr++;
|
||||
}
|
||||
|
||||
if ($newContent !== '' && $newContent !== '.') {
|
||||
$finalTokens[($newStackPtr - 1)]['content'] = $newContent;
|
||||
if (ctype_digit($newContent) === true) {
|
||||
$finalTokens[($newStackPtr - 1)]['code'] = constant('T_LNUMBER');
|
||||
$finalTokens[($newStackPtr - 1)]['type'] = 'T_LNUMBER';
|
||||
} else {
|
||||
$finalTokens[($newStackPtr - 1)]['code'] = constant('T_DNUMBER');
|
||||
$finalTokens[($newStackPtr - 1)]['type'] = 'T_DNUMBER';
|
||||
}
|
||||
|
||||
$stackPtr--;
|
||||
} else {
|
||||
$stackPtr = $oldStackPtr;
|
||||
}
|
||||
}//end if
|
||||
}//end for
|
||||
|
||||
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
||||
echo "\t*** END TOKENIZING ***".PHP_EOL;
|
||||
}
|
||||
|
||||
return $finalTokens;
|
||||
|
||||
}//end tokenizeString()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -1,398 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Tokenizes PHP code.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tokenizes PHP code.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @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_Tokenizers_PHP
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of tokens that are allowed to open a scope.
|
||||
*
|
||||
* This array also contains information about what kind of token the scope
|
||||
* opener uses to open and close the scope, if the token strictly requires
|
||||
* an opener, if the token can share a scope closer, and who it can be shared
|
||||
* with. An example of a token that shares a scope closer is a CASE scope.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $scopeOpeners = array(
|
||||
T_IF => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_TRY => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_CATCH => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_ELSE => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_ELSEIF => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_FOR => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_FOREACH => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_INTERFACE => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_FUNCTION => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_CLASS => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_WHILE => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => false,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_DO => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_SWITCH => array(
|
||||
'start' => T_OPEN_CURLY_BRACKET,
|
||||
'end' => T_CLOSE_CURLY_BRACKET,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
T_CASE => array(
|
||||
'start' => T_COLON,
|
||||
'end' => T_BREAK,
|
||||
'strict' => true,
|
||||
'shared' => true,
|
||||
'with' => array(
|
||||
T_DEFAULT,
|
||||
T_CASE,
|
||||
),
|
||||
),
|
||||
T_DEFAULT => array(
|
||||
'start' => T_COLON,
|
||||
'end' => T_BREAK,
|
||||
'strict' => true,
|
||||
'shared' => true,
|
||||
'with' => array(T_CASE),
|
||||
),
|
||||
T_START_HEREDOC => array(
|
||||
'start' => T_START_HEREDOC,
|
||||
'end' => T_END_HEREDOC,
|
||||
'strict' => true,
|
||||
'shared' => false,
|
||||
'with' => array(),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* A list of tokens that end the scope.
|
||||
*
|
||||
* This array is just a unique collection of the end tokens
|
||||
* from the _scopeOpeners array. The data is duplicated here to
|
||||
* save time during parsing of the file.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $endScopeTokens = array(
|
||||
T_CLOSE_CURLY_BRACKET,
|
||||
T_BREAK,
|
||||
T_END_HEREDOC,
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 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 string $eolChar The EOL character to use for splitting strings.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokenizeString($string, $eolChar='\n')
|
||||
{
|
||||
$tokens = @token_get_all($string);
|
||||
$finalTokens = array();
|
||||
|
||||
$newStackPtr = 0;
|
||||
$numTokens = count($tokens);
|
||||
for ($stackPtr = 0; $stackPtr < $numTokens; $stackPtr++) {
|
||||
$token = $tokens[$stackPtr];
|
||||
$tokenIsArray = is_array($token);
|
||||
|
||||
/*
|
||||
If we are using \r\n newline characters, the \r and \n are sometimes
|
||||
split over two tokens. This normally occurs after comments. We need
|
||||
to merge these two characters together so that our line endings are
|
||||
consistent for all lines.
|
||||
*/
|
||||
|
||||
if ($tokenIsArray === true && substr($token[1], -1) === "\r") {
|
||||
if (isset($tokens[($stackPtr + 1)]) === true && is_array($tokens[($stackPtr + 1)]) === true && $tokens[($stackPtr + 1)][1][0] === "\n") {
|
||||
$token[1] .= "\n";
|
||||
|
||||
if ($tokens[($stackPtr + 1)][1] === "\n") {
|
||||
// The next token's content has been merged into this token,
|
||||
// so we can skip it.
|
||||
$stackPtr++;
|
||||
} else {
|
||||
$tokens[($stackPtr + 1)][1] = substr($tokens[($stackPtr + 1)][1], 1);
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
|
||||
/*
|
||||
If this is a double quoted string, PHP will tokenise the whole
|
||||
thing which causes problems with the scope map when braces are
|
||||
within the string. So we need to merge the tokens together to
|
||||
provide a single string.
|
||||
*/
|
||||
|
||||
if ($tokenIsArray === false && $token === '"') {
|
||||
$tokenContent = '"';
|
||||
$nestedVars = array();
|
||||
for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
|
||||
$subTokenIsArray = is_array($tokens[$i]);
|
||||
|
||||
if ($subTokenIsArray === true) {
|
||||
$tokenContent .= $tokens[$i][1];
|
||||
if ($tokens[$i][1] === '{') {
|
||||
$nestedVars[] = $i;
|
||||
}
|
||||
} else {
|
||||
$tokenContent .= $tokens[$i];
|
||||
if ($tokens[$i] === '}') {
|
||||
array_pop($nestedVars);
|
||||
}
|
||||
}
|
||||
|
||||
if ($subTokenIsArray === false && $tokens[$i] === '"' && empty($nestedVars) === true) {
|
||||
// We found the other end of the double quoted string.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$stackPtr = $i;
|
||||
|
||||
// Convert each line within the double quoted string to a
|
||||
// new token, so it conforms with other multiple line tokens.
|
||||
$tokenLines = explode($eolChar, $tokenContent);
|
||||
$numLines = count($tokenLines);
|
||||
$newToken = array();
|
||||
|
||||
for ($j = 0; $j < $numLines; $j++) {
|
||||
$newToken['content'] = $tokenLines[$j];
|
||||
if ($j === ($numLines - 1)) {
|
||||
if ($tokenLines[$j] === '') {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$newToken['content'] .= $eolChar;
|
||||
}
|
||||
|
||||
$newToken['code'] = T_DOUBLE_QUOTED_STRING;
|
||||
$newToken['type'] = 'T_DOUBLE_QUOTED_STRING';
|
||||
$finalTokens[$newStackPtr] = $newToken;
|
||||
$newStackPtr++;
|
||||
}
|
||||
|
||||
// Continue, as we're done with this token.
|
||||
continue;
|
||||
}//end if
|
||||
|
||||
/*
|
||||
If this is a heredoc, PHP will tokenise the whole
|
||||
thing which causes problems when heredocs don't
|
||||
contain real PHP code, which is almost never.
|
||||
We want to leave the start and end heredoc tokens
|
||||
alone though.
|
||||
*/
|
||||
|
||||
if ($tokenIsArray === true && $token[0] === T_START_HEREDOC) {
|
||||
// Add the start heredoc token to the final array.
|
||||
$finalTokens[$newStackPtr] = PHP_CodeSniffer::standardiseToken($token);
|
||||
$newStackPtr++;
|
||||
|
||||
$tokenContent = '';
|
||||
for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
|
||||
$subTokenIsArray = is_array($tokens[$i]);
|
||||
if ($subTokenIsArray === true && $tokens[$i][0] === T_END_HEREDOC) {
|
||||
// We found the other end of the heredoc.
|
||||
break;
|
||||
}
|
||||
|
||||
if ($subTokenIsArray === true) {
|
||||
$tokenContent .= $tokens[$i][1];
|
||||
} else {
|
||||
$tokenContent .= $tokens[$i];
|
||||
}
|
||||
}
|
||||
|
||||
$stackPtr = $i;
|
||||
|
||||
// Convert each line within the heredoc to a
|
||||
// new token, so it conforms with other multiple line tokens.
|
||||
$tokenLines = explode($eolChar, $tokenContent);
|
||||
$numLines = count($tokenLines);
|
||||
$newToken = array();
|
||||
|
||||
for ($j = 0; $j < $numLines; $j++) {
|
||||
$newToken['content'] = $tokenLines[$j];
|
||||
if ($j === ($numLines - 1)) {
|
||||
if ($tokenLines[$j] === '') {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$newToken['content'] .= $eolChar;
|
||||
}
|
||||
|
||||
$newToken['code'] = T_HEREDOC;
|
||||
$newToken['type'] = 'T_HEREDOC';
|
||||
$finalTokens[$newStackPtr] = $newToken;
|
||||
$newStackPtr++;
|
||||
}
|
||||
|
||||
// Add the end heredoc token to the final array.
|
||||
$finalTokens[$newStackPtr] = PHP_CodeSniffer::standardiseToken($tokens[$stackPtr]);
|
||||
$newStackPtr++;
|
||||
|
||||
// Continue, as we're done with this token.
|
||||
continue;
|
||||
}//end if
|
||||
|
||||
/*
|
||||
If this token has newlines in its content, split each line up
|
||||
and create a new token for each line. We do this so it's easier
|
||||
to asertain where errors occur on a line.
|
||||
Note that $token[1] is the token's content.
|
||||
*/
|
||||
|
||||
if ($tokenIsArray === true && strpos($token[1], $eolChar) !== false) {
|
||||
$tokenLines = explode($eolChar, $token[1]);
|
||||
$numLines = count($tokenLines);
|
||||
$tokenName = token_name($token[0]);
|
||||
|
||||
for ($i = 0; $i < $numLines; $i++) {
|
||||
$newToken['content'] = $tokenLines[$i];
|
||||
if ($i === ($numLines - 1)) {
|
||||
if ($tokenLines[$i] === '') {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$newToken['content'] .= $eolChar;
|
||||
}
|
||||
|
||||
$newToken['type'] = $tokenName;
|
||||
$newToken['code'] = $token[0];
|
||||
$finalTokens[$newStackPtr] = $newToken;
|
||||
$newStackPtr++;
|
||||
}
|
||||
} else {
|
||||
$newToken = PHP_CodeSniffer::standardiseToken($token);
|
||||
|
||||
// This is a special condition for T_ARRAY tokens use to
|
||||
// type hint function arguments as being arrays. We want to keep
|
||||
// the parenthsis map clean, so let's tag these tokens as
|
||||
// T_ARRAY_HINT.
|
||||
if ($newToken['code'] === T_ARRAY) {
|
||||
// Recalculate number of tokens.
|
||||
$numTokens = count($tokens);
|
||||
for ($i = $stackPtr; $i < $numTokens; $i++) {
|
||||
if (is_array($tokens[$i]) === false) {
|
||||
if ($tokens[$i] === '(') {
|
||||
break;
|
||||
}
|
||||
} else if ($tokens[$i][0] === T_VARIABLE) {
|
||||
$newToken['code'] = T_ARRAY_HINT;
|
||||
$newToken['type'] = 'T_ARRAY_HINT';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$finalTokens[$newStackPtr] = $newToken;
|
||||
$newStackPtr++;
|
||||
}//end if
|
||||
}//end for
|
||||
|
||||
return $finalTokens;
|
||||
|
||||
}//end tokenizeString()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -1,389 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The Tokens class contains weightings for tokens based on their
|
||||
* probability of occurance in a file.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
*/
|
||||
|
||||
define('T_NONE', 0);
|
||||
define('T_OPEN_CURLY_BRACKET', 1000);
|
||||
define('T_CLOSE_CURLY_BRACKET', 1001);
|
||||
define('T_OPEN_SQUARE_BRACKET', 1002);
|
||||
define('T_CLOSE_SQUARE_BRACKET', 1003);
|
||||
define('T_OPEN_PARENTHESIS', 1004);
|
||||
define('T_CLOSE_PARENTHESIS', 1005);
|
||||
define('T_COLON', 1006);
|
||||
define('T_STRING_CONCAT', 1007);
|
||||
define('T_INLINE_THEN', 1008);
|
||||
define('T_NULL', 1009);
|
||||
define('T_FALSE', 1010);
|
||||
define('T_TRUE', 1011);
|
||||
define('T_SEMICOLON', 1012);
|
||||
define('T_EQUAL', 1013);
|
||||
define('T_MULTIPLY', 1015);
|
||||
define('T_DIVIDE', 1016);
|
||||
define('T_PLUS', 1017);
|
||||
define('T_MINUS', 1018);
|
||||
define('T_MODULUS', 1019);
|
||||
define('T_POWER', 1020);
|
||||
define('T_BITWISE_AND', 1021);
|
||||
define('T_BITWISE_OR', 1022);
|
||||
define('T_ARRAY_HINT', 1023);
|
||||
define('T_GREATER_THAN', 1024);
|
||||
define('T_LESS_THAN', 1025);
|
||||
define('T_BOOLEAN_NOT', 1026);
|
||||
define('T_SELF', 1027);
|
||||
define('T_PARENT', 1028);
|
||||
define('T_DOUBLE_QUOTED_STRING', 1029);
|
||||
define('T_COMMA', 1030);
|
||||
define('T_HEREDOC', 1031);
|
||||
define('T_PROTOTYPE', 1032);
|
||||
define('T_THIS', 1033);
|
||||
define('T_REGULAR_EXPRESSION', 1034);
|
||||
|
||||
/**
|
||||
* The Tokens class contains weightings for tokens based on their
|
||||
* probability of occurance in a file.
|
||||
*
|
||||
* The less the chance of a high occurance of an abitrary token, the higher
|
||||
* the weighting.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <[email protected]>
|
||||
* @author Marc McIntyre <[email protected]>
|
||||
* @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
|
||||
*/
|
||||
final class PHP_CodeSniffer_Tokens
|
||||
{
|
||||
|
||||
/**
|
||||
* The token weightings.
|
||||
*
|
||||
* @var array(int => int)
|
||||
*/
|
||||
public static $weightings = array(
|
||||
T_CLASS => 1000,
|
||||
T_FUNCTION => 100,
|
||||
|
||||
/*
|
||||
Conditions.
|
||||
*/
|
||||
|
||||
T_WHILE => 50,
|
||||
T_FOR => 50,
|
||||
T_FOREACH => 50,
|
||||
T_IF => 50,
|
||||
T_ELSE => 50,
|
||||
T_ELSEIF => 50,
|
||||
T_WHILE => 50,
|
||||
T_DO => 50,
|
||||
T_TRY => 50,
|
||||
T_CATCH => 50,
|
||||
T_SWITCH => 50,
|
||||
|
||||
T_SELF => 25,
|
||||
T_PARENT => 25,
|
||||
|
||||
/*
|
||||
Operators and arithmetic.
|
||||
*/
|
||||
|
||||
T_BITWISE_AND => 8,
|
||||
T_BITWISE_OR => 8,
|
||||
|
||||
T_MULTIPLY => 5,
|
||||
T_DIVIDE => 5,
|
||||
T_PLUS => 5,
|
||||
T_MINUS => 5,
|
||||
T_MODULUS => 5,
|
||||
T_POWER => 5,
|
||||
|
||||
T_EQUAL => 5,
|
||||
T_AND_EQUAL => 5,
|
||||
T_CONCAT_EQUAL => 5,
|
||||
T_DIV_EQUAL => 5,
|
||||
T_MINUS_EQUAL => 5,
|
||||
T_MOD_EQUAL => 5,
|
||||
T_MUL_EQUAL => 5,
|
||||
T_OR_EQUAL => 5,
|
||||
T_PLUS_EQUAL => 5,
|
||||
T_XOR_EQUAL => 5,
|
||||
|
||||
T_BOOLEAN_AND => 5,
|
||||
T_BOOLEAN_OR => 5,
|
||||
|
||||
/*
|
||||
Equality.
|
||||
*/
|
||||
|
||||
T_IS_EQUAL => 5,
|
||||
T_IS_NOT_EQUAL => 5,
|
||||
T_IS_IDENTICAL => 5,
|
||||
T_IS_NOT_IDENTICAL => 5,
|
||||
T_IS_SMALLER_OR_EQUAL => 5,
|
||||
T_IS_GREATER_OR_EQUAL => 5,
|
||||
|
||||
T_WHITESPACE => 0,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that represent assignments.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $assignmentTokens = array(
|
||||
T_EQUAL,
|
||||
T_AND_EQUAL,
|
||||
T_CONCAT_EQUAL,
|
||||
T_DIV_EQUAL,
|
||||
T_MINUS_EQUAL,
|
||||
T_MOD_EQUAL,
|
||||
T_MUL_EQUAL,
|
||||
T_PLUS_EQUAL,
|
||||
T_XOR_EQUAL,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that represent equality comparisons.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $equalityTokens = array(
|
||||
T_IS_EQUAL,
|
||||
T_IS_NOT_EQUAL,
|
||||
T_IS_IDENTICAL,
|
||||
T_IS_NOT_IDENTICAL,
|
||||
T_IS_SMALLER_OR_EQUAL,
|
||||
T_IS_GREATER_OR_EQUAL,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that represent comparison operator.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $comparisonTokens = array(
|
||||
T_IS_EQUAL,
|
||||
T_IS_IDENTICAL,
|
||||
T_IS_NOT_EQUAL,
|
||||
T_IS_NOT_IDENTICAL,
|
||||
T_LESS_THAN,
|
||||
T_GREATER_THAN,
|
||||
T_IS_SMALLER_OR_EQUAL,
|
||||
T_IS_GREATER_OR_EQUAL,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that represent arithmetic operators.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $arithmeticTokens = array(
|
||||
T_PLUS,
|
||||
T_MINUS,
|
||||
T_MULTIPLY,
|
||||
T_DIVIDE,
|
||||
T_MODULUS,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that represent casting.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $castTokens = array(
|
||||
T_INT_CAST,
|
||||
T_STRING_CAST,
|
||||
T_DOUBLE_CAST,
|
||||
T_ARRAY_CAST,
|
||||
T_BOOL_CAST,
|
||||
T_OBJECT_CAST,
|
||||
T_UNSET_CAST,
|
||||
);
|
||||
|
||||
/**
|
||||
* Token types that open parethesis.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $parenthesisOpeners = array(
|
||||
T_ARRAY,
|
||||
T_FUNCTION,
|
||||
T_WHILE,
|
||||
T_FOR,
|
||||
T_FOREACH,
|
||||
T_SWITCH,
|
||||
T_IF,
|
||||
T_ELSEIF,
|
||||
T_CATCH,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that are allowed to open scopes.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $scopeOpeners = array(
|
||||
T_CLASS,
|
||||
T_INTERFACE,
|
||||
T_FUNCTION,
|
||||
T_IF,
|
||||
T_SWITCH,
|
||||
T_CASE,
|
||||
T_DEFAULT,
|
||||
T_WHILE,
|
||||
T_ELSE,
|
||||
T_ELSEIF,
|
||||
T_FOR,
|
||||
T_FOREACH,
|
||||
T_DO,
|
||||
T_TRY,
|
||||
T_CATCH,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that represent scope modifiers.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $scopeModifiers = array(
|
||||
T_PRIVATE,
|
||||
T_PUBLIC,
|
||||
T_PROTECTED,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that perform operations.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $operators = array(
|
||||
T_MINUS,
|
||||
T_PLUS,
|
||||
T_MULTIPLY,
|
||||
T_DIVIDE,
|
||||
T_MODULUS,
|
||||
T_POWER,
|
||||
T_BITWISE_AND,
|
||||
T_BITWISE_OR,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that perform operations.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $blockOpeners = array(
|
||||
T_OPEN_CURLY_BRACKET,
|
||||
T_OPEN_SQUARE_BRACKET,
|
||||
T_OPEN_PARENTHESIS,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that don't represent code.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $emptyTokens = array(
|
||||
T_WHITESPACE,
|
||||
T_COMMENT,
|
||||
T_DOC_COMMENT,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that are comments.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $commentTokens = array(
|
||||
T_COMMENT,
|
||||
T_DOC_COMMENT,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that represent strings.
|
||||
*
|
||||
* Note that T_STRINGS are NOT represented in this list.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $stringTokens = array(
|
||||
T_CONSTANT_ENCAPSED_STRING,
|
||||
T_DOUBLE_QUOTED_STRING,
|
||||
);
|
||||
|
||||
/**
|
||||
* Tokens that include files.
|
||||
*
|
||||
* @var array(int)
|
||||
*/
|
||||
public static $includeTokens = array(
|
||||
T_REQUIRE_ONCE,
|
||||
T_REQUIRE,
|
||||
T_INCLUDE_ONCE,
|
||||
T_INCLUDE,
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* A PHP_CodeSniffer_Tokens class cannot be constructed.
|
||||
*
|
||||
* Only static calls are allowed.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
|
||||
}//end __construct()
|
||||
|
||||
|
||||
/**
|
||||
* Returns the highest weighted token type.
|
||||
*
|
||||
* Tokens are weighted by their approximate frequency of appearance in code
|
||||
* - the less frequently they appear in the code, the higher the weighting.
|
||||
* For example T_CLASS tokens apprear very infrequently in a file, and
|
||||
* therefore have a high weighting.
|
||||
*
|
||||
* Returns false if there are no weightings for any of the specified tokens.
|
||||
*
|
||||
* @param array(int) $tokens The token types to get the highest weighted
|
||||
* type for.
|
||||
*
|
||||
* @return int The highest weighted token.
|
||||
*/
|
||||
public static function getHighestWeightedToken(array $tokens)
|
||||
{
|
||||
$highest = -1;
|
||||
$highestType = false;
|
||||
|
||||
$weights = self::$weightings;
|
||||
|
||||
foreach ($tokens as $token) {
|
||||
if (isset($weights[$token]) === true && $weights[$token] > $highest) {
|
||||
$highest = $weights[$token];
|
||||
$highestType = $token;
|
||||
}
|
||||
}
|
||||
|
||||
return $highestType;
|
||||
|
||||
}//end getHighestWeightedToken()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -1,87 +0,0 @@
|
||||
<?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/>.
|
||||
/**
|
||||
* Sub-class of lib/pear/PHP/CodeSniffer.php
|
||||
*
|
||||
* Modified to read thirdpartylibs.xml from a recursed directory and apply
|
||||
* its contents to the ignored list.
|
||||
*
|
||||
* @package lib-pear-php-codesniffer
|
||||
* @copyright 2008 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
require_once('PHP/CodeSniffer/CLI.php');
|
||||
|
||||
if (class_exists('PHP_CodeSniffer', true) === false) {
|
||||
throw new Exception('Class PHP_CodeSniffer not found');
|
||||
}
|
||||
|
||||
class moodle_codesniffer extends php_codesniffer {
|
||||
public function processFiles($dir, $local=false) {
|
||||
try {
|
||||
if ($local === true) {
|
||||
$di = new DirectoryIterator($dir);
|
||||
} else {
|
||||
$di = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
|
||||
}
|
||||
|
||||
// MOODLE CODE: If thirdpartylibs.xml is found, add these values to the ignored array
|
||||
// first iteration to find thirdpartylibs.xml
|
||||
foreach ($di as $file) {
|
||||
if ($file->getFileName() == 'thirdpartylibs.xml') {
|
||||
$xml = simplexml_load_file($file->getPathName());
|
||||
foreach ($xml->library as $libobject) {
|
||||
$this->ignorePatterns[] = (string) $libobject->location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
/**
|
||||
* This script will run PHP CodeSniffer across given Moodle directories and
|
||||
* produce reports of coding standard violations.
|
||||
*
|
||||
* HOW TO USE:
|
||||
* php lib/pear/PHP/runsniffer mod/forum
|
||||
* USEFUL PARAMETERS:
|
||||
* -n : only show ERROR, not WARNING
|
||||
* --report=summary : Outputs a summary instead of a per-file list of errors
|
||||
*
|
||||
* @package lib-pear-PHP-CodeSniffer
|
||||
* @copyright 2009 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
require_once(dirname(__FILE__).'/../../../config.php');
|
||||
include_once('PHP/CodeSniffer/MoodleCLI.php');
|
||||
|
||||
$phpcs = new moodle_codesniffer_cli();
|
||||
$phpcs->checkRequirements();
|
||||
|
||||
$numErrors = $phpcs->process();
|
||||
if ($numErrors === 0) {
|
||||
exit(0);
|
||||
} else {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -31,18 +31,6 @@ XML/Parser
|
||||
* http://cvs.moodle.org/moodle/lib/pear/XML/Parser.php.diff?r1=1.1&r2=1.2
|
||||
|
||||
|
||||
PHP/CodeSniffer
|
||||
===============
|
||||
|
||||
MDL-20876 - replaced deprecated split() with explode()
|
||||
|
||||
A whole Moodle coding standards definition sits in lib/pear/PHP/CodeSniffer/Standards/Moodle
|
||||
|
||||
To run the codesniffer, you can call the runsniffer script using your command-line php binary:
|
||||
|
||||
Example: /usr/bin/php lib/pear/PHP/runsniffer mod/forum
|
||||
|
||||
|
||||
Quickforms
|
||||
==========
|
||||
Full of our custom hacks, no way to upgrade to latest upstream.
|
||||
|
||||
@@ -161,13 +161,6 @@
|
||||
<version>1.4.5</version>
|
||||
<licenseversion>3.0</licenseversion>
|
||||
</library>
|
||||
<library>
|
||||
<location>pear/PHP</location>
|
||||
<name>Pear_PHP_CodeSniffer</name>
|
||||
<license>BSD</license>
|
||||
<version>1.1.0</version>
|
||||
<licenseversion></licenseversion>
|
||||
</library>
|
||||
<library>
|
||||
<location>pear/Spreadsheet/Excel</location>
|
||||
<name>Pear_Spreadsheet_Excel</name>
|
||||
|
||||
Reference in New Issue
Block a user