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