Skip to content

Commit

Permalink
Adds support for @method tag
Browse files Browse the repository at this point in the history
Support has been added to the followin sniffs:
- `Namespaces\UnusedUseStatement`
- `PHP\CorrectClassNameCase`
- `PHP\DisallowFqn`

Includes unit tests.
  • Loading branch information
michalbundyra committed May 14, 2019
1 parent a6ef1ed commit 8a0c42f
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 56 deletions.
1 change: 1 addition & 0 deletions src/WebimpressCodingStandard/CodingStandard.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class CodingStandard
'@param',
'@return',
'@throws',
'@method',
'@property',
'@property-read',
'@property-write',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public function process(File $phpcsFile, $stackPtr)
if (($isStringToken && strtolower($tokens[$classUsed]['content']) === $lowerClassName)
|| ($tokens[$classUsed]['code'] === T_DOC_COMMENT_STRING
&& preg_match(
'/(\s|\||^)' . preg_quote($lowerClassName, '/') . '(\s|\||\\\\|$|\[\])/i',
'/(\s|\||\(|^)' . preg_quote($lowerClassName, '/') . '(\s|\||\\\\|$|\[\])/i',
$tokens[$classUsed]['content']
))
|| ($tokens[$classUsed]['code'] === T_DOC_COMMENT_TAG
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use function implode;
use function in_array;
use function ltrim;
use function preg_match_all;
use function preg_quote;
use function preg_replace;
use function str_replace;
Expand Down Expand Up @@ -261,33 +262,49 @@ private function checkTag(File $phpcsFile, int $stackPtr) : void
}

$string = $tokens[$stackPtr + 2]['content'];
[$types] = explode(' ', $string);
$typesArr = explode('|', $types);
[$type] = explode(' ', $string);
$types = [$type];

$newTypesArr = [];
foreach ($typesArr as $type) {
$expected = $this->getExpectedName($phpcsFile, $type, $stackPtr + 2);

$newTypesArr[] = $expected;
if ($tokens[$stackPtr]['content'] === '@method'
&& preg_match_all('/(?<=[\s(,])[^(\s,]+?(?=\s+\$)/', $string, $matches)
) {
$types = array_merge($types, $matches[0]);
}

$newTypes = implode('|', $newTypesArr);
foreach ($types as $typesString) {
$typesArr = explode('|', $typesString);

$newTypesArr = [];
foreach ($typesArr as $type) {
$expected = $this->getExpectedName($phpcsFile, $type, $stackPtr + 2);

$newTypesArr[] = $expected;
}

if ($newTypes !== $types) {
$error = 'Expected class name %s; found %s';
$data = [
$newTypes,
$types,
];
$fix = $phpcsFile->addFixableError($error, $stackPtr + 2, 'InvalidInPhpDocs', $data);
$newTypes = implode('|', $newTypesArr);

if ($fix) {
$phpcsFile->fixer->replaceToken(
$stackPtr + 2,
preg_replace('/^' . preg_quote($types, '/') . '/', $newTypes, $string)
if ($newTypes !== $typesString) {
$error = 'Expected class name %s; found %s';
$data = [
$newTypes,
$typesString,
];
$fix = $phpcsFile->addFixableError($error, $stackPtr + 2, 'InvalidInPhpDocs', $data);

$string = preg_replace(
'/(^|\s|,|\()' . preg_quote($typesString, '/') . '/',
'\\1' . $newTypes,
$string
);
}
}

if ($fix ?? false) {
$phpcsFile->fixer->replaceToken(
$stackPtr + 2,
$string
);
}
}

/**
Expand Down
72 changes: 42 additions & 30 deletions src/WebimpressCodingStandard/Sniffs/PHP/DisallowFqnSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use function implode;
use function in_array;
use function ltrim;
use function preg_match_all;
use function preg_quote;
use function preg_replace;
use function sprintf;
Expand Down Expand Up @@ -178,37 +179,52 @@ private function processTag(
}

$string = $tokens[$stackPtr + 2]['content'];
[$types] = explode(' ', $string);
$typesArr = explode('|', $types);

// Create local array with classes to import, as we want to update main one only in fix mode
$localToImport = [];
$newTypesArr = [];
foreach ($typesArr as $name) {
$suffix = strstr($name, '[');
$name = str_replace(['[', ']'], '', $name);

$newTypesArr[] = $this->getExpectedName($phpcsFile, $stackPtr + 2, $namespace, $name, $localToImport)
. $suffix;
[$type] = explode(' ', $string);
$types = [$type];

if ($tokens[$stackPtr]['content'] === '@method'
&& preg_match_all('/(?<=[\s(,])[^(\s,]+?(?=\s+\$)/', $string, $matches)
) {
$types = array_merge($types, $matches[0]);
}

$newTypes = implode('|', $newTypesArr);
foreach ($types as $typesString) {
$typesArr = explode('|', $typesString);

if ($newTypes !== $types) {
$error = 'Invalid class name references: expected %s; found %s';
$data = [
$newTypes,
$types,
];
$fix = $phpcsFile->addFixableError($error, $stackPtr + 2, 'InvalidInPhpDocs', $data);
// Create local array with classes to import, as we want to update main one only in fix mode
$localToImport = [];
$newTypesArr = [];
foreach ($typesArr as $name) {
$suffix = strstr($name, '[');
$name = str_replace(['[', ']'], '', $name);

if ($fix) {
// Update array with references to import
if ($localToImport) {
$toImport = array_merge($toImport, $localToImport);
}
$newTypesArr[] = $this->getExpectedName($phpcsFile, $stackPtr + 2, $namespace, $name, $localToImport)
. $suffix;
}

$newTypes = implode('|', $newTypesArr);

$toFix[$stackPtr + 2] = preg_replace('/^' . preg_quote($types, '/') . '/', $newTypes, $string);
if ($newTypes !== $typesString) {
$error = 'Invalid class name references: expected %s; found %s';
$data = [
$newTypes,
$typesString,
];
$fix = $phpcsFile->addFixableError($error, $stackPtr + 2, 'InvalidInPhpDocs', $data);

if ($fix) {
// Update array with references to import
if ($localToImport) {
$toImport = array_merge($toImport, $localToImport);
}

$string = preg_replace(
'/(^|\s|,|\()' . preg_quote($typesString, '/') . '/',
'\\1' . $newTypes,
$string
);
$toFix[$stackPtr + 2] = $string;
}
}
}
}
Expand Down Expand Up @@ -574,10 +590,6 @@ private function import(string $type, string $fqn, string $alias) : array
*/
private function importReferences(File $phpcsFile, int $namespacePtr, array $references) : void
{
if (! $references) {
return;
}

$tokens = $phpcsFile->getTokens();
if (isset($tokens[$namespacePtr]['scope_opener'])) {
$ptr = $tokens[$namespacePtr]['scope_opener'];
Expand Down
11 changes: 11 additions & 0 deletions test/Sniffs/Namespaces/UnusedUseStatementUnitTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,19 @@ use FooBar;
use FooB;
use Unused16;
use Unused17;
use Used23;
use Used24;
use Used25;
use Used26;
use Used27;
use Used28;

/**
* @method Used23 myMethod(Used24 $param1, Used25 $param2)
* @property Used26 $foo
* @property-read Used27 $bar
* @property-write Used28 $baz
*
* @Used10
* @Used11\Table
* @AliasUsed12(...)
Expand Down
11 changes: 11 additions & 0 deletions test/Sniffs/Namespaces/UnusedUseStatementUnitTest.inc.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,19 @@ use Used20;
use Used21;
use Used22;
use FooBar;
use Used23;
use Used24;
use Used25;
use Used26;
use Used27;
use Used28;

/**
* @method Used23 myMethod(Used24 $param1, Used25 $param2)
* @property Used26 $foo
* @property-read Used27 $bar
* @property-write Used28 $baz
*
* @Used10
* @Used11\Table
* @AliasUsed12(...)
Expand Down
3 changes: 3 additions & 0 deletions test/Sniffs/PHP/CorrectClassNameCaseUnitTest.1.inc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ DaTeTiMe::createFromFormat();

/**
* @property ArrayObject $ao
* @property-read ArrayObject $aor
* @property-write ArrayObject $aow
* @method ArrayObject method(ArrayObject|Datetime $p1, null|Arrayaccess $p2)
*/
class CorrectClassNameCase
{
Expand Down
3 changes: 3 additions & 0 deletions test/Sniffs/PHP/CorrectClassNameCaseUnitTest.1.inc.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ DateTime::createFromFormat();

/**
* @property AO $ao
* @property-read AO $aor
* @property-write AO $aow
* @method AO method(AO|DateTime $p1, null|ArrayAccess $p2)
*/
class CorrectClassNameCase
{
Expand Down
3 changes: 3 additions & 0 deletions test/Sniffs/PHP/CorrectClassNameCaseUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ protected function getErrorList(string $testFile = '') : array
10 => 1,
12 => 1,
15 => 1,
16 => 1,
17 => 1,
18 => 3,
];
case 'CorrectClassNameCaseUnitTest.2.inc':
return [
Expand Down
1 change: 1 addition & 0 deletions test/Sniffs/PHP/DisallowFqnUnitTest.3.inc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use ImportedClass;
* Class MyClass
*
* @package MyNamespace
* @method \Other\MethodReturn myMethod(\Other\Param1 $param1, \Other\Param2|\MyNamespace\Param2Other $param2)
* @property \MyNamespace\Date $date
* @property \MyNamespace\Service\DateService $dateService
* @property-read \DateTime $dateTime
Expand Down
4 changes: 4 additions & 0 deletions test/Sniffs/PHP/DisallowFqnUnitTest.3.inc.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace MyNamespace;

use Other\MethodReturn;
use Other\Param1;
use Other\Param2;
use DateTime;
use ArrayObject;
use ArrayAccess;
Expand All @@ -17,6 +20,7 @@ use ImportedClass;
* Class MyClass
*
* @package MyNamespace
* @method MethodReturn myMethod(Param1 $param1, Param2|Param2Other $param2)
* @property Date $date
* @property Service\DateService $dateService
* @property-read DateTime $dateTime
Expand Down
13 changes: 7 additions & 6 deletions test/Sniffs/PHP/DisallowFqnUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,19 @@ protected function getErrorList(string $testFile = '') : array
];
case 'DisallowFqnUnitTest.3.inc':
return [
11 => 1,
11 => 3,
12 => 1,
13 => 1,
14 => 1,
19 => 1,
24 => 1,
15 => 1,
20 => 1,
25 => 1,
32 => 1,
26 => 1,
33 => 1,
35 => 1,
41 => 1,
34 => 1,
36 => 1,
42 => 1,
43 => 1,
];
}

Expand Down

0 comments on commit 8a0c42f

Please sign in to comment.