Skip to content

Commit 288e4ad

Browse files
committed
Merge branch 'master' into 4.x
2 parents c551a86 + 7fb48d6 commit 288e4ad

File tree

6 files changed

+113
-9
lines changed

6 files changed

+113
-9
lines changed

src/Standards/Generic/Sniffs/Strings/UnnecessaryHeredocSniff.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,35 @@
1515
class UnnecessaryHeredocSniff implements Sniff
1616
{
1717

18+
/**
19+
* Escape chars which are supported in heredocs, but not in nowdocs.
20+
*
21+
* @var array<string>
22+
*/
23+
private $escapeChars = [
24+
// Octal sequences.
25+
'\0',
26+
'\1',
27+
'\2',
28+
'\3',
29+
'\4',
30+
'\5',
31+
'\6',
32+
'\7',
33+
34+
// Various whitespace and the escape char.
35+
'\n',
36+
'\r',
37+
'\t',
38+
'\v',
39+
'\e',
40+
'\f',
41+
42+
// Hex and unicode sequences.
43+
'\x',
44+
'\u',
45+
];
46+
1847

1948
/**
2049
* Returns an array of tokens this test wants to listen for.
@@ -81,14 +110,33 @@ public function process(File $phpcsFile, $stackPtr)
81110

82111
$phpcsFile->recordMetric($stackPtr, 'Heredoc contains interpolation or expression', 'no');
83112

113+
// Check for escape sequences which aren't supported in nowdocs.
114+
foreach ($this->escapeChars as $testChar) {
115+
if (strpos($body, $testChar) !== false) {
116+
return;
117+
}
118+
}
119+
84120
$warning = 'Detected heredoc without interpolation or expressions. Use nowdoc syntax instead';
85121

86122
$fix = $phpcsFile->addFixableWarning($warning, $stackPtr, 'Found');
87123
if ($fix === true) {
124+
$phpcsFile->fixer->beginChangeset();
125+
88126
$identifier = trim(ltrim($tokens[$stackPtr]['content'], '<'));
89127
$replaceWith = "'".trim($identifier, '"')."'";
90128
$replacement = str_replace($identifier, $replaceWith, $tokens[$stackPtr]['content']);
91129
$phpcsFile->fixer->replaceToken($stackPtr, $replacement);
130+
131+
for ($i = ($stackPtr + 1); $i < $closer; $i++) {
132+
$content = $tokens[$i]['content'];
133+
$content = str_replace(['\\$', '\\\\'], ['$', '\\'], $content);
134+
if ($tokens[$i]['content'] !== $content) {
135+
$phpcsFile->fixer->replaceToken($i, $content);
136+
}
137+
}
138+
139+
$phpcsFile->fixer->endChangeset();
92140
}
93141

94142
}//end process()

src/Standards/Generic/Tests/Strings/UnnecessaryHeredocUnitTest.1.inc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,19 @@ END;
104104
$heredoc = <<< "END"
105105
some text
106106
some \$text
107-
some text
107+
some text \\ including a backslash
108108
END;
109+
110+
$heredoc = <<<EOD
111+
<?php
112+
echo 'The below line contains escape characters and should be recognized as needing heredoc';
113+
echo "aa\xC3\xC3 \xC3\xB8aa";
114+
EOD;
115+
116+
echo <<<EOT
117+
This should print a capital 'A': \x41
118+
EOT;
119+
120+
echo <<<EOT
121+
Here we should have a tab and 2 'A's: \t \101 \u{41}
122+
EOT;

src/Standards/Generic/Tests/Strings/UnnecessaryHeredocUnitTest.1.inc.fixed

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,20 @@ END;
103103

104104
$heredoc = <<< 'END'
105105
some text
106-
some \$text
107-
some text
106+
some $text
107+
some text \ including a backslash
108108
END;
109+
110+
$heredoc = <<<EOD
111+
<?php
112+
echo 'The below line contains escape characters and should be recognized as needing heredoc';
113+
echo "aa\xC3\xC3 \xC3\xB8aa";
114+
EOD;
115+
116+
echo <<<EOT
117+
This should print a capital 'A': \x41
118+
EOT;
119+
120+
echo <<<EOT
121+
Here we should have a tab and 2 'A's: \t \101 \u{41}
122+
EOT;

src/Standards/Generic/Tests/Strings/UnnecessaryHeredocUnitTest.2.inc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,19 @@ $heredoc = <<<END
104104
$heredoc = <<< "END"
105105
some text
106106
some \$text
107-
some text
107+
some text \\ including a backslash
108108
END;
109+
110+
$heredoc = <<<EOD
111+
<?php
112+
echo 'The below line contains escape characters and should be recognized as needing heredoc';
113+
echo "aa\xC3\xC3 \xC3\xB8aa";
114+
EOD;
115+
116+
echo <<<EOT
117+
This should print a capital 'A': \x41
118+
EOT;
119+
120+
echo <<<EOT
121+
Here we should have a tab and 2 'A's: \t \101 \u{41}
122+
EOT;

src/Standards/Generic/Tests/Strings/UnnecessaryHeredocUnitTest.2.inc.fixed

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,20 @@ $heredoc = <<<'END'
103103

104104
$heredoc = <<< 'END'
105105
some text
106-
some \$text
107-
some text
106+
some $text
107+
some text \ including a backslash
108108
END;
109+
110+
$heredoc = <<<EOD
111+
<?php
112+
echo 'The below line contains escape characters and should be recognized as needing heredoc';
113+
echo "aa\xC3\xC3 \xC3\xB8aa";
114+
EOD;
115+
116+
echo <<<EOT
117+
This should print a capital 'A': \x41
118+
EOT;
119+
120+
echo <<<EOT
121+
Here we should have a tab and 2 'A's: \t \101 \u{41}
122+
EOT;

src/Standards/PSR2/Docs/Namespaces/NamespaceDeclarationStandard.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<documentation title="Namespace Declarations">
1+
<documentation title="Namespace Declaration">
22
<standard>
33
<![CDATA[
44
There must be one blank line after the namespace declaration.
@@ -7,14 +7,14 @@
77
<code_comparison>
88
<code title="Valid: One blank line after the namespace declaration.">
99
<![CDATA[
10-
namespace \Foo\Bar;
10+
namespace Foo\Bar;
1111
<em></em>
1212
use \Baz;
1313
]]>
1414
</code>
1515
<code title="Invalid: No blank line after the namespace declaration.">
1616
<![CDATA[
17-
namespace \Foo\Bar;
17+
namespace Foo\Bar;
1818
use \Baz;
1919
]]>
2020
</code>

0 commit comments

Comments
 (0)