RemoveComments::removeComments()   B
last analyzed

Complexity

Conditions 6
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 10
cts 10
cp 1
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 9
nc 4
nop 0
crap 6
1
<?php
2
3
/**
4
* @package   s9e\SourceOptimizer
5
* @copyright Copyright (c) 2014-2018 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\SourceOptimizer\Passes;
9
10
use s9e\SourceOptimizer\Helper;
11
12
class RemoveComments extends AbstractPass
13
{
14
	/**
15
	* @var string[] List of annotations to preserve
16
	*/
17
	public $preserveAnnotations = [
18
		'license'
19
	];
20
21
	/**
22
	* @var bool Whether to remove DocBlock comments
23
	*/
24
	public $removeDocBlocks = true;
25
26
	/**
27
	* @var bool Whether to remove "C style" comments
28
	*/
29
	public $removeMultiLineComments = true;
30
31
	/**
32
	* @var bool Whether to remove "one-line" comments
33
	*/
34
	public $removeSingleLineComments = true;
35
36
	/**
37
	* {@inheritdoc}
38
	*/
39 13
	protected function optimizeStream()
40
	{
41 13
		if ($this->removeDocBlocks)
42
		{
43 12
			$this->removeDocBlocks();
44
		}
45 13
		if ($this->removeMultiLineComments || $this->removeSingleLineComments)
46
		{
47 13
			$this->removeComments();
48
		}
49 13
		Helper::mergeWhitespace($this->stream);
0 ignored issues
show
Unused Code introduced by
The call to the method s9e\SourceOptimizer\Helper::mergeWhitespace() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
50 13
	}
51
52
	/**
53
	* Generate a regexp that matches preserved annotations
54
	*
55
	* @return string
56
	*/
57 12
	protected function getRegexp()
58
	{
59 12
		if (empty($this->preserveAnnotations))
60
		{
61
			return '((?!))';
62
		}
63
64 12
		return '(@(?:' . implode('|', $this->preserveAnnotations) . '))';
65
	}
66
67
	/**
68
	* Remove all docblocks tokens from given stream
69
	*
70
	* @return void
71
	*/
72 12
	protected function removeDocBlocks()
73
	{
74 12
		$regexp = $this->getRegexp();
75 12
		$this->stream->reset();
76 12
		while ($this->stream->skipTo(T_DOC_COMMENT))
77
		{
78 3
			$docblock = $this->stream->currentText();
79 3
			if (strpos($docblock, '@') !== false && preg_match($regexp, $docblock))
80
			{
81 2
				continue;
82
			}
83
84 1
			$this->removeComment();
85
		}
86 12
	}
87
88
	/**
89
	* Remove current comment token from given stream
90
	*
91
	* @return void
92
	*/
93 8
	protected function removeComment()
94
	{
95 8
		$offset = $this->stream->key();
96 8
		$this->stream->previous();
97 8
		if ($this->stream->is(T_WHITESPACE))
98
		{
99 6
			$ws = preg_replace('(\\n[ \\t]*$)', '', $this->stream->currentText());
100 6
			if ($ws === '')
101
			{
102 6
				$this->stream->remove();
103
			}
104
			else
105
			{
106
				$this->stream->replace([T_WHITESPACE, $ws]);
107
			}
108
		}
109
110 8
		$this->stream->seek($offset);
111 8
		if ($this->stream->canRemoveCurrentToken())
112
		{
113 7
			$this->stream->remove();
114
		}
115
		else
116
		{
117 1
			$this->stream->replace([T_WHITESPACE, ' ']);
118
		}
119 8
	}
120
121
	/**
122
	* Remove single-line and/or multi-line comments from given stream
123
	*
124
	* @return void
125
	*/
126 13
	protected function removeComments()
127
	{
128 13
		$this->stream->reset();
129 13
		while ($this->stream->skipTo(T_COMMENT))
130
		{
131 9
			$comment = $this->stream->currentText();
132 9
			if ($comment[1] === '/' && !$this->removeSingleLineComments)
133
			{
134 1
				continue;
135
			}
136 8
			if ($comment[1] === '*' && !$this->removeMultiLineComments)
137
			{
138 1
				continue;
139
			}
140
141 7
			$this->removeComment();
142
		}
143
	}
144
}