Skip to content

Commit 5169ab8

Browse files
committed
Replace NeutronStandard TypeHint with custom sniffs
1 parent 97212fd commit 5169ab8

File tree

4 files changed

+256
-4
lines changed

4 files changed

+256
-4
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php declare(strict_types=1); # -*- coding: utf-8 -*-
2+
/*
3+
* This file is part of the php-coding-standards package.
4+
*
5+
* (c) Inpsyde GmbH
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*
10+
* This file contains code from "phpcs-neutron-standard" repository
11+
* found at https://github.com/Automattic/phpcs-neutron-standard
12+
* Copyright (c) Automattic
13+
* released under MIT license.
14+
*/
15+
16+
namespace Inpsyde\InpsydeCodingStandard\Sniffs\CodeQuality;
17+
18+
use Inpsyde\InpsydeCodingStandard\Helpers;
19+
use PHP_CodeSniffer\Sniffs\Sniff;
20+
use PHP_CodeSniffer\Files\File;
21+
22+
class ArgumentTypeDeclarationSniff implements Sniff
23+
{
24+
const TYPE_CODES = [
25+
T_STRING,
26+
T_ARRAY_HINT,
27+
T_CALLABLE,
28+
T_SELF,
29+
];
30+
31+
/**
32+
* @inheritdoc
33+
*/
34+
public function register()
35+
{
36+
return [T_FUNCTION, T_CLOSURE];
37+
}
38+
39+
/**
40+
* @inheritdoc
41+
*/
42+
public function process(File $file, $position)
43+
{
44+
$tokens = $file->getTokens();
45+
46+
$paramsStart = $tokens[$position]['parenthesis_opener'] ?? 0;
47+
$paramsEnd = $tokens[$position]['parenthesis_closer'] ?? 0;
48+
49+
if (!$paramsStart || !$paramsEnd || $paramsStart >= ($paramsEnd - 1)) {
50+
return;
51+
}
52+
53+
$variables = Helpers::filterTokensByType($paramsStart, $paramsEnd, $file, T_VARIABLE);
54+
55+
foreach (array_keys($variables) as $varPosition) {
56+
$typePosition = $file->findPrevious(
57+
[T_WHITESPACE, T_ELLIPSIS],
58+
$varPosition - 1,
59+
$paramsStart + 1,
60+
true
61+
);
62+
63+
$type = $tokens[$typePosition] ?? null;
64+
if ($type && in_array($type['code'], self::TYPE_CODES, true)) {
65+
continue;
66+
}
67+
68+
if (!Helpers::isHookClosure($file, $position)) {
69+
$file->addWarning('Argument type is missing', $position, 'NoArgumentType');
70+
}
71+
}
72+
}
73+
74+
/**
75+
* @param File $file
76+
* @param int $position
77+
* @param array $tokens
78+
* @return bool
79+
*/
80+
private function isAddHook(File $file, int $position, array $tokens): bool
81+
{
82+
$lookForComma = $file->findPrevious(
83+
[T_WHITESPACE],
84+
$position - 1,
85+
null,
86+
true,
87+
null,
88+
true
89+
);
90+
91+
if (!$lookForComma || ($tokens[$lookForComma]['code'] ?? '') !== T_COMMA) {
92+
return false;
93+
}
94+
95+
$functionCallOpen = $file->findPrevious(
96+
[T_OPEN_PARENTHESIS],
97+
$lookForComma - 2,
98+
null,
99+
false,
100+
null,
101+
true
102+
);
103+
104+
if (!$functionCallOpen) {
105+
return false;
106+
}
107+
108+
$functionCall = $file->findPrevious(
109+
[T_WHITESPACE],
110+
$functionCallOpen - 1,
111+
null,
112+
true,
113+
null,
114+
true
115+
);
116+
117+
return in_array(
118+
($tokens[$functionCall]['content'] ?? ''),
119+
['add_action', 'add_filter'],
120+
true
121+
);
122+
}
123+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?php declare(strict_types=1); # -*- coding: utf-8 -*-
2+
/*
3+
* This file is part of the php-coding-standards package.
4+
*
5+
* (c) Inpsyde GmbH
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*
10+
* This file contains code from "phpcs-neutron-standard" repository
11+
* found at https://github.com/Automattic/phpcs-neutron-standard
12+
* Copyright (c) Automattic
13+
* released under MIT license.
14+
*/
15+
16+
namespace Inpsyde\InpsydeCodingStandard\Sniffs\CodeQuality;
17+
18+
use Inpsyde\InpsydeCodingStandard\Helpers;
19+
use PHP_CodeSniffer\Sniffs\Sniff;
20+
use PHP_CodeSniffer\Files\File;
21+
22+
class ReturnTypeDeclarationSniff implements Sniff
23+
{
24+
const TYPE_CODES = [
25+
T_STRING,
26+
T_ARRAY_HINT,
27+
T_CALLABLE,
28+
T_SELF,
29+
];
30+
31+
/**
32+
* @inheritdoc
33+
*/
34+
public function register()
35+
{
36+
return [T_FUNCTION, T_CLOSURE];
37+
}
38+
39+
/**
40+
* @inheritdoc
41+
*/
42+
public function process(File $file, $position)
43+
{
44+
list($functionStart, $functionEnd) = Helpers::functionBoundaries($file, $position);
45+
if (!$functionStart < 0 || $functionEnd <= 0) {
46+
return;
47+
}
48+
49+
list($hasNonVoidReturnType, $hasVoidReturnType, $hasNoReturnType) = $this->returnTypeInfo(
50+
$file,
51+
$position,
52+
$functionEnd
53+
);
54+
55+
list($nonVoidReturnCount, $voidReturnCount) = Helpers::countReturns($file, $position);
56+
57+
$this->maybeErrors(
58+
$hasNonVoidReturnType,
59+
$hasVoidReturnType,
60+
$hasNoReturnType,
61+
$nonVoidReturnCount,
62+
$voidReturnCount,
63+
$file,
64+
$position
65+
);
66+
}
67+
68+
/**
69+
* @param bool $hasNonVoidReturnType
70+
* @param bool $hasVoidReturnType
71+
* @param bool $hasNoReturnType
72+
* @param int $nonVoidReturnCount
73+
* @param int $voidReturnCount
74+
* @param File $file
75+
* @param int $position
76+
*/
77+
private function maybeErrors(
78+
bool $hasNonVoidReturnType,
79+
bool $hasVoidReturnType,
80+
bool $hasNoReturnType,
81+
int $nonVoidReturnCount,
82+
int $voidReturnCount,
83+
File $file,
84+
int $position
85+
) {
86+
if ($hasNonVoidReturnType && ($nonVoidReturnCount === 0 || $voidReturnCount > 0)) {
87+
$msg = 'Return type with';
88+
$file->addError(
89+
$nonVoidReturnCount === 0 ? "{$msg} no return" : "{$msg} void return",
90+
$position,
91+
$nonVoidReturnCount === 0 ? 'MissingReturn' : 'IncorrectVoidReturn'
92+
);
93+
}
94+
95+
if ($nonVoidReturnCount <= 0) {
96+
return;
97+
}
98+
99+
if ($hasNoReturnType) {
100+
$file->addWarning('Return type is missing', $position, 'NoReturnType');
101+
}
102+
103+
if ($hasVoidReturnType) {
104+
$file->addError(
105+
'Void return type when returning non-void',
106+
$position,
107+
'IncorrectVoidReturnType'
108+
);
109+
}
110+
}
111+
112+
/**
113+
* @param File $file
114+
* @param int $functionPosition
115+
* @param int $functionEnd
116+
* @return array
117+
*/
118+
private function returnTypeInfo(File $file, int $functionPosition, int $functionEnd): array
119+
{
120+
$returnType = $file->findNext(
121+
T_RETURN_TYPE,
122+
$functionPosition + 3, // open parenthesis, close parenthesis, colon
123+
$functionEnd - 1
124+
);
125+
126+
$hasNonVoidReturnType = $returnType && $returnType['content'] !== 'void';
127+
$hasVoidReturnType = $returnType && $returnType['content'] === 'void';
128+
$hasNoReturnType = !$returnType;
129+
130+
return [$hasNonVoidReturnType, $hasVoidReturnType, $hasNoReturnType];
131+
}
132+
}

Inpsyde/ruleset.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<rule ref="NeutronStandard">
3939
<exclude name="NeutronStandard.Functions.LongFunction"/>
4040
<exclude name="NeutronStandard.Functions.VariableFunctions"/>
41+
<exclude name="NeutronStandard.Functions.TypeHint"/>
4142
</rule>
4243

4344
<!--

docs/rules-list/neutron-standard.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616
- NeutronStandard.Functions
1717
- NeutronStandard.Functions.DisallowCallUserFunc
1818
- NeutronStandard.Functions.DisallowCallUserFunc.CallUserFunc
19-
- NeutronStandard.Functions.TypeHint
20-
- NeutronStandard.Functions.TypeHint.NoArgumentType
21-
- NeutronStandard.Functions.TypeHint.UnusedReturnType
22-
- NeutronStandard.Functions.TypeHint.IncorrectVoidReturnType
2319
- NeutronStandard.Globals
2420
- NeutronStandard.Globals.DisallowGlobalFunctions
2521
- NeutronStandard.Globals.DisallowGlobalFunctions.GlobalFunctions

0 commit comments

Comments
 (0)