• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

keradus / PHP-CS-Fixer / 17252691116

26 Aug 2025 11:09PM UTC coverage: 94.743% (-0.01%) from 94.755%
17252691116

push

github

keradus
chore: apply phpdoc_tag_no_named_arguments

28313 of 29884 relevant lines covered (94.74%)

45.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.97
/src/Fixer/StringNotation/HeredocToNowdocFixer.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of PHP CS Fixer.
7
 *
8
 * (c) Fabien Potencier <fabien@symfony.com>
9
 *     Dariusz RumiƄski <dariusz.ruminski@gmail.com>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14

15
namespace PhpCsFixer\Fixer\StringNotation;
16

17
use PhpCsFixer\AbstractFixer;
18
use PhpCsFixer\FixerDefinition\CodeSample;
19
use PhpCsFixer\FixerDefinition\FixerDefinition;
20
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
21
use PhpCsFixer\Preg;
22
use PhpCsFixer\Tokenizer\Token;
23
use PhpCsFixer\Tokenizer\Tokens;
24

25
/**
26
 * @author Gregor Harlan <gharlan@web.de>
27
 *
28
 * @no-named-arguments Parameter names are not covered by the backward compatibility promise.
29
 */
30
final class HeredocToNowdocFixer extends AbstractFixer
31
{
32
    public function getDefinition(): FixerDefinitionInterface
33
    {
34
        return new FixerDefinition(
3✔
35
            'Convert `heredoc` to `nowdoc` where possible.',
3✔
36
            [
3✔
37
                new CodeSample(
3✔
38
                    <<<'EOF'
3✔
39
                        <?php $a = <<<"TEST"
40
                        Foo
41
                        TEST;
42

43
                        EOF
3✔
44
                ),
3✔
45
            ]
3✔
46
        );
3✔
47
    }
48

49
    /**
50
     * {@inheritdoc}
51
     *
52
     * Must run after EscapeImplicitBackslashesFixer, StringImplicitBackslashesFixer.
53
     */
54
    public function getPriority(): int
55
    {
56
        return 0;
1✔
57
    }
58

59
    public function isCandidate(Tokens $tokens): bool
60
    {
61
        return $tokens->isTokenKindFound(\T_START_HEREDOC);
34✔
62
    }
63

64
    protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
65
    {
66
        foreach ($tokens as $index => $token) {
34✔
67
            if (!$token->isGivenKind(\T_START_HEREDOC) || str_contains($token->getContent(), "'")) {
34✔
68
                continue;
34✔
69
            }
70

71
            if ($tokens[$index + 1]->isGivenKind(\T_END_HEREDOC)) {
31✔
72
                $tokens[$index] = $this->convertToNowdoc($token);
3✔
73

74
                continue;
3✔
75
            }
76

77
            if (
78
                !$tokens[$index + 1]->isGivenKind(\T_ENCAPSED_AND_WHITESPACE)
28✔
79
                || !$tokens[$index + 2]->isGivenKind(\T_END_HEREDOC)
28✔
80
            ) {
81
                continue;
12✔
82
            }
83

84
            $content = $tokens[$index + 1]->getContent();
16✔
85
            // regex: odd number of backslashes, not followed by dollar
86
            if (Preg::match('/(?<!\\\)(?:\\\{2})*\\\(?![$\\\])/', $content)) {
16✔
87
                continue;
×
88
            }
89

90
            $tokens[$index] = $this->convertToNowdoc($token);
16✔
91
            $content = str_replace(['\\\\', '\$'], ['\\', '$'], $content);
16✔
92
            $tokens[$index + 1] = new Token([
16✔
93
                $tokens[$index + 1]->getId(),
16✔
94
                $content,
16✔
95
            ]);
16✔
96
        }
97
    }
98

99
    /**
100
     * Transforms the heredoc start token to nowdoc notation.
101
     */
102
    private function convertToNowdoc(Token $token): Token
103
    {
104
        return new Token([
19✔
105
            $token->getId(),
19✔
106
            Preg::replace('/^([Bb]?<<<)(\h*)"?([^\s"]+)"?/', '$1$2\'$3\'', $token->getContent()),
19✔
107
        ]);
19✔
108
    }
109
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc