Skip to content

Commit 359e5a1

Browse files
dmvdbruggeSpacePossum
authored andcommitted
SimpleToComplexStringVariableFixer - Introduction
1 parent e6285fd commit 359e5a1

23 files changed

+316
-90
lines changed

README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,6 +1696,11 @@ Choose from the list of available rules:
16961696

16971697
*Risky rule: silencing of deprecation errors might cause changes to code behaviour.*
16981698

1699+
* **simple_to_complex_string_variable** [@PhpCsFixer]
1700+
1701+
Converts explicit variables in double-quoted strings and heredoc syntax
1702+
from simple to complex format (``${`` to ``{$``).
1703+
16991704
* **simplified_null_return**
17001705

17011706
A return statement wishing to return ``void`` should not return ``null``.

src/Console/Output/ErrorOutput.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function listErrors($process, array $errors)
6565
$message = $e->getMessage();
6666
$code = $e->getCode();
6767
if (0 !== $code) {
68-
$message .= " (${code})";
68+
$message .= " ({$code})";
6969
}
7070

7171
$length = max(\strlen($class), \strlen($message));

src/DocBlock/Tag.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public function setName($name)
9494
throw new \RuntimeException('Cannot set name on unknown tag.');
9595
}
9696

97-
$this->line->setContent(Preg::replace("/@${current}/", "@${name}", $this->line->getContent(), 1));
97+
$this->line->setContent(Preg::replace("/@{$current}/", "@{$name}", $this->line->getContent(), 1));
9898

9999
$this->name = $name;
100100
}

src/Fixer/ControlStructure/NoBreakCommentFixer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ private function isNoBreakComment(Token $token)
184184

185185
$text = preg_quote($this->configuration['comment_text'], '~');
186186

187-
return 1 === Preg::match("~^((//|#)\\s*${text}\\s*)|(/\\*\\*?\\s*${text}\\s*\\*/)$~i", $token->getContent());
187+
return 1 === Preg::match("~^((//|#)\\s*{$text}\\s*)|(/\\*\\*?\\s*{$text}\\s*\\*/)$~i", $token->getContent());
188188
}
189189

190190
/**

src/Fixer/PhpUnit/PhpUnitInternalClassFixer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private function createDocBlock(Tokens $tokens, $docBlockIndex)
132132
$lineEnd = $this->whitespacesConfig->getLineEnding();
133133
$originalIndent = $this->detectIndent($tokens, $tokens->getNextNonWhitespace($docBlockIndex));
134134
$toInsert = [
135-
new Token([T_DOC_COMMENT, '/**'.$lineEnd."${originalIndent} * @internal".$lineEnd."${originalIndent} */"]),
135+
new Token([T_DOC_COMMENT, '/**'.$lineEnd."{$originalIndent} * @internal".$lineEnd."{$originalIndent} */"]),
136136
new Token([T_WHITESPACE, $lineEnd.$originalIndent]),
137137
];
138138
$index = $tokens->getNextMeaningfulToken($docBlockIndex);

src/Fixer/PhpUnit/PhpUnitNoExpectationAnnotationFixer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ private function annotationsToParamList(array $annotations)
280280
if ($this->configuration['use_class_const']) {
281281
$params[] = $exceptionClass.'::class';
282282
} else {
283-
$params[] = "'${exceptionClass}'";
283+
$params[] = "'{$exceptionClass}'";
284284
}
285285

286286
if (isset($annotations['expectedExceptionMessage'])) {

src/Fixer/PhpUnit/PhpUnitTestAnnotationFixer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ private function createDocBlock(Tokens $tokens, $docBlockIndex)
346346
$lineEnd = $this->whitespacesConfig->getLineEnding();
347347
$originalIndent = $this->detectIndent($tokens, $tokens->getNextNonWhitespace($docBlockIndex));
348348
$toInsert = [
349-
new Token([T_DOC_COMMENT, '/**'.$lineEnd."${originalIndent} * @test".$lineEnd."${originalIndent} */"]),
349+
new Token([T_DOC_COMMENT, '/**'.$lineEnd."{$originalIndent} * @test".$lineEnd."{$originalIndent} */"]),
350350
new Token([T_WHITESPACE, $lineEnd.$originalIndent]),
351351
];
352352
$index = $tokens->getNextMeaningfulToken($docBlockIndex);
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
/*
4+
* This file is part of PHP CS Fixer.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
* Dariusz Rumiński <dariusz.ruminski@gmail.com>
8+
*
9+
* This source file is subject to the MIT license that is bundled
10+
* with this source code in the file LICENSE.
11+
*/
12+
13+
namespace PhpCsFixer\Fixer\StringNotation;
14+
15+
use PhpCsFixer\AbstractFixer;
16+
use PhpCsFixer\FixerDefinition\CodeSample;
17+
use PhpCsFixer\FixerDefinition\FixerDefinition;
18+
use PhpCsFixer\Tokenizer\CT;
19+
use PhpCsFixer\Tokenizer\Token;
20+
use PhpCsFixer\Tokenizer\Tokens;
21+
22+
/**
23+
* @author Dave van der Brugge <dmvdbrugge@gmail.com>
24+
*/
25+
final class SimpleToComplexStringVariableFixer extends AbstractFixer
26+
{
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
public function getDefinition()
31+
{
32+
return new FixerDefinition(
33+
'Converts explicit variables in double-quoted strings and heredoc syntax from simple to complex format (`${` to `{$`).',
34+
[
35+
new CodeSample(
36+
<<<'EOT'
37+
<?php
38+
$name = 'World';
39+
echo "Hello ${name}!";
40+
41+
EOT
42+
),
43+
new CodeSample(
44+
<<<'EOT'
45+
<?php
46+
$name = 'World';
47+
echo <<<TEST
48+
Hello ${name}!
49+
TEST;
50+
51+
EOT
52+
),
53+
],
54+
"Doesn't touch implicit variables. Works together nicely with `explicit_string_variable`."
55+
);
56+
}
57+
58+
/**
59+
* {@inheritdoc}
60+
*/
61+
public function getPriority()
62+
{
63+
// should run after ExplicitStringVariableFixer
64+
return -10;
65+
}
66+
67+
/**
68+
* {@inheritdoc}
69+
*/
70+
public function isCandidate(Tokens $tokens)
71+
{
72+
return $tokens->isTokenKindFound(T_DOLLAR_OPEN_CURLY_BRACES);
73+
}
74+
75+
protected function applyFix(\SplFileInfo $file, Tokens $tokens)
76+
{
77+
for ($index = \count($tokens) - 3; $index > 0; --$index) {
78+
$token = $tokens[$index];
79+
80+
if (!$token->isGivenKind(T_DOLLAR_OPEN_CURLY_BRACES)) {
81+
continue;
82+
}
83+
84+
$varnameToken = $tokens[$index + 1];
85+
86+
if (!$varnameToken->isGivenKind(T_STRING_VARNAME)) {
87+
continue;
88+
}
89+
90+
$dollarCloseToken = $tokens[$index + 2];
91+
92+
if (!$dollarCloseToken->isGivenKind(CT::T_DOLLAR_CLOSE_CURLY_BRACES)) {
93+
continue;
94+
}
95+
96+
$tokens->overrideRange($index, $index + 2, [
97+
new Token([T_CURLY_OPEN, '{']),
98+
new Token([T_VARIABLE, '$'.$varnameToken->getContent()]),
99+
new Token([CT::T_CURLY_CLOSE, '}']),
100+
]);
101+
}
102+
}
103+
}

src/RuleSet.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ final class RuleSet implements RuleSetInterface
254254
'phpdoc_types_order' => true,
255255
'phpdoc_var_annotation_correct_order' => true,
256256
'return_assignment' => true,
257+
'simple_to_complex_string_variable' => true,
257258
'single_line_comment_style' => true,
258259
],
259260
'@PhpCsFixer:risky' => [

tests/AutoReview/FixerFactoryTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public function provideFixersPriorityCases()
8888
[$fixers['elseif'], $fixers['braces']],
8989
[$fixers['escape_implicit_backslashes'], $fixers['heredoc_to_nowdoc']],
9090
[$fixers['escape_implicit_backslashes'], $fixers['single_quote']],
91+
[$fixers['explicit_string_variable'], $fixers['simple_to_complex_string_variable']],
9192
[$fixers['fully_qualified_strict_types'], $fixers['no_superfluous_phpdoc_tags']],
9293
[$fixers['function_to_constant'], $fixers['native_function_casing']],
9394
[$fixers['function_to_constant'], $fixers['no_extra_blank_lines']],

0 commit comments

Comments
 (0)