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: TypeHintHelper.php
<?php declare(strict_types = 1); namespace SlevomatCodingStandard\Helpers; use PHP_CodeSniffer\Files\File; use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasImportTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasTagValueNode; use function array_key_exists; use function array_map; use function array_merge; use function array_unique; use function count; use function implode; use function in_array; use function preg_match; use function preg_split; use function sort; use function sprintf; use function substr; use const PREG_SPLIT_DELIM_CAPTURE; use const T_FUNCTION; use const T_WHITESPACE; /** * @internal */ class TypeHintHelper { public static function isValidTypeHint( string $typeHint, bool $enableObjectTypeHint, bool $enableStaticTypeHint, bool $enableMixedTypeHint, bool $enableStandaloneNullTrueFalseTypeHints ): bool { if (self::isSimpleTypeHint($typeHint)) { return true; } if ($typeHint === 'object') { return $enableObjectTypeHint; } if ($typeHint === 'static') { return $enableStaticTypeHint; } if ($typeHint === 'mixed') { return $enableMixedTypeHint; } if (in_array($typeHint, ['null', 'true', 'false'], true)) { return $enableStandaloneNullTrueFalseTypeHints; } return !self::isSimpleUnofficialTypeHints($typeHint); } public static function isSimpleTypeHint(string $typeHint): bool { return in_array($typeHint, self::getSimpleTypeHints(), true); } public static function isSimpleIterableTypeHint(string $typeHint): bool { return in_array($typeHint, self::getSimpleIterableTypeHints(), true); } public static function convertLongSimpleTypeHintToShort(string $typeHint): string { $longToShort = [ 'integer' => 'int', 'boolean' => 'bool', ]; return array_key_exists($typeHint, $longToShort) ? $longToShort[$typeHint] : $typeHint; } public static function isUnofficialUnionTypeHint(string $typeHint): bool { return in_array($typeHint, ['scalar', 'numeric', 'array-key'], true); } public static function isVoidTypeHint(string $typeHint): bool { return $typeHint === 'void'; } public static function isNeverTypeHint(string $typeHint): bool { return in_array($typeHint, ['never', 'never-return', 'never-returns', 'no-return'], true); } /** * @return list<string> */ public static function convertUnofficialUnionTypeHintToOfficialTypeHints(string $typeHint): array { $conversion = [ 'scalar' => ['string', 'int', 'float', 'bool'], 'numeric' => ['int', 'float', 'string'], 'array-key' => ['int', 'string'], ]; return $conversion[$typeHint]; } public static function isTypeDefinedInAnnotation(File $phpcsFile, int $pointer, string $typeHint): bool { $docCommentOpenPointer = DocCommentHelper::findDocCommentOpenPointer($phpcsFile, $pointer); if ($docCommentOpenPointer === null) { return false; } return self::isTemplate($phpcsFile, $docCommentOpenPointer, $typeHint) || self::isAlias($phpcsFile, $docCommentOpenPointer, $typeHint); } public static function getFullyQualifiedTypeHint(File $phpcsFile, int $pointer, string $typeHint): string { if (self::isSimpleTypeHint($typeHint)) { return self::convertLongSimpleTypeHintToShort($typeHint); } return NamespaceHelper::resolveClassName($phpcsFile, $typeHint, $pointer); } /** * @return list<string> */ public static function getSimpleTypeHints(): array { static $simpleTypeHints; $simpleTypeHints ??= [ 'int', 'integer', 'false', 'float', 'string', 'bool', 'boolean', 'callable', 'self', 'array', 'iterable', 'void', 'never', ]; return $simpleTypeHints; } /** * @return list<string> */ public static function getSimpleIterableTypeHints(): array { return [ 'array', 'iterable', ]; } public static function isSimpleUnofficialTypeHints(string $typeHint): bool { static $simpleUnofficialTypeHints; // See https://psalm.dev/docs/annotating_code/type_syntax/atomic_types/ $simpleUnofficialTypeHints ??= [ 'null', 'mixed', 'scalar', 'numeric', 'true', 'object', 'resource', 'static', '$this', 'array-key', 'list', 'non-empty-array', 'non-empty-list', 'empty', 'positive-int', 'non-positive-int', 'negative-int', 'non-negative-int', 'literal-int', 'int-mask', 'min', 'max', 'callable-array', 'callable-string', ]; return in_array($typeHint, $simpleUnofficialTypeHints, true) || preg_match('~-string$~i', $typeHint) === 1; } /** * @param list<string> $traversableTypeHints */ public static function isTraversableType(string $type, array $traversableTypeHints): bool { return self::isSimpleIterableTypeHint($type) || in_array($type, $traversableTypeHints, true); } public static function typeHintEqualsAnnotation( File $phpcsFile, int $functionPointer, string $typeHint, string $typeHintInAnnotation ): bool { /** @var list<string> $typeHintParts */ $typeHintParts = preg_split('~([&|])~', self::normalize($typeHint), -1, PREG_SPLIT_DELIM_CAPTURE); /** @var list<string> $typeHintInAnnotationParts */ $typeHintInAnnotationParts = preg_split('~([&|])~', self::normalize($typeHintInAnnotation), -1, PREG_SPLIT_DELIM_CAPTURE); if (count($typeHintParts) !== count($typeHintInAnnotationParts)) { return false; } for ($i = 0; $i < count($typeHintParts); $i++) { if ( ( $typeHintParts[$i] === '|' || $typeHintParts[$i] === '&' ) && $typeHintParts[$i] !== $typeHintInAnnotationParts[$i] ) { return false; } if (self::getFullyQualifiedTypeHint($phpcsFile, $functionPointer, $typeHintParts[$i]) !== self::getFullyQualifiedTypeHint( $phpcsFile, $functionPointer, $typeHintInAnnotationParts[$i], )) { return false; } } return true; } public static function getStartPointer(File $phpcsFile, int $endPointer): int { $previousPointer = TokenHelper::findPreviousExcluding( $phpcsFile, [T_WHITESPACE, ...TokenHelper::TYPE_HINT_TOKEN_CODES], $endPointer - 1, ); return TokenHelper::findNextNonWhitespace($phpcsFile, $previousPointer + 1); } private static function isTemplate(File $phpcsFile, int $docCommentOpenPointer, string $typeHint): bool { static $templateAnnotationNames = null; if ($templateAnnotationNames === null) { foreach (['template', 'template-covariant'] as $annotationName) { $templateAnnotationNames[] = sprintf('@%s', $annotationName); foreach (AnnotationHelper::STATIC_ANALYSIS_PREFIXES as $prefixAnnotationName) { $templateAnnotationNames[] = sprintf('@%s-%s', $prefixAnnotationName, $annotationName); } } } $containsTypeHintInTemplateAnnotation = static function (int $docCommentOpenPointer) use ($phpcsFile, $templateAnnotationNames, $typeHint): bool { foreach ($templateAnnotationNames as $templateAnnotationName) { /** @var list<Annotation<TemplateTagValueNode>> $annotations */ $annotations = AnnotationHelper::getAnnotations($phpcsFile, $docCommentOpenPointer, $templateAnnotationName); foreach ($annotations as $templateAnnotation) { if ($templateAnnotation->isInvalid()) { continue; } if ($templateAnnotation->getValue()->name === $typeHint) { return true; } } } return false; }; $tokens = $phpcsFile->getTokens(); $docCommentOwnerPointer = DocCommentHelper::findDocCommentOwnerPointer($phpcsFile, $docCommentOpenPointer); if ($docCommentOwnerPointer !== null) { if (in_array($tokens[$docCommentOwnerPointer]['code'], TokenHelper::CLASS_TYPE_TOKEN_CODES, true)) { return $containsTypeHintInTemplateAnnotation($docCommentOpenPointer); } if ($tokens[$docCommentOwnerPointer]['code'] === T_FUNCTION && $containsTypeHintInTemplateAnnotation($docCommentOpenPointer)) { return true; } } $classPointer = ClassHelper::getClassPointer($phpcsFile, $docCommentOpenPointer); if ($classPointer === null) { return false; } $classDocCommentOpenPointer = DocCommentHelper::findDocCommentOpenPointer($phpcsFile, $classPointer); if ($classDocCommentOpenPointer === null) { return false; } return $containsTypeHintInTemplateAnnotation($classDocCommentOpenPointer); } private static function isAlias(File $phpcsFile, int $docCommentOpenPointer, string $typeHint): bool { static $aliasAnnotationNames = null; if ($aliasAnnotationNames === null) { foreach (['type', 'import-type'] as $annotationName) { foreach (AnnotationHelper::STATIC_ANALYSIS_PREFIXES as $prefixAnnotationName) { $aliasAnnotationNames[] = sprintf('@%s-%s', $prefixAnnotationName, $annotationName); } } } $classPointer = ClassHelper::getClassPointer($phpcsFile, $docCommentOpenPointer); if ($classPointer === null) { return false; } $classDocCommentOpenPointer = DocCommentHelper::findDocCommentOpenPointer($phpcsFile, $classPointer); if ($classDocCommentOpenPointer === null) { return false; } foreach ($aliasAnnotationNames as $aliasAnnotationName) { $annotations = AnnotationHelper::getAnnotations($phpcsFile, $classDocCommentOpenPointer, $aliasAnnotationName); foreach ($annotations as $aliasAnnotation) { $aliasAnnotationValue = $aliasAnnotation->getValue(); if ($aliasAnnotationValue instanceof TypeAliasTagValueNode && $aliasAnnotationValue->alias === $typeHint) { return true; } if (!($aliasAnnotationValue instanceof TypeAliasImportTagValueNode)) { continue; } if ($aliasAnnotationValue->importedAs === $typeHint) { return true; } if ($aliasAnnotationValue->importedAlias === $typeHint) { return true; } } } return false; } private static function normalize(string $typeHint): string { if (StringHelper::startsWith($typeHint, '?')) { $typeHint = substr($typeHint, 1) . '|null'; } if (self::isNeverTypeHint($typeHint)) { return 'never'; } /** @var list<string> $parts */ $parts = preg_split('~([&|])~', $typeHint, -1, PREG_SPLIT_DELIM_CAPTURE); $hints = []; $delimiter = '|'; foreach ($parts as $part) { if ($part === '|' || $part === '&') { $delimiter = $part; continue; } $hints[] = $part; } if (in_array('mixed', $hints, true)) { return 'mixed'; } $convertedHints = []; foreach ($hints as $hint) { if (self::isUnofficialUnionTypeHint($hint) && $delimiter !== '&') { $convertedHints = array_merge($convertedHints, self::convertUnofficialUnionTypeHintToOfficialTypeHints($hint)); } else { $convertedHints[] = $hint; } } $convertedHints = array_unique($convertedHints); if (count($convertedHints) > 1) { $convertedHints = array_map(static fn (string $part): string => self::isVoidTypeHint($part) ? 'null' : $part, $convertedHints); } sort($convertedHints); return implode($delimiter, $convertedHints); } }
Save