Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
21 changes: 21 additions & 0 deletions src/Standards/PSR12/Docs/Operators/OperatorSpacingStandard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ if ($a===$b) {
$foo=$bar??$a??$b;
} elseif ($a>$b) {
$variable=$foo?'foo':'bar';
}
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
When the "perCompatible" property is set to "3.0" or higher, the requirement for spaces around the pipe operator in a catch block (union types) is removed.
]]>
</standard>
<code_comparison>
<code title="Valid: perCompatible set to 3.0 or higher.">
<![CDATA[
try {
} catch (Exception|RuntimeException $e) {
}
]]>
</code>
<code title="Valid: perCompatible set to a version lower than 3.0 (default 1.0).">
<![CDATA[
try {
} catch (Exception | RuntimeException $e) {
}
]]>
</code>
Expand Down
51 changes: 51 additions & 0 deletions src/Standards/PSR12/Sniffs/Operators/OperatorSpacingSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
class OperatorSpacingSniff extends SquizOperatorSpacingSniff
{

/**
* The PER version to be compatible with. For backwards compatibility this is set to 1.0 by default.
*
* @var string
*/
public $perCompatible = '1.0';


/**
* Returns an array of tokens this test wants to listen for.
Expand Down Expand Up @@ -75,6 +82,50 @@ public function process(File $phpcsFile, int $stackPtr)

$operator = $tokens[$stackPtr]['content'];

// PER-CS 3.0: Exception to the rule for catch blocks (union types) where no space is required.
// As union types didn't exist when PSR-12 was created, the pipe in catch statements
// was originally treated as a bitwise operator. This check changes the spacing requirement
// for that specific case when opting in to PER-CS 3.0 or higher.
if ($operator === '|' && version_compare($this->perCompatible, '3.0', '>=') === true) {
if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
$parenthesis = array_keys($tokens[$stackPtr]['nested_parenthesis']);
$bracket = array_pop($parenthesis);
if (isset($tokens[$bracket]['parenthesis_owner']) === true
&& $tokens[$tokens[$bracket]['parenthesis_owner']]['code'] === T_CATCH
) {
if ($tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) {
$error = 'Expected 0 spaces before "%s"; %s found';
$data = [
$operator,
$tokens[($stackPtr - 1)]['length'],
];

$fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBefore', $data);
if ($fix === true) {
$phpcsFile->fixer->replaceToken(($stackPtr - 1), '');
}
}

if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) {
$error = 'Expected 0 spaces after "%s"; %s found';
$data = [
$operator,
$tokens[($stackPtr + 1)]['length'],
];

$fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceAfter', $data);
if ($fix === true) {
$phpcsFile->fixer->replaceToken(($stackPtr + 1), '');
}
}

// Now that this special case is handled, we can return early as we don't need to do
// further checks.
return;
}
}
}

$checkBefore = true;
$checkAfter = true;

Expand Down
23 changes: 23 additions & 0 deletions src/Standards/PSR12/Tests/Operators/OperatorSpacingUnitTest.4.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

// phpcs:set PSR12.Operators.OperatorSpacing perCompatible 3.0

try {
// nothing
} catch (Exception | RuntimeException $e) {
}

// Testing that it works with future versions as well.
// phpcs:set PSR12.Operators.OperatorSpacing perCompatible 4.0

try {
// nothing
} catch (Exception | RuntimeException $e) {
}

// phpcs:set PSR12.Operators.OperatorSpacing perCompatible 1.0

try {
// nothing
} catch (Exception|RuntimeException $e) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

// phpcs:set PSR12.Operators.OperatorSpacing perCompatible 3.0

try {
// nothing
} catch (Exception|RuntimeException $e) {
}

// Testing that it works with future versions as well.
// phpcs:set PSR12.Operators.OperatorSpacing perCompatible 4.0

try {
// nothing
} catch (Exception|RuntimeException $e) {
}

// phpcs:set PSR12.Operators.OperatorSpacing perCompatible 1.0

try {
// nothing
} catch (Exception | RuntimeException $e) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public function getErrorList($testFile = '')
44 => 2,
47 => 2,
];
case 'OperatorSpacingUnitTest.4.inc':
return [
7 => 2,
15 => 2,
22 => 2,
];
default:
return [];
}
Expand Down