Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: ability to align array arrows when in new line #63

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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