mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-22 08:25:02 +02:00
Updated Rector to commit f7e99868356cf76b167e1010d5f9b3694202596e
f7e9986835
[PHP 8.0] Add downgrade for str_starts_with() (#126)
This commit is contained in:
parent
56b8376664
commit
fff9179119
@ -37,5 +37,6 @@ return static function (\RectorPrefix20210530\Symfony\Component\DependencyInject
|
||||
$services->set(\Rector\DowngradePhp80\Rector\ClassConstFetch\DowngradeClassOnObjectToGetClassRector::class);
|
||||
$services->set(\Rector\DowngradePhp80\Rector\NullsafeMethodCall\DowngradeNullsafeToTernaryOperatorRector::class);
|
||||
$services->set(\Rector\DowngradePhp80\Rector\ClassMethod\DowngradeTrailingCommasInParamUseRector::class);
|
||||
$services->set(\Rector\DowngradePhp80\Rector\Class_\DowngradeAttributeToAnnotationRector::class);
|
||||
$services->set(\Rector\DowngradePhp80\Rector\FuncCall\DowngradeStrStartsWithRector::class);
|
||||
$services->set(\Rector\DowngradePhp80\Rector\FuncCall\DowngradeStrEndsWithRector::class);
|
||||
};
|
||||
|
@ -84,7 +84,7 @@ final class ClassAnnotationMatcher
|
||||
return $useUse->name->toString();
|
||||
}
|
||||
$unaliasedShortClass = \RectorPrefix20210530\Nette\Utils\Strings::substring($tag, \RectorPrefix20210530\Nette\Utils\Strings::length($useUse->alias->toString()));
|
||||
if (\str_starts_with($unaliasedShortClass, '\\')) {
|
||||
if (\strncmp($unaliasedShortClass, '\\', \strlen('\\')) === 0) {
|
||||
return $useUse->name . $unaliasedShortClass;
|
||||
}
|
||||
return $useUse->name . '\\' . $unaliasedShortClass;
|
||||
|
@ -21,8 +21,9 @@ final class AnnotationExtractor
|
||||
if (!\is_string($docComment)) {
|
||||
return null;
|
||||
}
|
||||
// @see https://regex101.com/r/oYGaWU/1
|
||||
$pattern = '#' . \preg_quote($annotation, '#') . '\\s+(?<content>.*?)$#m';
|
||||
// @see https://3v4l.org/ouYfB
|
||||
// uses 'r?\n' instead of '$' because windows compat
|
||||
$pattern = '#' . \preg_quote($annotation, '#') . '\\s+(?<content>.*?)\\r?\\n#m';
|
||||
$matches = \RectorPrefix20210530\Nette\Utils\Strings::match($docComment, $pattern);
|
||||
return $matches['content'] ?? null;
|
||||
}
|
||||
|
@ -22,10 +22,10 @@ final class CommentRemover
|
||||
$this->commentRemovingNodeTraverser = $commentRemovingNodeTraverser;
|
||||
}
|
||||
/**
|
||||
* @param Node[]|Node|null $node
|
||||
* @return Node[]|null
|
||||
* @return mixed[]|null
|
||||
* @param mixed[]|\PhpParser\Node|null $node
|
||||
*/
|
||||
public function removeFromNode($node) : ?array
|
||||
public function removeFromNode($node)
|
||||
{
|
||||
if ($node === null) {
|
||||
return null;
|
||||
|
@ -69,7 +69,7 @@ final class XmlFileFormatter implements \Rector\FileFormatter\Contract\Formatter
|
||||
$output = '';
|
||||
$this->depth = 0;
|
||||
$parts = $this->getXmlParts($xml);
|
||||
if (\str_starts_with($parts[0], '<?xml')) {
|
||||
if (\strncmp($parts[0], '<?xml', \strlen('<?xml')) === 0) {
|
||||
$output = \array_shift($parts) . \PHP_EOL;
|
||||
}
|
||||
foreach ($parts as $part) {
|
||||
|
@ -116,6 +116,6 @@ final class Indent
|
||||
}
|
||||
private function startsWithSpace() : bool
|
||||
{
|
||||
return \str_starts_with($this->string, ' ');
|
||||
return \strncmp($this->string, ' ', \strlen(' ')) === 0;
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ final class AddedFileWithNodesFactory
|
||||
}
|
||||
// is already in the right group
|
||||
$currentNamespaceName = $currentNamespace->name->toString();
|
||||
if (\str_ends_with($currentNamespaceName, '\\' . $desiredGroupName)) {
|
||||
if (\substr_compare($currentNamespaceName, '\\' . $desiredGroupName, -\strlen('\\' . $desiredGroupName)) === 0) {
|
||||
return null;
|
||||
}
|
||||
$oldClassName = $currentNamespaceName . '\\' . $this->fileInfoDeletionAnalyzer->clearNameFromTestingPrefix($oldFileInfo->getBasenameWithoutSuffix());
|
||||
|
@ -269,7 +269,7 @@ final class NodeRepository
|
||||
{
|
||||
$classNodes = [];
|
||||
foreach ($this->parsedNodeCollector->getClasses() as $className => $classNode) {
|
||||
if (!\str_ends_with($className, $suffix)) {
|
||||
if (\substr_compare($className, $suffix, -\strlen($suffix)) !== 0) {
|
||||
continue;
|
||||
}
|
||||
$classNodes[] = $classNode;
|
||||
|
@ -114,7 +114,7 @@ final class ParsedNodeCollector
|
||||
public function findByShortName(string $shortName) : ?\PhpParser\Node\Stmt\Class_
|
||||
{
|
||||
foreach ($this->classes as $className => $classNode) {
|
||||
if (\str_ends_with($className, '\\' . $shortName)) {
|
||||
if (\substr_compare($className, '\\' . $shortName, -\strlen('\\' . $shortName)) === 0) {
|
||||
return $classNode;
|
||||
}
|
||||
}
|
||||
|
@ -43,12 +43,12 @@ final class NodeRemover
|
||||
$this->rectorChangeCollector->notifyNodeFileInfo($node);
|
||||
}
|
||||
/**
|
||||
* @param Class_|ClassMethod|Function_ $nodeWithStatements
|
||||
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $nodeWithStatements
|
||||
*/
|
||||
public function removeNodeFromStatements(\PhpParser\Node $nodeWithStatements, \PhpParser\Node $nodeToRemove) : void
|
||||
public function removeNodeFromStatements($nodeWithStatements, \PhpParser\Node $toBeRemovedNode) : void
|
||||
{
|
||||
foreach ((array) $nodeWithStatements->stmts as $key => $stmt) {
|
||||
if ($nodeToRemove !== $stmt) {
|
||||
if ($toBeRemovedNode !== $stmt) {
|
||||
continue;
|
||||
}
|
||||
unset($nodeWithStatements->stmts[$key]);
|
||||
|
@ -6,7 +6,6 @@ namespace Rector\NodeTypeResolver\PHPStan\Scope;
|
||||
use RectorPrefix20210530\Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use PhpParser\NodeTraverser;
|
||||
@ -141,9 +140,9 @@ final class PHPStanNodeScopeResolver
|
||||
$nodeTraverser->traverse($nodes);
|
||||
}
|
||||
/**
|
||||
* @param Class_|Interface_ $classLike
|
||||
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Interface_ $classLike
|
||||
*/
|
||||
private function resolveClassOrInterfaceScope(\PhpParser\Node\Stmt\ClassLike $classLike, \PHPStan\Analyser\Scope $scope) : \PHPStan\Analyser\Scope
|
||||
private function resolveClassOrInterfaceScope($classLike, \PHPStan\Analyser\Scope $scope) : \PHPStan\Analyser\Scope
|
||||
{
|
||||
$className = $this->resolveClassName($classLike);
|
||||
// is anonymous class? - not possible to enter it since PHPStan 0.12.33, see https://github.com/phpstan/phpstan-src/commit/e87fb0ec26f9c8552bbeef26a868b1e5d8185e91
|
||||
@ -184,9 +183,9 @@ final class PHPStanNodeScopeResolver
|
||||
$this->changedFilesDetector->addFileWithDependencies($smartFileInfo, $dependentFiles);
|
||||
}
|
||||
/**
|
||||
* @param Class_|Interface_|Trait_ $classLike
|
||||
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Interface_|\PhpParser\Node\Stmt\Trait_ $classLike
|
||||
*/
|
||||
private function resolveClassName(\PhpParser\Node\Stmt\ClassLike $classLike) : string
|
||||
private function resolveClassName($classLike) : string
|
||||
{
|
||||
if (\property_exists($classLike, 'namespacedName')) {
|
||||
return (string) $classLike->namespacedName;
|
||||
|
@ -69,7 +69,7 @@ final class UnderscoreRenamePhpDocNodeVisitor extends \RectorPrefix20210530\Symp
|
||||
if (!$staticType instanceof \PHPStan\Type\ObjectType) {
|
||||
return \true;
|
||||
}
|
||||
if (!\str_starts_with($staticType->getClassName(), $pseudoNamespaceToNamespace->getNamespacePrefix())) {
|
||||
if (\strncmp($staticType->getClassName(), $pseudoNamespaceToNamespace->getNamespacePrefix(), \strlen($pseudoNamespaceToNamespace->getNamespacePrefix())) !== 0) {
|
||||
return \true;
|
||||
}
|
||||
// excluded?
|
||||
|
@ -3,10 +3,9 @@
|
||||
declare (strict_types=1);
|
||||
namespace Rector\PHPStanStaticTypeMapper;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\UnionType as PhpParserUnionType;
|
||||
use PhpParser\Node\UnionType;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\Core\Exception\NotImplementedYetException;
|
||||
@ -35,9 +34,9 @@ final class PHPStanStaticTypeMapper
|
||||
throw new \Rector\Core\Exception\NotImplementedYetException(__METHOD__ . ' for ' . \get_class($type));
|
||||
}
|
||||
/**
|
||||
* @return Name|NullableType|PhpParserUnionType|null
|
||||
* @return \PhpParser\Node\Name|\PhpParser\Node\NullableType|\PhpParser\Node\UnionType|null
|
||||
*/
|
||||
public function mapToPhpParserNode(\PHPStan\Type\Type $type, ?string $kind = null) : ?\PhpParser\Node
|
||||
public function mapToPhpParserNode(\PHPStan\Type\Type $type, ?string $kind = null)
|
||||
{
|
||||
foreach ($this->typeMappers as $typeMapper) {
|
||||
if (!\is_a($type, $typeMapper->getNodeClass(), \true)) {
|
||||
|
@ -146,9 +146,9 @@ final class UnionTypeMapper implements \Rector\PHPStanStaticTypeMapper\Contract\
|
||||
return $unionTypeAnalysis->hasArray();
|
||||
}
|
||||
/**
|
||||
* @return Name|NullableType|null
|
||||
* @return \PhpParser\Node\Name|\PhpParser\Node\NullableType|null
|
||||
*/
|
||||
private function matchArrayTypes(\PHPStan\Type\UnionType $unionType) : ?\PhpParser\Node
|
||||
private function matchArrayTypes(\PHPStan\Type\UnionType $unionType)
|
||||
{
|
||||
$unionTypeAnalysis = $this->unionTypeAnalyzer->analyseForNullableAndIterable($unionType);
|
||||
if (!$unionTypeAnalysis instanceof \Rector\PHPStanStaticTypeMapper\ValueObject\UnionTypeAnalysis) {
|
||||
|
@ -40,6 +40,6 @@ final class FullyQualifiedNodeMapper implements \Rector\StaticTypeMapper\Contrac
|
||||
if ($originalName === $fullyQualifiedName) {
|
||||
return \false;
|
||||
}
|
||||
return !\str_ends_with($fullyQualifiedName, '\\' . $originalName);
|
||||
return \substr_compare($fullyQualifiedName, '\\' . $originalName, -\strlen('\\' . $originalName)) !== 0;
|
||||
}
|
||||
}
|
||||
|
@ -128,9 +128,9 @@ CODE_SAMPLE
|
||||
return $this->isObjectType($classLike, $objectType);
|
||||
}
|
||||
/**
|
||||
* @param ClassMethod|MethodCall|StaticCall $node
|
||||
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall $node
|
||||
*/
|
||||
private function processPositionWithDefaultValues(\PhpParser\Node $node, \Rector\Arguments\ValueObject\ArgumentAdder $argumentAdder) : void
|
||||
private function processPositionWithDefaultValues($node, \Rector\Arguments\ValueObject\ArgumentAdder $argumentAdder) : void
|
||||
{
|
||||
if ($this->shouldSkipParameter($node, $argumentAdder)) {
|
||||
return;
|
||||
|
@ -167,7 +167,7 @@ CODE_SAMPLE
|
||||
return \false;
|
||||
}
|
||||
foreach ($this->suffixes as $suffix) {
|
||||
if (\str_ends_with($className, $suffix)) {
|
||||
if (\substr_compare($className, $suffix, -\strlen($suffix)) === 0) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
@ -176,7 +176,7 @@ CODE_SAMPLE
|
||||
private function isKnownServiceType(string $className) : bool
|
||||
{
|
||||
foreach (self::COMMON_SERVICE_SUFFIXES as $commonServiceSuffix) {
|
||||
if (\str_ends_with($className, $commonServiceSuffix)) {
|
||||
if (\substr_compare($className, $commonServiceSuffix, -\strlen($commonServiceSuffix)) === 0) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
|
@ -63,15 +63,15 @@ CODE_SAMPLE
|
||||
/** @var string $includeValue */
|
||||
$includeValue = $this->valueResolver->getValue($node->expr);
|
||||
// skip phar
|
||||
if (\str_starts_with($includeValue, 'phar://')) {
|
||||
if (\strncmp($includeValue, 'phar://', \strlen('phar://')) === 0) {
|
||||
return null;
|
||||
}
|
||||
// skip absolute paths
|
||||
if (\str_starts_with($includeValue, '/')) {
|
||||
if (\strncmp($includeValue, '/', \strlen('/')) === 0) {
|
||||
return null;
|
||||
}
|
||||
// add preslash to string
|
||||
if (\str_starts_with($includeValue, './')) {
|
||||
if (\strncmp($includeValue, './', \strlen('./')) === 0) {
|
||||
$node->expr->value = \RectorPrefix20210530\Nette\Utils\Strings::substring($includeValue, 1);
|
||||
} else {
|
||||
$node->expr->value = '/' . $includeValue;
|
||||
|
@ -32,7 +32,7 @@ final class AliasClassNameImportSkipVoter implements \Rector\CodingStyle\Contrac
|
||||
foreach ($aliasedUses as $aliasedUse) {
|
||||
$aliasedUseLowered = \strtolower($aliasedUse);
|
||||
// its aliased, we cannot just rename it
|
||||
if (\str_ends_with($aliasedUseLowered, '\\' . $fullyQualifiedObjectType->getShortNameLowered())) {
|
||||
if (\substr_compare($aliasedUseLowered, '\\' . $fullyQualifiedObjectType->getShortNameLowered(), -\strlen('\\' . $fullyQualifiedObjectType->getShortNameLowered())) === 0) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ final class ClassNaming
|
||||
return \lcfirst($shortName);
|
||||
}
|
||||
/**
|
||||
* @param string|Name|Identifier|ClassLike $name
|
||||
* @param string|\PhpParser\Node\Name|\PhpParser\Node\Identifier|\PhpParser\Node\Stmt\ClassLike $name
|
||||
*/
|
||||
public function getShortName($name) : string
|
||||
{
|
||||
@ -69,7 +69,7 @@ final class ClassNaming
|
||||
}
|
||||
public function replaceSuffix(string $content, string $oldSuffix, string $newSuffix) : string
|
||||
{
|
||||
if (!\str_ends_with($content, $oldSuffix)) {
|
||||
if (\substr_compare($content, $oldSuffix, -\strlen($oldSuffix)) !== 0) {
|
||||
return $content . $newSuffix;
|
||||
}
|
||||
$contentWithoutOldSuffix = \RectorPrefix20210530\Nette\Utils\Strings::substring($content, 0, -\RectorPrefix20210530\Nette\Utils\Strings::length($oldSuffix));
|
||||
|
@ -13,6 +13,7 @@ use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\TraitUse;
|
||||
use PhpParser\Node\UnionType;
|
||||
use Rector\CodingStyle\ValueObject\NameAndParent;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
final class NameRenamer
|
||||
@ -54,6 +55,9 @@ final class NameRenamer
|
||||
if ($parentNode instanceof \PhpParser\Node\Expr\StaticCall) {
|
||||
$this->renameStaticCall($lastName, $parentNode);
|
||||
}
|
||||
if ($parentNode instanceof \PhpParser\Node\UnionType) {
|
||||
$this->renameUnionType($lastName, $parentNode, $usedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -98,6 +102,18 @@ final class NameRenamer
|
||||
}
|
||||
$param->type = new \PhpParser\Node\Name($lastName);
|
||||
}
|
||||
private function renameUnionType(string $lastName, \PhpParser\Node\UnionType $unionType, \PhpParser\Node $usedNameNode) : void
|
||||
{
|
||||
foreach ($unionType->types as $key => $unionedType) {
|
||||
if (!$this->nodeNameResolver->areNamesEqual($unionedType, $usedNameNode)) {
|
||||
continue;
|
||||
}
|
||||
if (!$unionedType instanceof \PhpParser\Node\Name) {
|
||||
continue;
|
||||
}
|
||||
$unionType->types[$key] = new \PhpParser\Node\Name($lastName);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param Name|Identifier $usedNameNode
|
||||
*/
|
||||
|
@ -122,7 +122,7 @@ CODE_SAMPLE
|
||||
$docContent = $this->getDocContent($node);
|
||||
// normalize content
|
||||
// starts with "/*", instead of "/**"
|
||||
if (\str_starts_with($docContent, '/* ')) {
|
||||
if (\strncmp($docContent, '/* ', \strlen('/* ')) === 0) {
|
||||
$docContent = \RectorPrefix20210530\Nette\Utils\Strings::replace($docContent, self::SINGLE_ASTERISK_COMMENT_START_REGEX, '/** ');
|
||||
}
|
||||
// $value is first, instead of type is first
|
||||
|
@ -64,7 +64,7 @@ CODE_SAMPLE
|
||||
}
|
||||
private function isRefactorableStringPath(\PhpParser\Node\Scalar\String_ $string) : bool
|
||||
{
|
||||
return !\str_starts_with($string->value, 'phar://');
|
||||
return \strncmp($string->value, 'phar://', \strlen('phar://')) !== 0;
|
||||
}
|
||||
private function prefixWithDir(\PhpParser\Node\Scalar\String_ $string) : \PhpParser\Node\Expr\BinaryOp\Concat
|
||||
{
|
||||
@ -77,14 +77,14 @@ CODE_SAMPLE
|
||||
*/
|
||||
private function removeExtraDotSlash(\PhpParser\Node\Scalar\String_ $string) : void
|
||||
{
|
||||
if (!\str_starts_with($string->value, './')) {
|
||||
if (\strncmp($string->value, './', \strlen('./')) !== 0) {
|
||||
return;
|
||||
}
|
||||
$string->value = \RectorPrefix20210530\Nette\Utils\Strings::replace($string->value, '#^\\.\\/#', '/');
|
||||
}
|
||||
private function prependSlashIfMissing(\PhpParser\Node\Scalar\String_ $string) : void
|
||||
{
|
||||
if (\str_starts_with($string->value, '/')) {
|
||||
if (\strncmp($string->value, '/', \strlen('/')) === 0) {
|
||||
return;
|
||||
}
|
||||
$string->value = '/' . $string->value;
|
||||
|
@ -101,7 +101,7 @@ CODE_SAMPLE
|
||||
if ($className === null) {
|
||||
return \false;
|
||||
}
|
||||
if (!\str_ends_with($className, 'Controller')) {
|
||||
if (\substr_compare($className, 'Controller', -\strlen('Controller')) !== 0) {
|
||||
return \false;
|
||||
}
|
||||
$classMethod = $variable->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::METHOD_NODE);
|
||||
|
@ -119,7 +119,7 @@ CODE_SAMPLE
|
||||
return \true;
|
||||
}
|
||||
foreach (self::FILES_TO_INCLUDE as $fileToInclude) {
|
||||
if (\str_ends_with($fileInfo->getRealPath(), $fileToInclude)) {
|
||||
if (\substr_compare($fileInfo->getRealPath(), $fileToInclude, -\strlen($fileToInclude)) === 0) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\DowngradePhp80\Rector\FuncCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\BinaryOp\Identical;
|
||||
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
|
||||
use PhpParser\Node\Expr\BooleanNot;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\UnaryMinus;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @changelog https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions
|
||||
*
|
||||
* @see \Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrEndsWithRector\DowngradeStrEndsWithRectorTest
|
||||
*/
|
||||
final class DowngradeStrEndsWithRector extends \Rector\Core\Rector\AbstractRector
|
||||
{
|
||||
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
|
||||
{
|
||||
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Downgrade str_ends_with() to strncmp() version', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample('str_ends_with($haystack, $needle);', '"" === $needle || ("" !== $haystack && 0 === substr_compare($haystack, $needle, -\\strlen($needle)));')]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [\PhpParser\Node\Expr\FuncCall::class, \PhpParser\Node\Expr\BooleanNot::class];
|
||||
}
|
||||
/**
|
||||
* @param FuncCall|BooleanNot $node
|
||||
*/
|
||||
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
|
||||
{
|
||||
if ($node instanceof \PhpParser\Node\Expr\FuncCall && $this->isName($node->name, 'str_ends_with')) {
|
||||
return new \PhpParser\Node\Expr\BinaryOp\Identical($this->createSubstrCompareFuncCall($node), new \PhpParser\Node\Scalar\LNumber(0));
|
||||
}
|
||||
if ($node instanceof \PhpParser\Node\Expr\BooleanNot) {
|
||||
$funcCall = $node->expr;
|
||||
if ($funcCall instanceof \PhpParser\Node\Expr\FuncCall && $this->isName($funcCall->name, 'str_ends_with')) {
|
||||
return new \PhpParser\Node\Expr\BinaryOp\NotIdentical($this->createSubstrCompareFuncCall($funcCall), new \PhpParser\Node\Scalar\LNumber(0));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private function createSubstrCompareFuncCall(\PhpParser\Node\Expr\FuncCall $funcCall) : \PhpParser\Node\Expr\FuncCall
|
||||
{
|
||||
$args = $funcCall->args;
|
||||
$strlenFuncCall = $this->createStrlenFuncCall($funcCall->args[1]->value);
|
||||
$args[] = new \PhpParser\Node\Arg(new \PhpParser\Node\Expr\UnaryMinus($strlenFuncCall));
|
||||
return new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('substr_compare'), $args);
|
||||
}
|
||||
private function createStrlenFuncCall(\PhpParser\Node\Expr $expr) : \PhpParser\Node\Expr\FuncCall
|
||||
{
|
||||
return new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('strlen'), [new \PhpParser\Node\Arg($expr)]);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\DowngradePhp80\Rector\FuncCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\BinaryOp\Identical;
|
||||
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
|
||||
use PhpParser\Node\Expr\BooleanNot;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @changelog https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions
|
||||
*
|
||||
* @see \Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrStartsWithRector\DowngradeStrStartsWithRectorTest
|
||||
*/
|
||||
final class DowngradeStrStartsWithRector extends \Rector\Core\Rector\AbstractRector
|
||||
{
|
||||
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
|
||||
{
|
||||
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Downgrade str_starts_with() to strncmp() version', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample('str_starts_with($haystack, $needle);', 'strncmp($haystack, $needle, strlen($needle)) === 0;')]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [\PhpParser\Node\Expr\FuncCall::class, \PhpParser\Node\Expr\BooleanNot::class];
|
||||
}
|
||||
/**
|
||||
* @param FuncCall|BooleanNot $node
|
||||
*/
|
||||
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
|
||||
{
|
||||
if ($node instanceof \PhpParser\Node\Expr\FuncCall && $this->isName($node, 'str_starts_with')) {
|
||||
return $this->createIdentical($node);
|
||||
}
|
||||
if ($node instanceof \PhpParser\Node\Expr\BooleanNot) {
|
||||
$negatedCall = $node->expr;
|
||||
if ($negatedCall instanceof \PhpParser\Node\Expr\FuncCall && $this->isName($negatedCall, 'str_starts_with')) {
|
||||
return $this->createNotIdenticalStrncmpFuncCall($negatedCall);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private function createIdentical(\PhpParser\Node\Expr\FuncCall $funcCall) : \PhpParser\Node\Expr\BinaryOp\Identical
|
||||
{
|
||||
$strlenFuncCall = $this->createStrlenFuncCall($funcCall);
|
||||
$strncmpFuncCall = $this->createStrncmpFuncCall($funcCall, $strlenFuncCall);
|
||||
return new \PhpParser\Node\Expr\BinaryOp\Identical($strncmpFuncCall, new \PhpParser\Node\Scalar\LNumber(0));
|
||||
}
|
||||
private function createNotIdenticalStrncmpFuncCall(\PhpParser\Node\Expr\FuncCall $funcCall) : \PhpParser\Node\Expr\BinaryOp\NotIdentical
|
||||
{
|
||||
$strlenFuncCall = $this->createStrlenFuncCall($funcCall);
|
||||
$strncmpFuncCall = $this->createStrncmpFuncCall($funcCall, $strlenFuncCall);
|
||||
return new \PhpParser\Node\Expr\BinaryOp\NotIdentical($strncmpFuncCall, new \PhpParser\Node\Scalar\LNumber(0));
|
||||
}
|
||||
private function createStrlenFuncCall(\PhpParser\Node\Expr\FuncCall $funcCall) : \PhpParser\Node\Expr\FuncCall
|
||||
{
|
||||
return new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('strlen'), [$funcCall->args[1]]);
|
||||
}
|
||||
private function createStrncmpFuncCall(\PhpParser\Node\Expr\FuncCall $funcCall, \PhpParser\Node\Expr\FuncCall $strlenFuncCall) : \PhpParser\Node\Expr\FuncCall
|
||||
{
|
||||
$newArgs = $funcCall->args;
|
||||
$newArgs[] = new \PhpParser\Node\Arg($strlenFuncCall);
|
||||
return new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('strncmp'), $newArgs);
|
||||
}
|
||||
}
|
@ -74,7 +74,7 @@ final class BreakingVariableRenameGuard
|
||||
{
|
||||
// is the suffix? → also accepted
|
||||
$expectedNameCamelCase = \ucfirst($expectedName);
|
||||
if (\str_ends_with($currentName, $expectedNameCamelCase)) {
|
||||
if (\substr_compare($currentName, $expectedNameCamelCase, -\strlen($expectedNameCamelCase)) === 0) {
|
||||
return \true;
|
||||
}
|
||||
if ($this->conflictingNameResolver->checkNameIsInFunctionLike($expectedName, $functionLike)) {
|
||||
@ -101,7 +101,7 @@ final class BreakingVariableRenameGuard
|
||||
{
|
||||
// is the suffix? → also accepted
|
||||
$expectedNameCamelCase = \ucfirst($expectedName);
|
||||
if (\str_ends_with($currentName, $expectedNameCamelCase)) {
|
||||
if (\substr_compare($currentName, $expectedNameCamelCase, -\strlen($expectedNameCamelCase)) === 0) {
|
||||
return \true;
|
||||
}
|
||||
$conflictingNames = $this->conflictingNameResolver->resolveConflictingVariableNamesForParam($classMethod);
|
||||
|
@ -14,7 +14,7 @@ final class NamespaceMatcher
|
||||
\krsort($oldToNewNamespace);
|
||||
/** @var string $oldNamespace */
|
||||
foreach ($oldToNewNamespace as $oldNamespace => $newNamespace) {
|
||||
if (\str_starts_with($name, $oldNamespace)) {
|
||||
if (\strncmp($name, $oldNamespace, \strlen($oldNamespace)) === 0) {
|
||||
return new \Rector\Renaming\ValueObject\RenamedNamespace($name, $oldNamespace, $newNamespace);
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ final class PropertyNaming
|
||||
private function removePrefixesAndSuffixes(string $shortClassName) : string
|
||||
{
|
||||
// is SomeInterface
|
||||
if (\str_ends_with($shortClassName, self::INTERFACE)) {
|
||||
if (\substr_compare($shortClassName, self::INTERFACE, -\strlen(self::INTERFACE)) === 0) {
|
||||
$shortClassName = \RectorPrefix20210530\Nette\Utils\Strings::substring($shortClassName, 0, -\strlen(self::INTERFACE));
|
||||
}
|
||||
// is ISomeClass
|
||||
@ -177,7 +177,7 @@ final class PropertyNaming
|
||||
$shortClassName = \RectorPrefix20210530\Nette\Utils\Strings::substring($shortClassName, 1);
|
||||
}
|
||||
// is AbstractClass
|
||||
if (\str_starts_with($shortClassName, 'Abstract')) {
|
||||
if (\strncmp($shortClassName, 'Abstract', \strlen('Abstract')) === 0) {
|
||||
$shortClassName = \RectorPrefix20210530\Nette\Utils\Strings::substring($shortClassName, \strlen('Abstract'));
|
||||
}
|
||||
return $shortClassName;
|
||||
@ -220,7 +220,7 @@ final class PropertyNaming
|
||||
}
|
||||
/** @var string $lastNamePart */
|
||||
$lastNamePart = \RectorPrefix20210530\Nette\Utils\Strings::after($fqn, '\\', -1);
|
||||
if (\str_ends_with($lastNamePart, self::INTERFACE)) {
|
||||
if (\substr_compare($lastNamePart, self::INTERFACE, -\strlen(self::INTERFACE)) === 0) {
|
||||
return \RectorPrefix20210530\Nette\Utils\Strings::substring($lastNamePart, 0, -\strlen(self::INTERFACE));
|
||||
}
|
||||
return $lastNamePart;
|
||||
@ -235,7 +235,7 @@ final class PropertyNaming
|
||||
if (\RectorPrefix20210530\Nette\Utils\Strings::match($shortName, self::I_PREFIX_REGEX)) {
|
||||
return \RectorPrefix20210530\Nette\Utils\Strings::substring($shortName, 1);
|
||||
}
|
||||
if (\str_ends_with($shortName, self::INTERFACE)) {
|
||||
if (\substr_compare($shortName, self::INTERFACE, -\strlen(self::INTERFACE)) === 0) {
|
||||
return \RectorPrefix20210530\Nette\Utils\Strings::substring($shortName, -\strlen(self::INTERFACE));
|
||||
}
|
||||
return $shortName;
|
||||
@ -270,7 +270,7 @@ final class PropertyNaming
|
||||
if (\strlen($shortClassName) <= 3) {
|
||||
return \false;
|
||||
}
|
||||
if (!\str_starts_with($shortClassName, 'I')) {
|
||||
if (\strncmp($shortClassName, 'I', \strlen('I')) !== 0) {
|
||||
return \false;
|
||||
}
|
||||
if (!\ctype_upper($shortClassName[1])) {
|
||||
|
@ -3,7 +3,6 @@
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Order;
|
||||
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassConst;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
@ -27,10 +26,10 @@ final class StmtVisibilitySorter
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
/**
|
||||
* @param Class_|Trait_ $classLike
|
||||
* @return string[]
|
||||
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Trait_ $classLike
|
||||
*/
|
||||
public function sortProperties(\PhpParser\Node\Stmt\ClassLike $classLike) : array
|
||||
public function sortProperties($classLike) : array
|
||||
{
|
||||
$propertyRankeables = [];
|
||||
foreach ($classLike->stmts as $position => $propertyStmt) {
|
||||
@ -60,10 +59,10 @@ final class StmtVisibilitySorter
|
||||
return $this->sortByRanksAndGetNames($classMethodsRankeables);
|
||||
}
|
||||
/**
|
||||
* @param Class_|Interface_ $classLike
|
||||
* @return string[]
|
||||
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Interface_ $classLike
|
||||
*/
|
||||
public function sortConstants(\PhpParser\Node\Stmt\ClassLike $classLike) : array
|
||||
public function sortConstants($classLike) : array
|
||||
{
|
||||
$classConstsRankeables = [];
|
||||
foreach ($classLike->stmts as $position => $constantStmt) {
|
||||
@ -77,9 +76,9 @@ final class StmtVisibilitySorter
|
||||
return $this->sortByRanksAndGetNames($classConstsRankeables);
|
||||
}
|
||||
/**
|
||||
* @param ClassMethod|Property|ClassConst $stmt
|
||||
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst $stmt
|
||||
*/
|
||||
private function getVisibilityLevelOrder(\PhpParser\Node\Stmt $stmt) : int
|
||||
private function getVisibilityLevelOrder($stmt) : int
|
||||
{
|
||||
if ($stmt->isPrivate()) {
|
||||
return 2;
|
||||
|
@ -27,7 +27,7 @@ final class PSR4NamespaceMatcher implements \Rector\PSR4\Contract\PSR4AutoloadNa
|
||||
$paths = \is_array($path) ? $path : [$path];
|
||||
foreach ($paths as $path) {
|
||||
$path = \rtrim($path, '/');
|
||||
if (!\str_starts_with($smartFileInfo->getRelativeDirectoryPath(), $path)) {
|
||||
if (\strncmp($smartFileInfo->getRelativeDirectoryPath(), $path, \strlen($path)) !== 0) {
|
||||
continue;
|
||||
}
|
||||
$expectedNamespace = $namespace . $this->resolveExtraNamespace($smartFileInfo, $path);
|
||||
|
@ -54,7 +54,7 @@ final class FileRelocationResolver
|
||||
*/
|
||||
private function resolveRootDirectory(\Symplify\SmartFileSystem\SmartFileInfo $smartFileInfo, string $suffixName, array $groupNames) : string
|
||||
{
|
||||
if (\str_starts_with($smartFileInfo->getRealPathDirectory(), '/tmp')) {
|
||||
if (\strncmp($smartFileInfo->getRealPathDirectory(), '/tmp', \strlen('/tmp')) === 0) {
|
||||
$currentTraversePath = $smartFileInfo->getRealPathDirectory();
|
||||
} else {
|
||||
$currentTraversePath = $smartFileInfo->getRelativeDirectoryPath();
|
||||
|
@ -100,7 +100,7 @@ final class EregToPregMatchRector extends \Rector\Core\Rector\AbstractRector
|
||||
*/
|
||||
private function processSplitLimitArgument(\PhpParser\Node\Expr\FuncCall $funcCall, string $functionName) : void
|
||||
{
|
||||
if (!\str_starts_with($functionName, 'split')) {
|
||||
if (\strncmp($functionName, 'split', \strlen('split')) !== 0) {
|
||||
return;
|
||||
}
|
||||
// 3rd argument - $limit, 0 → 1
|
||||
|
@ -50,7 +50,7 @@ final class PhpSpecRenaming
|
||||
// from PhpSpec to PHPUnit method naming convention
|
||||
$classMethodName = $this->stringFormatConverter->underscoreAndHyphenToCamelCase($classMethodName);
|
||||
// add "test", so PHPUnit runs the method
|
||||
if (!\str_starts_with($classMethodName, 'test')) {
|
||||
if (\strncmp($classMethodName, 'test', \strlen('test')) !== 0) {
|
||||
$classMethodName = 'test' . \ucfirst($classMethodName);
|
||||
}
|
||||
$classMethod->name = new \PhpParser\Node\Identifier($classMethodName);
|
||||
|
@ -4,7 +4,6 @@ declare (strict_types=1);
|
||||
namespace Rector\Removing\NodeManipulator;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticPropertyFetch;
|
||||
@ -95,10 +94,10 @@ final class ComplexNodeRemover
|
||||
$this->nodeRemover->removeNode($property);
|
||||
}
|
||||
/**
|
||||
* @param StaticPropertyFetch|PropertyFetch $expr
|
||||
* @param string[] $classMethodNamesToSkip
|
||||
* @param \PhpParser\Node\Expr\StaticPropertyFetch|\PhpParser\Node\Expr\PropertyFetch $expr
|
||||
*/
|
||||
private function shouldSkipPropertyForClassMethod(\PhpParser\Node\Expr $expr, array $classMethodNamesToSkip) : bool
|
||||
private function shouldSkipPropertyForClassMethod($expr, array $classMethodNamesToSkip) : bool
|
||||
{
|
||||
$classMethodNode = $expr->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::METHOD_NODE);
|
||||
if (!$classMethodNode instanceof \PhpParser\Node\Stmt\ClassMethod) {
|
||||
@ -108,9 +107,9 @@ final class ComplexNodeRemover
|
||||
return \in_array($classMethodName, $classMethodNamesToSkip, \true);
|
||||
}
|
||||
/**
|
||||
* @param PropertyFetch|StaticPropertyFetch $expr
|
||||
* @param \PhpParser\Node\Expr\PropertyFetch|\PhpParser\Node\Expr\StaticPropertyFetch $expr
|
||||
*/
|
||||
private function resolveAssign(\PhpParser\Node\Expr $expr) : ?\PhpParser\Node\Expr\Assign
|
||||
private function resolveAssign($expr) : ?\PhpParser\Node\Expr\Assign
|
||||
{
|
||||
$assign = $expr->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE);
|
||||
while ($assign !== null && !$assign instanceof \PhpParser\Node\Expr\Assign) {
|
||||
|
@ -145,7 +145,7 @@ final class ObjectTypeSpecifier
|
||||
private function matchPartialNamespaceObjectType(\PHPStan\Type\ObjectType $objectType, \PhpParser\Node\Stmt\UseUse $useUse) : ?\Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType
|
||||
{
|
||||
// partial namespace
|
||||
if (!\str_starts_with($objectType->getClassName(), $useUse->name->getLast() . '\\')) {
|
||||
if (\strncmp($objectType->getClassName(), $useUse->name->getLast() . '\\', \strlen($useUse->name->getLast() . '\\')) !== 0) {
|
||||
return null;
|
||||
}
|
||||
$classNameWithoutLastUsePart = \RectorPrefix20210530\Nette\Utils\Strings::after($objectType->getClassName(), '\\', 1);
|
||||
|
@ -112,7 +112,7 @@ final class NonInformativeReturnTagRemover
|
||||
if (!$nullabledReturnTagValueNode instanceof \PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode) {
|
||||
return;
|
||||
}
|
||||
if (!\str_ends_with($nullabledReturnType->getClassName(), $nullabledReturnTagValueNode->name)) {
|
||||
if (\substr_compare($nullabledReturnType->getClassName(), $nullabledReturnTagValueNode->name, -\strlen($nullabledReturnTagValueNode->name)) !== 0) {
|
||||
return;
|
||||
}
|
||||
$phpDocInfo->removeByType(\PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode::class);
|
||||
@ -184,6 +184,6 @@ final class NonInformativeReturnTagRemover
|
||||
if ('\\' . $className === $returnTagValueNodeType) {
|
||||
return \true;
|
||||
}
|
||||
return \str_ends_with($className, '\\' . $returnTagValueNodeType);
|
||||
return \substr_compare($className, '\\' . $returnTagValueNodeType, -\strlen('\\' . $returnTagValueNodeType)) === 0;
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\NullableType;
|
||||
@ -121,9 +122,9 @@ CODE_SAMPLE
|
||||
return $node;
|
||||
}
|
||||
/**
|
||||
* @param ClassMethod|Function_|Closure $node
|
||||
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure $node
|
||||
*/
|
||||
private function isSkipped(\PhpParser\Node $node) : bool
|
||||
private function isSkipped($node) : bool
|
||||
{
|
||||
if (!$this->phpVersionProvider->isAtLeastPhpVersion(\Rector\Core\ValueObject\PhpVersionFeature::SCALAR_TYPES)) {
|
||||
return \true;
|
||||
@ -135,7 +136,7 @@ CODE_SAMPLE
|
||||
}
|
||||
/**
|
||||
* @param Return_[] $returns
|
||||
* @return array<Name|NullableType|UnionType>
|
||||
* @return array<Identifier|Name|NullableType|PhpParserUnionType>
|
||||
*/
|
||||
private function collectStrictReturnTypes(array $returns) : array
|
||||
{
|
||||
@ -186,9 +187,9 @@ CODE_SAMPLE
|
||||
return $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($returnType);
|
||||
}
|
||||
/**
|
||||
* @return Name|NullableType|PhpParserUnionType|null
|
||||
* @return \PhpParser\Node\Name|\PhpParser\Node\NullableType|PhpParserUnionType|null
|
||||
*/
|
||||
private function resolveFuncCallReturnNode(\PhpParser\Node\Expr\FuncCall $funcCall) : ?\PhpParser\Node
|
||||
private function resolveFuncCallReturnNode(\PhpParser\Node\Expr\FuncCall $funcCall)
|
||||
{
|
||||
$returnType = $this->reflectionTypeResolver->resolveFuncCallReturnType($funcCall);
|
||||
if (!$returnType instanceof \PHPStan\Type\Type) {
|
||||
@ -197,10 +198,10 @@ CODE_SAMPLE
|
||||
return $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($returnType);
|
||||
}
|
||||
/**
|
||||
* @param ClassMethod|Function_|Closure $functionLike
|
||||
* @param Name|NullableType|PhpParserUnionType $returnedStrictTypeNode
|
||||
* @param \PhpParser\Node\Identifier|\PhpParser\Node\Name|\PhpParser\Node\NullableType|PhpParserUnionType $returnedStrictTypeNode
|
||||
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure $functionLike
|
||||
*/
|
||||
private function refactorSingleReturnType(\PhpParser\Node\Stmt\Return_ $return, \PhpParser\Node $returnedStrictTypeNode, \PhpParser\Node\FunctionLike $functionLike) : \PhpParser\Node\FunctionLike
|
||||
private function refactorSingleReturnType(\PhpParser\Node\Stmt\Return_ $return, $returnedStrictTypeNode, $functionLike) : \PhpParser\Node\FunctionLike
|
||||
{
|
||||
$resolvedType = $this->nodeTypeResolver->resolve($return);
|
||||
if ($resolvedType instanceof \PHPStan\Type\UnionType) {
|
||||
|
@ -180,7 +180,7 @@ final class ConstructorPropertyTypeInferer implements \Rector\TypeDeclaration\Co
|
||||
return null;
|
||||
}
|
||||
// if the FQN has different ending than the original, it was aliased and we need to return the alias
|
||||
if (!\str_ends_with($fullyQualifiedName, '\\' . $originalName->toString())) {
|
||||
if (\substr_compare($fullyQualifiedName, '\\' . $originalName->toString(), -\strlen('\\' . $originalName->toString())) !== 0) {
|
||||
$className = $originalName->toString();
|
||||
if ($this->reflectionProvider->hasClass($className)) {
|
||||
return new \Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType($className);
|
||||
|
@ -81,7 +81,7 @@ final class DoctrineRelationPropertyTypeInferer implements \Rector\TypeDeclarati
|
||||
if ($targetEntity === null) {
|
||||
return new \PHPStan\Type\MixedType();
|
||||
}
|
||||
if (\str_ends_with($targetEntity, '::class')) {
|
||||
if (\substr_compare($targetEntity, '::class', -\strlen('::class')) === 0) {
|
||||
$targetEntity = \RectorPrefix20210530\Nette\Utils\Strings::before($targetEntity, '::class');
|
||||
}
|
||||
// resolve to FQN
|
||||
|
@ -91,9 +91,9 @@ final class YieldNodesReturnTypeInferer implements \Rector\TypeDeclaration\Contr
|
||||
return $yieldNodes;
|
||||
}
|
||||
/**
|
||||
* @param Yield_|YieldFrom $yieldExpr
|
||||
* @param \PhpParser\Node\Expr\Yield_|\PhpParser\Node\Expr\YieldFrom $yieldExpr
|
||||
*/
|
||||
private function resolveYieldValue(\PhpParser\Node\Expr $yieldExpr) : ?\PhpParser\Node\Expr
|
||||
private function resolveYieldValue($yieldExpr) : ?\PhpParser\Node\Expr
|
||||
{
|
||||
if ($yieldExpr instanceof \PhpParser\Node\Expr\Yield_) {
|
||||
return $yieldExpr->value;
|
||||
|
@ -16,11 +16,11 @@ final class VersionResolver
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = '223ad8fca8280a298b02dce0226b91269e3b3535';
|
||||
public const PACKAGE_VERSION = 'f7e99868356cf76b167e1010d5f9b3694202596e';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2021-05-30 09:42:32';
|
||||
public const RELEASE_DATE = '2021-05-30 10:02:38';
|
||||
public static function resolvePackageVersion() : string
|
||||
{
|
||||
$process = new \RectorPrefix20210530\Symfony\Component\Process\Process(['git', 'log', '--pretty="%H"', '-n1', 'HEAD'], __DIR__);
|
||||
|
@ -180,7 +180,7 @@ final class ProcessCommand extends \RectorPrefix20210530\Symfony\Component\Conso
|
||||
foreach ($files as $file) {
|
||||
$smartFileInfo = $file->getSmartFileInfo();
|
||||
$pathName = $smartFileInfo->getPathname();
|
||||
if (\str_ends_with($pathName, '.php')) {
|
||||
if (\substr_compare($pathName, '.php', -\strlen('.php')) === 0) {
|
||||
$filePaths[] = $pathName;
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ final class VerifyRectorServiceExistsCompilerPass implements \RectorPrefix202105
|
||||
if ($class === null) {
|
||||
continue;
|
||||
}
|
||||
if (!\str_ends_with($class, 'Rector')) {
|
||||
if (\substr_compare($class, 'Rector', -\strlen('Rector')) !== 0) {
|
||||
continue;
|
||||
}
|
||||
if (!\is_a($class, \Rector\Core\Contract\Rector\RectorInterface::class, \true)) {
|
||||
|
@ -35,7 +35,7 @@ final class PhpFilesFinder
|
||||
$phpFileInfos = $this->filesFinder->findInDirectoriesAndFiles($paths, $this->configuration->getFileExtensions());
|
||||
// filter out non-PHP php files, e.g. blade templates in Laravel
|
||||
$phpFileInfos = \array_filter($phpFileInfos, function (\Symplify\SmartFileSystem\SmartFileInfo $smartFileInfo) : bool {
|
||||
return !\str_ends_with($smartFileInfo->getPathname(), '.blade.php');
|
||||
return \substr_compare($smartFileInfo->getPathname(), '.blade.php', -\strlen('.blade.php')) !== 0;
|
||||
});
|
||||
return $this->cachedFileInfoFilterAndReporter->filterFileInfos($phpFileInfos);
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ final class VariableManipulator
|
||||
{
|
||||
/** @var string $className */
|
||||
$className = $variable->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CLASS_NAME);
|
||||
if (!\str_ends_with($className, 'Test')) {
|
||||
if (\substr_compare($className, 'Test', -\strlen('Test')) !== 0) {
|
||||
return \false;
|
||||
}
|
||||
return $this->nodeNameResolver->isName($variable, 'expect*');
|
||||
|
@ -37,7 +37,7 @@ final class NonPhpFileProcessor implements \Rector\Core\Contract\Processor\FileP
|
||||
$smartFileInfo = $file->getSmartFileInfo();
|
||||
// bug in path extension
|
||||
foreach ($this->getSupportedFileExtensions() as $supportedFileExtension) {
|
||||
if (\str_ends_with($smartFileInfo->getPathname(), '.' . $supportedFileExtension)) {
|
||||
if (\substr_compare($smartFileInfo->getPathname(), '.' . $supportedFileExtension, -\strlen('.' . $supportedFileExtension)) === 0) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,8 @@ final class PhpVersionProvider
|
||||
}
|
||||
public function provide() : int
|
||||
{
|
||||
/** @var int|null $phpVersionFeatures */
|
||||
$phpVersionFeatures = $this->parameterProvider->provideParameter(\Rector\Core\Configuration\Option::PHP_VERSION_FEATURES);
|
||||
if ($phpVersionFeatures !== null) {
|
||||
$phpVersionFeatures = $this->parameterProvider->provideIntParameter(\Rector\Core\Configuration\Option::PHP_VERSION_FEATURES);
|
||||
if ($phpVersionFeatures > 0) {
|
||||
return $phpVersionFeatures;
|
||||
}
|
||||
// for tests
|
||||
|
@ -438,11 +438,11 @@ abstract class AbstractRector extends \PhpParser\NodeVisitorAbstract implements
|
||||
$this->nodeRemover->removeNode($node);
|
||||
}
|
||||
/**
|
||||
* @param Class_|ClassMethod|Function_ $nodeWithStatements
|
||||
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $nodeWithStatements
|
||||
*/
|
||||
protected function removeNodeFromStatements(\PhpParser\Node $nodeWithStatements, \PhpParser\Node $nodeToRemove) : void
|
||||
protected function removeNodeFromStatements($nodeWithStatements, \PhpParser\Node $toBeRemovedNode) : void
|
||||
{
|
||||
$this->nodeRemover->removeNodeFromStatements($nodeWithStatements, $nodeToRemove);
|
||||
$this->nodeRemover->removeNodeFromStatements($nodeWithStatements, $toBeRemovedNode);
|
||||
}
|
||||
/**
|
||||
* @param Node[] $nodes
|
||||
|
@ -44,7 +44,7 @@ final class StaticRectorStrings
|
||||
public static function removePrefixes(string $value, array $prefixesToRemove) : string
|
||||
{
|
||||
foreach ($prefixesToRemove as $prefixToRemove) {
|
||||
if (\str_starts_with($value, $prefixToRemove)) {
|
||||
if (\strncmp($value, $prefixToRemove, \strlen($prefixToRemove)) === 0) {
|
||||
$value = \RectorPrefix20210530\Nette\Utils\Strings::substring($value, \RectorPrefix20210530\Nette\Utils\Strings::length($prefixToRemove));
|
||||
}
|
||||
}
|
||||
@ -56,7 +56,7 @@ final class StaticRectorStrings
|
||||
public static function removeSuffixes(string $value, array $suffixesToRemove) : string
|
||||
{
|
||||
foreach ($suffixesToRemove as $suffixToRemove) {
|
||||
if (\str_ends_with($value, $suffixToRemove)) {
|
||||
if (\substr_compare($value, $suffixToRemove, -\strlen($suffixToRemove)) === 0) {
|
||||
$value = \RectorPrefix20210530\Nette\Utils\Strings::substring($value, 0, -\RectorPrefix20210530\Nette\Utils\Strings::length($suffixToRemove));
|
||||
}
|
||||
}
|
||||
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
@ -4,4 +4,4 @@
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367::getLoader();
|
||||
return ComposerAutoloaderInit97f4f51a084df5e9a8869348edb2e8da::getLoader();
|
||||
|
2
vendor/composer/autoload_classmap.php
vendored
2
vendor/composer/autoload_classmap.php
vendored
@ -2129,6 +2129,8 @@ return array(
|
||||
'Rector\\DowngradePhp80\\Rector\\Class_\\DowngradePropertyPromotionRector' => $baseDir . '/rules/DowngradePhp80/Rector/Class_/DowngradePropertyPromotionRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\Expression\\DowngradeMatchToSwitchRector' => $baseDir . '/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FuncCall\\DowngradeStrContainsRector' => $baseDir . '/rules/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FuncCall\\DowngradeStrEndsWithRector' => $baseDir . '/rules/DowngradePhp80/Rector/FuncCall/DowngradeStrEndsWithRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FuncCall\\DowngradeStrStartsWithRector' => $baseDir . '/rules/DowngradePhp80/Rector/FuncCall/DowngradeStrStartsWithRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FunctionLike\\DowngradeMixedTypeDeclarationRector' => $baseDir . '/rules/DowngradePhp80/Rector/FunctionLike/DowngradeMixedTypeDeclarationRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FunctionLike\\DowngradeUnionTypeDeclarationRector' => $baseDir . '/rules/DowngradePhp80/Rector/FunctionLike/DowngradeUnionTypeDeclarationRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\NullsafeMethodCall\\DowngradeNullsafeToTernaryOperatorRector' => $baseDir . '/rules/DowngradePhp80/Rector/NullsafeMethodCall/DowngradeNullsafeToTernaryOperatorRector.php',
|
||||
|
14
vendor/composer/autoload_real.php
vendored
14
vendor/composer/autoload_real.php
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367
|
||||
class ComposerAutoloaderInit97f4f51a084df5e9a8869348edb2e8da
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
@ -22,15 +22,15 @@ class ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInit97f4f51a084df5e9a8869348edb2e8da', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit97f4f51a084df5e9a8869348edb2e8da', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitb3c3f0bc3b39123d94667d6b15846367::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit97f4f51a084df5e9a8869348edb2e8da::getInitializer($loader));
|
||||
} else {
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
@ -42,19 +42,19 @@ class ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367
|
||||
$loader->register(true);
|
||||
|
||||
if ($useStaticLoader) {
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInitb3c3f0bc3b39123d94667d6b15846367::$files;
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInit97f4f51a084df5e9a8869348edb2e8da::$files;
|
||||
} else {
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
}
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequireb3c3f0bc3b39123d94667d6b15846367($fileIdentifier, $file);
|
||||
composerRequire97f4f51a084df5e9a8869348edb2e8da($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequireb3c3f0bc3b39123d94667d6b15846367($fileIdentifier, $file)
|
||||
function composerRequire97f4f51a084df5e9a8869348edb2e8da($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
require $file;
|
||||
|
10
vendor/composer/autoload_static.php
vendored
10
vendor/composer/autoload_static.php
vendored
@ -4,7 +4,7 @@
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInitb3c3f0bc3b39123d94667d6b15846367
|
||||
class ComposerStaticInit97f4f51a084df5e9a8869348edb2e8da
|
||||
{
|
||||
public static $files = array (
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
@ -2478,6 +2478,8 @@ class ComposerStaticInitb3c3f0bc3b39123d94667d6b15846367
|
||||
'Rector\\DowngradePhp80\\Rector\\Class_\\DowngradePropertyPromotionRector' => __DIR__ . '/../..' . '/rules/DowngradePhp80/Rector/Class_/DowngradePropertyPromotionRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\Expression\\DowngradeMatchToSwitchRector' => __DIR__ . '/../..' . '/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FuncCall\\DowngradeStrContainsRector' => __DIR__ . '/../..' . '/rules/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FuncCall\\DowngradeStrEndsWithRector' => __DIR__ . '/../..' . '/rules/DowngradePhp80/Rector/FuncCall/DowngradeStrEndsWithRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FuncCall\\DowngradeStrStartsWithRector' => __DIR__ . '/../..' . '/rules/DowngradePhp80/Rector/FuncCall/DowngradeStrStartsWithRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FunctionLike\\DowngradeMixedTypeDeclarationRector' => __DIR__ . '/../..' . '/rules/DowngradePhp80/Rector/FunctionLike/DowngradeMixedTypeDeclarationRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\FunctionLike\\DowngradeUnionTypeDeclarationRector' => __DIR__ . '/../..' . '/rules/DowngradePhp80/Rector/FunctionLike/DowngradeUnionTypeDeclarationRector.php',
|
||||
'Rector\\DowngradePhp80\\Rector\\NullsafeMethodCall\\DowngradeNullsafeToTernaryOperatorRector' => __DIR__ . '/../..' . '/rules/DowngradePhp80/Rector/NullsafeMethodCall/DowngradeNullsafeToTernaryOperatorRector.php',
|
||||
@ -3824,9 +3826,9 @@ class ComposerStaticInitb3c3f0bc3b39123d94667d6b15846367
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitb3c3f0bc3b39123d94667d6b15846367::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitb3c3f0bc3b39123d94667d6b15846367::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInitb3c3f0bc3b39123d94667d6b15846367::$classMap;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit97f4f51a084df5e9a8869348edb2e8da::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit97f4f51a084df5e9a8869348edb2e8da::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit97f4f51a084df5e9a8869348edb2e8da::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
10
vendor/scoper-autoload.php
vendored
10
vendor/scoper-autoload.php
vendored
@ -21,8 +21,8 @@ if (!class_exists('SomeTestCase', false) && !interface_exists('SomeTestCase', fa
|
||||
if (!class_exists('CheckoutEntityFactory', false) && !interface_exists('CheckoutEntityFactory', false) && !trait_exists('CheckoutEntityFactory', false)) {
|
||||
spl_autoload_call('RectorPrefix20210530\CheckoutEntityFactory');
|
||||
}
|
||||
if (!class_exists('ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367', false) && !interface_exists('ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367', false) && !trait_exists('ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367', false)) {
|
||||
spl_autoload_call('RectorPrefix20210530\ComposerAutoloaderInitb3c3f0bc3b39123d94667d6b15846367');
|
||||
if (!class_exists('ComposerAutoloaderInit97f4f51a084df5e9a8869348edb2e8da', false) && !interface_exists('ComposerAutoloaderInit97f4f51a084df5e9a8869348edb2e8da', false) && !trait_exists('ComposerAutoloaderInit97f4f51a084df5e9a8869348edb2e8da', false)) {
|
||||
spl_autoload_call('RectorPrefix20210530\ComposerAutoloaderInit97f4f51a084df5e9a8869348edb2e8da');
|
||||
}
|
||||
if (!class_exists('Doctrine\Inflector\Inflector', false) && !interface_exists('Doctrine\Inflector\Inflector', false) && !trait_exists('Doctrine\Inflector\Inflector', false)) {
|
||||
spl_autoload_call('RectorPrefix20210530\Doctrine\Inflector\Inflector');
|
||||
@ -3320,9 +3320,9 @@ if (!function_exists('print_node')) {
|
||||
return \RectorPrefix20210530\print_node(...func_get_args());
|
||||
}
|
||||
}
|
||||
if (!function_exists('composerRequireb3c3f0bc3b39123d94667d6b15846367')) {
|
||||
function composerRequireb3c3f0bc3b39123d94667d6b15846367() {
|
||||
return \RectorPrefix20210530\composerRequireb3c3f0bc3b39123d94667d6b15846367(...func_get_args());
|
||||
if (!function_exists('composerRequire97f4f51a084df5e9a8869348edb2e8da')) {
|
||||
function composerRequire97f4f51a084df5e9a8869348edb2e8da() {
|
||||
return \RectorPrefix20210530\composerRequire97f4f51a084df5e9a8869348edb2e8da(...func_get_args());
|
||||
}
|
||||
}
|
||||
if (!function_exists('parseArgs')) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user