�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!PK<4]eBRector/Property/RestoreDefaultNullToNullableTypePropertyRector.phpnu[constructorAssignDetector = $constructorAssignDetector; $this->phpDocInfoFactory = $phpDocInfoFactory; } public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('Add null default to properties with PHP 7.4 property nullable type', [new CodeSample(<<<'CODE_SAMPLE' class SomeClass { public ?string $name; } CODE_SAMPLE , <<<'CODE_SAMPLE' class SomeClass { public ?string $name = null; } CODE_SAMPLE )]); } /** * @return array> */ public function getNodeTypes() : array { return [Class_::class]; } /** * @param Class_ $node */ public function refactor(Node $node) : ?Node { if ($this->isReadonlyClass($node)) { return null; } $hasChanged = \false; foreach ($node->getProperties() as $property) { if ($this->shouldSkip($property, $node)) { continue; } $onlyProperty = $property->props[0]; $onlyProperty->default = $this->nodeFactory->createNull(); $hasChanged = \true; } if ($hasChanged) { return $node; } return null; } public function provideMinPhpVersion() : int { return PhpVersionFeature::TYPED_PROPERTIES; } private function shouldSkip(Property $property, Class_ $class) : bool { if ($property->type === null) { return \true; } if (\count($property->props) > 1) { return \true; } $onlyProperty = $property->props[0]; if ($onlyProperty->default instanceof Expr) { return \true; } if ($this->isReadonlyProperty($property)) { return \true; } if (!$this->nodeTypeResolver->isNullableType($property)) { return \true; } // is variable assigned in constructor $propertyName = $this->getName($property); return $this->constructorAssignDetector->isPropertyAssigned($class, $propertyName); } private function isReadonlyProperty(Property $property) : bool { // native readonly if ($property->isReadonly()) { return \true; } // @readonly annotation $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property); return $phpDocInfo->hasByName('@readonly'); } private function isReadonlyClass(Class_ $class) : bool { // native readonly if ($class->isReadonly()) { return \true; } // @immutable annotation $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($class); return $phpDocInfo->hasByName('@immutable'); } } PK<4]z]߇.Rector/Assign/NullCoalescingOperatorRector.phpnu[> */ public function getNodeTypes() : array { return [Assign::class]; } /** * @param Assign $node */ public function refactor(Node $node) : ?AssignCoalesce { if (!$node->expr instanceof Coalesce) { return null; } if (!$this->nodeComparator->areNodesEqual($node->var, $node->expr->left)) { return null; } return new AssignCoalesce($node->var, $node->expr->right); } public function provideMinPhpVersion() : int { return PhpVersionFeature::NULL_COALESCE_ASSIGN; } } PK<4]DD2Rector/Ternary/ParenthesizeNestedTernaryRector.phpnu[parenthesizedNestedTernaryAnalyzer = $parenthesizedNestedTernaryAnalyzer; } public function provideMinPhpVersion() : int { return PhpVersionFeature::DEPRECATE_NESTED_TERNARY; } public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('Add parentheses to nested ternary', [new CodeSample(<<<'CODE_SAMPLE' $value = $a ? $b : $a ?: null; CODE_SAMPLE , <<<'CODE_SAMPLE' $value = ($a ? $b : $a) ?: null; CODE_SAMPLE )]); } /** * @return array> */ public function getNodeTypes() : array { return [Ternary::class]; } /** * @param Ternary $node */ public function refactor(Node $node) : ?Node { if ($node->cond instanceof Ternary || $node->else instanceof Ternary) { if ($this->parenthesizedNestedTernaryAnalyzer->isParenthesized($this->file, $node)) { return null; } // re-print with brackets $node->setAttribute(AttributeKey::ORIGINAL_NODE, null); return $node; } return null; } } PK<4]L`k+8Rector/FuncCall/RestoreIncludePathToIniRestoreRector.phpnu[> */ public function getNodeTypes() : array { return [FuncCall::class]; } /** * @param FuncCall $node */ public function refactor(Node $node) : ?FuncCall { if (!$this->isName($node, 'restore_include_path')) { return null; } if ($node->isFirstClassCallable()) { return null; } $node->name = new Name('ini_restore'); $node->args[0] = new Arg(new String_('include_path')); return $node; } } PK<4]k9ä 3Rector/FuncCall/MoneyFormatToNumberFormatRector.phpnu[argsAnalyzer = $argsAnalyzer; $this->valueResolver = $valueResolver; } public function provideMinPhpVersion() : int { return PhpVersionFeature::DEPRECATE_MONEY_FORMAT; } public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('Change money_format() to equivalent number_format()', [new CodeSample(<<<'CODE_SAMPLE' $value = money_format('%i', $value); CODE_SAMPLE , <<<'CODE_SAMPLE' $value = number_format(round($value, 2, PHP_ROUND_HALF_ODD), 2, '.', ''); CODE_SAMPLE )]); } /** * @return array> */ public function getNodeTypes() : array { return [FuncCall::class]; } /** * @param FuncCall $node */ public function refactor(Node $node) : ?FuncCall { if (!$this->isName($node, 'money_format')) { return null; } if ($node->isFirstClassCallable()) { return null; } $args = $node->getArgs(); if ($this->argsAnalyzer->hasNamedArg($args)) { return null; } $formatValue = $args[0]->value; if (!$this->valueResolver->isValue($formatValue, '%i')) { return null; } return $this->warpInNumberFormatFuncCall($node, $args[1]->value); } private function warpInNumberFormatFuncCall(FuncCall $funcCall, Expr $expr) : FuncCall { $roundFuncCall = $this->nodeFactory->createFuncCall('round', [$expr, new LNumber(2), new ConstFetch(new Name('PHP_ROUND_HALF_ODD'))]); $funcCall->name = new Name('number_format'); $funcCall->args = [new Arg($roundFuncCall), new Arg(new LNumber(2)), new Arg(new String_('.')), new Arg(new String_(''))]; return $funcCall; } } PK<4]̀.Rector/FuncCall/HebrevcToNl2brHebrevRector.phpnu[> */ public function getNodeTypes() : array { return [FuncCall::class]; } /** * @param FuncCall $node */ public function refactor(Node $node) : ?FuncCall { if (!$this->isName($node, 'hebrevc')) { return null; } if ($node->isFirstClassCallable()) { return null; } $node->name = new Name('hebrev'); return new FuncCall(new Name('nl2br'), [new Arg($node)]); } } PK<4]Y,,/Rector/FuncCall/FilterVarToAddSlashesRector.phpnu[> */ public function getNodeTypes() : array { return [FuncCall::class]; } /** * @param FuncCall $node */ public function refactor(Node $node) : ?Node { if (!$this->isName($node, 'filter_var')) { return null; } if (!isset($node->args[1])) { return null; } if (!$node->args[1] instanceof Arg) { return null; } if (!$this->isName($node->args[1]->value, 'FILTER_SANITIZE_MAGIC_QUOTES')) { return null; } $node->name = new Name('addslashes'); unset($node->args[1]); return $node; } } PK<4]M2Rector/FuncCall/ArrayKeyExistsOnPropertyRector.phpnu[> */ public function getNodeTypes() : array { return [FuncCall::class]; } /** * @param FuncCall $node */ public function refactor(Node $node) : ?Node { if (!$this->isName($node, 'array_key_exists')) { return null; } if (!isset($node->args[1])) { return null; } if (!$node->args[1] instanceof Arg) { return null; } $firstArgStaticType = $this->getType($node->args[1]->value); if (!$firstArgStaticType instanceof ObjectType) { return null; } $node->name = new Name('property_exists'); $node->args = \array_reverse($node->args); return $node; } } PK<4]6Sii;Rector/FuncCall/MbStrrposEncodingArgumentPositionRector.phpnu[> */ public function getNodeTypes() : array { return [FuncCall::class]; } /** * @param FuncCall $node */ public function refactor(Node $node) : ?Node { if (!$this->isName($node, 'mb_strrpos')) { return null; } if (!isset($node->args[2])) { return null; } if (isset($node->args[3])) { return null; } if (!$node->args[2] instanceof Arg) { return null; } $secondArgType = $this->getType($node->args[2]->value); if ($secondArgType->isInteger()->yes()) { return null; } $node->args[3] = $node->args[2]; $node->args[2] = new Arg(new LNumber(0)); return $node; } } PK<4]^m|O /Rector/Closure/ClosureToArrowFunctionRector.phpnu[closureArrowFunctionAnalyzer = $closureArrowFunctionAnalyzer; } public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('Change closure to arrow function', [new CodeSample(<<<'CODE_SAMPLE' class SomeClass { public function run($meetups) { return array_filter($meetups, function (Meetup $meetup) { return is_object($meetup); }); } } CODE_SAMPLE , <<<'CODE_SAMPLE' class SomeClass { public function run($meetups) { return array_filter($meetups, fn(Meetup $meetup) => is_object($meetup)); } } CODE_SAMPLE )]); } /** * @return array> */ public function getNodeTypes() : array { return [Closure::class]; } /** * @param Closure $node */ public function refactor(Node $node) : ?Node { $returnExpr = $this->closureArrowFunctionAnalyzer->matchArrowFunctionExpr($node); if (!$returnExpr instanceof Expr) { return null; } $arrowFunction = new ArrowFunction(['params' => $node->params, 'returnType' => $node->returnType, 'byRef' => $node->byRef, 'expr' => $returnExpr]); if ($node->static) { $arrowFunction->static = \true; } $comments = $node->stmts[0]->getAttribute(AttributeKey::COMMENTS) ?? []; if ($comments !== []) { $this->mirrorComments($arrowFunction->expr, $node->stmts[0]); $arrowFunction->setAttribute(AttributeKey::COMMENT_CLOSURE_RETURN_MIRRORED, \true); } return $arrowFunction; } public function provideMinPhpVersion() : int { return PhpVersionFeature::ARROW_FUNCTION; } } PK<4] 8  +Rector/Double/RealToFloatTypeCastRector.phpnu[> */ public function getNodeTypes() : array { return [Double::class]; } /** * @param Double $node */ public function refactor(Node $node) : ?Node { $kind = $node->getAttribute(AttributeKey::KIND); if ($kind !== Double::KIND_REAL) { return null; } $node->setAttribute(AttributeKey::KIND, Double::KIND_FLOAT); $node->setAttribute(AttributeKey::ORIGINAL_NODE, null); return $node; } } PK<4]G>Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.phpnu[> */ public function getNodeTypes() : array { return [ArrayDimFetch::class]; } /** * @param ArrayDimFetch $node */ public function refactor(Node $node) : ?Node { if (!$this->isFollowedByCurlyBracket($this->file, $node)) { return null; } // re-draw the ArrayDimFetch to use [] bracket $node->setAttribute(AttributeKey::ORIGINAL_NODE, null); return $node; } private function isFollowedByCurlyBracket(File $file, ArrayDimFetch $arrayDimFetch) : bool { $oldTokens = $file->getOldTokens(); $endTokenPost = $arrayDimFetch->getEndTokenPos(); if (isset($oldTokens[$endTokenPost]) && $oldTokens[$endTokenPost] === '}') { $startTokenPost = $arrayDimFetch->getStartTokenPos(); return !(isset($oldTokens[$startTokenPost][1]) && $oldTokens[$startTokenPost][1] === '${'); } return \false; } } PK<4]Y04Rector/LNumber/AddLiteralSeparatorToNumberRector.phpnu[limitValue = $limitValue; } public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('Add "_" as thousands separator in numbers for higher or equals to limitValue config', [new ConfiguredCodeSample(<<<'CODE_SAMPLE' class SomeClass { public function run() { $int = 500000; $float = 1000500.001; } } CODE_SAMPLE , <<<'CODE_SAMPLE' class SomeClass { public function run() { $int = 500_000; $float = 1_000_500.001; } } CODE_SAMPLE , [self::LIMIT_VALUE => 1000000])]); } /** * @return array> */ public function getNodeTypes() : array { return [LNumber::class, DNumber::class]; } /** * @param LNumber|DNumber $node */ public function refactor(Node $node) : ?Node { $rawValue = $node->getAttribute(AttributeKey::RAW_VALUE); if ($this->shouldSkip($node, $rawValue)) { return null; } if (\strpos((string) $rawValue, '.') !== \false) { [$mainPart, $decimalPart] = \explode('.', (string) $rawValue); $chunks = $this->strSplitNegative($mainPart, self::GROUP_SIZE); $literalSeparatedNumber = \implode('_', $chunks) . '.' . $decimalPart; } else { $chunks = $this->strSplitNegative($rawValue, self::GROUP_SIZE); $literalSeparatedNumber = \implode('_', $chunks); // PHP converts: (string) 1000.0 -> "1000"! if (\is_float($node->value)) { $literalSeparatedNumber .= '.0'; } } // this cannot be integer directly to $node->value, as PHPStan sees it as error type // @see https://github.com/rectorphp/rector/issues/7454 $node->setAttribute(AttributeKey::RAW_VALUE, $literalSeparatedNumber); $node->setAttribute(AttributeKey::REPRINT_RAW_VALUE, \true); $node->setAttribute(AttributeKey::ORIGINAL_NODE, null); return $node; } public function provideMinPhpVersion() : int { return PhpVersionFeature::LITERAL_SEPARATOR; } /** * @param \PhpParser\Node\Scalar\LNumber|\PhpParser\Node\Scalar\DNumber $node * @param mixed $rawValue */ private function shouldSkip($node, $rawValue) : bool { if (!\is_string($rawValue)) { return \true; } // already contains separator if (\strpos($rawValue, '_') !== \false) { return \true; } if ($node->value < $this->limitValue) { return \true; } $kind = $node->getAttribute(AttributeKey::KIND); if (\in_array($kind, [LNumber::KIND_BIN, LNumber::KIND_OCT, LNumber::KIND_HEX], \true)) { return \true; } // e+/e- if (StringUtils::isMatch($rawValue, '#e#i')) { return \true; } // too short return \strlen($rawValue) <= self::GROUP_SIZE; } /** * @return string[] */ private function strSplitNegative(string $string, int $length) : array { $inversed = \strrev($string); /** @var string[] $chunks */ $chunks = \str_split($inversed, $length); $chunks = \array_reverse($chunks); foreach ($chunks as $key => $chunk) { $chunks[$key] = \strrev($chunk); } return $chunks; } } PK<4] 6Rector/StaticCall/ExportToReflectionFunctionRector.phpnu[valueResolver = $valueResolver; } public function provideMinPhpVersion() : int { return PhpVersionFeature::EXPORT_TO_REFLECTION_FUNCTION; } public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('Change export() to ReflectionFunction alternatives', [new CodeSample(<<<'CODE_SAMPLE' $reflectionFunction = ReflectionFunction::export('foo'); $reflectionFunctionAsString = ReflectionFunction::export('foo', true); CODE_SAMPLE , <<<'CODE_SAMPLE' $reflectionFunction = new ReflectionFunction('foo'); $reflectionFunctionAsString = (string) new ReflectionFunction('foo'); CODE_SAMPLE )]); } /** * @return array> */ public function getNodeTypes() : array { return [StaticCall::class]; } /** * @param StaticCall $node */ public function refactor(Node $node) : ?Node { if (!$node->class instanceof Name) { return null; } $callerType = $this->nodeTypeResolver->getType($node->class); if (!$callerType->isSuperTypeOf(new ObjectType('ReflectionFunction'))->yes()) { return null; } if (!$this->isName($node->name, 'export')) { return null; } if ($node->isFirstClassCallable()) { return null; } $firstArg = $node->getArgs()[0] ?? null; if (!$firstArg instanceof Arg) { return null; } $new = new New_($node->class, [new Arg($firstArg->value)]); $secondArg = $node->getArgs()[1] ?? null; if (!$secondArg instanceof Arg) { return $new; } if ($this->valueResolver->isTrue($secondArg->value)) { return new String_($new); } return $new; } } PK<4]Q{0Tokenizer/ParenthesizedNestedTernaryAnalyzer.phpnu[getOldTokens(); $startTokenPos = $ternary->getStartTokenPos(); $endTokenPos = $ternary->getEndTokenPos(); $hasOpenParentheses = isset($oldTokens[$startTokenPos]) && $oldTokens[$startTokenPos] === '('; $hasCloseParentheses = isset($oldTokens[$endTokenPos]) && $oldTokens[$endTokenPos] === ')'; return $hasOpenParentheses || $hasCloseParentheses; } } PK<4]ɯLZZ-NodeAnalyzer/ClosureArrowFunctionAnalyzer.phpnu[betterNodeFinder = $betterNodeFinder; $this->nodeComparator = $nodeComparator; $this->arrayChecker = $arrayChecker; } public function matchArrowFunctionExpr(Closure $closure) : ?Expr { if (\count($closure->stmts) !== 1) { return null; } $onlyStmt = $closure->stmts[0]; if (!$onlyStmt instanceof Return_) { return null; } /** @var Return_ $return */ $return = $onlyStmt; if (!$return->expr instanceof Expr) { return null; } if ($this->shouldSkipForUsedReferencedValue($closure)) { return null; } return $return->expr; } private function shouldSkipForUsedReferencedValue(Closure $closure) : bool { $referencedValues = $this->resolveReferencedUseVariablesFromClosure($closure); if ($referencedValues === []) { return \false; } $isFoundInStmt = (bool) $this->betterNodeFinder->findFirstInFunctionLikeScoped($closure, function (Node $node) use($referencedValues) : bool { foreach ($referencedValues as $referencedValue) { if ($this->nodeComparator->areNodesEqual($node, $referencedValue)) { return \true; } } return \false; }); if ($isFoundInStmt) { return \true; } return $this->isFoundInInnerUses($closure, $referencedValues); } /** * @param Variable[] $referencedValues */ private function isFoundInInnerUses(Closure $node, array $referencedValues) : bool { return (bool) $this->betterNodeFinder->findFirstInFunctionLikeScoped($node, function (Node $subNode) use($referencedValues) : bool { if (!$subNode instanceof Closure) { return \false; } foreach ($referencedValues as $referencedValue) { $isFoundInInnerUses = $this->arrayChecker->doesExist($subNode->uses, function (ClosureUse $closureUse) use($referencedValue) : bool { return $closureUse->byRef && $this->nodeComparator->areNodesEqual($closureUse->var, $referencedValue); }); if ($isFoundInInnerUses) { return \true; } } return \false; }); } /** * @return Variable[] */ private function resolveReferencedUseVariablesFromClosure(Closure $closure) : array { $referencedValues = []; /** @var ClosureUse $use */ foreach ($closure->uses as $use) { if ($use->byRef) { $referencedValues[] = $use->var; } } return $referencedValues; } } PK<4]ao !Guard/PropertyTypeChangeGuard.phpnu[nodeNameResolver = $nodeNameResolver; $this->propertyAnalyzer = $propertyAnalyzer; $this->propertyManipulator = $propertyManipulator; $this->parentPropertyLookupGuard = $parentPropertyLookupGuard; } public function isLegal(Property $property, ClassReflection $classReflection, bool $inlinePublic = \true, bool $isConstructorPromotion = \false) : bool { if (\count($property->props) > 1) { return \false; } /** * - trait properties are unpredictable based on class context they appear in * - on interface properties as well, as interface not allowed to have property */ if (!$classReflection->isClass()) { return \false; } $propertyName = $this->nodeNameResolver->getName($property); if ($this->propertyManipulator->isUsedByTrait($classReflection, $propertyName)) { return \false; } if ($this->propertyAnalyzer->hasForbiddenType($property)) { return \false; } if ($inlinePublic) { return \true; } if ($property->isPrivate()) { return \true; } if ($isConstructorPromotion) { return \true; } return $this->isSafeProtectedProperty($classReflection, $property); } private function isSafeProtectedProperty(ClassReflection $classReflection, Property $property) : bool { if (!$property->isProtected()) { return \false; } if (!$classReflection->isFinalByKeyword()) { return \false; } return $this->parentPropertyLookupGuard->isLegal($property, $classReflection); } } PK<4]r Guard/MakePropertyTypedGuard.phpnu[propertyTypeChangeGuard = $propertyTypeChangeGuard; } public function isLegal(Property $property, ClassReflection $classReflection, bool $inlinePublic = \true) : bool { if ($property->type !== null) { return \false; } return $this->propertyTypeChangeGuard->isLegal($property, $classReflection, $inlinePublic); } } PK<4]eBRector/Property/RestoreDefaultNullToNullableTypePropertyRector.phpnu[PK<4]z]߇.QRector/Assign/NullCoalescingOperatorRector.phpnu[PK<4]DD26Rector/Ternary/ParenthesizeNestedTernaryRector.phpnu[PK<4]L`k+8Rector/FuncCall/RestoreIncludePathToIniRestoreRector.phpnu[PK<4]k9ä 3 'Rector/FuncCall/MoneyFormatToNumberFormatRector.phpnu[PK<4]̀.3Rector/FuncCall/HebrevcToNl2brHebrevRector.phpnu[PK<4]Y,,/9Rector/FuncCall/FilterVarToAddSlashesRector.phpnu[PK<4]M2 ARector/FuncCall/ArrayKeyExistsOnPropertyRector.phpnu[PK<4]6Sii;{IRector/FuncCall/MbStrrposEncodingArgumentPositionRector.phpnu[PK<4]^m|O /OQRector/Closure/ClosureToArrowFunctionRector.phpnu[PK<4] 8  +`\Rector/Double/RealToFloatTypeCastRector.phpnu[PK<4]G>cRector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.phpnu[PK<4]Y04lRector/LNumber/AddLiteralSeparatorToNumberRector.phpnu[PK<4] 6Rector/StaticCall/ExportToReflectionFunctionRector.phpnu[PK<4]Q{0zTokenizer/ParenthesizedNestedTernaryAnalyzer.phpnu[PK<4]ɯLZZ-NodeAnalyzer/ClosureArrowFunctionAnalyzer.phpnu[PK<4]ao !DGuard/PropertyTypeChangeGuard.phpnu[PK<4]r Guard/MakePropertyTypedGuard.phpnu[PK