Test Failed
Pull Request — master (#124)
by Andrii
11:47
created

PhpPrinter::pExpr_Closure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 1
c 1
b 0
f 1
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Composer\Config\Util;
6
7
use PhpParser\Node\Expr;
8
use PhpParser\Node\Stmt;
9
use PhpParser\PrettyPrinter\Standard;
10
11
class PhpPrinter extends Standard
12
{
13
    private bool $isBuildtime = false;
14
15
    protected function pExpr_MethodCall(Expr\MethodCall $node)
16
    {
17
        return $this->tokenize(parent::pExpr_MethodCall($node));
18
    }
19
20
    protected function pExpr_StaticCall(Expr\StaticCall $node)
21
    {
22
        $class = $this->pDereferenceLhs($node->class);
23
        if ('Buildtime' === $class) {
24
            $this->isBuildtime = true;
25
            $res = $this->my_pMaybeMultiline($node->args);
26
            $this->isBuildtime = false;
27
28
            return $res;
29
        }
30
31
        return $this->tokenize(parent::pExpr_StaticCall($node));
32
    }
33
34
    protected function pExpr_Eval(Expr\Eval_ $node)
35
    {
36
        return $this->tokenize(parent::pExpr_Eval($node));
37
    }
38
39
    protected function pExpr_Include(Expr\Include_ $node)
40
    {
41
        return $this->tokenize(parent::pExpr_Include($node));
42
    }
43
44
    // XXX Did not find it useful. What is it for?
45
    //protected function pExpr_ArrayItem(Expr\ArrayItem $node)
46
    //{
47
    //    $code = ($node->byRef ? '&' : '')
48
    //        . ($node->unpack ? '...' : '')
49
    //        . $this->p($node->value);
50
51
    //    if (isset($node->value) && $node->value instanceof Expr\FuncCall) {
52
    //        $code = $this->tokenize($code);
53
    //    }
54
55
    //    return (null !== $node->key ? $this->p($node->key) . ' => ' : '')
56
    //        . $code;
57
    //}
58
59
    protected function pExpr_Closure(Expr\Closure $node)
60
    {
61
        return $this->tokenize(parent::pExpr_Closure($node));
62
    }
63
64
    protected function pExpr_ArrowFunction(Expr\ArrowFunction $node)
65
    {
66
        return $this->tokenize(parent::pExpr_ArrowFunction($node));
67
    }
68
69
    protected function pExpr_New(Expr\New_ $node)
70
    {
71
        return $this->tokenize(parent::pExpr_New($node));
72
    }
73
74
    // XXX Can we get rid of `ReverseBlockMerge`
75
    //protected function pExpr_New(Expr\New_ $node) {
76
    //    if ($node->class instanceof Stmt\Class_) {
77
    //        $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : '';
78
    //        $code = 'new ' . $this->pClassCommon($node->class, $args);
79
    //        $token = '\'__' . md5($code) . '__\'';
80
    //        $this->options['builder']->closures[$token] = $code;
81
    //        return $token;
82
    //    }
83
    //    $code = 'new ' . $this->pNewVariable($node->class)
84
    //        . '(' . $this->pMaybeMultiline($node->args) . ')';
85
    //    if($this->pNewVariable($node->class) == 'ReverseBlockMerge'){
86
    //        return $code;
87
    //    }
88
    //    $token = '\'__' . md5($code) . '__\'';
89
    //    $this->options['builder']->closures[$token] = $code;
90
    //    return $token;
91
    //}
92
93
    protected function pStmt_ClassMethod(Stmt\ClassMethod $node)
94
    {
95
        return $this->tokenize(parent::pStmt_ClassMethod($node));
96
    }
97
98
    protected function pStmt_Function(Stmt\Function_ $node)
99
    {
100
        return $this->tokenize(parent::pStmt_Function($node));
101
    }
102
103
    private static array $tokens = [];
104
105
    protected function tokenize(string $code): string
106
    {
107
        if ($this->isBuildtime) {
108
            return $code;
109
        }
110
111
        $token = "'__" . md5($code) . "__'";
112
        static::$tokens[$token] = $code;
0 ignored issues
show
Bug introduced by
Since $tokens is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $tokens to at least protected.
Loading history...
113
114
        return $token;
115
    }
116
117
    public static function resolveTokens(string $output): string
118
    {
119
        $limit = 10;
120
        while (preg_match('~\'__(\w+)__\'~', $output)) {
121
            // TODO will be fixed soon
122
            if (--$limit<1) {
123
                throw new \Exception('too much');
124
            }
125
            $output = strtr($output, static::$tokens);
0 ignored issues
show
Bug introduced by
Since $tokens is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $tokens to at least protected.
Loading history...
126
        }
127
128
        return $output;
129
    }
130
131
    /**
132
     * XXX could these methods be converted to protected in php-parser?
133
     */
134
    protected function my_pMaybeMultiline(array $nodes, bool $trailingComma = false) {
135
        if (!$this->my_hasNodeWithComments($nodes)) {
136
            return $this->pCommaSeparated($nodes);
137
        } else {
138
            return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl;
139
        }
140
    }
141
142
    protected function my_hasNodeWithComments(array $nodes) {
143
        foreach ($nodes as $node) {
144
            if ($node && $node->getComments()) {
145
                return true;
146
            }
147
        }
148
        return false;
149
    }
150
}
151