Skip to content

Commit

Permalink
Support multi-directive statements
Browse files Browse the repository at this point in the history
  • Loading branch information
fredden committed Jul 31, 2024
1 parent 71144b5 commit 66ddbf4
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 48 deletions.
107 changes: 59 additions & 48 deletions src/Standards/PSR12/Sniffs/Files/DeclareStatementSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,70 +82,81 @@ public function process(File $phpcsFile, $stackPtr)

$closeParen = $tokens[$openParen]['parenthesis_closer'];

$directive = $phpcsFile->findNext(T_STRING, ($openParen + 1), $closeParen);
$tokenBeforeDirective = $openParen;

if ($directive === false) {
// Live coding / parse error.
return;
}
do {
$directive = $phpcsFile->findNext(T_STRING, ($tokenBeforeDirective + 1), $closeParen);

// There should be no space between open parenthesis and the directive.
$this->complainIfTokensNotAdjacent(
$phpcsFile,
$openParen,
$directive,
'SpaceFoundBeforeDirective'
);
if ($directive === false) {
// Live coding / parse error.
return;
}

// The directive must be in lowercase.
if ($tokens[$directive]['content'] !== strtolower($tokens[$directive]['content'])) {
$error = 'The directive of a declare statement must be in lowercase';
$fix = $phpcsFile->addFixableError($error, $directive, 'DirectiveNotLowercase');
if ($fix === true) {
$phpcsFile->fixer->replaceToken($directive, strtolower($tokens[$directive]['content']));
if ($tokens[$tokenBeforeDirective]['code'] === T_OPEN_PARENTHESIS) {
// There should be no space between open parenthesis and the directive.
$this->complainIfTokensNotAdjacent(
$phpcsFile,
$tokenBeforeDirective,
$directive,
'SpaceFoundBeforeDirective'
);
// There's no 'else' clause here, because PSR12 makes no mention of
// formatting of the comma in a multi-directive statement.
}
}

// When wishing to declare strict types in files containing markup outside PHP opening
// and closing tags, the declaration MUST be on the first line of the file and include
// an opening PHP tag, the strict types declaration and closing tag.
if ($tokens[$stackPtr]['line'] !== 1 && strtolower($tokens[$directive]['content']) === 'strict_types') {
$nonPHP = $phpcsFile->findNext(T_INLINE_HTML, 0);
if ($nonPHP !== false) {
$error = 'When declaring strict_types in a file with markup outside PHP tags, the declare statement must be on the first line';
$phpcsFile->addError($error, $stackPtr, 'DeclareNotOnFirstLine');
// The directive must be in lowercase.
if ($tokens[$directive]['content'] !== strtolower($tokens[$directive]['content'])) {
$error = 'The directive of a declare statement must be in lowercase';
$fix = $phpcsFile->addFixableError($error, $directive, 'DirectiveNotLowercase');
if ($fix === true) {
$phpcsFile->fixer->replaceToken($directive, strtolower($tokens[$directive]['content']));
}
}
}

$equals = $phpcsFile->findNext(T_EQUAL, ($directive + 1), $closeParen);
// When wishing to declare strict types in files containing markup outside PHP opening
// and closing tags, the declaration MUST be on the first line of the file and include
// an opening PHP tag, the strict types declaration and closing tag.
if ($tokens[$stackPtr]['line'] !== 1 && strtolower($tokens[$directive]['content']) === 'strict_types') {
$nonPHP = $phpcsFile->findNext(T_INLINE_HTML, 0);
if ($nonPHP !== false) {
$error = 'When declaring strict_types in a file with markup outside PHP tags, the declare statement must be on the first line';
$phpcsFile->addError($error, $stackPtr, 'DeclareNotOnFirstLine');
}
}

if ($equals === false) {
// Live coding / parse error.
return;
}
$equals = $phpcsFile->findNext(T_EQUAL, ($directive + 1), $closeParen);

// There should be no space between directive and the equal sign.
$this->complainIfTokensNotAdjacent(
$phpcsFile,
$directive,
$equals,
'SpaceFoundAfterDirective'
);
if ($equals === false) {
// Live coding / parse error.
return;
}

$value = $phpcsFile->findNext([T_LNUMBER, T_CONSTANT_ENCAPSED_STRING], ($equals + 1), $closeParen);
// There should be no space between directive and the equal sign.
$this->complainIfTokensNotAdjacent(
$phpcsFile,
$directive,
$equals,
'SpaceFoundAfterDirective'
);

if ($value === false) {
// Live coding / parse error.
return;
}
$value = $phpcsFile->findNext([T_LNUMBER, T_CONSTANT_ENCAPSED_STRING], ($equals + 1), $closeParen);

// There should be no space between equals sign and directive value.
$this->complainIfTokensNotAdjacent(
if ($value === false) {
// Live coding / parse error.
return;
}

// There should be no space between equals sign and directive value.
$this->complainIfTokensNotAdjacent(
$phpcsFile,
$equals,
$value,
'SpaceFoundBeforeDirectiveValue'
);
);

// Handle multi-directive statements.
$tokenBeforeDirective = $phpcsFile->findNext(T_COMMA, $value + 1, $closeParen);
} while ($tokenBeforeDirective !== false);

// $closeParen was defined earlier as $closeParen = $tokens[$openParen]['parenthesis_closer'];
// There should be no space between directive value and closing parenthesis.
Expand Down
12 changes: 12 additions & 0 deletions src/Standards/PSR12/Tests/Files/DeclareStatementUnitTest.1.inc
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,15 @@ declare(ticks=1) { $test = true;
// Ensure that we handle non-number values properly.
declare(encoding='ISO-8859-1');
declare ( encoding = 'ISO-8859-1' ) ;

// Multi-directive statements should be handled correctly too.
declare(strict_types=1,ticks=1);
// Note that PSR12 makes no mention of the formatting of the comma, so all of these should be valid.
declare(strict_types=1, ticks=1);
declare(strict_types=1, ticks=1);
declare(strict_types=1,
ticks=1);
declare(strict_types=1,
ticks=1);
declare(strict_types=1 , ticks=1);
declare(strict_types=1 ,ticks=1);
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,15 @@ declare(ticks=1) {
// Ensure that we handle non-number values properly.
declare(encoding='ISO-8859-1');
declare(encoding='ISO-8859-1');

// Multi-directive statements should be handled correctly too.
declare(strict_types=1,ticks=1);
// Note that PSR12 makes no mention of the formatting of the comma, so all of these should be valid.
declare(strict_types=1, ticks=1);
declare(strict_types=1, ticks=1);
declare(strict_types=1,
ticks=1);
declare(strict_types=1,
ticks=1);
declare(strict_types=1 , ticks=1);
declare(strict_types=1 ,ticks=1);

0 comments on commit 66ddbf4

Please sign in to comment.