Skip to content

Commit 8f89123

Browse files
committed
Support multi-directive statements
1 parent 71144b5 commit 8f89123

File tree

3 files changed

+87
-52
lines changed

3 files changed

+87
-52
lines changed

src/Standards/PSR12/Sniffs/Files/DeclareStatementSniff.php

+63-52
Original file line numberDiff line numberDiff line change
@@ -82,70 +82,81 @@ public function process(File $phpcsFile, $stackPtr)
8282

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

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

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

92-
// There should be no space between open parenthesis and the directive.
93-
$this->complainIfTokensNotAdjacent(
94-
$phpcsFile,
95-
$openParen,
96-
$directive,
97-
'SpaceFoundBeforeDirective'
98-
);
90+
if ($directive === false) {
91+
// Live coding / parse error.
92+
return;
93+
}
9994

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

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

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

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

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

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

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

142-
// There should be no space between equals sign and directive value.
143-
$this->complainIfTokensNotAdjacent(
144-
$phpcsFile,
145-
$equals,
146-
$value,
147-
'SpaceFoundBeforeDirectiveValue'
148-
);
144+
if ($value === false) {
145+
// Live coding / parse error.
146+
return;
147+
}
148+
149+
// There should be no space between equals sign and directive value.
150+
$this->complainIfTokensNotAdjacent(
151+
$phpcsFile,
152+
$equals,
153+
$value,
154+
'SpaceFoundBeforeDirectiveValue'
155+
);
156+
157+
// Handle multi-directive statements.
158+
$tokenBeforeDirective = $phpcsFile->findNext(T_COMMA, ($value + 1), $closeParen);
159+
} while ($tokenBeforeDirective !== false);
149160

150161
// $closeParen was defined earlier as $closeParen = $tokens[$openParen]['parenthesis_closer'];
151162
// There should be no space between directive value and closing parenthesis.

src/Standards/PSR12/Tests/Files/DeclareStatementUnitTest.1.inc

+12
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,15 @@ declare(ticks=1) { $test = true;
5252
// Ensure that we handle non-number values properly.
5353
declare(encoding='ISO-8859-1');
5454
declare ( encoding = 'ISO-8859-1' ) ;
55+
56+
// Multi-directive statements should be handled correctly too.
57+
declare(strict_types=1,ticks=1);
58+
// Note that PSR12 makes no mention of the formatting of the comma, so all of these should be valid.
59+
declare(strict_types=1, ticks=1);
60+
declare(strict_types=1, ticks=1);
61+
declare(strict_types=1,
62+
ticks=1);
63+
declare(strict_types=1,
64+
ticks=1);
65+
declare(strict_types=1 , ticks=1);
66+
declare(strict_types=1 ,ticks=1);

src/Standards/PSR12/Tests/Files/DeclareStatementUnitTest.1.inc.fixed

+12
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,15 @@ declare(ticks=1) {
6060
// Ensure that we handle non-number values properly.
6161
declare(encoding='ISO-8859-1');
6262
declare(encoding='ISO-8859-1');
63+
64+
// Multi-directive statements should be handled correctly too.
65+
declare(strict_types=1,ticks=1);
66+
// Note that PSR12 makes no mention of the formatting of the comma, so all of these should be valid.
67+
declare(strict_types=1, ticks=1);
68+
declare(strict_types=1, ticks=1);
69+
declare(strict_types=1,
70+
ticks=1);
71+
declare(strict_types=1,
72+
ticks=1);
73+
declare(strict_types=1 , ticks=1);
74+
declare(strict_types=1 ,ticks=1);

0 commit comments

Comments
 (0)