Skip to content

Commit a5bf741

Browse files
authored
Merge pull request #72 from magento/20-ForeachArrayMerge
#20 Impelement ArrayMerge sniff in foreach
2 parents 4c5a79e + 0ad611c commit a5bf741

File tree

4 files changed

+153
-0
lines changed

4 files changed

+153
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
/**
3+
* Copyright © Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento2\Sniffs\Performance;
7+
8+
use PHP_CodeSniffer\Files\File;
9+
use PHP_CodeSniffer\Sniffs\Sniff;
10+
11+
/**
12+
* Detects array_merge(...) is used in a loop and is a resources greedy construction.
13+
*/
14+
class ForeachArrayMergeSniff implements Sniff
15+
{
16+
/**
17+
* String representation of warning.
18+
*
19+
* @var string
20+
*/
21+
protected $warningMessage = 'array_merge(...) is used in a loop and is a resources greedy construction.';
22+
23+
/**
24+
* Warning violation code.
25+
*
26+
* @var string
27+
*/
28+
protected $warningCode = 'ForeachArrayMerge';
29+
30+
/**
31+
* @var array
32+
*/
33+
protected $foreachCache = [];
34+
35+
/**
36+
* @inheritdoc
37+
*/
38+
public function register()
39+
{
40+
return [T_FOREACH, T_FOR];
41+
}
42+
43+
/**
44+
* @inheritdoc
45+
*/
46+
public function process(File $phpcsFile, $stackPtr)
47+
{
48+
$tokens = $phpcsFile->getTokens();
49+
50+
$scopeOpener = $tokens[$stackPtr]['scope_opener'];
51+
$scopeCloser = $tokens[$stackPtr]['scope_closer'];
52+
53+
for ($i = $scopeOpener; $i < $scopeCloser; $i++) {
54+
$tag = $tokens[$i];
55+
if ($tag['code'] !== T_STRING) {
56+
continue;
57+
}
58+
if ($tag['content'] !== 'array_merge') {
59+
continue;
60+
}
61+
62+
$cacheKey = $phpcsFile->getFilename() . $i;
63+
if (isset($this->foreachCache[$cacheKey])) {
64+
continue;
65+
}
66+
67+
$this->foreachCache[$cacheKey] = '';
68+
$phpcsFile->addWarning($this->warningMessage, $i, $this->warningCode);
69+
}
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
$configurationSources = [
3+
0 => 'value',
4+
1 => 'value2',
5+
];
6+
7+
$options = [];
8+
9+
foreach ([] as $collection) {
10+
foreach ($configurationSources as $source) {
11+
$options = array_merge($options, $source);
12+
}
13+
}
14+
15+
$options = [];
16+
$itemCount = count($configurationSources);
17+
for ($i = 0; $i <= $itemCount; $i++) {
18+
$source = $options[$itemCount];
19+
$options = array_merge($options, $source);
20+
}
21+
22+
class SelectBuilder
23+
{
24+
private $columns = [];
25+
26+
public function getColumns()
27+
{
28+
return $this->columns;
29+
}
30+
31+
public function setColumns(array $columns)
32+
{
33+
$this->columns = $columns;
34+
}
35+
}
36+
37+
$selectBuilder = new SelectBuilder();
38+
39+
foreach ([] as $collection) {
40+
foreach ($configurationSources as $source) {
41+
$selectBuilder->setColumns(array_merge($selectBuilder->getColumns(), $source));
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
/**
3+
* Copyright © Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento2\Tests\Performance;
8+
9+
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
10+
11+
/**
12+
* Class EmptyCheckUnitTest
13+
*/
14+
class ForeachArrayMergeUnitTest extends AbstractSniffUnitTest
15+
{
16+
/**
17+
* @inheritdoc
18+
*/
19+
public function getErrorList()
20+
{
21+
return [];
22+
}
23+
24+
/**
25+
* @inheritdoc
26+
*/
27+
public function getWarningList()
28+
{
29+
return [
30+
11 => 1,
31+
19 => 1,
32+
41 => 1
33+
];
34+
}
35+
}

Magento2/ruleset.xml

+4
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@
235235
<severity>7</severity>
236236
<type>warning</type>
237237
</rule>
238+
<rule ref="Magento2.Performance.ForeachArrayMerge">
239+
<severity>7</severity>
240+
<type>warning</type>
241+
</rule>
238242
<rule ref="Magento2.Strings.StringConcat">
239243
<severity>7</severity>
240244
<type>warning</type>

0 commit comments

Comments
 (0)