Skip to content

Commit

Permalink
Merge branch 'master' into patch-3
Browse files Browse the repository at this point in the history
  • Loading branch information
photodude authored Feb 14, 2017
2 parents 85e4b9f + 9c5f6a9 commit 384fe95
Show file tree
Hide file tree
Showing 143 changed files with 3,447 additions and 683 deletions.
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@
/CodeSniffer/Standards/Zend/Tests export-ignore
.travis.yml export-ignore
package.xml export-ignore
phpunit.xml.dist export-ignore
php5-testingConfig.ini export-ignore
php7-testingConfig.ini export-ignore
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
sudo: false

language: php

php:
Expand All @@ -12,11 +11,16 @@ php:
- nightly

matrix:
fast_finish: true
include:
- php: hhvm
sudo: true
dist: trusty
group: edge # until the next update
allow_failures:
# Allow failures for unstable builds.
- php: nightly
- php: hhvm

before_script:
- if [[ ${TRAVIS_PHP_VERSION:0:1} != "7" && $TRAVIS_PHP_VERSION != "nightly" && $TRAVIS_PHP_VERSION != hhv* ]]; then phpenv config-add php5-testingConfig.ini; fi
Expand Down
47 changes: 32 additions & 15 deletions CodeSniffer.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class PHP_CodeSniffer
*
* @var string
*/
const VERSION = '2.7.1';
const VERSION = '2.8.1';

/**
* Package stability; either stable, beta or alpha.
Expand Down Expand Up @@ -533,34 +533,51 @@ public function initStandard($standards, array $restrictions=array(), array $exc
// be detected properly for files created on a Mac with the /r line ending.
ini_set('auto_detect_line_endings', true);

$sniffs = array();
foreach ($standards as $standard) {
$installed = $this->getInstalledStandardPath($standard);
if (defined('PHP_CODESNIFFER_IN_TESTS') === true && empty($restrictions) === false) {
// Should be one standard and one sniff being tested at a time.
$installed = $this->getInstalledStandardPath($standards[0]);
if ($installed !== null) {
$standard = $installed;
} else {
$standard = self::realpath($standard);
$standard = self::realpath($standards[0]);
if (is_dir($standard) === true
&& is_file(self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml')) === true
) {
$standard = self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml');
}
}

if (PHP_CODESNIFFER_VERBOSITY === 1) {
$ruleset = simplexml_load_string(file_get_contents($standard));
if ($ruleset !== false) {
$standardName = (string) $ruleset['name'];
$sniffs = $this->_expandRulesetReference($restrictions[0], dirname($standard));
} else {
$sniffs = array();
foreach ($standards as $standard) {
$installed = $this->getInstalledStandardPath($standard);
if ($installed !== null) {
$standard = $installed;
} else {
$standard = self::realpath($standard);
if (is_dir($standard) === true
&& is_file(self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml')) === true
) {
$standard = self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml');
}
}

echo "Registering sniffs in the $standardName standard... ";
if (count($standards) > 1 || PHP_CODESNIFFER_VERBOSITY > 2) {
echo PHP_EOL;
if (PHP_CODESNIFFER_VERBOSITY === 1) {
$ruleset = simplexml_load_string(file_get_contents($standard));
if ($ruleset !== false) {
$standardName = (string) $ruleset['name'];
}

echo "Registering sniffs in the $standardName standard... ";
if (count($standards) > 1 || PHP_CODESNIFFER_VERBOSITY > 2) {
echo PHP_EOL;
}
}
}

$sniffs = array_merge($sniffs, $this->processRuleset($standard));
}//end foreach
$sniffs = array_merge($sniffs, $this->processRuleset($standard));
}//end foreach
}//end if

$sniffRestrictions = array();
foreach ($restrictions as $sniffCode) {
Expand Down
17 changes: 15 additions & 2 deletions CodeSniffer/CLI.php
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,13 @@ public function processLongArgument($arg, $pos)
// Passed report file is a file in the current directory.
$this->values['reportFile'] = getcwd().'/'.basename($this->values['reportFile']);
} else {
$dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
if ($dir{0} === '/') {
// An absolute path.
$dir = PHP_CodeSniffer::realpath($dir);
} else {
$dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
}

if ($dir !== false) {
// Report file path is relative.
$this->values['reportFile'] = $dir.'/'.basename($this->values['reportFile']);
Expand Down Expand Up @@ -771,7 +777,13 @@ public function processLongArgument($arg, $pos)
// Passed report file is a filename in the current directory.
$output = getcwd().'/'.basename($output);
} else {
$dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
if ($dir{0} === '/') {
// An absolute path.
$dir = PHP_CodeSniffer::realpath($dir);
} else {
$dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
}

if ($dir !== false) {
// Report file path is relative.
$output = $dir.'/'.basename($output);
Expand Down Expand Up @@ -1001,6 +1013,7 @@ public function process($values=array())
$this->printUsage();
exit(2);
} else {
$this->values['stdin'] = $fileContents;
$phpcs->processFile('STDIN', $fileContents);
}
}
Expand Down
97 changes: 68 additions & 29 deletions CodeSniffer/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,10 @@ public function start($contents=null)
// If short open tags are off but the file being checked uses
// short open tags, the whole content will be inline HTML
// and nothing will be checked. So try and handle this case.
if ($foundCode === false && $this->tokenizerType === 'PHP') {
// We don't show this error for STDIN because we can't be sure the content
// actually came directly from the user. It could be something like
// refs from a Git pre-push hook.
if ($foundCode === false && $this->tokenizerType === 'PHP' && $this->_file !== 'STDIN') {
$shortTags = (bool) ini_get('short_open_tag');
if ($shortTags === false) {
$error = 'No PHP code was found in this file and short open tags are not allowed by this install of PHP. This file may be using short open tags but PHP does not allow them.';
Expand Down Expand Up @@ -1942,7 +1945,9 @@ private static function _recurseScopeMap(
// scope tokens. E.g., if (1) 1; 1 ? (1 ? 1 : 1) : 1;
// If an IF statement below this one has an opener but no
// keyword, the opener will be incorrectly assigned to this IF statement.
if (($currType === T_IF || $currType === T_ELSE)
// The same case also applies to USE statements, which don't have to have
// openers, so a following USE statement can cause an incorrect brace match.
if (($currType === T_IF || $currType === T_ELSE || $currType === T_USE)
&& $opener === null
&& $tokens[$i]['code'] === T_SEMICOLON
) {
Expand Down Expand Up @@ -2645,25 +2650,23 @@ private static function _createLevelMap(&$tokens, $tokenizer, $eolChar)


/**
* Returns the declaration names for T_CLASS, T_INTERFACE and T_FUNCTION tokens.
* Returns the declaration names for classes, interfaces, and functions.
*
* @param int $stackPtr The position of the declaration token which
* declared the class, interface or function.
*
* @return string|null The name of the class, interface or function.
* or NULL if the function is a closure.
* or NULL if the function or class is anonymous.
* @throws PHP_CodeSniffer_Exception If the specified token is not of type
* T_FUNCTION, T_CLASS or T_INTERFACE.
* T_FUNCTION, T_CLASS, T_ANON_CLASS,
* or T_INTERFACE.
*/
public function getDeclarationName($stackPtr)
{
$tokenCode = $this->_tokens[$stackPtr]['code'];
if ($tokenCode !== T_FUNCTION
&& $tokenCode !== T_CLASS
&& $tokenCode !== T_INTERFACE
&& $tokenCode !== T_TRAIT
) {
throw new PHP_CodeSniffer_Exception('Token type "'.$this->_tokens[$stackPtr]['type'].'" is not T_FUNCTION, T_CLASS, T_INTERFACE or T_TRAIT');

if ($tokenCode === T_ANON_CLASS) {
return null;
}

if ($tokenCode === T_FUNCTION
Expand All @@ -2672,6 +2675,14 @@ public function getDeclarationName($stackPtr)
return null;
}

if ($tokenCode !== T_FUNCTION
&& $tokenCode !== T_CLASS
&& $tokenCode !== T_INTERFACE
&& $tokenCode !== T_TRAIT
) {
throw new PHP_CodeSniffer_Exception('Token type "'.$this->_tokens[$stackPtr]['type'].'" is not T_FUNCTION, T_CLASS, T_INTERFACE or T_TRAIT');
}

$content = null;
for ($i = $stackPtr; $i < $this->numTokens; $i++) {
if ($this->_tokens[$i]['code'] === T_STRING) {
Expand Down Expand Up @@ -2731,46 +2742,53 @@ public function isAnonymousFunction($stackPtr)


/**
* Returns the method parameters for the specified T_FUNCTION token.
* Returns the method parameters for the specified function token.
*
* Each parameter is in the following format:
*
* <code>
* 0 => array(
* 'token' => int, // The position of the var in the token stack.
* 'name' => '$var', // The variable name.
* 'pass_by_reference' => false, // Passed by reference.
* 'type_hint' => string, // Type hint for array or custom type
* 'content' => string, // The full content of the variable definition.
* 'pass_by_reference' => boolean, // Is the variable passed by reference?
* 'type_hint' => string, // The type hint for the variable.
* 'nullable_type' => boolean, // Is the variable using a nullable type?
* )
* </code>
*
* Parameters with default values have an additional array index of
* 'default' with the value of the default as a string.
*
* @param int $stackPtr The position in the stack of the T_FUNCTION token
* @param int $stackPtr The position in the stack of the function token
* to acquire the parameters for.
*
* @return array
* @throws PHP_CodeSniffer_Exception If the specified $stackPtr is not of
* type T_FUNCTION.
* type T_FUNCTION or T_CLOSURE.
*/
public function getMethodParameters($stackPtr)
{
if ($this->_tokens[$stackPtr]['code'] !== T_FUNCTION) {
throw new PHP_CodeSniffer_Exception('$stackPtr must be of type T_FUNCTION');
if ($this->_tokens[$stackPtr]['code'] !== T_FUNCTION
&& $this->_tokens[$stackPtr]['code'] !== T_CLOSURE
) {
throw new PHP_CodeSniffer_Exception('$stackPtr must be of type T_FUNCTION or T_CLOSURE');
}

$opener = $this->_tokens[$stackPtr]['parenthesis_opener'];
$closer = $this->_tokens[$stackPtr]['parenthesis_closer'];

$vars = array();
$currVar = null;
$paramStart = ($opener + 1);
$defaultStart = null;
$paramCount = 0;
$passByReference = false;
$variableLength = false;
$typeHint = '';
$nullableType = false;

for ($i = ($opener + 1); $i <= $closer; $i++) {
for ($i = $paramStart; $i <= $closer; $i++) {
// Check to see if this token has a parenthesis or bracket opener. If it does
// it's likely to be an array which might have arguments in it. This
// could cause problems in our parsing below, so lets just skip to the
Expand Down Expand Up @@ -2801,7 +2819,15 @@ public function getMethodParameters($stackPtr)
break;
case T_ARRAY_HINT:
case T_CALLABLE:
$typeHint = $this->_tokens[$i]['content'];
$typeHint .= $this->_tokens[$i]['content'];
break;
case T_SELF:
case T_PARENT:
case T_STATIC:
// Self is valid, the others invalid, but were probably intended as type hints.
if (isset($defaultStart) === false) {
$typeHint .= $this->_tokens[$i]['content'];
}
break;
case T_STRING:
// This is a string, so it may be a type hint, but it could
Expand Down Expand Up @@ -2838,6 +2864,12 @@ public function getMethodParameters($stackPtr)
$typeHint .= $this->_tokens[$i]['content'];
}
break;
case T_NULLABLE:
if ($defaultStart === null) {
$nullableType = true;
$typeHint .= $this->_tokens[$i]['content'];
}
break;
case T_CLOSE_PARENTHESIS:
case T_COMMA:
// If it's null, then there must be no parameters for this
Expand All @@ -2846,26 +2878,27 @@ public function getMethodParameters($stackPtr)
continue;
}

$vars[$paramCount] = array();
$vars[$paramCount]['name'] = $this->_tokens[$currVar]['content'];
$vars[$paramCount] = array();
$vars[$paramCount]['token'] = $currVar;
$vars[$paramCount]['name'] = $this->_tokens[$currVar]['content'];
$vars[$paramCount]['content'] = trim($this->getTokensAsString($paramStart, ($i - $paramStart)));

if ($defaultStart !== null) {
$vars[$paramCount]['default']
= $this->getTokensAsString(
$defaultStart,
($i - $defaultStart)
);
$vars[$paramCount]['default'] = trim($this->getTokensAsString($defaultStart, ($i - $defaultStart)));
}

$vars[$paramCount]['pass_by_reference'] = $passByReference;
$vars[$paramCount]['variable_length'] = $variableLength;
$vars[$paramCount]['type_hint'] = $typeHint;
$vars[$paramCount]['nullable_type'] = $nullableType;

// Reset the vars, as we are about to process the next parameter.
$defaultStart = null;
$paramStart = ($i + 1);
$passByReference = false;
$variableLength = false;
$typeHint = '';
$nullableType = false;

$paramCount++;
break;
Expand Down Expand Up @@ -3000,6 +3033,7 @@ public function getMemberProperties($stackPtr)
$ptr = array_pop($conditions);
if (isset($this->_tokens[$ptr]) === false
|| ($this->_tokens[$ptr]['code'] !== T_CLASS
&& $this->_tokens[$ptr]['code'] !== T_ANON_CLASS
&& $this->_tokens[$ptr]['code'] !== T_TRAIT)
) {
if (isset($this->_tokens[$ptr]) === true
Expand Down Expand Up @@ -3503,6 +3537,7 @@ public function findEndOfStatement($start, $ignore=null)
if ($this->_tokens[$i]['code'] === T_CLOSE_PARENTHESIS
|| $this->_tokens[$i]['code'] === T_CLOSE_SQUARE_BRACKET
|| $this->_tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET
|| $this->_tokens[$i]['code'] === T_CLOSE_SHORT_ARRAY
|| $this->_tokens[$i]['code'] === T_OPEN_TAG
|| $this->_tokens[$i]['code'] === T_CLOSE_TAG
) {
Expand Down Expand Up @@ -3682,7 +3717,9 @@ public function findExtendedClassName($stackPtr)
return false;
}

if ($this->_tokens[$stackPtr]['code'] !== T_CLASS) {
if ($this->_tokens[$stackPtr]['code'] !== T_CLASS
&& $this->_tokens[$stackPtr]['code'] !== T_ANON_CLASS
) {
return false;
}

Expand Down Expand Up @@ -3731,7 +3768,9 @@ public function findImplementedInterfaceNames($stackPtr)
return false;
}

if ($this->_tokens[$stackPtr]['code'] !== T_CLASS) {
if ($this->_tokens[$stackPtr]['code'] !== T_CLASS
&& $this->_tokens[$stackPtr]['code'] !== T_ANON_CLASS
) {
return false;
}

Expand Down
9 changes: 7 additions & 2 deletions CodeSniffer/Fixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,13 @@ public function generateDiff($filePath=null, $colors=true)
$filePath = $this->_currentFile->getFilename();
}

$cwd = getcwd().DIRECTORY_SEPARATOR;
$filename = str_replace($cwd, '', $filePath);
$cwd = getcwd().DIRECTORY_SEPARATOR;
if (strpos($filePath, $cwd) === 0) {
$filename = substr($filePath, strlen($cwd));
} else {
$filename = $filePath;
}

$contents = $this->getContents();

if (function_exists('sys_get_temp_dir') === true) {
Expand Down
Loading

0 comments on commit 384fe95

Please sign in to comment.