Skip to content

Commit cd09be9

Browse files
committed
Add custom rules instead of Object calisthenic
1 parent d663896 commit cd09be9

12 files changed

+882
-89
lines changed

Inpsyde/Helpers.php

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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+
11+
namespace Inpsyde\CodingStandard;
12+
13+
use PHP_CodeSniffer\Files\File;
14+
15+
/**
16+
* @package php-coding-standards
17+
* @license MIT
18+
*/
19+
class Helpers
20+
{
21+
const CODE_TO_TYPE_MAP = [
22+
T_CONST => 'Constant',
23+
T_CLASS => 'Class',
24+
T_FUNCTION => 'Function',
25+
T_TRAIT => 'Trait',
26+
];
27+
28+
/**
29+
* @param File $file
30+
* @param int $position
31+
* @return mixed[]
32+
*/
33+
public static function classPropertiesTokenIndexes(
34+
File $file,
35+
int $position
36+
): array {
37+
$tokens = $file->getTokens();
38+
$token = $tokens[$position] ?? [];
39+
40+
if (!array_key_exists('scope_opener', $token)
41+
|| !array_key_exists('scope_closer', $token)
42+
) {
43+
return [];
44+
}
45+
46+
$propertyList = [];
47+
$pointer = (int)$token['scope_opener'];
48+
49+
while ($pointer) {
50+
if (self::isProperty($file, $pointer)) {
51+
$propertyList[] = $pointer;
52+
}
53+
$pointer = (int)$file->findNext(
54+
T_VARIABLE,
55+
($pointer + 1),
56+
$token['scope_closer']
57+
);
58+
}
59+
60+
return $propertyList;
61+
}
62+
63+
/**
64+
* @param File $file
65+
* @param int $variablePosition
66+
* @return bool
67+
*/
68+
public static function isProperty(File $file, int $variablePosition): bool
69+
{
70+
$propertyPointer = $file->findPrevious(
71+
[T_STATIC, T_WHITESPACE, T_COMMENT],
72+
$variablePosition - 1,
73+
null,
74+
true
75+
);
76+
77+
$propertyPointerToken = $file->getTokens()[$propertyPointer] ?? [];
78+
79+
return in_array(
80+
($propertyPointerToken['code'] ?? ''),
81+
[T_PRIVATE, T_PROTECTED, T_PUBLIC, T_VAR],
82+
true
83+
);
84+
}
85+
86+
/**
87+
* @param File $file
88+
* @param int $position
89+
* @return string
90+
*/
91+
public static function tokenTypeName(File $file, int $position): string
92+
{
93+
$token = $file->getTokens()[$position];
94+
$tokenCode = $token['code'];
95+
if (isset(self::CODE_TO_TYPE_MAP[$tokenCode])) {
96+
return self::CODE_TO_TYPE_MAP[$tokenCode];
97+
}
98+
99+
if ($token['code'] === T_VARIABLE) {
100+
if (self::isProperty($file, $position)) {
101+
return 'Property';
102+
}
103+
104+
return 'Variable';
105+
}
106+
107+
return '';
108+
}
109+
110+
/**
111+
* @param File $file
112+
* @param int $position
113+
* @return string
114+
*/
115+
public static function tokenName(File $file, int $position): string
116+
{
117+
$name = $file->getTokens()[$position]['content'] ?? '';
118+
119+
if (strpos($name, '$') === 0) {
120+
return trim($name, '$');
121+
}
122+
123+
$namePosition = $file->findNext(T_STRING, $position, $position + 3);
124+
125+
return $file->getTokens()[$namePosition]['content'];
126+
}
127+
}

Inpsyde/PHPCSAliases.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
/**
3+
* PHPCS cross-version compatibility helper.
4+
*
5+
* @package WPCS\WordPressCodingStandards
6+
* @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
7+
* @license https://opensource.org/licenses/MIT MIT
8+
* @since 0.13.0
9+
*/
10+
11+
/*
12+
* Alias a number of PHPCS 3.x classes to their PHPCS 2.x equivalents.
13+
*
14+
* This file is auto-loaded by PHPCS 3.x before any sniffs are loaded
15+
* through the PHPCS 3.x `<autoload>` ruleset directive.
16+
*
17+
* {@internal The PHPCS files have been reorganized in PHPCS 3.x, quite
18+
* a few "old" classes have been split and spread out over several "new"
19+
* classes. In other words, this will only work for a limited number
20+
* of classes.}}
21+
*
22+
* {@internal The `class_exists` wrappers are needed to play nice with other
23+
* external PHPCS standards creating cross-version compatibility in the same
24+
* manner.}}
25+
*/
26+
if (!defined('WPCS_PHPCS_ALIASES_SET')) {
27+
// PHPCS base classes/interface.
28+
if (!interface_exists('\PHP_CodeSniffer_Sniff')) {
29+
class_alias('PHP_CodeSniffer\Sniffs\Sniff', '\PHP_CodeSniffer_Sniff');
30+
}
31+
if (!class_exists('\PHP_CodeSniffer_File')) {
32+
class_alias('PHP_CodeSniffer\Files\File', '\PHP_CodeSniffer_File');
33+
}
34+
if (!class_exists('\PHP_CodeSniffer_Tokens')) {
35+
class_alias('PHP_CodeSniffer\Util\Tokens', '\PHP_CodeSniffer_Tokens');
36+
}
37+
38+
// PHPCS classes which are being extended by WPCS sniffs.
39+
if (!class_exists('\PHP_CodeSniffer_Standards_AbstractVariableSniff')) {
40+
class_alias('PHP_CodeSniffer\Sniffs\AbstractVariableSniff',
41+
'\PHP_CodeSniffer_Standards_AbstractVariableSniff');
42+
}
43+
if (!class_exists('\PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff')) {
44+
class_alias('PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidFunctionNameSniff',
45+
'\PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff');
46+
}
47+
if (!class_exists('\Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff')) {
48+
class_alias('PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\OperatorSpacingSniff',
49+
'\Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff');
50+
}
51+
if (!class_exists('\Squiz_Sniffs_WhiteSpace_SemicolonSpacingSniff')) {
52+
class_alias('PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\SemicolonSpacingSniff',
53+
'\Squiz_Sniffs_WhiteSpace_SemicolonSpacingSniff');
54+
}
55+
56+
define('WPCS_PHPCS_ALIASES_SET', true);
57+
58+
/*
59+
* Register our own autoloader for the WPCS abstract classes & the helper class.
60+
*
61+
* This can be removed once the minimum required version of WPCS for the
62+
* PHPCS 3.x branch has gone up to 3.1.0 (unreleased as of yet) or
63+
* whichever version contains the fix for upstream #1591.
64+
*
65+
* @link https://github.com/squizlabs/PHP_CodeSniffer/issues/1564
66+
* @link https://github.com/squizlabs/PHP_CodeSniffer/issues/1591
67+
*/
68+
spl_autoload_register(function ($class) {
69+
// Only try & load our own classes.
70+
if (stripos($class, 'WordPress') !== 0) {
71+
return;
72+
}
73+
74+
// PHPCS handles the Test and Sniff classes without problem.
75+
if (stripos($class, '\Tests\\') !== false || stripos($class,
76+
'\Sniffs\\') !== false) {
77+
return;
78+
}
79+
80+
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR . strtr($class, '\\',
81+
DIRECTORY_SEPARATOR) . '.php';
82+
83+
if (file_exists($file)) {
84+
include_once $file;
85+
}
86+
});
87+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
11+
namespace Inpsyde\CodingStandard\Sniffs\CodeQuality;
12+
13+
use Inpsyde\CodingStandard\Helpers;
14+
use PHP_CodeSniffer\Files\File;
15+
use PHP_CodeSniffer\Sniffs\Sniff;
16+
17+
/**
18+
* @package php-coding-standards
19+
* @license MIT
20+
*/
21+
final class ElementNameMinimalLengthSniff implements Sniff
22+
{
23+
24+
/**
25+
* @var int
26+
*/
27+
public $minLength = 3;
28+
29+
/**
30+
* @var string[]
31+
*/
32+
public $allowedShortNames = ['i', 'id', 'to', 'up', 'ok', 'no', 'go', 'it'];
33+
34+
/**
35+
* @return int[]
36+
*/
37+
public function register(): array
38+
{
39+
return [T_CLASS, T_TRAIT, T_INTERFACE, T_CONST, T_FUNCTION, T_VARIABLE];
40+
}
41+
42+
/**
43+
* @param File $file
44+
* @param int $position
45+
*/
46+
public function process(File $file, $position): void
47+
{
48+
$elementName = Helpers::tokenName($file, $position);
49+
$elementNameLength = mb_strlen($elementName);
50+
51+
if ($this->shouldBeSkipped($elementNameLength, $elementName)) {
52+
return;
53+
}
54+
55+
$typeName = Helpers::tokenTypeName($file, $position);
56+
$message = sprintf(
57+
'%s name "%s" is only %d chars long. Must be at least %d.',
58+
$typeName,
59+
$elementName,
60+
$elementNameLength,
61+
$this->minLength
62+
);
63+
64+
$file->addError($message, $position, 'ElementNameMinimalLength');
65+
}
66+
67+
/**
68+
* @param int $elementNameLength
69+
* @param string $elementName
70+
* @return bool
71+
*/
72+
private function shouldBeSkipped(
73+
int $elementNameLength,
74+
string $elementName
75+
): bool {
76+
if ($elementNameLength >= $this->minLength) {
77+
return true;
78+
}
79+
80+
if ($this->isShortNameAllowed($elementName)) {
81+
return true;
82+
}
83+
84+
return false;
85+
}
86+
87+
/**
88+
* @param string $variableName
89+
* @return bool
90+
*/
91+
private function isShortNameAllowed(string $variableName): bool
92+
{
93+
return in_array($variableName, $this->allowedShortNames);
94+
}
95+
}

0 commit comments

Comments
 (0)