Skip to content

Commit

Permalink
Merge pull request #63 from michalbundyra/feature/align-arrow-new-line
Browse files Browse the repository at this point in the history
Feature: ability to align array arrows when in new line
  • Loading branch information
michalbundyra committed Dec 6, 2019
2 parents 5a640c5 + 5b3f3e4 commit e2e5393
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 18 deletions.
45 changes: 38 additions & 7 deletions src/WebimpressCodingStandard/Sniffs/Arrays/DoubleArrowSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\AbstractArraySniff;
use PHP_CodeSniffer\Util\Common;
use PHP_CodeSniffer\Util\Tokens;
use WebimpressCodingStandard\Helper\ArrayTrait;

Expand Down Expand Up @@ -38,6 +37,14 @@ class DoubleArrowSniff extends AbstractArraySniff
*/
public $maxPadding = 1;

/**
* Whether array arrows which are in new lines should be ignored when
* aligning array arrows (when $maxPadding property is > 1).
*
* @var bool
*/
public $ignoreNewLineArrayArrow = true;

/**
* Processes a single-line array definition.
*
Expand Down Expand Up @@ -108,6 +115,8 @@ protected function processMultiLineArray($phpcsFile, $stackPtr, $arrayStart, $ar
$index = $tokens[$data['index_end']];
if ($index['line'] === $arrow['line']) {
$this->checkSpace($phpcsFile, $data, $spaces[$k] ?? 1);
} elseif (! $this->ignoreNewLineArrayArrow && $index['line'] < $arrow['line']) {
$this->checkSpace($phpcsFile, $data, $spaces[$k] ?? 0);
}
}
}
Expand All @@ -120,6 +129,8 @@ private function calculateExpectedSpaces(File $phpcsFile, array $indices) : arra

$tokens = $phpcsFile->getTokens();

$newLineArrow = [];

$chars = [];
foreach ($indices as $k => $data) {
if (! isset($data['arrow'])) {
Expand All @@ -130,10 +141,14 @@ private function calculateExpectedSpaces(File $phpcsFile, array $indices) : arra
$index = $tokens[$data['index_end']];

if ($arrow['line'] !== $index['line']) {
if (! $this->ignoreNewLineArrayArrow) {
$newLineArrow[$k] = true;
$chars[$k] = $index['column'] - 1;
}
continue;
}

$chars[$k] = $index['column'] + $index['length'] - 1;
$chars[$k] = $index['column'] + $index['length'];
}

$res = [];
Expand Down Expand Up @@ -192,7 +207,7 @@ private function calculateExpectedSpaces(File $phpcsFile, array $indices) : arra
}
}

$spaces[$k] = $max - $length + 1;
$spaces[$k] = isset($newLineArrow[$k]) ? $max : $max - $length + 1;
}

return $spaces;
Expand All @@ -204,17 +219,33 @@ private function checkSpace(File $phpcsFile, array $element, int $expectedSpaces

$space = $tokens[$element['arrow'] - 1];
$expected = str_repeat(' ', $expectedSpaces);
if ($space['code'] === T_WHITESPACE && $space['content'] !== $expected) {
$error = 'Expected "%s" before "=>"; "%s" found';
if ($space['code'] === T_WHITESPACE
&& $space['line'] === $tokens[$element['arrow']]['line']
&& $space['content'] !== $expected
) {
$error = 'Expected %s before double arrow; %d found';
$data = [
Common::prepareForOutput($expected),
Common::prepareForOutput($space['content']),
$expectedSpaces === 1 ? '1 space' : $expectedSpaces . ' spaces',
$space['length'],
];
$fix = $phpcsFile->addFixableError($error, $element['arrow'], 'SpacesBefore', $data);

if ($fix) {
$phpcsFile->fixer->replaceToken($element['arrow'] - 1, $expected);
}
} elseif ($expected !== ''
&& ($space['code'] !== T_WHITESPACE
|| $space['line'] !== $tokens[$element['arrow']]['line'])
) {
$error = 'Expected %s before double arrow; 0 found';
$data = [
$expectedSpaces === 1 ? '1 space' : $expectedSpaces . ' spaces',
];
$fix = $phpcsFile->addFixableError($error, $element['arrow'], 'SpacesBefore', $data);

if ($fix) {
$phpcsFile->fixer->addContentBefore($element['arrow'], $expected);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use const T_CONSTANT_ENCAPSED_STRING;
use const T_CONTINUE;
use const T_DOC_COMMENT_OPEN_TAG;
use const T_DOUBLE_ARROW;
use const T_DOUBLE_QUOTED_STRING;
use const T_ECHO;
use const T_ELSEIF;
Expand Down Expand Up @@ -87,6 +88,15 @@ class ScopeIndentSniff implements Sniff
*/
public $alignObjectOperators = true;

/**
* Ignore alignment of array arrows which are at the beginning of new line.
* If set to true, other sniff should check alignment of these arrows
* - for example WebimpressCodingStandard.Arrays.DoubleArrow
*
* @var bool
*/
public $ignoreNewLineArrayArrow = false;

/**
* @var int[]
*/
Expand Down Expand Up @@ -740,6 +750,8 @@ public function process(File $phpcsFile, $stackPtr)
$expectedIndent += $this->indent;
}
}
} elseif ($this->ignoreNewLineArrayArrow && $tokens[$next]['code'] === T_DOUBLE_ARROW) {
continue;
}

$expectedIndent += $extraIndent;
Expand Down
10 changes: 10 additions & 0 deletions test/Integration/AlignOperators.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

$array = [
'key' => 'value',
'k'
=> 'value',
'k1' => 'value',
];
10 changes: 10 additions & 0 deletions test/Integration/AlignOperators.php.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

$array = [
'key' => 'value',
'k'
=> 'value',
'k1' => 'value',
];
23 changes: 23 additions & 0 deletions test/Integration/AlignOperators.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0"?>
<ruleset name="Webimpress Coding Standard">
<rule ref="../../src/WebimpressCodingStandard/ruleset.xml"/>

<rule ref="WebimpressCodingStandard.Arrays.DoubleArrow">
<properties>
<property name="maxPadding" value="30"/>
<property name="ignoreNewLineArrayArrow" value="false"/>
</properties>
</rule>

<rule ref="WebimpressCodingStandard.WhiteSpace.ScopeIndent">
<properties>
<property name="ignoreNewLineArrayArrow" value="true"/>
</properties>
</rule>

<rule ref="WebimpressCodingStandard.WhiteSpace.OperatorAndKeywordSpacing">
<properties>
<property name="ignoreSpacingBeforeAssignments" value="true"/>
</properties>
</rule>
</ruleset>
7 changes: 6 additions & 1 deletion test/IntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
use function basename;
use function copy;
use function exec;
use function file_exists;
use function glob;
use function implode;
use function str_replace;
use function sys_get_temp_dir;
use function tempnam;

Expand All @@ -25,7 +27,10 @@ public function testIntegration(string $file) : void
$tmpname = tempnam(sys_get_temp_dir(), '') . '_' . basename($file);
copy($file, $tmpname);

exec('vendor/bin/phpcbf ' . $tmpname, $output, $returnVal);
$rulesetFile = str_replace('.php', '.xml', $file);
$options = file_exists($rulesetFile) ? ' --standard=' . $rulesetFile : '';

exec('vendor/bin/phpcbf ' . $tmpname . $options, $output, $returnVal);

self::assertSame(1, $returnVal, 'Output: ' . "\n" . implode("\n", $output));
self::assertFileEquals($file . '.fixed', $tmpname);
Expand Down
2 changes: 1 addition & 1 deletion test/Sniffs/Arrays/DoubleArrowUnitTest.1.inc.fixed
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
// @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow maxPadding 30

$s = ['a' => 'b', 'c'=>'d'];
$s = ['a' => 'b', 'c' =>'d'];
$m = [
'a'
=> 'b',
Expand Down
33 changes: 33 additions & 0 deletions test/Sniffs/Arrays/DoubleArrowUnitTest.2.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
// @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow maxPadding 30
// @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow ignoreNewLineArrayArrow false

$m = [
'foo' => 'bar',
'very-long-key'
=> 'value',
'foo-bar' => 'baz',
];

$x = [
'1' => 1,
'1_____' => 1,
'1__' => 1,
'2_____________________________________________________' => 2,
'3' => 3,
'3____' => 3,
'3_' => 3,
'3_______' => 3,
'3____________________' => 3,
'3___'
=> 'value in new line does not break aligning group',
'3__' => 3,
'3_____' => 3,
'value without index breaks aligning group',
'4___' => 4,
'4' => 4,

'5_' => 'empty line breaks alignment group',
// comment
'6_____' => 'comment breaks alignment group',
];
33 changes: 33 additions & 0 deletions test/Sniffs/Arrays/DoubleArrowUnitTest.2.inc.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
// @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow maxPadding 30
// @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow ignoreNewLineArrayArrow false

$m = [
'foo' => 'bar',
'very-long-key'
=> 'value',
'foo-bar' => 'baz',
];

$x = [
'1' => 1,
'1_____' => 1,
'1__' => 1,
'2_____________________________________________________' => 2,
'3' => 3,
'3____' => 3,
'3_' => 3,
'3_______' => 3,
'3____________________' => 3,
'3___'
=> 'value in new line does not break aligning group',
'3__' => 3,
'3_____' => 3,
'value without index breaks aligning group',
'4___' => 4,
'4' => 4,

'5_' => 'empty line breaks alignment group',
// comment
'6_____' => 'comment breaks alignment group',
];
4 changes: 3 additions & 1 deletion test/Sniffs/Arrays/DoubleArrowUnitTest.inc
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php // @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow maxPadding 1
<?php
// @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow maxPadding 1
// @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow ignoreNewLineArrayArrow true

$s = ['a' => 'b', 'c'=>'d'];
$m = [
Expand Down
6 changes: 4 additions & 2 deletions test/Sniffs/Arrays/DoubleArrowUnitTest.inc.fixed
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php // @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow maxPadding 1
<?php
// @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow maxPadding 1
// @phpcs:set WebimpressCodingStandard.Arrays.DoubleArrow ignoreNewLineArrayArrow true

$s = ['a' => 'b', 'c'=>'d'];
$s = ['a' => 'b', 'c' =>'d'];
$m = [
'a'
=> 'b',
Expand Down
28 changes: 22 additions & 6 deletions test/Sniffs/Arrays/DoubleArrowUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ protected function getErrorList(string $testFile = '') : array
switch ($testFile) {
case 'DoubleArrowUnitTest.1.inc':
return [
4 => 1,
4 => 2,
6 => 1,
10 => 1,
14 => 1,
Expand Down Expand Up @@ -41,15 +41,31 @@ protected function getErrorList(string $testFile = '') : array
59 => 1,
61 => 1,
];
case 'DoubleArrowUnitTest.2.inc':
return [
6 => 1,
8 => 1,
13 => 1,
15 => 1,
17 => 1,
18 => 1,
19 => 1,
20 => 1,
23 => 1,
24 => 1,
25 => 1,
28 => 1,
30 => 1,
];
}

return [
3 => 1,
5 => 1,
9 => 1,
13 => 1,
14 => 1,
5 => 2,
7 => 1,
11 => 1,
15 => 1,
16 => 1,
18 => 1,
];
}

Expand Down

0 comments on commit e2e5393

Please sign in to comment.