ColorNode   B
last analyzed

Complexity

Total Complexity 42

Size/Duplication

Total Lines 298
Duplicated Lines 0 %

Coupling/Cohesion

Dependencies 7

Importance

Changes 0
Metric Value
wmc 42
cbo 7
dl 0
loc 298
rs 8.295
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 2
A getColor() 0 4 1
A generateCSS() 0 4 1
A getRGB() 0 4 1
A toHSV() 0 4 1
A getRed() 0 4 2
A getGreen() 0 4 2
A getBlue() 0 4 2
A getAlpha() 0 4 2
A getSaturation() 0 5 2
A getHue() 0 4 2
A getLightness() 0 5 2
A getLuma() 0 6 2
A getLuminance() 0 6 2
A toARGB() 0 4 1
A toHSL() 0 4 1
A toCSS() 0 4 2
C operate() 0 30 7
C compare() 0 24 7

How to fix   Complexity   

Complex Class

Complex classes like ColorNode often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ColorNode, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of the ILess
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace ILess\Node;
11
12
use ILess\Color;
13
use ILess\Context;
14
use InvalidArgumentException;
15
use ILess\Math;
16
use ILess\Node;
17
use ILess\Output\OutputInterface;
18
19
/**
20
 * Color node.
21
 */
22
class ColorNode extends Node implements ComparableInterface
23
{
24
    /**
25
     * Node type.
26
     *
27
     * @var string
28
     */
29
    protected $type = 'Color';
30
31
    /**
32
     * @var string
33
     */
34
    protected $originalForm;
35
36
    /**
37
     * Constructor.
38
     *
39
     * @param string|array $rgb The rgb value
40
     * @param int $alpha Alpha channel
41
     * @param string $originalForm Original form of the color
42
     *
43
     * @throws InvalidArgumentException
44
     */
45
    public function __construct($rgb, $alpha = 1, $originalForm = null)
46
    {
47
        if (!$rgb instanceof Color) {
48
            $value = new Color($rgb, $alpha, $originalForm);
49
        } else {
50
            $value = $rgb;
51
        }
52
53
        /* @var $value \ILess\Color */
54
        parent::__construct($value);
55
    }
56
57
    /**
58
     * Returns the color object.
59
     *
60
     * @return Color
61
     */
62
    public function getColor()
63
    {
64
        return $this->value;
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function generateCSS(Context $context, OutputInterface $output)
71
    {
72
        $output->add($this->toCSS($context));
73
    }
74
75
    /**
76
     * Returns the RGB channels.
77
     *
78
     * @return array
79
     */
80
    public function getRGB()
81
    {
82
        return $this->value->rgb;
83
    }
84
85
    /**
86
     * Returns the HSV components of the color.
87
     *
88
     * @return array
89
     */
90
    public function toHSV()
91
    {
92
        return $this->value->toHSV();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method toHSV() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
93
    }
94
95
    /**
96
     * Returns the red channel.
97
     *
98
     * @param bool $raw Return raw value?
99
     *
100
     * @return mixed
101
     */
102
    public function getRed($raw = false)
103
    {
104
        return $raw ? $this->value->getRed() : new DimensionNode($this->value->getRed());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getRed() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
105
    }
106
107
    /**
108
     * Returns the green channel.
109
     *
110
     * @param bool $raw Return raw value?
111
     *
112
     * @return mixed
113
     */
114
    public function getGreen($raw = false)
115
    {
116
        return $raw ? $this->value->getGreen() : new DimensionNode($this->value->getGreen());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getGreen() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
117
    }
118
119
    /**
120
     * Returns the blue channel.
121
     *
122
     * @param bool $raw Return raw value?
123
     *
124
     * @return mixed
125
     */
126
    public function getBlue($raw = false)
127
    {
128
        return $raw ? $this->value->getBlue() : new DimensionNode($this->value->getBlue());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getBlue() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
129
    }
130
131
    /**
132
     * Returns the alpha channel.
133
     *
134
     * @param bool $raw Return raw value?
135
     *
136
     * @return mixed
137
     */
138
    public function getAlpha($raw = false)
139
    {
140
        return $raw ? $this->value->getAlpha() : new DimensionNode($this->value->getAlpha());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getAlpha() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
141
    }
142
143
    /**
144
     * Returns the color saturation.
145
     *
146
     * @param bool $raw Return raw value?
147
     *
148
     * @return mixed
149
     */
150
    public function getSaturation($raw = false)
151
    {
152
        return $raw ? $this->value->getSaturation() :
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getSaturation() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
153
            new DimensionNode(round($this->value->getSaturation() * 100), '%');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getSaturation() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
154
    }
155
156
    /**
157
     * Returns the color hue.
158
     *
159
     * @param bool $raw Raw value?
160
     *
161
     * @return mixed
162
     */
163
    public function getHue($raw = false)
164
    {
165
        return $raw ? $this->value->getHue() : new DimensionNode(round($this->value->getHue()));
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getHue() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
166
    }
167
168
    /**
169
     * Returns the lightness.
170
     *
171
     * @param bool $raw Return raw value?
172
     *
173
     * @return mixed ILessNode\DimensionNode if $raw is false
174
     */
175
    public function getLightness($raw = false)
176
    {
177
        return $raw ? $this->value->getLightness() :
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getLightness() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
178
            new DimensionNode(round($this->value->getLightness() * 100), '%');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getLightness() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
179
    }
180
181
    /**
182
     * Returns the luma.
183
     *
184
     * @param bool $raw Return raw value?
185
     *
186
     * @return mixed ILessNode\DimensionNode if $raw is false
187
     */
188
    public function getLuma($raw = false)
189
    {
190
        return $raw ? $this->value->getLuma() : new DimensionNode(
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getLuma() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
191
            $this->value->getLuma() * $this->value->getAlpha() * 100, '%'
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getLuma() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getAlpha() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
192
        );
193
    }
194
195
    /**
196
     * Returns the luminance.
197
     *
198
     * @param bool $raw Return raw value?
199
     *
200
     * @return mixed ILessNode\DimensionNode if $raw is false
201
     */
202
    public function getLuminance($raw = false)
203
    {
204
        return $raw ? $this->value->getLuminance() : new DimensionNode(
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getLuminance() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
205
            $this->value->getLuminance() * $this->value->getAlpha() * 100, '%'
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getLuminance() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getAlpha() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
206
        );
207
    }
208
209
    /**
210
     * Converts the node to ARGB.
211
     *
212
     * @return AnonymousNode
213
     */
214
    public function toARGB()
215
    {
216
        return new AnonymousNode($this->value->toARGB());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method toARGB() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
217
    }
218
219
    /**
220
     * Returns the HSL components of the color.
221
     *
222
     * @return array
223
     */
224
    public function toHSL()
225
    {
226
        return $this->value->toHSL();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method toHSL() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
227
    }
228
229
    /**
230
     * Converts the node to string.
231
     *
232
     * @param Context $context
233
     *
234
     * @return string
235
     */
236
    public function toCSS(Context $context)
237
    {
238
        return $this->value->toString($context->compress, $context->compress && $context->canShortenColors);
0 ignored issues
show
Unused Code introduced by
The call to Node::toString() has too many arguments starting with $context->compress.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
239
    }
240
241
    /**
242
     * Operations have to be done per-channel, if not,
243
     * channels will spill onto each other. Once we have
244
     * our result, in the form of an integer triplet,
245
     * we create a new color node to hold the result.
246
     *
247
     * @param Context $context
248
     * @param string $op
249
     * @param Node $other
250
     *
251
     * @return ColorNode
252
     *
253
     * @throws InvalidArgumentException
254
     */
255
    public function operate(Context $context, $op, Node $other)
256
    {
257
        $result = [];
258
259
        if (!($other instanceof self)) {
260
            if (!$other instanceof ToColorConvertibleInterface) {
261
                throw new InvalidArgumentException(
262
                    'The other node must implement toColor() method to operate, see ILess\Node\Node_ToColorConvertibleInterface'
263
                );
264
            }
265
            $other = $other->toColor();
266
            if (!$other instanceof self) {
267
                throw new InvalidArgumentException('The toColor() method must return an instance of ILess\Node\Node_Color');
268
            }
269
        }
270
271
        $t = $this->getRGB();
272
        $o = $other->getRGB();
273
274
        for ($c = 0; $c < 3; ++$c) {
275
            $result[$c] = Math::operate($op, $t[$c], $o[$c]);
276
            if ($result[$c] > 255) {
277
                $result[$c] = 255;
278
            } elseif ($result < 0) {
279
                $result[$c] = 0;
280
            }
281
        }
282
283
        return new self($result, $this->value->getAlpha() + $other->value->getAlpha());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class ILess\Node as the method getAlpha() does only exist in the following sub-classes of ILess\Node: ILess\Node\ColorNode. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
284
    }
285
286
    /**
287
     * Compares with another node.
288
     *
289
     * @param Node $other
290
     *
291
     * @return int
292
     *
293
     * @throws InvalidArgumentException
294
     */
295
    public function compare(Node $other)
296
    {
297
        if (!($other instanceof self)) {
298
            if (!$other instanceof ToColorConvertibleInterface) {
299
                throw new InvalidArgumentException(
300
                    'The other node must implement toColor() method to operate, see ILess\Node\Node_ToColorConvertibleInterface'
301
                );
302
            }
303
            $other = $other->toColor();
304
            if (!$other instanceof self) {
305
                throw new InvalidArgumentException('The toColor() method must return an instance of ILess\Node\Node_Color');
306
            }
307
        }
308
309
        // cannot compare with another node
310
        if (!$other instanceof self) {
311
            return -1;
312
        }
313
314
        $color = $this->getColor();
315
        $other = $other->getColor();
316
317
        return ($color->rgb === $other->rgb && $color->alpha === $other->alpha) ? 0 : -1;
318
    }
319
}
320