-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The phpcs:disable and phpcs:ignore comments can now selectively ignor…
…e specific sniffs (request #604)
- Loading branch information
Showing
4 changed files
with
433 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -151,7 +151,7 @@ private function createPositionMap() | |
$currColumn = 1; | ||
$lineNumber = 1; | ||
$eolLen = (strlen($this->eolChar) * -1); | ||
$ignoring = false; | ||
$ignoring = null; | ||
$inTests = defined('PHP_CODESNIFFER_IN_TESTS'); | ||
|
||
$checkEncoding = false; | ||
|
@@ -225,38 +225,72 @@ private function createPositionMap() | |
|| ($inTests === true && $this->tokens[$i]['code'] === T_INLINE_HTML)) | ||
) { | ||
$commentText = ltrim($this->tokens[$i]['content'], ' /*'); | ||
$commentText = rtrim($commentText, " */\r\n"); | ||
$commentTextLower = strtolower($commentText); | ||
if (strpos($commentText, '@codingStandards') !== false) { | ||
if ($ignoring === false | ||
// If this comment is the only thing on the line, it tells us | ||
// to ignore the following line. If the line contains other content | ||
// then we are just ignoring this one single line. | ||
$ownLine = false; | ||
for ($prev = ($i - 1); $prev >= 0; $prev--) { | ||
if ($this->tokens[$prev]['code'] === T_WHITESPACE) { | ||
continue; | ||
} | ||
|
||
break; | ||
} | ||
|
||
if ($this->tokens[$prev]['line'] !== $this->tokens[$i]['line']) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
jrfnl
Contributor
|
||
$ownLine = true; | ||
} | ||
|
||
if ($ignoring === null | ||
&& strpos($commentText, '@codingStandardsIgnoreStart') !== false | ||
) { | ||
$ignoring = true; | ||
} else if ($ignoring === true | ||
$ignoring = array('all' => true); | ||
if ($ownLine === true) { | ||
$this->ignoredLines[$this->tokens[$i]['line']] = array('all' => true); | ||
} | ||
} else if ($ignoring !== null | ||
&& strpos($commentText, '@codingStandardsIgnoreEnd') !== false | ||
) { | ||
$ignoring = false; | ||
// Ignore this comment too. | ||
$this->ignoredLines[$this->tokens[$i]['line']] = true; | ||
} else if ($ignoring === false | ||
if ($ownLine === true) { | ||
$this->ignoredLines[$this->tokens[$i]['line']] = array('all' => true); | ||
} else { | ||
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring; | ||
} | ||
|
||
$ignoring = null; | ||
} else if ($ignoring === null | ||
&& strpos($commentText, '@codingStandardsIgnoreLine') !== false | ||
) { | ||
// If this comment is the only thing on the line, it tells us | ||
// to ignore the following line. If the line contains other content | ||
// then we are just ignoring this one single line. | ||
$this->ignoredLines[$this->tokens[$i]['line']] = true; | ||
for ($prev = ($i - 1); $prev >= 0; $prev--) { | ||
if ($this->tokens[$prev]['code'] === T_WHITESPACE) { | ||
continue; | ||
} | ||
|
||
break; | ||
$ignoring = array('all' => true); | ||
if ($ownLine === true) { | ||
$this->ignoredLines[$this->tokens[$i]['line']] = array('all' => true); | ||
$this->ignoredLines[($this->tokens[$i]['line'] + 1)] = $ignoring; | ||
} else { | ||
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring; | ||
} | ||
|
||
if ($this->tokens[$prev]['line'] !== $this->tokens[$i]['line']) { | ||
$this->ignoredLines[($this->tokens[$i]['line'] + 1)] = true; | ||
} | ||
$ignoring = null; | ||
}//end if | ||
} else if (substr($commentTextLower, 0, 6) === 'phpcs:') { | ||
// If this comment is the only thing on the line, it tells us | ||
// to ignore the following line. If the line contains other content | ||
// then we are just ignoring this one single line. | ||
$ownLine = false; | ||
for ($prev = ($i - 1); $prev >= 0; $prev--) { | ||
if ($this->tokens[$prev]['code'] === T_WHITESPACE) { | ||
continue; | ||
} | ||
|
||
break; | ||
} | ||
|
||
if ($this->tokens[$prev]['line'] !== $this->tokens[$i]['line']) { | ||
$ownLine = true; | ||
} | ||
|
||
if (substr($commentTextLower, 0, 9) === 'phpcs:set') { | ||
// Ignore standards for lines that change sniff settings. | ||
$this->ignoredLines[$this->tokens[$i]['line']] = true; | ||
|
@@ -266,46 +300,103 @@ private function createPositionMap() | |
// The whole file will be ignored, but at least set the correct token. | ||
$this->tokens[$i]['code'] = T_PHPCS_IGNORE_FILE; | ||
$this->tokens[$i]['type'] = 'T_PHPCS_IGNORE_FILE'; | ||
} else if ($ignoring === false | ||
&& substr($commentTextLower, 0, 13) === 'phpcs:disable' | ||
) { | ||
$ignoring = true; | ||
$this->tokens[$i]['code'] = T_PHPCS_DISABLE; | ||
$this->tokens[$i]['type'] = 'T_PHPCS_DISABLE'; | ||
} else if ($ignoring === true | ||
} else if (substr($commentTextLower, 0, 13) === 'phpcs:disable') { | ||
if ($ownLine === true) { | ||
// Completely ignore the comment line. | ||
$this->ignoredLines[$this->tokens[$i]['line']] = array('all' => true); | ||
} | ||
|
||
if ($ignoring === null) { | ||
$ignoring = array(); | ||
} | ||
|
||
$disabledSniffs = array(); | ||
|
||
$additionalText = substr($commentText, 14); | ||
if ($additionalText === false) { | ||
$ignoring = array('all' => true); | ||
} else { | ||
$parts = explode(',', substr($commentText, 13)); | ||
foreach ($parts as $sniffCode) { | ||
$sniffCode = trim($sniffCode); | ||
$disabledSniffs[$sniffCode] = true; | ||
$ignoring[$sniffCode] = true; | ||
} | ||
} | ||
|
||
$this->tokens[$i]['code'] = T_PHPCS_DISABLE; | ||
$this->tokens[$i]['type'] = 'T_PHPCS_DISABLE'; | ||
$this->tokens[$i]['sniffCodes'] = $disabledSniffs; | ||
} else if ($ignoring !== null | ||
&& substr($commentTextLower, 0, 12) === 'phpcs:enable' | ||
) { | ||
$ignoring = false; | ||
$this->ignoredLines[$this->tokens[$i]['line']] = true; | ||
$this->tokens[$i]['code'] = T_PHPCS_ENABLE; | ||
$this->tokens[$i]['type'] = 'T_PHPCS_ENABLE'; | ||
} else if ($ignoring === false | ||
$enabledSniffs = array(); | ||
|
||
$additionalText = substr($commentText, 13); | ||
if ($additionalText === false) { | ||
$ignoring = null; | ||
} else { | ||
$parts = explode(',', substr($commentText, 13)); | ||
foreach ($parts as $sniffCode) { | ||
$sniffCode = trim($sniffCode); | ||
$enabledSniffs[$sniffCode] = true; | ||
if (isset($ignoring[$sniffCode]) === true) { | ||
unset($ignoring[$sniffCode]); | ||
} | ||
} | ||
|
||
if (empty($ignoring) === true) { | ||
$ignoring = null; | ||
} | ||
} | ||
|
||
if ($ownLine === true) { | ||
// Completely ignore the comment line. | ||
$this->ignoredLines[$this->tokens[$i]['line']] = array('all' => true); | ||
} else { | ||
// The comment is on the same line as the code it is ignoring, | ||
// so respect the new ignore rules. | ||
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring; | ||
} | ||
|
||
$this->tokens[$i]['code'] = T_PHPCS_ENABLE; | ||
$this->tokens[$i]['type'] = 'T_PHPCS_ENABLE'; | ||
$this->tokens[$i]['sniffCodes'] = $enabledSniffs; | ||
} else if ($ignoring === null | ||
&& substr($commentTextLower, 0, 12) === 'phpcs:ignore' | ||
) { | ||
// If this comment is the only thing on the line, it tells us | ||
// to ignore the following line. If the line contains other content | ||
// then we are just ignoring this one single line. | ||
$this->ignoredLines[$this->tokens[$i]['line']] = true; | ||
for ($prev = ($i - 1); $prev >= 0; $prev--) { | ||
if ($this->tokens[$prev]['code'] === T_WHITESPACE) { | ||
continue; | ||
} | ||
$ignoreRules = array(); | ||
|
||
break; | ||
$additionalText = substr($commentText, 13); | ||
if ($additionalText === false) { | ||
$ignoreRules = array('all' => true); | ||
} else { | ||
$parts = explode(',', substr($commentText, 13)); | ||
foreach ($parts as $sniffCode) { | ||
$ignoreRules[trim($sniffCode)] = true; | ||
} | ||
} | ||
|
||
if ($this->tokens[$prev]['line'] !== $this->tokens[$i]['line']) { | ||
$this->ignoredLines[($this->tokens[$i]['line'] + 1)] = true; | ||
if ($ownLine === true) { | ||
// Completely ignore the comment line, and set the folllowing | ||
// line to include the ignore rules we've set. | ||
$this->ignoredLines[$this->tokens[$i]['line']] = array('all' => true); | ||
$this->ignoredLines[($this->tokens[$i]['line'] + 1)] = $ignoreRules; | ||
} else { | ||
// The comment is on the same line as the code it is ignoring, | ||
// so respect the ignore rules it set. | ||
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoreRules; | ||
} | ||
|
||
$this->tokens[$i]['code'] = T_PHPCS_IGNORE; | ||
$this->tokens[$i]['type'] = 'T_PHPCS_IGNORE'; | ||
$this->tokens[$i]['code'] = T_PHPCS_IGNORE; | ||
$this->tokens[$i]['type'] = 'T_PHPCS_IGNORE'; | ||
$this->tokens[$i]['sniffCodes'] = $ignoreRules; | ||
}//end if | ||
}//end if | ||
}//end if | ||
|
||
if ($ignoring === true) { | ||
$this->ignoredLines[$this->tokens[$i]['line']] = true; | ||
if ($ignoring !== null && isset($this->ignoredLines[$this->tokens[$i]['line']]) === false) { | ||
$this->ignoredLines[$this->tokens[$i]['line']] = $ignoring; | ||
} | ||
}//end for | ||
|
||
|
Oops, something went wrong.
This change causes an
Undefined offset -1
error when a@codingStandardsChangeSetting
command is at the very start of a (mixed HTML/PHP) file. Either thefor()
should be wrapped in aif ($i !== 0) {}
or some other defensive coding check is needed.See: https://travis-ci.org/WordPress-Coding-Standards/WordPress-Coding-Standards/jobs/295128540
Came across this with test case files for WPCS where properties need to be set before the
T_OPEN_TAG
, like for a filename sniff.