Passed
Push — master ( 359688...c508dd )
by Théo
02:20
created

NewdocPrefixer::enterNode()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5.0342

Importance

Changes 0
Metric Value
cc 5
nc 6
nop 1
dl 0
loc 20
ccs 8
cts 9
cp 0.8889
crap 5.0342
rs 9.2888
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the humbug/php-scoper package.
7
 *
8
 * Copyright (c) 2017 Théo FIDRY <[email protected]>,
9
 *                    Pádraic Brady <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Humbug\PhpScoper\PhpParser\NodeVisitor;
16
17
use Humbug\PhpScoper\Scoper\PhpScoper;
18
use Humbug\PhpScoper\Whitelist;
19
use PhpParser\Error as PhpParserError;
20
use PhpParser\Node;
21
use PhpParser\Node\Scalar\String_;
22
use PhpParser\NodeVisitorAbstract;
23
use function ltrim;
24
use function strpos;
25
use function substr;
26
27
final class NewdocPrefixer extends NodeVisitorAbstract
28
{
29
    private $scoper;
30
    private $prefix;
31
    private $whitelist;
32
33 541
    public function __construct(PhpScoper $scoper, string $prefix, Whitelist $whitelist)
34
    {
35 541
        $this->scoper = $scoper;
36 541
        $this->prefix = $prefix;
37 541
        $this->whitelist = $whitelist;
38
    }
39
40
    /**
41
     * @inheritdoc
42
     */
43 540
    public function enterNode(Node $node): Node
44
    {
45 540
        if ($node instanceof String_ && $this->isPhpNowdoc($node)) {
46
            try {
47 1
                $lastChar = substr($node->value, -1);
48
49 1
                $newValue = $this->scoper->scopePhp($node->value, $this->prefix, $this->whitelist);
50
51 1
                if ("\n" !== $lastChar) {
52 1
                    $newValue = substr($newValue, 0, -1);
53
                }
54
55 1
                $node->value = $newValue;
56
            } catch (PhpParserError $error) {
57
                // Continue without scoping the heredoc which for some reasons contains invalid PHP code
58
            }
59
        }
60
61 540
        return $node;
62
    }
63
64 92
    private function isPhpNowdoc(String_ $node): bool
65
    {
66 92
        if (String_::KIND_NOWDOC !== $node->getAttribute('kind')) {
67 88
            return false;
68
        }
69
70 5
        return 0 === strpos(
71 5
            substr(ltrim($node->value), 0, 5),
72 5
            '<?php'
73
        );
74
    }
75
}
76