Skip to content

Commit cb2466c

Browse files
committed
implement sniff to force only one space after assigment operator
1 parent c8e32d3 commit cb2466c

16 files changed

+251
-6
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ install: travis_retry composer update --prefer-dist
2121
script:
2222
- vendor/bin/phpcs
2323
- vendor/bin/phpcs $(find tests/input/* | sort) --report=summary --report-file=phpcs.log; diff tests/expected_report.txt phpcs.log
24+
- vendor/bin/phpstan analyse
25+
- vendor/bin/phpunit
2426

2527
stages:
2628
- Validate against schema

composer.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,17 @@
3838
"branch-alias": {
3939
"dev-master": "7.0.x-dev"
4040
}
41+
},
42+
"require-dev": {
43+
"phpunit/phpunit": "^7.5",
44+
"phpstan/phpstan": "^0.11",
45+
"phpstan/phpstan-phpunit": "^0.11",
46+
"phpstan/phpstan-deprecation-rules": "^0.11",
47+
"phpstan/phpstan-strict-rules": "^0.11"
48+
},
49+
"autoload-dev": {
50+
"psr-4": {
51+
"Doctrine\\": "tests/Doctrine"
52+
}
4153
}
4254
}

docs/en/reference/index.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,15 @@ need to execute PHP_CodeSniffer with the tests folder and ensure it matches the
132132
.. code-block:: bash
133133
134134
$ ./vendor/bin/phpcs tests/input --report=summary --report-file=phpcs.log; diff tests/expected_report.txt phpcs.log
135+
136+
If you have implemented custom sniff also run PHPStan and PHPUnit.
137+
The PHPUnit version to be used is the one installed as a dev- dependency
138+
via composer (same rules are for PHPStan):
139+
140+
.. code-block:: console
141+
142+
$ ./vendor/bin/phpunit
143+
$ ./vendor/bin/phpstan analyse
144+
145+
Accepted coverage for new contributions is 80%. There must not be any errors shown by PHPStan.
146+
Any contribution not satisfying this requirement won’t be merged.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Sniffs\Arrays;
6+
7+
use PHP_CodeSniffer\Files\File;
8+
use PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\OperatorSpacingSniff as SquizOperatorSpacingSniff;
9+
use const T_EQUAL;
10+
use const T_INLINE_ELSE;
11+
use const T_INLINE_THEN;
12+
use const T_WHITESPACE;
13+
use function strlen;
14+
15+
final class OperatorSpacingAfterSniff extends SquizOperatorSpacingSniff
16+
{
17+
private const MESSAGE_AFTER = 'Expected exactly 1 space after "%s"; %d found';
18+
19+
/**
20+
* {@inheritdoc}
21+
*/
22+
public function register() : array
23+
{
24+
return [T_EQUAL];
25+
}
26+
27+
/**
28+
* {@inheritdoc}
29+
*
30+
* @param int $pointer
31+
*/
32+
public function process(File $phpcsFile, $pointer) : void
33+
{
34+
if (! $this->isOperator($phpcsFile, $pointer)) {
35+
return;
36+
}
37+
38+
$this->ensureOneSpaceAfterOperator($phpcsFile, $pointer, $phpcsFile->getTokens());
39+
}
40+
41+
/**
42+
* @param mixed[] $tokens
43+
*/
44+
private function ensureOneSpaceAfterOperator(File $file, int $pointer, array $tokens) : void
45+
{
46+
if (! $this->shouldValidateAfter($pointer, $tokens)) {
47+
return;
48+
}
49+
50+
$numberOfSpaces = $this->numberOfSpaces($tokens[$pointer + 1]);
51+
52+
if ($numberOfSpaces === 1 || ! $this->recordErrorAfter($file, $pointer, $tokens[$pointer], $numberOfSpaces)) {
53+
return;
54+
}
55+
56+
if ($numberOfSpaces === 0) {
57+
$file->fixer->addContent($pointer, ' ');
58+
59+
return;
60+
}
61+
62+
$file->fixer->replaceToken($pointer + 1, ' ');
63+
}
64+
65+
/**
66+
* @param mixed[] $tokens
67+
*/
68+
private function shouldValidateAfter(int $pointer, array $tokens) : bool
69+
{
70+
if (! isset($tokens[$pointer + 1])) {
71+
return false;
72+
}
73+
74+
return $tokens[$pointer]['code'] !== T_INLINE_THEN || $tokens[$pointer + 1]['code'] !== T_INLINE_ELSE;
75+
}
76+
77+
/**
78+
* @param mixed[] $token
79+
*/
80+
private function recordErrorAfter(File $file, int $pointer, array $token, int $numberOfSpaces) : bool
81+
{
82+
return $file->addFixableError(
83+
self::MESSAGE_AFTER,
84+
$pointer,
85+
'NoSpaceAfterAssigment',
86+
[$token['content'], $numberOfSpaces]
87+
);
88+
}
89+
90+
/**
91+
* @param mixed[] $token
92+
*/
93+
private function numberOfSpaces(array $token) : int
94+
{
95+
if ($token['code'] !== T_WHITESPACE) {
96+
return 0;
97+
}
98+
99+
return strlen($token['content']);
100+
}
101+
}

phpcs.xml.dist

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,8 @@
1515

1616
<rule ref="Doctrine"/>
1717

18-
<file>lib</file>
18+
<file>lib/</file>
19+
<file>tests/Doctrine/</file>
20+
21+
<exclude-pattern>tests/**/data/*</exclude-pattern>
1922
</ruleset>

phpstan.neon.dist

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
parameters:
2+
level: 7
3+
paths:
4+
- "%currentWorkingDirectory%/lib/"
5+
- "%currentWorkingDirectory%/tests/Doctrine"
6+
autoload_files:
7+
- "%currentWorkingDirectory%/tests/bootstrap.php"
8+
ignoreErrors:
9+
-
10+
message: '#Method [a-zA-Z0-9\\_]+::process\(\) has parameter \$pointer with no typehint specified#'
11+
path: %currentWorkingDirectory%/lib/Doctrine/Sniffs/*
12+
13+
includes:
14+
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
15+
- vendor/phpstan/phpstan-phpunit/extension.neon
16+
- vendor/phpstan/phpstan-phpunit/rules.neon
17+
- vendor/phpstan/phpstan-strict-rules/rules.neon

phpunit.xml.dist

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
4+
colors="true"
5+
beStrictAboutOutputDuringTests="true"
6+
beStrictAboutTodoAnnotatedTests="true"
7+
failOnRisky="true"
8+
failOnWarning="true"
9+
bootstrap="tests/bootstrap.php"
10+
>
11+
12+
<testsuite name="Doctrine Coding Standard Test Suite">
13+
<directory suffix="Test.php">tests/Doctrine/</directory>
14+
</testsuite>
15+
</phpunit>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Sniffs\Arrays;
6+
7+
use SlevomatCodingStandard\Sniffs\TestCase;
8+
9+
final class OperatorSpacingAfterSniffTest extends TestCase
10+
{
11+
public function testNoErrors() : void
12+
{
13+
$phpcsFile = self::checkFile(__DIR__ . '/data/operatorSpacingAfterSniff.noErrors.php');
14+
self::assertNoSniffErrorInFile($phpcsFile);
15+
}
16+
17+
public function testErrors() : void
18+
{
19+
$phpcsFile = self::checkFile(__DIR__ . '/data/operatorSpacingAfterSniff.errors.php');
20+
21+
self::assertSame(1, $phpcsFile->getErrorCount());
22+
23+
self::assertSniffError($phpcsFile, 4, 'NoSpaceAfterAssigment');
24+
}
25+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
4+
$arrayWithMultipleSpacesAfterAssigmentOperator = [
5+
0,
6+
1,
7+
2,
8+
3,
9+
4,
10+
5,
11+
];
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
$array = [
6+
0,
7+
1,
8+
2,
9+
3,
10+
4,
11+
5,
12+
];
13+
14+
$arrayWithMultipleSpacesBeforeAssigmentOperator = [
15+
0,
16+
1,
17+
2,
18+
3,
19+
4,
20+
5,
21+
];

0 commit comments

Comments
 (0)