ContextHelper::forEachFunction()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 0
cts 4
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 2
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;
9
10
abstract class ContextHelper
11
{
12
	/**
13
	* Execute given callback on each namespace block in given stream
14
	*
15
	* @param  TokenStream $stream   Token stream
16
	* @param  callable    $callback Callback
17
	* @return void
18
	*/
19
	public static function forEachNamespace(TokenStream $stream, callable $callback)
20
	{
21
		foreach (self::getNamespaces($stream) as $block)
22
		{
23
			call_user_func_array($callback, $block);
24
		}
25
	}
26
27
	/**
28
	* Execute given callback on each function block in given stream
29
	*
30
	* @param  TokenStream $stream   Token stream
31
	* @param  callable    $callback Callback
32
	* @return void
33
	*/
34
	public static function forEachFunction(TokenStream $stream, callable $callback)
35
	{
36
		foreach (self::getFunctionBlocks($stream) as $block)
37
		{
38
			call_user_func_array($callback, $block);
39
		}
40
	}
41
42
	/**
43
	* Get the list of function blocks in given stream
44
	*
45
	* @param  TokenStream $stream Token stream
46
	* @return array[]             List of arrays of [start, end] offsets
47
	*/
48 3
	public static function getFunctionBlocks(TokenStream $stream)
49
	{
50 3
		$blocks = [];
51 3
		$stream->reset();
52 3
		while ($stream->skipTo(T_FUNCTION))
53
		{
54 2
			$offset = $stream->key();
55 2
			$stream->skipToToken('{');
56 2
			$cnt = 0;
57 2
			while ($stream->valid())
58
			{
59 2
				$token = $stream->current();
60 2
				if ($token === '{')
61
				{
62 2
					++$cnt;
63
				}
64 2
				elseif ($token === '}')
65
				{
66 2
					if (--$cnt === 0)
67
					{
68 2
						$blocks[] = [$offset, $stream->key()];
69 2
						break;
70
					}
71
				}
72 2
				$stream->next();
73
			}
74
		}
75
76 3
		return $blocks;
77
	}
78
79
	/**
80
	* Get the list of namespaces in given stream
81
	*
82
	* @param  TokenStream $stream Token stream
83
	* @return array[]             List of arrays with namespace, start offset, end offset
84
	*/
85 4
	public static function getNamespaces(TokenStream $stream)
86
	{
87 4
		$namespaces = [''];
88 4
		$stream->reset();
89 4
		while ($stream->skipTo(T_NAMESPACE))
90
		{
91 3
			$offset = $stream->key();
92 3
			$stream->next();
93 3
			$stream->skipNoise();
94 3
			$namespace = '';
95 3
			while ($stream->valid())
96
			{
97 3
				$token = $stream->current();
98 3
				if (in_array($token, [';', '{'], true))
99
				{
100 3
					break;
101
				}
102 3
				$namespace .= $token[1];
103 3
				$stream->next();
104 3
				$stream->skipNoise();
105
			}
106 3
			$namespaces[$offset] = $namespace;
107
		}
108
109 4
		$i = 0;
110 4
		$blocks = [];
111 4
		foreach ($namespaces as $offset => $namespace)
112
		{
113 4
			if ($i > 0)
114
			{
115 3
				$blocks[$i - 1][2] = $offset - 1;
116
			}
117 4
			$blocks[] = [$namespace, $offset];
118 4
			++$i;
119
		}
120 4
		$blocks[$i - 1][2] = $stream->key() - 1;
121
122 4
		return $blocks;
123
	}
124
}