Skip to content

File::getDeclarationName(): stop accepting tokens for non-named structures #1007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions src/Files/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -1204,20 +1204,15 @@ public function getFilename()
* @param int $stackPtr The position of the declaration token which
* declared the class, interface, trait, or function.
*
* @return string|null The name of the class, interface, trait, or function;
* or NULL if the function or class is anonymous.
* @return string The name of the class, interface, trait, or function or an empty string
* if the name could not be determined (live coding).
* @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified token is not of type
* T_FUNCTION, T_CLASS, T_ANON_CLASS,
* T_CLOSURE, T_TRAIT, T_ENUM, or T_INTERFACE.
* T_FUNCTION, T_CLASS, T_TRAIT, T_ENUM, or T_INTERFACE.
*/
public function getDeclarationName($stackPtr)
{
$tokenCode = $this->tokens[$stackPtr]['code'];

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

if ($tokenCode !== T_FUNCTION
&& $tokenCode !== T_CLASS
&& $tokenCode !== T_INTERFACE
Expand All @@ -1236,7 +1231,7 @@ public function getDeclarationName($stackPtr)
$stopPoint = $this->tokens[$stackPtr]['scope_opener'];
}

$content = null;
$content = '';
for ($i = $stackPtr; $i < $stopPoint; $i++) {
if ($this->tokens[$i]['code'] === T_STRING) {
$content = $this->tokens[$i]['content'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,10 @@ public function process(File $phpcsFile, $stackPtr)
$classPtr = $phpcsFile->getCondition($stackPtr, T_CLASS);
if ($classPtr !== false) {
// Check for magic methods and ignore these as the method signature cannot be changed.
$methodName = $phpcsFile->getDeclarationName($stackPtr);
if (empty($methodName) === false) {
$methodNameLc = strtolower($methodName);
if (isset($this->magicMethods[$methodNameLc]) === true) {
return;
}
$methodName = $phpcsFile->getDeclarationName($stackPtr);
$methodNameLc = strtolower($methodName);
if (isset($this->magicMethods[$methodNameLc]) === true) {
return;
}

// Check for extends/implements and adjust the error code when found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function process(File $phpcsFile, $stackPtr)
}

$className = $phpcsFile->getDeclarationName($stackPtr);
if ($className === null) {
if ($className === '') {
// Live coding or parse error.
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScop
}

$methodName = $phpcsFile->getDeclarationName($stackPtr);
if ($methodName === null) {
if ($methodName === '') {
// Live coding or parse error. Bow out.
return;
}

$className = $phpcsFile->getDeclarationName($currScope);
if (isset($className) === false) {
$className = '[Anonymous Class]';
$className = '[Anonymous Class]';
if ($tokens[$currScope]['code'] !== T_ANON_CLASS) {
$className = $phpcsFile->getDeclarationName($currScope);
}

$errorData = [$className.'::'.$methodName];
Expand Down Expand Up @@ -187,7 +187,7 @@ protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScop
protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
{
$functionName = $phpcsFile->getDeclarationName($stackPtr);
if ($functionName === null) {
if ($functionName === '') {
// Live coding or parse error. Bow out.
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,9 @@ protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScop
return;
}

$className = $phpcsFile->getDeclarationName($currScope);
if (empty($className) === false) {
// Not an anonymous class.
$className = strtolower($className);
$className = '[Anonymous Class]';
if ($tokens[$currScope]['code'] !== T_ANON_CLASS) {
$className = strtolower($phpcsFile->getDeclarationName($currScope));
}

if ($className !== $this->currentClass) {
Expand All @@ -79,7 +78,7 @@ protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScop
}

$methodName = $phpcsFile->getDeclarationName($stackPtr);
if ($methodName === null) {
if ($methodName === '') {
// Live coding or parse error. Bow out.
return;
}
Expand Down Expand Up @@ -170,7 +169,7 @@ protected function loadFunctionNamesInScope(File $phpcsFile, $currScope)
}

$methodName = $phpcsFile->getDeclarationName($i);
if ($methodName === null) {
if ($methodName === '') {
// Live coding or parse error. Ignore.
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function register()
public function process(File $phpcsFile, $stackPtr)
{
$interfaceName = $phpcsFile->getDeclarationName($stackPtr);
if ($interfaceName === null) {
if ($interfaceName === '') {
// Live coding or parse error. Bow out.
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function register()
public function process(File $phpcsFile, $stackPtr)
{
$traitName = $phpcsFile->getDeclarationName($stackPtr);
if ($traitName === null) {
if ($traitName === '') {
// Live coding or parse error. Bow out.
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

// Intentional parse error (missing method name). This should be the only test in the file.

class Bar {
function {
parent::CallMe();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

// Intentional parse error (missing method name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.

$anon = class {
public function {}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

// Intentional parse error (missing method name when gathering list).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.

class LiveCoding {
public function __construct() {}
public function {}
public function myMethod() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

// Intentional parse error (missing method name when gathering list).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.

$anon = class {
public function __construct() {}
public function {}
public function myMethod() {}
};
72 changes: 37 additions & 35 deletions src/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,47 +94,49 @@ public function process(File $phpcsFile, $stackPtr)
// and the opening parenthesis.
// Unfinished closures are tokenized as T_FUNCTION however, and can be excluded
// by checking if the function has a name.
$methodProps = $phpcsFile->getMethodProperties($stackPtr);
$methodName = $phpcsFile->getDeclarationName($stackPtr);
if ($tokens[$stackPtr]['code'] === T_FUNCTION && $methodName !== null) {
if ($tokens[($openBracket - 1)]['content'] === $phpcsFile->eolChar) {
$spaces = 'newline';
} else if ($tokens[($openBracket - 1)]['code'] === T_WHITESPACE) {
$spaces = $tokens[($openBracket - 1)]['length'];
} else {
$spaces = 0;
}

if ($spaces !== 0) {
$error = 'Expected 0 spaces before opening parenthesis; %s found';
$data = [$spaces];
$fix = $phpcsFile->addFixableError($error, $openBracket, 'SpaceBeforeOpenParen', $data);
if ($fix === true) {
$phpcsFile->fixer->replaceToken(($openBracket - 1), '');
if ($tokens[$stackPtr]['code'] === T_FUNCTION) {
$methodProps = $phpcsFile->getMethodProperties($stackPtr);
$methodName = $phpcsFile->getDeclarationName($stackPtr);
if ($methodName !== '') {
if ($tokens[($openBracket - 1)]['content'] === $phpcsFile->eolChar) {
$spaces = 'newline';
} else if ($tokens[($openBracket - 1)]['code'] === T_WHITESPACE) {
$spaces = $tokens[($openBracket - 1)]['length'];
} else {
$spaces = 0;
}
}

// Must be no space before semicolon in abstract/interface methods.
if ($methodProps['has_body'] === false) {
$end = $phpcsFile->findNext(T_SEMICOLON, $closeBracket);
if ($end !== false) {
if ($tokens[($end - 1)]['content'] === $phpcsFile->eolChar) {
$spaces = 'newline';
} else if ($tokens[($end - 1)]['code'] === T_WHITESPACE) {
$spaces = $tokens[($end - 1)]['length'];
} else {
$spaces = 0;
if ($spaces !== 0) {
$error = 'Expected 0 spaces before opening parenthesis; %s found';
$data = [$spaces];
$fix = $phpcsFile->addFixableError($error, $openBracket, 'SpaceBeforeOpenParen', $data);
if ($fix === true) {
$phpcsFile->fixer->replaceToken(($openBracket - 1), '');
}
}

if ($spaces !== 0) {
$error = 'Expected 0 spaces before semicolon; %s found';
$data = [$spaces];
$fix = $phpcsFile->addFixableError($error, $end, 'SpaceBeforeSemicolon', $data);
if ($fix === true) {
$phpcsFile->fixer->replaceToken(($end - 1), '');
// Must be no space before semicolon in abstract/interface methods.
if ($methodProps['has_body'] === false) {
$end = $phpcsFile->findNext(T_SEMICOLON, $closeBracket);
if ($end !== false) {
if ($tokens[($end - 1)]['content'] === $phpcsFile->eolChar) {
$spaces = 'newline';
} else if ($tokens[($end - 1)]['code'] === T_WHITESPACE) {
$spaces = $tokens[($end - 1)]['length'];
} else {
$spaces = 0;
}

if ($spaces !== 0) {
$error = 'Expected 0 spaces before semicolon; %s found';
$data = [$spaces];
$fix = $phpcsFile->addFixableError($error, $end, 'SpaceBeforeSemicolon', $data);
if ($fix === true) {
$phpcsFile->fixer->replaceToken(($end - 1), '');
}
}
}
}
}//end if
}//end if
}//end if

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScop
}

$methodName = $phpcsFile->getDeclarationName($stackPtr);
if ($methodName === null) {
// Ignore closures.
if ($methodName === '') {
// Ignore live coding.
return;
}

$className = $phpcsFile->getDeclarationName($currScope);
if (isset($className) === false) {
$className = '[Anonymous Class]';
$className = '[Anonymous Class]';
if ($tokens[$currScope]['code'] !== T_ANON_CLASS) {
$className = $phpcsFile->getDeclarationName($currScope);
}

$errorData = [$className.'::'.$methodName];
Expand Down Expand Up @@ -181,11 +181,6 @@ protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScop
protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
{
$functionName = $phpcsFile->getDeclarationName($stackPtr);
if ($functionName === null) {
// Ignore closures.
return;
}

if (ltrim($functionName, '_') === '') {
// Ignore special functions.
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

// Intentional parse error (missing interface name). This should be the only test in the file.

namespace Vendor\Package;

interface
Loading