golden hour
/opt/cpanel/ea-wappspector/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers
⬆️ Go Up
Upload
File/Folder
Size
Actions
Annotation.php
1.11 KB
Del
OK
AnnotationHelper.php
8.67 KB
Del
OK
AnnotationTypeHelper.php
10.15 KB
Del
OK
ArrayHelper.php
6.25 KB
Del
OK
ArrayKeyValue.php
3.6 KB
Del
OK
Attribute.php
1.14 KB
Del
OK
AttributeHelper.php
5 KB
Del
OK
CatchHelper.php
2.18 KB
Del
OK
ClassHelper.php
3.03 KB
Del
OK
Comment.php
430 B
Del
OK
CommentHelper.php
2.52 KB
Del
OK
ConditionHelper.php
10.2 KB
Del
OK
ConstantHelper.php
2.03 KB
Del
OK
DocCommentHelper.php
7.12 KB
Del
OK
EmptyFileException.php
502 B
Del
OK
FixerHelper.php
1.97 KB
Del
OK
FunctionHelper.php
16.55 KB
Del
OK
IdentificatorHelper.php
7.34 KB
Del
OK
IndentationHelper.php
2.84 KB
Del
OK
NamespaceHelper.php
5.8 KB
Del
OK
ParameterHelper.php
893 B
Del
OK
ParsedDocComment.php
2.27 KB
Del
OK
PhpDocParserHelper.php
1.56 KB
Del
OK
PropertyHelper.php
6.39 KB
Del
OK
ReferencedName.php
1.32 KB
Del
OK
ReferencedNameHelper.php
15.13 KB
Del
OK
ScopeHelper.php
1.48 KB
Del
OK
SniffLocalCache.php
1.2 KB
Del
OK
SniffSettingsHelper.php
2.01 KB
Del
OK
StringHelper.php
485 B
Del
OK
SuppressHelper.php
2.27 KB
Del
OK
TernaryOperatorHelper.php
4.97 KB
Del
OK
TokenHelper.php
12.87 KB
Del
OK
TokenPointerOutOfBoundsException.php
774 B
Del
OK
TypeHelper.php
740 B
Del
OK
TypeHint.php
966 B
Del
OK
TypeHintHelper.php
10.67 KB
Del
OK
UseStatement.php
2.53 KB
Del
OK
UseStatementHelper.php
7.82 KB
Del
OK
VariableHelper.php
5.03 KB
Del
OK
YodaHelper.php
9.28 KB
Del
OK
Edit: FunctionHelper.php
<?php declare(strict_types = 1); namespace SlevomatCodingStandard\Helpers; use Generator; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\TypelessParamTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode; use function array_filter; use function array_map; use function array_pop; use function array_reverse; use function array_values; use function in_array; use function iterator_to_array; use function preg_match; use function preg_replace; use function sprintf; use function substr_count; use const T_ANON_CLASS; use const T_BITWISE_AND; use const T_CLASS; use const T_CLOSURE; use const T_COLON; use const T_ELLIPSIS; use const T_ENUM; use const T_FUNCTION; use const T_INTERFACE; use const T_NULLABLE; use const T_RETURN; use const T_SEMICOLON; use const T_STRING; use const T_TRAIT; use const T_USE; use const T_VARIABLE; use const T_WHITESPACE; use const T_YIELD; use const T_YIELD_FROM; /** * @internal */ class FunctionHelper { public const LINE_INCLUDE_COMMENT = 1; public const LINE_INCLUDE_WHITESPACE = 2; public const SPECIAL_FUNCTIONS = [ 'array_key_exists', 'array_slice', 'assert', 'boolval', 'call_user_func', 'call_user_func_array', 'chr', 'constant', 'count', 'define', 'defined', 'dirname', 'doubleval', 'extension_loaded', 'floatval', 'func_get_args', 'func_num_args', 'function_exists', 'get_called_class', 'get_class', 'gettype', 'in_array', 'ini_get', 'intval', 'is_array', 'is_bool', 'is_callable', 'is_double', 'is_float', 'is_int', 'is_integer', 'is_long', 'is_null', 'is_object', 'is_real', 'is_resource', 'is_scalar', 'is_string', 'ord', 'sizeof', 'sprintf', 'strlen', 'strval', ]; public static function getTypeLabel(File $phpcsFile, int $functionPointer): string { return self::isMethod($phpcsFile, $functionPointer) ? 'Method' : 'Function'; } public static function getName(File $phpcsFile, int $functionPointer): string { $tokens = $phpcsFile->getTokens(); return $tokens[TokenHelper::findNext( $phpcsFile, T_STRING, $functionPointer + 1, $tokens[$functionPointer]['parenthesis_opener'], )]['content']; } public static function getFullyQualifiedName(File $phpcsFile, int $functionPointer): string { $name = self::getName($phpcsFile, $functionPointer); $namespace = NamespaceHelper::findCurrentNamespaceName($phpcsFile, $functionPointer); if (self::isMethod($phpcsFile, $functionPointer)) { foreach (array_reverse( $phpcsFile->getTokens()[$functionPointer]['conditions'], true, ) as $conditionPointer => $conditionTokenCode) { if ($conditionTokenCode === T_ANON_CLASS) { return sprintf('class@anonymous::%s', $name); } if (in_array($conditionTokenCode, [T_CLASS, T_INTERFACE, T_TRAIT, T_ENUM], true)) { $name = sprintf( '%s%s::%s', NamespaceHelper::NAMESPACE_SEPARATOR, ClassHelper::getName($phpcsFile, $conditionPointer), $name, ); break; } } return $namespace !== null ? sprintf('%s%s%s', NamespaceHelper::NAMESPACE_SEPARATOR, $namespace, $name) : $name; } return $namespace !== null ? sprintf('%s%s%s%s', NamespaceHelper::NAMESPACE_SEPARATOR, $namespace, NamespaceHelper::NAMESPACE_SEPARATOR, $name) : $name; } public static function isAbstract(File $phpcsFile, int $functionPointer): bool { return !isset($phpcsFile->getTokens()[$functionPointer]['scope_opener']); } public static function isMethod(File $phpcsFile, int $functionPointer): bool { $functionPointerConditions = $phpcsFile->getTokens()[$functionPointer]['conditions']; if ($functionPointerConditions === []) { return false; } $lastFunctionPointerCondition = array_pop($functionPointerConditions); return in_array($lastFunctionPointerCondition, Tokens::$ooScopeTokens, true); } public static function findClassPointer(File $phpcsFile, int $functionPointer): ?int { $tokens = $phpcsFile->getTokens(); if ($tokens[$functionPointer]['code'] === T_CLOSURE) { return null; } foreach (array_reverse($tokens[$functionPointer]['conditions'], true) as $conditionPointer => $conditionTokenCode) { if (!in_array($conditionTokenCode, Tokens::$ooScopeTokens, true)) { continue; } return $conditionPointer; } return null; } /** * @return list<string> */ public static function getParametersNames(File $phpcsFile, int $functionPointer): array { $tokens = $phpcsFile->getTokens(); $parametersNames = []; for ($i = $tokens[$functionPointer]['parenthesis_opener'] + 1; $i < $tokens[$functionPointer]['parenthesis_closer']; $i++) { if ($tokens[$i]['code'] !== T_VARIABLE) { continue; } $parametersNames[] = $tokens[$i]['content']; } return $parametersNames; } /** * @return array<string, TypeHint|null> */ public static function getParametersTypeHints(File $phpcsFile, int $functionPointer): array { $tokens = $phpcsFile->getTokens(); $parametersTypeHints = []; for ($i = $tokens[$functionPointer]['parenthesis_opener'] + 1; $i < $tokens[$functionPointer]['parenthesis_closer']; $i++) { if ($tokens[$i]['code'] !== T_VARIABLE) { continue; } $parameterName = $tokens[$i]['content']; $pointerBeforeVariable = TokenHelper::findPreviousExcluding( $phpcsFile, [...TokenHelper::INEFFECTIVE_TOKEN_CODES, T_BITWISE_AND, T_ELLIPSIS], $i - 1, ); if (!in_array($tokens[$pointerBeforeVariable]['code'], TokenHelper::TYPE_HINT_TOKEN_CODES, true)) { $parametersTypeHints[$parameterName] = null; continue; } $typeHintEndPointer = $pointerBeforeVariable; $typeHintStartPointer = TypeHintHelper::getStartPointer($phpcsFile, $typeHintEndPointer); $pointerBeforeTypeHint = TokenHelper::findPreviousEffective($phpcsFile, $typeHintStartPointer - 1); $isNullable = $tokens[$pointerBeforeTypeHint]['code'] === T_NULLABLE; if ($isNullable) { $typeHintStartPointer = $pointerBeforeTypeHint; } $typeHint = TokenHelper::getContent($phpcsFile, $typeHintStartPointer, $typeHintEndPointer); /** @var string $typeHint */ $typeHint = preg_replace('~\s+~', '', $typeHint); if (!$isNullable) { $isNullable = preg_match('~(?:^|\|)null(?:\||$)~i', $typeHint) === 1; } $parametersTypeHints[$parameterName] = new TypeHint($typeHint, $isNullable, $typeHintStartPointer, $typeHintEndPointer); } return $parametersTypeHints; } public static function returnsValue(File $phpcsFile, int $functionPointer): bool { $tokens = $phpcsFile->getTokens(); $firstPointerInScope = $tokens[$functionPointer]['scope_opener'] + 1; for ($i = $firstPointerInScope; $i < $tokens[$functionPointer]['scope_closer']; $i++) { if (!in_array($tokens[$i]['code'], [T_YIELD, T_YIELD_FROM], true)) { continue; } if (!ScopeHelper::isInSameScope($phpcsFile, $i, $firstPointerInScope)) { continue; } return true; } for ($i = $firstPointerInScope; $i < $tokens[$functionPointer]['scope_closer']; $i++) { if ($tokens[$i]['code'] !== T_RETURN) { continue; } if (!ScopeHelper::isInSameScope($phpcsFile, $i, $firstPointerInScope)) { continue; } $nextEffectiveTokenPointer = TokenHelper::findNextEffective($phpcsFile, $i + 1); return $tokens[$nextEffectiveTokenPointer]['code'] !== T_SEMICOLON; } return false; } public static function findReturnTypeHint(File $phpcsFile, int $functionPointer): ?TypeHint { $tokens = $phpcsFile->getTokens(); $nextPointer = TokenHelper::findNextEffective($phpcsFile, $tokens[$functionPointer]['parenthesis_closer'] + 1); if ($tokens[$nextPointer]['code'] === T_USE) { $useParenthesisOpener = TokenHelper::findNextEffective($phpcsFile, $nextPointer + 1); $colonPointer = TokenHelper::findNextEffective($phpcsFile, $tokens[$useParenthesisOpener]['parenthesis_closer'] + 1); } else { $colonPointer = $nextPointer; } if ($tokens[$colonPointer]['code'] !== T_COLON) { return null; } $typeHintStartPointer = TokenHelper::findNextEffective($phpcsFile, $colonPointer + 1); $nullable = $tokens[$typeHintStartPointer]['code'] === T_NULLABLE; $pointerAfterTypeHint = self::isAbstract($phpcsFile, $functionPointer) ? TokenHelper::findNext($phpcsFile, T_SEMICOLON, $typeHintStartPointer + 1) : $tokens[$functionPointer]['scope_opener']; $typeHintEndPointer = TokenHelper::findPreviousEffective($phpcsFile, $pointerAfterTypeHint - 1); $typeHint = TokenHelper::getContent($phpcsFile, $typeHintStartPointer, $typeHintEndPointer); /** @var string $typeHint */ $typeHint = preg_replace('~\s+~', '', $typeHint); if (!$nullable) { $nullable = preg_match('~(?:^|\|)null(?:\||$)~i', $typeHint) === 1; } return new TypeHint($typeHint, $nullable, $typeHintStartPointer, $typeHintEndPointer); } public static function hasReturnTypeHint(File $phpcsFile, int $functionPointer): bool { return self::findReturnTypeHint($phpcsFile, $functionPointer) !== null; } /** * @return list<Annotation<ParamTagValueNode>|Annotation<TypelessParamTagValueNode>> */ public static function getParametersAnnotations(File $phpcsFile, int $functionPointer): array { return AnnotationHelper::getAnnotations($phpcsFile, $functionPointer, '@param'); } /** * @return array<string, Annotation<VarTagValueNode>|Annotation<ParamTagValueNode>|Annotation<TypelessParamTagValueNode>> */ public static function getValidParametersAnnotations(File $phpcsFile, int $functionPointer): array { $tokens = $phpcsFile->getTokens(); $parametersAnnotations = []; if (self::getName($phpcsFile, $functionPointer) === '__construct') { for ($i = $tokens[$functionPointer]['parenthesis_opener'] + 1; $i < $tokens[$functionPointer]['parenthesis_closer']; $i++) { if ($tokens[$i]['code'] !== T_VARIABLE) { continue; } $varAnnotations = AnnotationHelper::getAnnotations($phpcsFile, $i, '@var'); if ($varAnnotations === []) { continue; } $parametersAnnotations[$tokens[$i]['content']] = $varAnnotations[0]; } } foreach (self::getParametersAnnotations($phpcsFile, $functionPointer) as $parameterAnnotation) { if ($parameterAnnotation->isInvalid()) { continue; } $parametersAnnotations[$parameterAnnotation->getValue()->parameterName] = $parameterAnnotation; } return $parametersAnnotations; } /** * @return array<string, Annotation<VarTagValueNode>|Annotation<ParamTagValueNode>> */ public static function getValidPrefixedParametersAnnotations(File $phpcsFile, int $functionPointer): array { $tokens = $phpcsFile->getTokens(); $parametersAnnotations = []; foreach (AnnotationHelper::STATIC_ANALYSIS_PREFIXES as $prefix) { if (self::getName($phpcsFile, $functionPointer) === '__construct') { for ($i = $tokens[$functionPointer]['parenthesis_opener'] + 1; $i < $tokens[$functionPointer]['parenthesis_closer']; $i++) { if ($tokens[$i]['code'] !== T_VARIABLE) { continue; } /** @var list<Annotation<VarTagValueNode>> $varAnnotations */ $varAnnotations = AnnotationHelper::getAnnotations($phpcsFile, $i, sprintf('@%s-var', $prefix)); if ($varAnnotations === []) { continue; } $parametersAnnotations[$tokens[$i]['content']] = $varAnnotations[0]; } } /** @var list<Annotation<ParamTagValueNode>> $annotations */ $annotations = AnnotationHelper::getAnnotations($phpcsFile, $functionPointer, sprintf('@%s-param', $prefix)); foreach ($annotations as $parameterAnnotation) { if ($parameterAnnotation->isInvalid()) { continue; } $parametersAnnotations[$parameterAnnotation->getValue()->parameterName] = $parameterAnnotation; } } return $parametersAnnotations; } /** * @return Annotation<ReturnTagValueNode>|null */ public static function findReturnAnnotation(File $phpcsFile, int $functionPointer): ?Annotation { /** @var list<Annotation<ReturnTagValueNode>> $returnAnnotations */ $returnAnnotations = AnnotationHelper::getAnnotations($phpcsFile, $functionPointer, '@return'); if ($returnAnnotations === []) { return null; } return $returnAnnotations[0]; } /** * @return list<Annotation> */ public static function getValidPrefixedReturnAnnotations(File $phpcsFile, int $functionPointer): array { $returnAnnotations = []; $annotations = AnnotationHelper::getAnnotations($phpcsFile, $functionPointer); foreach (AnnotationHelper::STATIC_ANALYSIS_PREFIXES as $prefix) { $prefixedAnnotationName = sprintf('@%s-return', $prefix); foreach ($annotations as $annotation) { if ($annotation->isInvalid()) { continue; } if ($annotation->getName() === $prefixedAnnotationName) { $returnAnnotations[] = $annotation; } } } return $returnAnnotations; } /** * @return list<string> */ public static function getAllFunctionNames(File $phpcsFile): array { $previousFunctionPointer = 0; return array_map( static fn (int $functionPointer): string => self::getName($phpcsFile, $functionPointer), array_values(array_filter( iterator_to_array(self::getAllFunctionOrMethodPointers($phpcsFile, $previousFunctionPointer)), static fn (int $functionOrMethodPointer): bool => !self::isMethod($phpcsFile, $functionOrMethodPointer), )), ); } /** * @param int $flags optional bitmask of self::LINE_INCLUDE_* constants */ public static function getFunctionLengthInLines(File $file, int $functionPosition, int $flags = 0): int { if (self::isAbstract($file, $functionPosition)) { return 0; } return self::getLineCount($file, $functionPosition, $flags); } public static function getLineCount(File $file, int $tokenPosition, int $flags = 0): int { $includeWhitespace = ($flags & self::LINE_INCLUDE_WHITESPACE) === self::LINE_INCLUDE_WHITESPACE; $includeComments = ($flags & self::LINE_INCLUDE_COMMENT) === self::LINE_INCLUDE_COMMENT; $tokens = $file->getTokens(); $token = $tokens[$tokenPosition]; $tokenOpenerPosition = $token['scope_opener'] ?? $tokenPosition; $tokenCloserPosition = $token['scope_closer'] ?? $file->numTokens - 1; $tokenOpenerLine = $tokens[$tokenOpenerPosition]['line']; $tokenCloserLine = $tokens[$tokenCloserPosition]['line']; $lineCount = 0; $lastCommentLine = null; $previousIncludedPosition = null; for ($position = $tokenOpenerPosition; $position <= $tokenCloserPosition - 1; $position++) { $token = $tokens[$position]; if ($includeComments === false) { if (in_array($token['code'], Tokens::$commentTokens, true)) { if ( $previousIncludedPosition !== null && substr_count($token['content'], $file->eolChar) > 0 && $token['line'] === $tokens[$previousIncludedPosition]['line'] ) { // Comment with linebreak starting on same line as included Token $lineCount++; } // Don't include comment $lastCommentLine = $token['line']; continue; } if ( $previousIncludedPosition !== null && $token['code'] === T_WHITESPACE && $token['line'] === $lastCommentLine && $token['line'] !== $tokens[$previousIncludedPosition]['line'] ) { // Whitespace after block comment... still on comment line... // Ignore along with the comment continue; } } if ($token['code'] === T_WHITESPACE) { $nextNonWhitespacePosition = $file->findNext(T_WHITESPACE, $position + 1, $tokenCloserPosition + 1, true); if ( $includeWhitespace === false && $token['column'] === 1 && $nextNonWhitespacePosition !== false && $tokens[$nextNonWhitespacePosition]['line'] !== $token['line'] ) { // This line is nothing but whitepace $position = $nextNonWhitespacePosition - 1; continue; } if ($previousIncludedPosition === $tokenOpenerPosition && $token['line'] === $tokenOpenerLine) { // Don't linclude line break after opening "{" // Unless there was code or an (included) comment following the "{" continue; } } if ($token['code'] !== T_WHITESPACE) { $previousIncludedPosition = $position; } $newLineFoundCount = substr_count($token['content'], $file->eolChar); $lineCount += $newLineFoundCount; } if ($tokens[$previousIncludedPosition]['line'] === $tokenCloserLine) { // There is code or comment on the closing "}" line... $lineCount++; } return $lineCount; } /** * @return Generator<int> */ private static function getAllFunctionOrMethodPointers(File $phpcsFile, int &$previousFunctionPointer): Generator { do { $nextFunctionPointer = TokenHelper::findNext($phpcsFile, T_FUNCTION, $previousFunctionPointer + 1); if ($nextFunctionPointer === null) { break; } $previousFunctionPointer = $nextFunctionPointer; yield $nextFunctionPointer; } while (true); } }
Save