Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.83% covered (success)
95.83%
23 / 24
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Less_Visitor
95.83% covered (success)
95.83%
23 / 24
66.67% covered (warning)
66.67%
2 / 3
10
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 visitObj
94.74% covered (success)
94.74%
18 / 19
0.00% covered (danger)
0.00%
0 / 1
7.01
 visitArray
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2declare( strict_types = 1 );
3
4/**
5 * @private
6 */
7class Less_Visitor {
8
9    /** @var array */
10    protected $_visitFnCache = [];
11
12    public function __construct() {
13        $this->_visitFnCache = get_class_methods( get_class( $this ) );
14        $this->_visitFnCache = array_flip( $this->_visitFnCache );
15    }
16
17    public function visitObj( $node ) {
18        static $funcNames = [];
19
20        if ( !$node instanceof Less_Tree ) {
21            return $node;
22        }
23
24        // Map a class name like "Less_Tree_Foo_Bar" to method like "visitFooBar".
25        //
26        // We do this by taking the last part of the class name (instead of doing
27        // a find-replace from "Less_Tree" to "visit"), so that we support codemod
28        // tools (such as Strauss and Mozart), which may modify our code in-place
29        // to add a namespace or class prefix.
30        // "MyVendor\Something_Less_Tree_Foo_Bar" should also map to "FooBar".
31        //
32        // https://packagist.org/packages/brianhenryie/strauss
33        // https://packagist.org/packages/coenjacobs/mozart
34        $class = get_class( $node );
35        $funcName = $funcNames[$class] ??= 'visit' . str_replace( [ '_', '\\' ], '',
36            substr( $class, strpos( $class, 'Less_Tree_' ) + 10 )
37        );
38
39        if ( isset( $this->_visitFnCache[$funcName] ) ) {
40            $visitDeeper = true;
41            $newNode = $this->$funcName( $node, $visitDeeper );
42            if ( $this instanceof Less_VisitorReplacing ) {
43                $node = $newNode;
44            }
45
46            if ( $visitDeeper && $node instanceof Less_Tree ) {
47                $node->accept( $this );
48            }
49
50            $funcName .= 'Out';
51            if ( isset( $this->_visitFnCache[$funcName] ) ) {
52                $this->$funcName( $node );
53            }
54
55        } else {
56            $node->accept( $this );
57        }
58
59        return $node;
60    }
61
62    public function visitArray( &$nodes ) {
63        // NOTE: The use of by-ref in a normal (non-replacing) Visitor may be surprising,
64        // but upstream relies on this for Less_ImportVisitor, which modifies values of
65        // `$importParent->rules` yet is not a replacing visitor.
66        foreach ( $nodes as &$node ) {
67            $this->visitObj( $node );
68        }
69        return $nodes;
70    }
71}